I have an RFID reader that sends 7 bytes at a time when it reads a card, using the following code
#include <SoftwareSerial.h>
SoftwareSerial mySerial(6,7);
void setup() {
Serial.begin(9600);
while (!Serial);
mySerial.begin(9600);
delay(1000);
Serial.println("Setup Complete!");
}
void loop() {
while(!mySerial.available()); // wait for the serial port to send data
int incomingByte = mySerial.read();
Serial.println(incomingByte,HEX);
}
I would like to get all these incoming bytes into a 7 element array, but they all seem to come at once rather than individually, so if I try to write then to consecutive elements of an array nothing happens - the program just jumps back to the start of loop. I’m sure this is a simple task, but I think my basic problem is that I don’t really understand Software Serial.
Try this code. Tested on my Uno by sending from serial monitor through a USB-TTL convrter connected to pins 6 and 7 to Uno with hardware serial connected to a separate instance of serial monitor. All that is modified from the tutorial is to change the receiver to software serial by including the library, creating a software serial object, initializing it and using the object to read the incoming serial data.
The received data is in a null terminated character array (string) called receivedChars. Test the newData flag to see if new data is available. Clear the flag to be able to receive a new data set.
// Robin2's Example 2 - Receive with an end-marker modified to work with software serial
// by groundfungus aka c. goulding
#include <SoftwareSerial.h>
SoftwareSerial ssPort(6, 7);
const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;
void setup()
{
Serial.begin(9600);
ssPort.begin(9600);
Serial.println("<Arduino is ready>");
}
void loop()
{
recvWithEndMarker();
showNewData();
}
void recvWithEndMarker()
{
static byte ndx = 0;
char endMarker = '\n';
char rc;
while (ssPort.available() > 0 && newData == false)
{
rc = ssPort.read();
if (rc != endMarker)
{
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{
ndx = numChars - 1;
}
}
else
{
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
}
void showNewData()
{
if (newData == true)
{
Serial.print("This just in ... ");
Serial.println(receivedChars);
newData = false;
}
}
For this code to work, line endings in serial monitor must be set to Newline.
Thanks - I don't have an end marker from the RFID card, so I think I basically need to count 7 bytes to know that all have come through. With your code, all I get is "this just in" followed by nothing. But I'm slowly starting to understand - I think
The end marker is a new line character in that code, but it can be changed in the code. What, exactly, does the RFID card send? Can you provide some samples? Perhaps the RFID sends something that can be used as an end marker.
Can I ask which library that you are using for the RFID? There may be an option in the library to set up the outgoing data set to add a newline or some terminating character.
Is the first byte always the same? No, it varies. At least, according to the bytes that turn up on the serial monitor in the original sketch. However, I think there is more to it than this. The full data sheet is annoyingly password protected except to customers, but I’ve saved a jpg of some of it here
I wrote a slightly more complex sketch, like this:
#include <SoftwareSerial.h>
int inBuffer[21];
byte bufIndx = 0;
SoftwareSerial mySerial(6, 7);
void setup() {
Serial.begin(9600);
while (!Serial);
mySerial.begin(9600);
delay(1000);
Serial.println("Setup Complete!");
}
void loop() {
bufIndx = 0;
while (!mySerial.available()); // wait for the serial port to send data
if (mySerial.available() > 0) {
Serial.println();
while (mySerial.available() > 0) {
inBuffer[bufIndx] = mySerial.read();
bufIndx ++;
}
inBuffer[bufIndx] = 0;
}
for (int i = 0; i < 21; i++) Serial.println (inBuffer[i], DEC);
}
This produces some odd results, for example the first read of a card produces this
136
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
14849
then the next read of the same card produces this:
So there is a lot of inconsistency (and a lot of zeros). This is strange to me because the original sketch produces completely consistent results. I’m guessing that the software serial and the running code are somehow out of sync (I’ve tried changing the software serial baud rate but it only makes things worse).
I’m not using any library for the RFID reader - it’s a quite basic 125kHz model which just uses serial output.
zoomkat:
"This produces some odd results, for example the first read of a card produces this"
You may be reading the serial buffer much faster than the characters are arriving. Try putting a delay(3) after the
bufIndx ++; to see if that helps.
Thank you - this seems to have fixed the problem. It has also produced the missing 2 start code and 3 end code, and I now have 13 bytes (including the first and last) rather than 7.