Hi, I'm working on an RFID door lock system. For now I'm just trying to get my program to distinguish between a "good" card and a "bad" card. My problem is that it is reading the card in Hex (pretty sure) and when I try to use that number in the program, there's an error saying it's an invalid interger. I really haven't had much experience with programming so any help is appreciated.
// RFID reader for Arduino
// Wiring version by BARRAGAN <http://people.interaction-ivrea.it/h.barragan>
// Modified for Arudino by djmatic
int val = 0;
char code[10];
int bytesread = 0;
void setup() {
Serial.begin(2400); // RFID reader SOUT pin connected to Serial RX pin at 2400bps
pinMode(2,OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(2, LOW); // Activate the RFID reader
}
void loop() {
if(Serial.available() > 0) { // if data available from reader
if((val = Serial.read()) == 10) { // check for header
bytesread = 0;
while(bytesread<10) { // read 10 digit code
if( Serial.available() > 0) {
val = Serial.read();
if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading
break; // stop reading
}
code[bytesread] = val; // add the digit
bytesread++; // ready to read next digit
}
}
if(bytesread == 10) { // if 10 digit read is complete
Serial.print("TAG code is: "); // possibly a good TAG
Serial.println(code); // print the TAG code
}
bytesread = 0;
digitalWrite(2, HIGH); // deactivate the RFID reader for a moment so it will not flood
delay(1500); // wait for a bit
digitalWrite(2, LOW); // Activate the RFID reader
}
}
}
// extra stuff
// digitalWrite(2, HIGH); // deactivate RFID reader
That's the stock code I'm running from the arduino website.
Perhaps there's a way to get it to just read in decimal instead of hex?
The value being read from the RFID tag is reported as neither HEX or decimal. It is a string of characters. You need to use strcmp() to compare that string to a (set of) known value(s).
and add code[bytesread]=0 before the if (bytesread==10).
the code you read is a string, so you usually need to convert it and you can try to use the sscanf function, i.e.:
unsigned long value;
sscanf(code,"%x", &value); // if hex string
BUT (and this is crucially important), the RFID will give you a 40 bits code, which does not fit in a 32bit unsigned integer value.
So, if you convert it in an unsigned long you loose 8bits. Even worse, if you use unsigned int you will loose much more. You should continue to use the string as is for further processing.
I agree. Treat the string of characters as a string of characters.
Might be a good time to use the String type:
// PARALLAX RFID VCC to Arduino 5V
// PARALLAX RFID /ENABLE to Arduino D2
// PARALLAX RFID SOUT to Arduino D3
// PARALLAX RFID GND to Arduino Gnd
// Modified by Worapoht K.
#include <SoftwareSerial.h>
int val = 0;
String code;
int bytesread = 0;
#define enablePin 2
#define rxPin 3
#define txPin 4
SoftwareSerial RFID = SoftwareSerial(rxPin, txPin);
#define START_CHAR 10
#define END_CHAR 13
void setup()
{
Serial.begin(9600); // Hardware serial for Monitor 2400bps
RFID.begin(2400); // RFID reader SOUT at 2400bps
pinMode(enablePin,OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(enablePin, LOW); // Activate the RFID reader
}
void loop()
{
digitalWrite(enablePin, LOW); // Activate the RFID reader
code = "";
// Wait for header byte
while(RFID.read() != START_CHAR) ;
for (bytesread = 0; bytesread < 10; bytesread++)
{
val = RFID.read();
if (val == END_CHAR)
break;
code += val; // append the character
}
digitalWrite(enablePin, HIGH); // Deactivate the RFID reader
if (bytesread == 10)
{ // if 10 digit read is complete
Serial.print("TAG code is: "); // possibly a good TAG
Serial.println(code); // print the TAG code
if (code == "48524953696548555648")
Serial.println("That's the round tag.");
if (code == "48704851485249505067")
Serial.println("That's the rectangular tag.");
}
delay(1000); // wait for a second
}
I notice that my Parallax RFID was getting spurious hits. Probably best to check the END_CHAR as well as the START_CHAR rather than accepting nay 10 characters that follow a START_CHAR:
{code]
// PARALLAX RFID VCC to Arduino 5V
// PARALLAX RFID /ENABLE to Arduino D2
// PARALLAX RFID SOUT to Arduino D3
// PARALLAX RFID GND to Arduino Gnd
// Modified by Worapoht K.
#include <SoftwareSerial.h>
#define enablePin 2
#define rxPin 3
#define txPin 4
SoftwareSerial RFID = SoftwareSerial(rxPin, txPin);
#define START_CHAR 10
#define END_CHAR 13
void setup()
{
Serial.begin(9600); // Hardware serial for Monitor 2400bps
RFID.begin(2400); // RFID reader SOUT at 2400bps
pinMode(enablePin,OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(enablePin, LOW); // Activate the RFID reader
}
void loop()
{
int bytesread, val;
String code = "";
digitalWrite(enablePin, LOW); // Activate the RFID reader
// Wait for header byte
while(RFID.read() != START_CHAR)
/* DO NOTHING */ ;
bytesread = 0;
while ((val = RFID.read()) != END_CHAR)
{
if (val == START_CHAR)
break; // Bad frame
bytesread++;
if (bytesread > 10)
break; // Too many characters
code += val; // append the character
}
digitalWrite(enablePin, HIGH); // Deactivate the RFID reader
if (bytesread == 10) // Valid read. 10 characters + END_CHAR
{ // if 10 digit read is complete
if (code == "48524953696548555648")
Serial.println("That's the round tag.");
else
if (code == "48704851485249505067")
Serial.println("That's the rectangular tag.");
else
{
Serial.print("Unrecognized code: "); // possibly a good TAG
Serial.println(code); // print the TAG code
}
}
delay(1000); // wait for a second
}
So here's the modified version of your code that I'm going to use. It needs a little bit of work yet, as there is a bug that leaves pin 4 active from when the program starts running until you swipe a good card. But I think I'll just deal with it and swipe a card when i start it up.
// PARALLAX RFID VCC to Arduino 5V
// PARALLAX RFID /ENABLE to Arduino D2
// PARALLAX RFID SOUT to Arduino D3
// PARALLAX RFID GND to Arduino Gnd
// Modified by Alex G.
#include <SoftwareSerial.h>
#define enablePin 2
#define rxPin 3
#define txPin 4
SoftwareSerial RFID = SoftwareSerial(rxPin, txPin);
#define START_CHAR 10
#define END_CHAR 13
void setup()
{
Serial.begin(9600); // Hardware serial for Monitor 2400bps
RFID.begin(2400); // RFID reader SOUT at 2400bps
pinMode(enablePin,OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(enablePin, LOW); // Activate the RFID reader
pinMode(4,OUTPUT); // Set digital pin 4 as OUTPUT to connect it to the lock relay
pinMode(5,OUTPUT); // Set digital pin 5 as OUTPUT to connect it to the buzzer
}
void loop()
{
int bytesread, val;
String code = "";
digitalWrite(enablePin, LOW); // Activate the RFID reader
// Wait for header byte
while(RFID.read() != START_CHAR)
/* DO NOTHING */ ;
bytesread = 0;
while ((val = RFID.read()) != END_CHAR)
{
if (val == START_CHAR)
break; // Bad frame
bytesread++;
if (bytesread > 10)
break; // Too many characters
code += val; // append the character
}
digitalWrite(enablePin, HIGH); // Deactivate the RFID reader
if (bytesread == 10) // Valid read. 10 characters + END_CHAR
{ // if 10 digit read is complete
if (code == "50544848685656485166","50544848685667505470") // add allowed tags in this area
{
Serial.println("That's a good tag."); // good tag
digitalWrite(4,HIGH); // activate lock relay for 5 seconds
delay(5000);
digitalWrite(4,LOW);
}
else
{
Serial.print("Invalid Tag: "); // tag not allowed. Use this number from the serial monitor to add new cards to program.
Serial.println(code); // print the TAG code
digitalWrite(5, HIGH); // sound buzzer or alarm for 3 seconds
delay(3000);
digitalWrite(5, LOW);
}
}
delay(1000); // wait for a second
}
Thanks again for the help. The only other code I found for a similar project was on Instructables. But I like having the ability to put the tags into the program myself instead of using the Master and Delete cards. Hopefully this helps out somebody else in the future as well.