Australia
Offline
Jr. Member
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
|
 |
« on: July 12, 2012, 07:38:35 am » |
Hi all, Some of you may have seen my previous post regarding NewSoftwareSerial library, and I'm sorry to bother you all again, but my newbie brain has run into another wall  . I'm trying to get a RDM630 RFID Tag Reader (See below for datasheet) to read an RFID tag and send the serial ID to my PC. The reader uses a serial interface to connect to the Arduino, and so I need to use the NewSoftwareSerial library to connect to the reader. What is supposed to happen in the Serial Monitor is this: Computer to Arduino Serial Ready RFID to Arduino Serial Ready Awaiting Tag RFID Tag ID: (Tag's ID Here)
However, what is actually happening is this: Computer to Arduino Serial Ready RFID to Arduino Serial Ready Awaiting Tag RFID Tag ID: ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
If you swipe the tag again, the ID appears as normal. But, if you were to swipe a DIFFERENT tag, the ID would be the same as the first tag on the first swipe, and then would return to the second tag's ID. From this, I get the feeling that it is 'one behind' the whole time, like the data is being sent to the PC first and then the Arduino is recieving data, although that is obviously not the case from my code (Which is yet to include XOR Checksum functionality because of this speedbump): /*==Libraries==*/ #include <SoftwareSerial.h>
/*==Pin Definitions==*/ #define RFID_LED 2 #define RFID_RX 3 #define RFID_TX 4
/*==Variables==*/ char RFID_Data[15]; boolean RFID_Data_Stored = false;
SoftwareSerial RFID = SoftwareSerial(RFID_RX, RFID_TX);
void setup() { Serial.begin(57600); //Setup connection to Computer via HardwareSerial Serial.println("Computer to Arduino Serial Ready"); //Acknowledge connection establihment to Computer RFID.begin(9600); //Setup connection to RFID Reader via SoftwareSerial pinMode(RFID_TX, OUTPUT);//Define RFID TX pin as OUTPUT (Not nessesary) pinMode(RFID_RX, INPUT);//Define RFID RX pin as INPUT (Nessesary) Serial.println("RFID to Arduino Serial Ready");//Acknowledge connection establishment to RFID Reader Serial.println("Awaiting Tag");//Provide Arduino's current status }
void loop() { if(digitalRead(RFID_LED) == LOW) { //Wait for LED pin from RFID Reader to go LOW Recieve_RFID(); //And go to 'Recieve_RFID' function } if(RFID_Data_Stored) { //If the RFID Reader has been read, then: Serial.print("RFID Tag ID: "); //Print to the computer the Tag ID for(int i = 1; i <=14; i++) { Serial.write(RFID_Data[i]); } Serial.println(""); RFID_Data_Stored = false; //Say that the data has been printed delay(500); //Delay to avoid false readings } } void Recieve_RFID() { for(int i = 1; i <= 14; i++) { //Recieve data coming from RFID Reader RFID_Data[i] = RFID.read(); //Store it in a string if(i == 14) { RFID_Data_Stored = true; //Tell the Arduino that there is data stored } } }
Oh, and here is the Reader datasheet: http://australianrobotics.com.au/sites/default/files/RDM630-Spec..pdfThanks for all your help, Koop
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 299
Posts: 26024
Solder is electric glue
|
 |
« Reply #1 on: July 12, 2012, 07:44:39 am » |
You are not waiting for all the data to be sent before reading it. Your rubbish characters are the result of getting -1 from the read because there is nothing to read. Then by the time the data has arrived in the buffer you have stopped reading it until next time. You have to ensure that there is something to trad EACH TIME you read the serial.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 334
Posts: 36443
Seattle, WA USA
|
 |
« Reply #2 on: July 12, 2012, 07:47:04 am » |
SoftwareSerial RFID = SoftwareSerial(RFID_RX, RFID_TX);
pinMode(RFID_TX, OUTPUT);//Define RFID TX pin as OUTPUT (Not nessesary) pinMode(RFID_RX, INPUT);//Define RFID RX pin as INPUT (Nessesary) You have told the SoftwareSerial instance that the pins are its to manage. So, why are you diddling with them? void Recieve_RFID() { for(int i = 1; i <= 14; i++) { //Recieve data coming from RFID Reader RFID_Data[i] = RFID.read(); //Store it in a string if(i == 14) { RFID_Data_Stored = true; //Tell the Arduino that there is data stored } } } As soon as the reader senses a tag, you expect the data to be available in the serial buffer to be read. At 9600 baud, that is a most unrealistic expectation. The data trickles in slowly. By the time you get frustrated, and wave the tag again, the first set of data has arrived. If you wave a second tag, all you will read is the first tag's data. This function needs to block (not indefinitely, though) and WAIT for the 14 bytes to arrive, before trying to read them. Why does the first byte get stored in the second position in the array? Array indices start at 0.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Online
Brattain Member
Karma: 143
Posts: 19368
I don't think you connected the grounds, Dave.
|
 |
« Reply #3 on: July 12, 2012, 07:48:44 am » |
More on this subject here
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Australia
Offline
Jr. Member
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
|
 |
« Reply #4 on: July 12, 2012, 08:36:36 am » |
Thanks all, I changed the Recieve_RFID Function to this, but it still won't work :/ void Recieve_RFID() { if(RFID.available() >= 13) { for(int i = 0; i <= 13; i++) { //Recieve data coming from RFID Reader RFID_Data = RFID.read(); //Store it in a string if(i == 13) { RFID_Data_Stored = true; //Tell the Arduino that there is data stored } } } }
And AWOL, I know! That was my original post 
|
|
|
|
|
Logged
|
|
|
|
|
Australia
Offline
Jr. Member
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
|
 |
« Reply #5 on: July 12, 2012, 08:39:22 am » |
Sorry, this is the code, actually: void Recieve_RFID() { if(RFID.available() >= 13) { for(int i = 0; i <= 13; i++) { //Recieve data coming from RFID Reader RFID_Data = RFID.read(); //Store it in a string if(i == 13) { RFID_Data_Stored = true; //Tell the Arduino that there is data stored } } } else { delay(1); } }
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 334
Posts: 36443
Seattle, WA USA
|
 |
« Reply #6 on: July 12, 2012, 08:41:26 am » |
So, if there are 13 bytes, it's OK to read all 14 of them. Hmmm. I don't think so.
Since you are not using the hardware serial port to talk to the RFID reader, that means that you can use the hardware serial port to debug the issue. I'd suggest that you do that.
By the way, I really don't think your code looks like what you posted. Using the quote button is inappropriate for code. Use the code button, instead (the one with the # on it).
|
|
|
|
|
Logged
|
|
|
|
|
Australia
Offline
Jr. Member
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
|
 |
« Reply #7 on: July 12, 2012, 08:43:43 am » |
Oh sorry about that. I just hit 'Copy for Forum' in the IDE. Thanks for your help. If I figure it out, I'll be sure to post it up here!
|
|
|
|
|
Logged
|
|
|
|
|
Gosport, UK
Offline
Faraday Member
Karma: 19
Posts: 3117
|
 |
« Reply #8 on: July 12, 2012, 08:52:03 am » |
I just hit 'Copy for Forum' in the IDE. They really need to fix that button, or get rid of it completely.
|
|
|
|
|
Logged
|
|
|
|
|
Massachusetts, USA
Offline
Tesla Member
Karma: 108
Posts: 6607
|
 |
« Reply #9 on: July 12, 2012, 08:55:03 am » |
Are there any framing characters to let you know when a tag begins and ends? Those might be useful to check for. Note: Your new code is reading 14 characters (0-13). Try a test sketch that echoes characters from SoftwareSerial() to the serial monitor: const int RFID_RX = 3; const int RFID_TX = 4; SoftwareSerial RFID = SoftwareSerial(RFID_RX, RFID_TX);
void setup() { Serial.begin(57600); //Setup connection to Computer via HardwareSerial RFID.begin(9600); //Setup connection to RFID Reader via SoftwareSerial Serial.println("Awaiting Tag");//Provide Arduino's current status }
void loop() { if (RFID.available()) { char val = RFID.read(); Serial.print(val, HEX); Serial.print(" "); if (val == 10 || val == 13) Serial.println(); } }
|
|
|
|
|
Logged
|
|
|
|
|
Australia
Offline
Jr. Member
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
|
 |
« Reply #10 on: July 12, 2012, 09:11:51 am » |
Awesome, guys! I adapted my Receive_RFID function so that if there is not 14 bytes, then it waits 1 millisecond and tries again, and it works fine! Here is the completed code: /*==Libraries==*/ #include <SoftwareSerial.h>
/*==Pin Definitions==*/ #define RFID_LED 2 #define RFID_RX 3 #define RFID_TX 4
/*==Variables==*/ char RFID_Data[15]; boolean RFID_Data_Stored = false;
SoftwareSerial RFID = SoftwareSerial(RFID_RX, RFID_TX);
void setup() { Serial.begin(57600); //Setup connection to Computer via HardwareSerial Serial.println("Computer to Arduino Serial Ready"); //Acknowledge connection establihment to Computer RFID.begin(9600); //Setup connection to RFID Reader via SoftwareSerial pinMode(RFID_TX, OUTPUT);//Define RFID TX pin as OUTPUT (Not nessesary) pinMode(RFID_RX, INPUT);//Define RFID RX pin as INPUT (Nessesary) Serial.println("RFID to Arduino Serial Ready");//Acknowledge connection establishment to RFID Reader Serial.println("Awaiting Tag");//Provide Arduino's current status }
void loop() { if(digitalRead(RFID_LED) == LOW) { //Wait for LED pin from RFID Reader to go LOW Recieve_RFID(); //And go to 'Recieve_RFID' function } if(RFID_Data_Stored) { //If the RFID Reader has been read, then: Serial.print("RFID Tag ID: "); //Print to the computer the Tag ID for(int i = 0; i <=13; i++) { Serial.write(RFID_Data[i]); } Serial.println(""); RFID_Data_Stored = false; //Say that the data has been printed delay(500); //Delay to avoid false readings } }
void Recieve_RFID() { Wait_Loop: if(RFID.available() >= 14) { for(int i = 0; i <= 13; i++) { //Recieve data coming from RFID Reader RFID_Data[i] = RFID.read(); //Store it in a string if(i == 13) { RFID_Data_Stored = true; //Tell the Arduino that there is data stored } } } else { delay(1); goto Wait_Loop; } } Now all I need to do is do some verification, and I'm done! Johnwasser: Yes there are, and to the Serial Monitor, they appear as spaces. I think that they are ASCII beginning and end of transmission decimal values (that is, they are 002 and 003) the code for understanding them will be added in for verification.
|
|
|
|
« Last Edit: July 12, 2012, 09:14:15 am by Koop »
|
Logged
|
|
|
|
|
Global Moderator
UK
Online
Brattain Member
Karma: 143
Posts: 19368
I don't think you connected the grounds, Dave.
|
 |
« Reply #11 on: July 12, 2012, 09:14:11 am » |
goto Wait_Loop; A "while" loop would attract a lot less flak. Edit: typo "look" -> "loop"
|
|
|
|
« Last Edit: July 12, 2012, 09:20:09 am by AWOL »
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Australia
Offline
Jr. Member
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
|
 |
« Reply #12 on: July 12, 2012, 09:14:48 am » |
Why, AWOL?
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 334
Posts: 36443
Seattle, WA USA
|
 |
« Reply #13 on: July 12, 2012, 09:18:59 am » |
Why, AWOL? Because in 30 years of writing C/C++ code, I have yet to use a single goto. You want there to be 14 bytes to read. So, while(Serial.available() < 14) { // Do nothing } makes it very clear that you are waiting for 14 characters. Your goto mess does not.
|
|
|
|
|
Logged
|
|
|
|
|
Australia
Offline
Jr. Member
Karma: 0
Posts: 59
char CoolThings[] = "Vegemite", "Swimming", "Arduino";
|
 |
« Reply #14 on: July 12, 2012, 09:21:26 am » |
Your goto mess does not. Why is Goto considered a 'mess', may I ask?
|
|
|
|
|
Logged
|
|
|
|
|
|