Hello there,
I have a SparkFun Simultaneous RFID Reader - M6E Nano reader connected to a Redboard UNO, these two read RFID tags and send the readings to an ESP8266, and then the ESP sends these data to a server to be shown on a website.
the problem is that the ESP8266 sends the data every 800ms, and the RFID reader reads a new tag every 500ms. so while the ESP sends a packet of data to the server, there might be new readings on the RFID reader, so we lose that data.
My idea to fix this was to make the code in such a way that the Redboard saves the RFID readings somewhere and sends them to the ESP for example every 5 seconds. this way I wouldn't lose any data and ESP would have more time to send the data to the server, and also I could reduce the RFID reading time even more to have more readings. but this is a bit out of my knowledge and I could use some help. I'll share the Redboard and ESP code below.
Redboard Qwiic code:
#include <SoftwareSerial.h> //Used for transmitting to the device
SoftwareSerial softSerial(2, 3); //RX, TX
SoftwareSerial mySerial(7, 8); //RX, TX
#include "SparkFun_UHF_RFID_Reader.h" //Library for controlling the M6E Nano module
RFID nano; //Create instance
///#define BUZZER1 9
///#define BUZZER2 10
char c;
#define EPC_COUNT 50
#define EPC_ENTRY 12
uint8_t EPC_recv[EPC_COUNT][EPC_ENTRY];
bool enable_clr = false;
byte type_s;
byte addr[8];
int val1;
unsigned long previousMillis = 0; // last time update
long interval = 2000; // interval at which to do something (milliseconds)
#define PRMDEBUG 0
void setup(void) {
Serial.begin(115200);
mySerial.begin(115200);
initialize_RFID();
init_array();
}
void loop(void) {
Check_EPC();
}
void initialize_RFID() {
retry:
Serial.println(F("try to connect to RFID reader"));
//Configure nano to run at certain speed
int RunStatus = setupNano(38400);
if (RunStatus == 0) {
serialTrigger(F("Module failed to respond. Please check wiring."));
yield();
goto retry;
}
if (RunStatus == 1) { // was not yet in continues mode
nano.setRegion(REGION_EUROPE);
nano.setTagProtocol(); //Set protocol to GEN2
nano.setAntennaPort(); //Set TX/RX antenna ports to 1
nano.setReadPower(2000); //10.00 dBm. Higher values may cause USB port to brown out
//Max Read TX Power is 27.00 dBm and may cause temperature-limit throttling
}
Serial.println("RFID shield initialized");
}
/* initialize/empty the array to capture detected EPC */
void init_array() {
for (val1 = 0; val1 < EPC_COUNT; val1++) EPC_recv[val1][0] = 0;
Serial.println("done");
}
void Check_EPC() {
uint8_t myEPC[EPC_ENTRY]; // Most EPCs are 12 bytes
//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) {
if (PRMDEBUG > 1) Serial.println(F("scanning"));
Serial.println("hi");
}
else if (responseType == RESPONSE_IS_TAGFOUND) {
for (byte x = 0; x < EPC_ENTRY; x++) {
myEPC[x] = nano.msg[31 + x];
}
add_ECP_entry(myEPC, EPC_ENTRY);
if (PRMDEBUG > 0) {
//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,
Serial.print(F(" epc["));
for (byte x = 0; x < EPC_ENTRY; x++) {
if (myEPC[x] < 0x10) Serial.print(F("0")); //Pretty print adding zero
Serial.print(myEPC[x], HEX);
Serial.print(F(" "));
}
Serial.println("]");
}
} else {
//Unknown response
if (PRMDEBUG > 1) nano.printMessageArray(); //Print the response message. Look up errors in tmr__status_8h.html
}
}
//Gracefully handles a reader that is already configured and already reading continuously
int setupNano(long baudRate) {
if (PRMDEBUG == 3) nano.enableDebugging(softSerial);
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) yield(); //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();
val1 = 0;
while (val1 < 2) {
nano.getVersion();
if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE) {
if (PRMDEBUG > 1) Serial.println(F("Module continuously reading. Not Asking it to stop..."));
return (2);
}
else if (nano.msg[0] != ALL_GOOD) {
if (PRMDEBUG > 1) Serial.println(F("Try reset RFID speed"));
//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
}
else {
return (1); // Responded, but have to be set in the right mode
}
val1++;
}
return (0);
}
void add_ECP_entry(uint8_t *msg, byte mlength) {
byte j;
val1 = 0;
bool found;
// as long as not end of list or end of array
while (val1 < EPC_COUNT && EPC_recv[val1][0] != 0) {
found = true;
// check each entry for a match
for (j = 0; j < mlength, j < EPC_ENTRY; j++) {
if (EPC_recv[val1][j] != msg[j]) {
found = false; // indicate not fuond
j = EPC_ENTRY;
}
}
// if found
if (found == true) {
if (PRMDEBUG > 1) {
Serial.print(F("FOUND EPC in array entry "));
Serial.println(val1);
}
return;
}
val1++; // next entry
}
// Not found, can we still add?
if (val1 == EPC_COUNT) {
if (PRMDEBUG > 0) Serial.println(F("Can not add more to array"));
return;
}
// debug info
if (PRMDEBUG > 1) {
Serial.print(F("New entry number is "));
Serial.println(val1);
}
// add entry to the array
for (j = 0; j < mlength, j < EPC_ENTRY; j++) EPC_recv[val1][j] = msg[j];
}
void serialTrigger(String message) {
Serial.println();
Serial.println(message);
Serial.println();
while (!Serial.available())
;
while (Serial.available()) Serial.read();
}
ESP8266 Code:
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <SoftwareSerial.h>
const char *ssid = "...";
const char *password = "...";
SoftwareSerial mySerial(D1, D2); // RX, TX
String httpGET(String path, String header, String val1, String val2);
void ESPSendData(int tempe, int humid);
int connectionCounter = 0;
int rebootCount = 0;
void setup() {
mySerial.begin(115200);
Serial.begin(115200);
Serial.println();
for (uint8_t t = 4; t > 0; t--)
{
Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
Serial.println();
Serial.print("connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
WiFi.begin(ssid, password);
delay(300);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
connectionCounter++;
if (connectionCounter == 10) {
WiFi.begin(ssid, password);
connectionCounter = 0;
Serial.println();
Serial.print("Connecting");
}
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
Serial.println("listen");
String payload = "";
bool readingFlag = false;
char s = 0;
while (1) {
if (mySerial.available()) {
s = mySerial.read();
if (s == '$') {
break;
}
if (readingFlag) {
payload += s;
mySerial.println(s);
Serial.println(s);
}
if (s == '@') {
readingFlag = true;
}
}
delay(2);
}
if (payload.length() != 0) {
//Serial.println(payload.length());
String val1 = payload.substring(0, payload.indexOf('#'));
String val2 = payload.substring(payload.indexOf('#') + 1, payload.length());
//Serial.println(val1);
Serial.print('\n');
Serial.println(val1 + "," + val2);
httpGET("", "", val1, val2);
delay(800);
}
}
String httpGET(String path, String header, String val1, String val2) {
String response = "";
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
WiFiClient client;
HTTPClient http;
String payload = "http://api';
//payload += "api_key";
payload += "zone_number=1";
payload += "&tag_id=";
payload += val1;
payload += "&rssi=";
payload += val2;
http.begin(client, payload); //Specify request destination
http.addHeader("Content-Type", "application/json"); //Specify content-type header
int httpCode = http.GET(); //Send the request
response = http.getString(); //Get the response payload
Serial.println(httpCode); //Print HTTP return code
Serial.println(response); //Print request response payload
http.end(); //Close connection
}
else {
Serial.println("Error in WiFi connection");
WiFi.disconnect();
WiFi.begin(ssid, password);
delay(300);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
connectionCounter++;
if (connectionCounter == 10) {
WiFi.begin(ssid, password);
connectionCounter = 0;
Serial.println();
Serial.print("Connecting");
}
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
return response;
}
The Redboard and the ESP connected together in this way:
- Pin 7 of Redboard <-> Pin D2 of ESP8266
- Pin 8 of RedBoard <-> Pin D1 of ESP8266
- GND of RedBoard <-> G of ESP8266 (GROUNDS)