Feather M0 SoftwareSerial RFID Problem

Hey everyone,

Kind of been banging my head against the wall for a few days trying to figure this out. I'm a beginner to Arduino, so if this post is confusing, it's because I'm not sure how to phrase my question (I'm out of my depth, big time).

I'm trying to connect this RFID Reader (https://www.sparkfun.com/products/14066) to a Feather m0 Bluetooth (Adafruit Feather M0 Bluefruit LE : ID 2995 : $29.95 : Adafruit Industries, Unique & fun DIY electronics and kits), and I keep getting this error: "Module failed to respond. Please check wiring."

I had it working perfectly with my Uno, but ran into tons of problems as soon as I tried getting to work with the Feather M0.

The example code that SparkFun provides starts off like this:

#include <SoftwareSerial.h> //Used for transmitting to the device
SoftwareSerial Serial1(2, 3); //RX, TX

Which results in this error: fatal error: SoftwareSerial.h: No such file or directory

It seems like SAMD devices(?) don't support SoftwareSerial.
So I tried making a local copy of SoftwareSerial.h and SoftwareSerial.cpp - and changing a few lines. (see here: SoftwareSerial examples for Arduino M0 will not compile · Issue #234 · arduino/ArduinoCore-samd · GitHub). That didn't appear to work.

After reading through this thread (Arduino Zero - SoftwareSerial library - Arduino Zero - Arduino Forum) and being wildly confused, I tried to follow the instructions here (Creating a new Serial | Using ATSAMD21 SERCOM for more SPI, I2C and Serial ports | Adafruit Learning System) to create(?) a new "Serial" SERCOM on pins 10 and 11. But still got the same error.

I attached a picture of my setup / wiring below.

On top of that, even though I've reread SparkFun's docs several times, I still have no idea what the HW-UART / SW-UART switch does.

I also have no clue where to plug in the jumper cables on the RFID reader.

If anyone could help me with the wiring / programming here, or explain what's going on, that would be incredible.

I've been trying to figure this out for a few days now, and haven't had any luck.

Thanks in advance!

Here's the example code that SparkFun provides:

#include <SoftwareSerial.h> //Used for transmitting to the device

SoftwareSerial softSerial(2, 3); //RX, TX

#include "SparkFun_UHF_RFID_Reader.h" //Library for controlling the M6E Nano module
RFID nano; //Create instance

void setup()
{
  Serial.begin(115200);
  while (!Serial); //Wait for the serial port to come online

  if (setupNano(38400) == false) //Configure nano to run at 38400bps
  {
    Serial.println(F("Module failed to respond. Please check wiring."));
    while (1); //Freeze!
  }

  nano.setRegion(REGION_NORTHAMERICA); //Set to North America

  nano.setReadPower(500); //5.00 dBm. Higher values may caues USB port to brown out
  //Max Read TX Power is 27.00 dBm and may cause temperature-limit throttling

  Serial.println(F("Press a key to begin scanning for tags."));
  while (!Serial.available()); //Wait for user to send a character
  Serial.read(); //Throw away the user's character

  nano.startReading(); //Begin scanning for tags
}

void loop()
{
  if (nano.check() == true) //Check to see if any new data has come in from module
  {
    byte responseType = nano.parseResponse(); //Break response into tag ID, RSSI, frequency, and timestamp

    if (responseType == RESPONSE_IS_KEEPALIVE)
    {
      Serial.println(F("Scanning"));
    }
    else if (responseType == RESPONSE_IS_TAGFOUND)
    {
      //If we have a full record we can pull out the fun bits
      int rssi = nano.getTagRSSI(); //Get the RSSI for this tag read

      long freq = nano.getTagFreq(); //Get the frequency this tag was detected at

      long timeStamp = nano.getTagTimestamp(); //Get the time this was read, (ms) since last keep-alive message

      byte tagEPCBytes = nano.getTagEPCBytes(); //Get the number of bytes of EPC from response

      Serial.print(F(" rssi["));
      Serial.print(rssi);
      Serial.print(F("]"));

      Serial.print(F(" freq["));
      Serial.print(freq);
      Serial.print(F("]"));

      Serial.print(F(" time["));
      Serial.print(timeStamp);
      Serial.print(F("]"));

      //Print EPC bytes, this is a subsection of bytes from the response/msg array
      Serial.print(F(" epc["));
      for (byte x = 0 ; x < tagEPCBytes ; x++)
      {
        if (nano.msg[31 + x] < 0x10) Serial.print(F("0")); //Pretty print
        Serial.print(nano.msg[31 + x], HEX);
        Serial.print(F(" "));
      }
      Serial.print(F("]"));

      Serial.println();
    }
    else if (responseType == ERROR_CORRUPT_RESPONSE)
    {
      Serial.println("Bad CRC");
    }
    else
    {
      //Unknown response
      Serial.print("Unknown error");
    }
  }
}

//Gracefully handles a reader that is already configured and already reading continuously
//Because Stream does not have a .begin() we have to do this outside the library
boolean setupNano(long baudRate)
{
  nano.begin(softSerial); //Tell the library to communicate over software serial port

  //Test to see if we are already connected to a module
  //This would be the case if the Arduino has been reprogrammed and the module has stayed powered
  softSerial.begin(baudRate); //For this test, assume module is already at our desired baud rate
  while(!softSerial); //Wait for port to open

  //About 200ms from power on the module will send its firmware version at 115200. We need to ignore this.
  while(softSerial.available()) softSerial.read();
  
  nano.getVersion();

  if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE)
  {
    //This happens if the baud rate is correct but the module is doing a ccontinuous read
    nano.stopReading();

    Serial.println(F("Module continuously reading. Asking it to stop..."));

    delay(1500);
  }
  else
  {
    //The module did not respond so assume it's just been powered on and communicating at 115200bps
    softSerial.begin(115200); //Start software serial at 115200

    nano.setBaud(baudRate); //Tell the module to go to the chosen baud rate. Ignore the response msg

    softSerial.begin(baudRate); //Start the software serial port, this time at user's chosen baud rate
  }

  //Test the connection
  nano.getVersion();
  if (nano.msg[0] != ALL_GOOD) return (false); //Something is not right

  //The M6E has these settings no matter what
  nano.setTagProtocol(); //Set protocol to GEN2

  nano.setAntennaPort(); //Set TX/RX antenna ports to 1

  return (true); //We are ready to rock
}

