I'm using Arduino UNO R3 and a Sparkfun RFID-Shield. What I want to do is to read out RFID-Tags and display a special value which depends on the Tag-ID on a 2x16 LCD display. My problem: The Tag-ID is saved in an array. How can I make that to a variable which I can use in an if-statement? Here's the code that prints the Tag-ID to the LCD:
/*
RFID Eval 13.56MHz Shield example sketch v10
Aaron Weiss, aaron at sparkfun dot com
OSHW license: http://freedomdefined.org/OSHW
works with 13.56MHz MiFare 1k tags
Based on hardware v13:
D7 -> RFID RX
D8 -> RFID TX
D9 -> XBee TX
D10 -> XBee RX
Note: RFID Reset attached to D13 (aka status LED)
Note: be sure include the SoftwareSerial lib, http://arduiniana.org/libraries/newsoftserial/
Usage: Sketch prints 'Start' and waits for a tag. When a tag is in range, the shield reads the tag,
blinks the 'Found' LED and prints the serial number of the tag to the serial port
and the XBee port.
06/04/2013 - Modified for compatibility with Arudino 1.0. Seb Madgwick.
*/
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(6, 9, 5, 1, 3, 0);
SoftwareSerial rfid(7, 8);
SoftwareSerial xbee(10, 9);
//Prototypes
void check_for_notag(void);
void halt(void);
void parse(void);
void print_serial(void);
void read_serial(void);
void seek(void);
void set_flag(void);
//Global var
int flag = 0;
int Str1[11];
//INIT
void setup()
{
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(" Wilkommen!");
// set the data rate for the SoftwareSerial ports
rfid.begin(19200);
delay(10);
halt();
}
//MAIN
void loop()
{
read_serial();
}
void check_for_notag()
{
seek();
delay(10);
parse();
set_flag();
if(flag = 1){
seek();
delay(10);
parse();
}
}
void halt()
{
//Halt tag
rfid.write((uint8_t)255);
rfid.write((uint8_t)0);
rfid.write((uint8_t)1);
rfid.write((uint8_t)147);
rfid.write((uint8_t)148);
}
void parse()
{
while(rfid.available()){
if(rfid.read() == 255){
for(int i=1;i<11;i++){
Str1[i]= rfid.read();
}
}
}
}
void print_serial()
{
if(flag == 1){
//print to serial port
lcd.setCursor(0, 1);
lcd.print(Str1[8], HEX);
lcd.print(Str1[7], HEX);
lcd.print(Str1[6], HEX);
lcd.print(Str1[5], HEX);
delay(100);
check_for_notag();
}
}
void read_serial()
{
seek();
delay(10);
parse();
set_flag();
print_serial();
delay(100);
}
void seek()
{
//search for RFID tag
rfid.write((uint8_t)255);
rfid.write((uint8_t)0);
rfid.write((uint8_t)1);
rfid.write((uint8_t)130);
rfid.write((uint8_t)131);
delay(10);
}
void set_flag()
{
if(Str1[2] == 6){
flag++;
}
if(Str1[2] == 2){
flag = 0;
}
}
Ok so I can get every single value into a variable. But I want to have one variable which contains all values. So how can I make one variable of those - in my case 11- values?
This is crap. Just because there is one byte to read does NOT mean that you can read 11 bytes.
The Tag-ID is saved in an array. How can I make that to a variable
An array IS a variable.
which I can use in an if-statement?
You can't. You can pass the array to a function, and use the value returned by a function in an if statement. For instance, you might pass the array to memcmp() and use the return value in an if statement:
all the functions you mentioned are originally like that in the Sparkfun Code. As they work like that and I'm not quite familiar with Arduino I don't want to change anything there. Could you please explain to me what this does exactly and why I need another array:
arduino2013:
Ok so I can get every single value into a variable. But I want to have one variable which contains all values. So how can I make one variable of those - in my case 11- values?
You can't. The array contains all the values. You can access them, one at a time.
Could you please explain to me what this does exactly and why I need another array:
The first part of that google will help you with.
As for the second part, presumably you want to implement something like "If the tag that was scanned was the blue one, open the door. If the tag scanned was the red one, honk the horn. If the tag scanned was the yellow one, turn the headlights on". How is the Arduino supposed to know that the tag is the blue one, the red one, or the yellow one? The tags have values, right? You store those values in arrays, and then compare the array containing the just scanned tag's value with the array containing the blue tag's value. They either match, so you open the door, or they don't, and the door stays shut. If the scanned tag is not the blue one, you could then compare the value with the red tag's value, and so on.
all the functions you mentioned are originally like that in the Sparkfun Code.
Sparkfun has some good code (though not all that much), but they have a lot of crap, too. If behooves you to learn which is which, and to learn to write good code (or at least proper code) to replace the crappy code.
If you need to read 11 values, there are two ways to do it. One is to read and store the data as it becomes available, and deal with it when the 11th byte arrives. The other is to ignore the data until 11 bytes are in the buffer, and then read it all at once (as that code does).
So the problem is that when I use the changed code by PaulS it displays the correct Tag-ID when I try it for the first time. But when I read the same Tag again it displays things like FFFFFFFF instead of the Tag-ID and even changes the values for the same tag to things like 20FF42FF. Here's the current code:
/*
RFID Eval 13.56MHz Shield example sketch v10
Aaron Weiss, aaron at sparkfun dot com
OSHW license: http://freedomdefined.org/OSHW
works with 13.56MHz MiFare 1k tags
Based on hardware v13:
D7 -> RFID RX
D8 -> RFID TX
D9 -> XBee TX
D10 -> XBee RX
Note: RFID Reset attached to D13 (aka status LED)
Note: be sure include the SoftwareSerial lib, http://arduiniana.org/libraries/newsoftserial/
Usage: Sketch prints 'Start' and waits for a tag. When a tag is in range, the shield reads the tag,
blinks the 'Found' LED and prints the serial number of the tag to the serial port
and the XBee port.
06/04/2013 - Modified for compatibility with Arudino 1.0. Seb Madgwick.
*/
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(6, 9, 5, 1, 3, 0);
SoftwareSerial rfid(7, 8);
SoftwareSerial xbee(10, 9);
//Prototypes
void check_for_notag(void);
void halt(void);
void parse(void);
void print_serial(void);
void read_serial(void);
void seek(void);
void set_flag(void);
//Global var
int flag = 0;
int Str1[11];
//INIT
void setup()
{
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(" Wilkommen!");
// set the data rate for the SoftwareSerial ports
rfid.begin(19200);
delay(10);
halt();
}
//MAIN
void loop()
{
read_serial();
}
void check_for_notag()
{
seek();
delay(10);
parse();
set_flag();
if(flag = 1){
seek();
delay(10);
parse();
}
}
void halt()
{
//Halt tag
rfid.write((uint8_t)255);
rfid.write((uint8_t)0);
rfid.write((uint8_t)1);
rfid.write((uint8_t)147);
rfid.write((uint8_t)148);
}
void parse()
{
if(rfid.available() >= 11)
{
if(rfid.read() == 255)
{
for(int i=1;i<11;i++)
{
Str1[i]= rfid.read();
}
}
}
}
void print_serial()
{
if(flag == 1){
//print to serial port
lcd.setCursor(0, 1);
lcd.print(Str1[8], HEX);
lcd.print(Str1[7], HEX);
lcd.print(Str1[6], HEX);
lcd.print(Str1[5], HEX);
delay(100);
check_for_notag();
}
}
void read_serial()
{
seek();
delay(10);
parse();
set_flag();
print_serial();
delay(100);
}
void seek()
{
//search for RFID tag
rfid.write((uint8_t)255);
rfid.write((uint8_t)0);
rfid.write((uint8_t)1);
rfid.write((uint8_t)130);
rfid.write((uint8_t)131);
delay(10);
}
void set_flag()
{
if(Str1[2] == 6){
flag++;
}
if(Str1[2] == 2){
flag = 0;
}
}
The parse() function now may not actually read anything. It should return a value indicating whether or not it did read data. If it didn't, there is no sense calling set_flag() or print_serial().
You asked why sometimes you get good results and sometimes you don't. I pointed out that sometimes parse() reads something, and sometimes it doesn't. When it does, you get good results. When it doesn't, you don't.
It's easy to have parse() return one value if it read data, and another if it doesn't. Whether you elect to do that, and whether you elect to use the result to determine whether or not to perform the follow on steps (that are the part that produce the erroneous results), only you can decide.
It's easy to have parse() return one value if it read data, and another if it doesn't.
So how do I do that?
I've got another problem: when I read a Tag it displays the ID but I want to have some text on the LCD if there's no tag. I tried to realize that by the following code but unfortunately it overwrites my message but doesn't completely delete it. How can I fix that?
In addition it should display the message again when the Tag is out of range. How to realize that?
My code:
/*
RFID Eval 13.56MHz Shield example sketch v10
Aaron Weiss, aaron at sparkfun dot com
OSHW license: http://freedomdefined.org/OSHW
works with 13.56MHz MiFare 1k tags
Based on hardware v13:
D7 -> RFID RX
D8 -> RFID TX
D9 -> XBee TX
D10 -> XBee RX
Note: RFID Reset attached to D13 (aka status LED)
Note: be sure include the SoftwareSerial lib, http://arduiniana.org/libraries/newsoftserial/
Usage: Sketch prints 'Start' and waits for a tag. When a tag is in range, the shield reads the tag,
blinks the 'Found' LED and prints the serial number of the tag to the serial port
and the XBee port.
06/04/2013 - Modified for compatibility with Arudino 1.0. Seb Madgwick.
*/
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(6, 9, 5, 1, 3, 0);
SoftwareSerial rfid(7, 8);
SoftwareSerial xbee(10, 9);
//Prototypes
void check_for_notag(void);
void halt(void);
void parse(void);
void print_serial(void);
void read_serial(void);
void seek(void);
void set_flag(void);
//Global var
int flag = 0;
int Str1[11];
//INIT
void setup()
{
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(" Wilkommen!");
// set the data rate for the SoftwareSerial ports
rfid.begin(19200);
delay(10);
halt();
}
//MAIN
void loop()
{
read_serial();
}
void check_for_notag()
{
seek();
delay(10);
parse();
set_flag();
if(flag = 1){
seek();
delay(10);
parse();
}
}
void halt()
{
//Halt tag
rfid.write((uint8_t)255);
rfid.write((uint8_t)0);
rfid.write((uint8_t)1);
rfid.write((uint8_t)147);
rfid.write((uint8_t)148);
}
void parse()
{
if(rfid.available() >= 11)
{
if(rfid.read() == 255)
{
for(int i=1;i<11;i++)
{
lcd.setCursor(0,1);
Str1[i]= rfid.read();
}
}
}
else {lcd.setCursor(0,1); lcd.print("Chip auflegen");}
}
void print_serial()
{
if(flag == 1){
//print to serial port
lcd.setCursor(0, 1);
lcd.print(Str1[8], HEX);
lcd.print(Str1[7], HEX);
lcd.print(Str1[6], HEX);
lcd.print(Str1[5], HEX);
delay(100);
check_for_notag();
}
}
void read_serial()
{
seek();
delay(10);
parse();
set_flag();
print_serial();
delay(100);
}
void seek()
{
//search for RFID tag
rfid.write((uint8_t)255);
rfid.write((uint8_t)0);
rfid.write((uint8_t)1);
rfid.write((uint8_t)130);
rfid.write((uint8_t)131);
delay(10);
}
void set_flag()
{
if(Str1[2] == 6){
flag++;
}
if(Str1[2] == 2){
flag = 0;
}
}
You try something. You don't keep expecting others to write your code for you for free.
lcd.setCursor(0,1);
Why do you need to set the cursor to the same place 10 times?
tried to realize that by the following code but unfortunately it overwrites my message but doesn't completely delete it. How can I fix that?
With vague terms like "it overwrites", "doesn't completely delete it", "fix that", etc., I doubt that you can fix it.
In addition it should display the message again when the Tag is out of range.
First, you modify the reader. It sends data when a tag comes in range. It sends nothing when there is no tag in range, or if the tag stays in range. You need to modify the hardware to keep bleating "I'm lonely; there are no tags around..." as long as there are no tags.
PaulS,
I agree to your approach of not spoon-feeding. I also appreciate your guidance though you are not writing code for us(offcourse for free of cost) but your guidance plays a major role in grooming of our programming skills and out-of-the-box analytical thinking.
I am great fan of yours.
Regards