This is my first time posting to this forum so I apologize in advance for any missing information or incorrect formatting.
This is a pretty specific question regarding the Data Logger shield (https://learn.adafruit.com/adafruit-data-logger-shield). I am working on building a system that reads tag IDs from two UHF RFID modules and saves the time/tag number to an SD card, controlled by an Arduino Uno R3. I had a working system when I was prototyping with a DS3231 RTC and generic SD card unit from amazon but (without getting into too much detail), I need to make a lot of these and wanted to save time on soldering and space by using the Data Logger shield as the RTC and SD card.
I have been able to read tag IDs from both RFID units using the shield and save them to the SD card. However, I am having trouble getting the RTC to read times correctly for both modules. The RTC is a PCF8523. The module that is listed second in the void loop (their order in the code is what matters, I've swapped pins for the modules and it's always the one written second in the void loop that has the errors) will have an incorrect time/date and/or cause a crash back to the void setup. I thought maybe there was an issue with serial overflow or perhaps it needed to be cleared after the for loops, but I've also added a serial.flush() to nearly every logical location to no avail.
I'm happy to provide more detailed information on the errors I am seeing but I've been troubleshooting this for weeks so the list is extensive (some symptoms are summarized in the code below), and I thought I might just wait and see what information is requested first (maybe it's a simple issue with this RTC model and too many UART communication lines that I've overlooked or something).
I think it's a pretty interesting problem but I'm running out of ideas on the root of the issue. Any ideas would be greatly appreciated!
The code is below with some troubleshooting notes:
Code: Select all
/*
Adafruit shield on top of the Arduino Uno R3
V1 starting with the RTC (Newer Adafruit shield uses PCF8523 RTC) and SD card only
V2 added in the first RFID reader and saving it to the SD card with the time
V3 adding in the further RFID reader, RTC causing some kind of return to start up sequence
Pins A4 and A5 are reserved for the RTC
Pins 10 (Chipselect), 11, 12, 13 are reserved for the SD card
Closer RFID reader pins 5, 6
Further RFID reader pins 8, 9
Testing notes:
-removing all time stamps from the void loop while leaving everything else the same, results
in successful scanning of tags and saving to SD card from both modules.
-Keeping time readings to serial monitor but not saving them to SD card for both modules: second module
works just fine. first module will read the correct time/date but then always crash and go back to void setup
-Running the code with only one module, RTC, and SD card works as well.
-Running the code with both modules saving the tag numbers to the SD card:
Variation 1: the module first in the void loop has code to reads the RTC, and the other does not: results in
scanning of second module (without time) fine but has wrong time for first module and either freezes
the serial monitor or goes back to void setup if asking it to save time to the SD card. If only reading the time
(without saving) then it just says the incorrect time.
Variation 2: the module first in the void loop does not have code to read the RTC, and the other does: if you
scan the second module first, then it reads the correct time and saves it. However, if you then scan from the
first module, the time from the second is corrupted and no longer scans correctly. Once it is corrupted: if you
are saving the time to the SD card in the code then it either crashes serial or sends back to void setup. if not
saving the time to SD card then just displays incorrect time on serial monitor but tag scans are still possible.
*/
#include "RTClib.h" //RTC
#include <SPI.h> //SD
#include <SD.h> //SD
#include <SoftwareSerial.h> //for the reader
//RTC Adafruit Shield (pins A4, A5)
RTC_PCF8523 rtc;
char t[32];
char z[32];
//global variables
#define delaytime 100
//SD Card
const int chipSelect = 10;
// Create a file to store the data
File myFile;
//RFID Closer
byte read_byte_close;
bool found_close;
byte data_close[20];
//Specify Arduino pins for Serial connection, closer module:
//SoftwareSerial UHF(RX_pin, TX_pin);
SoftwareSerial UHFclose(8, 9);
//for the reader further from the colony
byte read_byte_far;
bool found_far;
byte data_far[20];
//Specify Arduino pins for Serial connection, further module:
//SoftwareSerial UHF(RX_pin, TX_pin);
SoftwareSerial UHFfar(5, 6);
void setup() {
Serial.begin(57600); //baud rate from adafruit datalogger shield example
//RTC set up from adafruit example:
#ifndef ESP8266
while (!Serial); // wait for serial port to connect. Needed for native USB
#endif
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (! rtc.initialized() || rtc.lostPower()) {
Serial.println("RTC is NOT initialized, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
rtc.start();
//displaying date in setup to see if it's correct
DateTime now = rtc.now();
sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
Serial.println(t);
//SD Card initialization
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
//don't do anything more:
while (1);
}
Serial.println("card initialized.");
//Software UART interface to FM-504 for further module
UHFfar.begin(38400); //Baud rate: 38400 Baud
delay(delaytime);
//Read RFID reader ID
Serial.print("Probing further RFID reader...");
//Command to RFID - display reader ID
UHFfar.write(0x0A); //Reader ID: 0A 53 0D
UHFfar.write(0x53); // <LF>S<CR>
UHFfar.write(0x0D);
delay(delaytime);
while (UHFfar.available() > 0){ //checks return bytes in buffer
read_byte_far = UHFfar.read();
Serial.write(read_byte_far);
}
Serial.println(" ");
//RFID Reader (Closer)
//Software UART interface to FM-504
UHFclose.begin(38400); //Baud rate: 38400 Baud
delay(delaytime);
//Read RFID reader ID
Serial.print("Probing closer RFID reader...");
//Command to RFID - display reader ID
UHFclose.write(0x0A); //Reader ID: 0A 53 0D
UHFclose.write(0x53); // <LF>S<CR>
UHFclose.write(0x0D);
delay(delaytime);
while (UHFclose.available() > 0){ //checks return bytes in buffer
read_byte_close = UHFclose.read();
Serial.write(read_byte_close);
}
Serial.println(" ");
}
void loop() {
//Command to RFID - read bee tag - Query EPC for further module
UHFfar.listen();
UHFfar.write(0x0A); //Reader ID: 0A 51 0D
UHFfar.write(0x51); // <LF> Q <CR>
UHFfar.write(0x0D); //EPC: PC + EPC + CRC16
delay(delaytime);
found_far = false;
int size_far = 0;
while (UHFfar.available() > 0) {
read_byte_far = UHFfar.read();
if (read_byte_far != 'Q' && read_byte_far != '\r' && read_byte_far != '\n'){
data_far[size_far] = read_byte_far;
size_far++;
found_far = true;
}
}
if (found_far && size_far>10){
for (int k=0; k<size_far; k++) {
Serial.write(data_far[k]);
if(UHFfar.overflow()){
Serial.print("UHF far overflow");
}
}
Serial.print(" Further RFID Read");
Serial.print('\n');
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (myFile) {
Serial.println("File opened ok");
for (int m = 0; m < size_far; m++){
myFile.print(data_far[m]);
}
myFile.print(", ");
myFile.print("Further");
myFile.print(", ");
//Saving time to SD card and serial monitor
DateTime now = rtc.now();
sprintf(z, "%02d:%02d:%02d %02d/%02d/%02d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
myFile.println(z);
Serial.println(z);
Serial.println("successfully written on SD card");
Serial.print('\n');
myFile.close();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error datalog.txt");
}
delay(delaytime);
}
//Command to RFID - read bee tag - Query EPC for closer module
UHFclose.listen();
UHFclose.write(0x0A); //Reader ID: 0A 51 0D
UHFclose.write(0x51); // <LF> Q <CR>
UHFclose.write(0x0D); //EPC: PC + EPC + CRC16
delay(delaytime);
found_close = false;
int size_close = 0;
while (UHFclose.available() > 0) {
read_byte_close = UHFclose.read();
if (read_byte_close != 'Q' && read_byte_close != '\r' && read_byte_close != '\n'){
data_close[size_close] = read_byte_close;
size_close++;
found_close = true;
}
}
if (found_close && size_close>10){
for (int j=0; j<size_close; j++) {
Serial.write(data_close[j]);
if(UHFclose.overflow()){
Serial.print("UHF close overflow");
}
}
Serial.print(" Closer RFID Read");
Serial.print('\n');
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (myFile) {
Serial.println("File opened ok");
for (int n = 0; n < size_close; n++){
myFile.print(data_close[n]);
}
myFile.print(", ");
myFile.print("Closer");
myFile.print(", ");
//Saving time to SD card and monitor
DateTime now = rtc.now();
sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
myFile.println(t);
Serial.println(t);
Serial.println("successfully written on SD card");
Serial.print('\n');
myFile.close();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error datalog.txt");
}
}
}