Hello there!

I did some searching and discovered that the RFID card you use operates of 5V logic, whereas the Feather board operates on 3.3V logic. This difference creates an issue due to the fact that a 3.3V cannot accept a 5V signal, and a 5V board doesn't always recognize a 3.3V signal as a HIGH. This would also explain why your Arduino Uno did work, because the Uno is a 5V board.

Hi!

Thanks for the quick reply! :slight_smile:

My understanding is that the USB pin on the Feather M0 will output 5V. The module seems to be powering on correctly and all that. I believe that it's causing an issue now that you mention it. Is there something on the market that is small, and similar memory/size to the Feather M0 that operates on 5V logic, that you know of?

The USB will put out 5V, but there is a regulator on the board that brings the 5V down to 3.3V.

The Arduino Micro is similar in size to the Feather, but it does not have any built-in BLE technology. There is also the Arduino Nano, also without BLE.

I think the main problem is that the BLE chips require 3.3V, so even if the main microcontroller runs on 5V, the BLE would not be able to be used.

Hey, thanks for recommendations. I was looking through the datasheet for the Nano (the reader) out of curiosity.

It shows the following:

That it requires 3.7V to 5.5V to power the reader, but in this section, it seems to say that it runs on 3.3V logic, doesn't it?
Imgur

I'm totally new to reading data sheets, so I'm not sure.

If it's the case that it runs on 3.3V logic, then the Feather should work, shouldn't it?