How to get one variable out of all values of an array

Hi there,

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;
  }
}

Thanks in advance
arduino2013

How can I make that to a variable which I can use in an if-statement?

var = array[index];
if (var == somevalue) ...

TIP: Read the tutorial section about Arrays

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?

  if(flag = 1){

This is STILL wrong. Don't start new topics just because you don't like being told your code is wrong. Fix the damned problems.

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);
}

This is a dumb name for a function. It does not describe AT ALL what the function is doing.

  while(rfid.available()){
    if(rfid.read() == 255){
      for(int i=1;i<11;i++){
        Str1[i]= rfid.read();
      }
    }
  }

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:

if(memcmp(Str, SomeOtherArrayWithValidTagData) == 27)
{
}

Of course, you'll need to look up what the possible return types are, and decide what the if statement should then look like.

Hi PaulS,

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:

if(memcmp(Str, SomeOtherArrayWithValidTagData) == 27)
{
}

Thanks
arduino2013

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.

But how can I check if a certain Tag is on the reader?

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).

  while(rfid.available()){
    if(rfid.read() == 255){
      for(int i=1;i<11;i++){
        Str1[i]= rfid.read();
      }
    }
  }

should be:

  if(rfid.available() >= 11)
  {
    if(rfid.read() == 255)
    {
      for(int i=1;i<11;i++)
      {
        Str1[i]= rfid.read();
      }
    }
  }

Ok so I replaced that part that PaulS told me to. But unfortunately it doesn't display the correct Tag-ID anymore HOw to fix that?

But unfortunately it doesn't display the correct Tag-ID anymore

How do you know what "correct" is?

How do you know what "correct" is?

And what does "it" display, instead, and where is "it"?

Presumably "it" is code you have modified, and that you now expect us to guess what it looks like.

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;
  }
}

How can I fix that?

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().

So what does that mean for my problem?

So what does that mean for my problem?

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;
  }
}

So how do I do that?

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

Hi PaulS,

so I resolved the problem with the message myself. Could you explain me how to filter out the wrong IDs, please?

Thanks a lot.