I am attempting to use the SparkFun M7E RFID reader, with basic assembly and the library provided onsite.
The module works perfectly fine with the USB connection via ThingMagic Universal Reader Assistant.
But when it comes to UART, I only receive “Module failed to respond. Please check the wiring.”
I have tried the example codes on Uno R3 (RX/TX, as well as SoftSerial) and Mega 2560 (RX1/TX1, etc). None works. (yes the switch was on SER).
I tried powering the module via USB (while the switch was still on SER), while reading data through UART. same error.
doubting maybe my serial pins are defective, I checked the hardware, and the UART pins seem to function fine.
After placing costume lines in the code, it returned the error code 1, which is defined as:
ERROR_COMMAND_RESPONSE_TIMEOUT.
After lots of effort, I checked the provided library. It (only) checks for the " _moduleType == ThingMagic_M6E_NANO" in some lines, but no checking for “M7E_HECTO”.
This is while M7E_HECTO has been initially defined in the library, but no further command corresponds to it.
I am not sure if the problem is related to the library.
Has anyone used M7E Hecto using Arduino?
Any possible help or insight is greatly appreciated.
Since you mentioned that the library checks for ThingMagic_M6E_NANO but not for M7E_HECTO, you might need to modify the library to support your module explicitly. If you think about switching to a different RFID reader, you can switch to MFRC522.
Make sure to use the latest library. (1.2.0) That has been updated for work with the M7E_HECTO, check one of the examples to see how to set it for M7E-HECTO. This setting will only impact the correct frequency setting in NA in case of the M6E-NANO.
else It should work as it is. Pictures ? which board ? ?connected to 5v?
aliarifat794:
Since you mentioned that the library checks for ThingMagic_M6E_NANO but not for M7E_HECTO, you might need to modify the library to support your module explicitly. If you think about switching to a different RFID reader, you can switch to MFRC522.
Thanks for the advice. I was mistaken with the library. The problem seems to be in the procedure of initiating the module.
paulvha:
Make sure to use the latest library. (1.2.0) That has been updated for work with the M7E_HECTO, check one of the examples to see how to set it for M7E-HECTO. This setting will only impact the correct frequency setting in NA in case of the M6E-NANO.
That's right, thanks. The problem was not with the the library, since, as you mentioned, the check was only for the M6E-NANO configs.
paulvha:
else It should work as it is. Pictures ? which board ? ?connected to 5v?
I tried to reset the module with connecting EN to GND, when it was on serial mode but connected to USB for the power. (a small note here: It seems like it doesn’t reset when it is connected to Arduino.)
It has started working for now, although some times I need to reset it to work again.
This specifically happens when the Baud Rate changes within the code (e.g., changing thee protocol from SoftSerial to RX/TX). Here I need to cut the power of the module so it starts responding with the new BR.
paulvha:
good to hear there is progress. Which board do you connect to?
I have tried it on UNO R3 and MEGA 2560, but UNO is of my interest.
I need to re-initiate the M7E board some times to respond to a changed BR, with cutting the power. However, I don’t know how to do it properly, since I have other modules connected to the UNO board (HC05 and Easy Driver).
For now I have placed this to re-start the serial pins at the beginning, but I am not sure if this even helps. Do you have any suggestions? Do you think it is even necessary ?
SoftwareSerial softSerial(12, 13); //RX, TX
....
void setup() {
digitalWrite(12, LOW);
digitalWrite(13, LOW);
Serial.begin(115200);
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
while (!Serial); // Wait for the serial port to come online
#include "SparkFun_UHF_RFID_Reader.h"
#include <SoftwareSerial.h>
SoftwareSerial softSerial(12, 13); //RX, TX
RFID rfidModule;
//#define rfidSerial Serial3
#define rfidSerial softSerial // Serial3
#define rfidBaud 38400
#define moduleType ThingMagic_M7E_HECTO
long hc05_baudrate = 38400;
int ledPin = 8;
int button_pin = 7;
const long nchan = 6;
long pinout[nchan] = {7, 8, 9, 10, 11};
#define stp 2
#define dir 3
#define MS1 4
#define MS2 5
#define EN 6
int x;
unsigned long duration;
int rotation_counter = 0;
byte lastUID[24]; // To store the last read UID, assuming maximum EPC length
byte lastUIDLength = 0; // Length of the last read UID
void setup() {
digitalWrite(12, LOW);
digitalWrite(13, LOW);
Serial.begin(115200);
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
while (!Serial); // Wait for the serial port to come online
if (setupRfidModule(rfidBaud) == false) {
Serial.println(F("Module failed to respond. Please check wiring."));
while (1); // Freeze!
}
//.....M7E-HECTO configs..................................................................
rfidModule.setRegion(REGION_NORTHAMERICA); // Set to North America
rfidModule.setReadPower(500); // 5.00 dBm. Higher values may cause USB port to burn out
//rfidModule.enableDebugging(); // Turns on commands sent to and heard from RFID module
rfidModule.startReading(); // Begin scanning for tags
//....Bluetooth and Motor Control Initialization...
for (size_t m = 0; m < nchan; m++) {
pinMode(pinout[m], OUTPUT);
digitalWrite(pinout[m], LOW);
}
pinMode(LED_BUILTIN, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(button_pin, INPUT_PULLUP);
Serial.begin(hc05_baudrate);
pinMode(stp, OUTPUT);
pinMode(dir, OUTPUT);
pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(EN, OUTPUT);
resetEDPins();
}
void loop() {
if (rfidModule.check() == true) { // Check to see if any new data has come in from the module
byte responseType = rfidModule.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) {
handleTagFound();
} else if (responseType == ERROR_CORRUPT_RESPONSE) {
Serial.println("Bad CRC");
} else if (responseType == RESPONSE_IS_HIGHRETURNLOSS) {
Serial.println("High return loss, check antenna!");
} else {
// Unknown response
Serial.println("Unknown error");
}
}
// Manual activation of reward with button press
if (digitalRead(button_pin) == LOW) {
digitalWrite(EN, LOW); // Pull enable pin low to allow motor control
digitalWrite(ledPin, HIGH);
SmallStepMode(30); // Set the size of the steps in the function below. Added duration input
resetEDPins(); // Reset pins to save power
digitalWrite(ledPin, LOW);
}
if (0 < Serial.available()) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
if (0 == cmd.length()) return;
String result = "P1"; // Command not understood
switch (cmd.charAt(0)) {
case 'Q': // Query current state
result = "READY";
break;
case 'R': // Reset
result = "OK";
break;
case 'Y': { // Deliver reward, Y<juice line>,<duration>,<num reward>,<pause time between multiple rewards>
long comma1 = cmd.indexOf(',', 1);
long comma2 = cmd.indexOf(',', comma1 + 1);
long comma3 = cmd.indexOf(',', comma2 + 1);
if (comma1 < 1 || comma2 < 1 | comma3 < 1) {
result = "P3"; // Parameter error
break;
}
unsigned long juiceline = cmd.substring(1, comma1).toInt() - 1; // 0-based
unsigned long duration = cmd.substring(comma1 + 1, comma2).toInt(); // Coming from timing script of monkeylogic.
unsigned long numreward = cmd.substring(comma2 + 1, comma3).toInt();
unsigned long pausetime = cmd.substring(comma3 + 1).toInt();
if (nchan <= juiceline) {
result = "P2"; // Solenoid does not exist
break;
}
for (size_t m = 1; m <= numreward; m++) {
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(ledPin, HIGH);
digitalWrite(EN, LOW); // Pull enable pin low to allow motor control
SmallStepMode(duration); // Set the size of the steps in the function below. Added duration input
resetEDPins(); // Reset pins to save power
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(ledPin, LOW);
if (m < numreward) delay(pausetime); // Pause between rewards set in ML
}
result = "OK";
break;
}
}
Serial.write((result + '\n').c_str());
}
}
// Reset Easy Driver pins to default states
void resetEDPins() {
digitalWrite(stp, LOW);
digitalWrite(dir, LOW);
digitalWrite(MS1, LOW);
digitalWrite(MS2, LOW);
digitalWrite(EN, HIGH); // Saves power!
}
// 1/8th microstep forward mode function
void SmallStepMode(int duration) {
rotation_counter++;
digitalWrite(dir, LOW); // Pull direction pin low to move "forward"
digitalWrite(MS1, HIGH); // Pull MS1, and MS2 high to set logic to 1/8th microstep resolution
digitalWrite(MS2, HIGH);
for (x = 0; x < duration; x++) { // Loop the forward stepping enough times for a pellet to fall in
digitalWrite(stp, HIGH); // Trigger one step forward
delay(1);
digitalWrite(stp, LOW); // Pull step pin low so it can be triggered again
delay(1);
}
}
void handleTagFound() {
// If we have a full record we can pull out the fun bits
int rssi = rfidModule.getTagRSSI(); // Get the RSSI for this tag read
long freq = rfidModule.getTagFreq(); // Get the frequency this tag was detected at
long timeStamp = rfidModule.getTagTimestamp(); // Get the time this was read, (ms) since last keep-alive message
byte tagEPCBytes = rfidModule.getTagEPCBytes(); // Get the number of bytes of EPC from response
byte currentUID[24]; // To store the current UID
for (byte x = 0; x < tagEPCBytes; x++) {
currentUID[x] = rfidModule.msg[31 + x]; // Extract EPC
}
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("]"));
Serial.print(F(" epc["));
for (byte x = 0; x < tagEPCBytes; x++) {
if (currentUID[x] < 0x10) Serial.print(F("0")); // Pretty print
Serial.print(currentUID[x], HEX);
Serial.print(F(" "));
}
Serial.print(F("] "));
if (isNewTag(currentUID, tagEPCBytes)) {
Serial.println("New UID read!");
memcpy(lastUID, currentUID, tagEPCBytes);
lastUIDLength = tagEPCBytes;
// Operate motor and LED for new tag
digitalWrite(ledPin, HIGH);
digitalWrite(EN, LOW);
SmallStepMode(30);
resetEDPins();
digitalWrite(ledPin, LOW);
} else {
Serial.println("Already read");
}
}
boolean setupRfidModule(long baudRate) {
rfidModule.begin(rfidSerial, moduleType); // Tell the library to communicate over serial port
// Test to see if we are already connected to a module
rfidSerial.begin(baudRate); // For this test, assume module is already at our desired baud rate
delay(100); // 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 (rfidSerial.available())
rfidSerial.read();
rfidModule.getVersion();
if (rfidModule.msg[0] == ERROR_WRONG_OPCODE_RESPONSE) {
// This happens if the baud rate is correct but the module is doing a continuous read
rfidModule.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
rfidSerial.begin(115200); // Start serial at 115200
rfidModule.setBaud(baudRate); // Tell the module to go to the chosen baud rate. Ignore the response msg
rfidSerial.begin(baudRate); // Start the serial port, this time at user's chosen baud rate
delay(250);
}
// Test the connection
rfidModule.getVersion();
if (rfidModule.msg[0] != ALL_GOOD)
return false; // Something is not right
// The module has these settings no matter what
rfidModule.setTagProtocol(); // Set protocol to GEN2
rfidModule.setAntennaPort(); // Set TX/RX antenna ports to 1
return true; // We are ready to rock
}
boolean isNewTag(byte* currentUID, byte currentUIDLength) {
if (currentUIDLength != lastUIDLength) {
return true; // Different length means different tag
}
for (byte i = 0; i < currentUIDLength; i++) {
if (currentUID[i] != lastUID[i]) {
return true; // Different UID means different tag
}
}
return false; // Same UID means same tag
}
Spend more time looking at the M7E and there are important differences between the M6E and M7E. I documented my first findings (attached).
One aspect that could be important in this case is that the M6E has an onboard level shifter (TXB0104) to make RX and TX 5V compatible. The M7E does not have a level shifter and looks 3v3 compatible. The M7E datasheet indicates this also: UART; 3.3V logic levels 9.6 to 921.6 kbps.
Try to connect a level shifter on the RX/TX lines
OR try a resistor voltage divider on the M7E RX line. There is no need to do that on the M7E TX line.
I’ve spent some time playing with the module, but the problem persists and it’s driving me crazy!
So far, I have observed the following:
With a direct USB connection, the module works perfectly.
If you program the module with a specific baud rate, it will initiate communication with that baud rate on subsequent startups (and not 115700).
When using the serial connection (SoftSerial on pins 11 & 12), the response is unstable. Most of the time, or from code to code, it fails to start a serial connection and sends a “check the wiring” message. The connections are solid.
Initially, I was powering the RFID module with the +5V from the Arduino. I then switched to 3.3V using a breadboard power supply connected to a 12V DC battery pack for the RFID, while the Arduino remained connected to the PC. The instability persists.
paulvha:
Try to connect a level shifter on the RX/TX lines.
OR try a resistor voltage divider on the M7E RX line. There is no need to do that on the M7E TX line.
I haven’t tried these yet, as I’m not sure how to approach this. I will try these in the upcoming days. I hope it resolves the issue because otherwise, I have no clue what could be causing the problem!
paulvha:
The M7E does not have a level shifter and looks 3v3 compatible. The M7E datasheet indicates this also: UART; 3.3V logic levels 9.6 to 921.6 kbps.
I measured the pin voltages on my M7E , and whether it was connected to a 5V or 3.3V power supply (via a breadboard power supply module with 12V DC input) or directly to the Arduino’s 5V (connected to PC), the RX and TX lines both are 2.49V.
Additionally, I observed the following current measurements:
between Vcc and Gnd: 1 µA
RX and Gnd: 0.48 µA
TX and Gnd: 1 µA
What do you think could be the problem? If it is the internal pull-up resistor, could it be fixed?
What do you think could be the problem? If it is the internal pull-up resistor, could it be fixed?
Nothing can be done about the internal pull-up nor should it.
If you program the module with a specific baud rate, it will initiate communication with that baud rate on subsequent startups (and not 115700).
I expect only after you remove the power and re-apply it will reset to the default 115200. Else it would stay on the latest selected power. (as with the M6E)
For test I would propose to go back to the basics: remove all the other hardware boards only keep the UNO and M7E. Connect directly to the UNO with software serial pin 2 and 3 and use example1. Connect power 5V and GND. Does that work?