SAMD21 Pro Rf LoRa GPIO not working

I have 2 SAMD21 Pro Rf LoRa modules with antennas and the given transmitter receiver sketch is working. I am trying to get a digital on off signal working (specifically D2 on the board) but its not working. The onboard LED on PA13 works but no other (D2, D3, D4, D5, A0, A1, A2, A3, A4) GPIO is working in output mode. I see this problem on both boards so I must be doing something wrong. I am using PlatformIO on VScode but also tried to use Arduino IDE following the sparkfun guide but no luck. Any help is appreciated.

#include <Arduino.h>
#include <SPI.h>
//Radio Head Library:
#include <RH_RF95.h>

// We need to provide the RFM95 module’s chip select and interrupt pins to the
// rf95 instance below.On the SparkFun ProRF those pins are 12 and 6 respectively.
RH_RF95 rf95(12, 6);

int LED = 13; //Status LED is on pin 13

int rs485pin = PIN_PA14;
bool pinState = false;

int packetCounter = 0; //Counts the number of packets sent
long timeSinceLastPacket = 0; //Tracks the time stamp of last packet received

// The broadcast frequency is set to 921.2, but the SADM21 ProRf operates
// anywhere in the range of 902-928MHz in the Americas.
// Europe operates in the frequencies 863-870, center frequency at 868MHz.
// This works but it is unknown how well the radio configures to this frequency:
//float frequency = 864.1;
float frequency = 921.2; //Broadcast frequency

void setup()
{
pinMode(LED, OUTPUT);

pinMode(rs485pin, OUTPUT);
digitalWrite(rs485pin, LOW);
pinState = false;

SerialUSB.begin(9600);
// It may be difficult to read serial messages on startup. The following line
// will wait for serial to be ready before continuing. Comment out if not needed.
while(!SerialUSB);
SerialUSB.println(“RFM Client!”);

//Initialize the Radio.
if (rf95.init() == false){
SerialUSB.println(“Radio Init Failed - Freezing”);
while (1);
}
else{
//An LED inidicator to let us know radio initialization has completed.
SerialUSB.println(“Transmitter up!”);
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
delay(500);
}

// Set frequency
rf95.setFrequency(frequency);

// The default transmitter power is 13dBm, using PA_BOOST.
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm:
// Transmitter power can range from 14-20dbm.
rf95.setTxPower(14, false);

}

void loop()
{
SerialUSB.println(“Sending message”);

//Send a message to the other radio
uint8_t toSend = “Hi there!”;
//sprintf(toSend, “Hi, my counter is: %d”, packetCounter++);
rf95.send(toSend, sizeof(toSend));
rf95.waitPacketSent();

// Now wait for a reply
byte buf[RH_RF95_MAX_MESSAGE_LEN];
byte len = sizeof(buf);

if (rf95.waitAvailableTimeout(2000)) {
// Should be a reply message for us now
if (rf95.recv(buf, &len)) {
SerialUSB.print("Got reply: “);
SerialUSB.println((char*)buf);
//SerialUSB.print(” RSSI: ");
//SerialUSB.print(rf95.lastRssi(), DEC);
}
else {
SerialUSB.println(“Receive failed”);
}
}
else {
SerialUSB.println(“No reply, is the receiver running?”);
}
delay(5000);
if (pinState == false) {
pinState = true;
digitalWrite(rs485pin, HIGH);
digitalWrite(LED, HIGH);
}
else {
pinState = false;
digitalWrite(rs485pin, LOW);
digitalWrite(LED, LOW);
}
}

Please post the Arduino code that demonstrates this, and describe how you determined that this is “not working”.

Please use code tags (select code with mouse and use the <> editor button). You can also edit your previous post to add code tags.

I have had success using the SAMD21 Pro Rf board adapting the example sketches from various lorawan libraries on github, but I have not had any luck getting the GPIO pins to work on the SAMD21 Pro Rf board. Even just a simple sketch without any Lora libraries fails to yield any activity on those pins. Specifically, I have tried connecting a simple steel momentary reset push button using code that I had working on an uno to this board and had no luck whatsoever. The code does compile and uploads to the board, but no activity. The problematic pins include D2, D3, D4, D5 and D9. It would be helpful if someone from sparkfun included an example lora sketch using said pins…here is the barebones code without any lora code:


#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
const int switchPin0 = 5;
char * rtkState = "RTK OFF";
void setup() {
  // put your setup code here, to run once:
  pinMode(switchPin0, INPUT_PULLUP);


  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  byte switchState0 = digitalRead(switchPin0);
  if (switchState0 == LOW){
    if (rtkState == "RTK OFF"){
      rtkState = "RTK ON";
    }
    else if (rtkState == "RTK ON"){
      rtkState = "RTK OFF";
    }
  }
  Serial.println(rtkState);
}

You might need to declare their PA#'s if using HAL instead of arduino.h?

Here’s a sample sketch (*untested):

// SAMD21 GPIO Test Sketch
#include <Arduino.h>

// Define the pin we want to test
// Note: Use the actual GPIO number, not the Arduino pin number
const int TEST_PIN = PIN_PA15;  // This corresponds to D5 on the SAMD21 Pro RF

// LED pin for visual feedback
const int LED_PIN = LED_BUILTIN;

// Debounce timeout in milliseconds
const unsigned long DEBOUNCE_DELAY = 50;

// Variables for button state tracking
int lastButtonState = HIGH;
int buttonState;
unsigned long lastDebounceTime = 0;
bool ledState = false;

void setup() {
  // Initialize serial communication
  Serial.begin(9600);
  while (!Serial) {
    ; // Wait for serial port to connect
  }
  
  Serial.println("SAMD21 GPIO Test Starting...");
  
  // Configure pins
  pinMode(TEST_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  
  // Print pin configuration
  Serial.print("Test Pin Number: ");
  Serial.println(TEST_PIN);
  Serial.println("Pin configured as INPUT_PULLUP");
}

void loop() {
  // Read the button state (with noise)
  int reading = digitalRead(TEST_PIN);
  
  // If the switch changed, due to noise or pressing
  if (reading != lastButtonState) {
    // Reset the debouncing timer
    lastDebounceTime = millis();
  }
  
  // Check if enough time has passed since the last state change
  if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) {
    // If the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
      
      // Only toggle the LED if the new button state is LOW (pressed)
      if (buttonState == LOW) {
        ledState = !ledState;
        digitalWrite(LED_PIN, ledState);
        
        // Print debug information
        Serial.println("Button Pressed!");
        Serial.print("LED State: ");
        Serial.println(ledState ? "ON" : "OFF");
      }
    }
  }
  
  // Save the reading for next loop
  lastButtonState = reading;
  
  // Print pin state every second for debugging
  static unsigned long lastPrintTime = 0;
  if (millis() - lastPrintTime > 1000) {
    Serial.print("Current Pin State: ");
    Serial.println(digitalRead(TEST_PIN));
    lastPrintTime = millis();
  }
}

Thank you for the response and the example. I do recall declaring the PAs as well and did not have any luck, but I will try that again using that method of declaration. I may have used the wrong PA number for that particular gpio pin. I’ll give it a try and see if that was the issue. Thanks.

I have tried your example, but it does not seem to work. Does the voltage rating of the button itself connected to pin D5 have to be rated for 3v3, or is the voltage rating of the button irrelevant? The button I am using is rated for up to 12V.

I found the issue. I was using Serial.begin instead of SerialUSB.begin … All is well now!