Extracting data from a serially written string (buffer)

Hi. I am working on a project with NFC chips and I need to be able to make a comparison between the date coming from the chip and a set of preset values to make something happen.

I'm using the NFRC522 library from RFID Master.

I have programmed the chips for example with the word ONE, TWO, THREE etc.

The part of the code that reads the serial data from the chip is as follows:

Serial.print(F("Read data: "));
//Dump a byte array to Serial
for (byte i = 0; i < 15; i++) {

Serial.write(buffer*);*
}
It seems to me that the code is taking 1 byte from the chip at a time and combining them together until the whole 16 byte word is read.
My question is: How do I get to access that information so I can do my comparisons. I can't use buffer as a variable, it won't work.
I am a relative newbie and I would be grateful for any help.
Thanks
Jim

My question is: How do I get to access that information so I can do my comparisons.

It's all in the array called "buffer".

Please remember to use code tags when posting code.

Thanks for the information.

Let's say the data in the buffer was "123ABC001"

What function would I have to use to compare the value of the buffer with a preset value, for example "124ABD001"

So far I'm over my head in examples from other sites and hardly any of them seem to do what I want to do.

Once again, advice truly appreciated.

Thanks.

Jim

If the data is a null-terminated C string, use strcmp (or its near relatives) otherwise, use memcmp

If the data in buffer is terminated by a zero then it is a C style string (lowercase s) and can be compared with other C style strings by using the strcmp() function. However, it may be that buffer is a String (uppercase S) in which case it can be compared with other Strings using the normal C comparison operators such as == and !=

Please post the complete program

Hi Guys, Thanks for the advice. I using the rfid-master library which contains lots of examples on how to write / read to NFC cards. The particular example I'm using is contained in the library. I removed the write function as I only want to read.

When a card is read lines 79 to 87 appear to read data serially from the car to fill the buffer.

What I want to do is compare what's in the buffer with preset value(s) to make things happen appropriately. In the part of the code I included there is a sub called buzzone, which makes a small vibrating motor run for about 500ms then stop.

There were other lines of code with more buzzer operations that I left off for the sake of brevity.

I hope I got the right idea about the code tags

Thanks in advance

Jim

#include <SPI.h>

#include <deprecated.h>
#include <MFRC522.h>
#include <MFRC522Extended.h>
#include <require_cpp11.h>


/* mifare ultralight example (25-02-2018)
 * 
 *   RFID-RC522 (SPI connexion)
 *   
 *   CARD RC522      Arduino (UNO)
 *     SDA  -----------  10 (Configurable, see SS_PIN constant)
 *     SCK  -----------  13
 *     MOSI -----------  11
 *     MISO -----------  12
 *     IRQ  -----------  
 *     GND  -----------  GND
 *     RST  -----------  9 (onfigurable, see RST_PIN constant)
 *     3.3V ----------- 3.3V
 *     
 */

  #include <SPI.h>
  #include <MFRC522.h>
  
  
  #define SS_PIN          10
  #define RST_PIN         9
  int BuzzerPin = 7;
  int x;

  MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance
  MFRC522::StatusCode status; //variable to get card status
  
  byte buffer[18];  //data transfer buffer (16+2 bytes data+CRC)
  byte size = sizeof(buffer);

  uint8_t pageAddr = 0x06;  //In this example we will write/read 16 bytes (page 6,7,8 and 9).
                            //Ultraligth mem = 16 pages. 4 bytes per page.  
                            //Pages 0 to 4 are for special functions.           
  
void setup() 
{
  pinMode(BuzzerPin, OUTPUT);      // sets the digital pin as output
  Serial.begin(9600); // Initialize serial communications with the PC
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card  
  Serial.println(F("Sketch has been started!"));
  memcpy(buffer,"Jim Hatton ;-)",16);
}

void loop() {
 //Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
    return;
  CardDetected();
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
    return;
  byte block;
  byte len;
  byte buffer2;
 

  // Read data ***************************************************
  Serial.println(F("Reading data ... "));
  //data in 4 block is readed at once.
  status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(pageAddr, buffer, &size);
 
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Read() failed: "));
    BadCard();
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  Serial.print(F("Read data: "));
  //Dump a byte array to Serial
  for (byte i = 0; i < 15; i++) {

    Serial.write(buffer[i]);
    //byte buffer2[16];
    //block = 1;
    //Serial.print(block);
  }{  
  
Serial.print(F("Block ")); Serial.print(block); Serial.print(F(":"));
}
  Serial.println();

  mfrc522.PICC_HaltA();

}
void CardDetected(){
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(50);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
  delay(50);                  // waits for a second
 
}

void  buzzone(){
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(200);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
  delay(200);                  // waits for a second
}

[code/]

When a card is read lines 79 to 87 appear to read data serially from the car to fill the buffer.

In the code you posted this is the line that reads the code from the card and puts it in the buffer array

  status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(pageAddr, buffer, &size);

What do you see if you print buffer immediately afterwards ?

It would be interesting if you printed "> immediately before it and "<" after it on the same line so that leading and/or trailing spaces are visible. If you also print sizeof(buffer) then we should have a better picture of what is going on

Hi

Thanks for the advice. I'm sorry but my brain is simply not in gear. I can't work out how to print the buffer. I've scanned loads of other examples but it still eludes me here. Could you help with this. It probably is trivial to you but it has me beat.

Thanks

I can't work out how to print the buffer.

Serial.print("buffer : >");
Serial.print(buffer);
Serial.println("<");
Serial.print("sizeof(buffer) : ");
Serial.println(sizeof(buffer));

When I try the code you suggest I get the following compiling error:

The second line of your code is highlighted

The error message is: no matching function for call to 'print(byte[18])'

OK. Take out my 4 lines of debugging code.

Your program actually dumps the first 16 characters of the buffer array in this portion of code

  Serial.print(F("Read data: "));
  //Dump a byte array to Serial
  for (byte i = 0; i < 15; i++)
  {
    Serial.write(buffer[i]);
    //byte buffer2[16];
    //block = 1;
    //Serial.print(block);
  }

What do you see ?

What I see is that the data is read from i=0 to i=15 (16 bytes). Each byte is then written to the buffer.

From my own experiments I created some variables (a,b,c,d,e,f,g,h,j,k,l,m,p,q,r) and wrote each byte of i to a consecutive variables, effectively splitting the 16 bytes up into 16 individual values. These values turned out to be decimal values.

I was then able to do the comparison I wanted. it is VERY messy right now but it works. /there must be an easier way to get the data out of the buffer but as an excellent teacher I'm sure you will tease it out of me by making me think hard :slight_smile:

#include <SPI.h>

#include <deprecated.h>
#include <MFRC522.h>
#include <MFRC522Extended.h>
#include <require_cpp11.h>


/* mifare ultralight example (25-02-2018)
 * 
 *   RFID-RC522 (SPI connexion)
 *   
 *   CARD RC522      Arduino (UNO)
 *     SDA  -----------  10 (Configurable, see SS_PIN constant)
 *     SCK  -----------  13
 *     MOSI -----------  11
 *     MISO -----------  12
 *     IRQ  -----------  
 *     GND  -----------  GND
 *     RST  -----------  9 (onfigurable, see RST_PIN constant)
 *     3.3V ----------- 3.3V
 *     
 */

  #include <SPI.h>
  #include <MFRC522.h>
  
  
  #define SS_PIN          10
  #define RST_PIN         9
  int BuzzerPin = 7;
  int x;
  int a;
int b;
int c;
int d;
int e;
int f;
int g;
int h;

int j;
int k;
int l;
int m;

int o;
int p;
int q;
int r;
int n;
  MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance
  MFRC522::StatusCode status; //variable to get card status
  
  byte buffer[18];  //data transfer buffer (16+2 bytes data+CRC)
  byte size = sizeof(buffer);

  uint8_t pageAddr = 0x06;  //In this example we will write/read 16 bytes (page 6,7,8 and 9).
                            //Ultraligth mem = 16 pages. 4 bytes per page.  
                            //Pages 0 to 4 are for special functions.           
  
void setup() 
{
  pinMode(BuzzerPin, OUTPUT);      // sets the digital pin as output
  Serial.begin(9600); // Initialize serial communications with the PC
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522 card  
  Serial.println(F("Sketch has been started!"));
  //memcpy(buffer,"Jim Hatton ;-)",16);
}

void loop() {
 //Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
    return;

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
    return;
  byte block;
  byte len;
  byte buffer2;
 

  // Read data ***************************************************
  Serial.println(F("Reading data ... "));
  //data in 4 block is readed at once.
  status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(pageAddr, buffer, &size);

//serial,print buffer;
 
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Read() failed: "));
    BadCard();
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  Serial.print(F("Readed data: "));
  //Dump a byte array to Serial
  for (byte i = 0; i < 15; i++) {

    Serial.write(buffer[i]);
    Serial.println();
    //Serial.print(buffer[i]);
    //Serial.println();
  }
  {
   a = buffer[0];
    Serial.print (a);
    Serial.print (" ; ");
   b = buffer[1];
   Serial.print (b);
      Serial.print (" ; ");
   c = buffer[2];
   Serial.print (c);
      Serial.print (" ; ");
   d = buffer[3];
   Serial.print (d);
      Serial.print (" ; ");
   e = buffer[4];
   Serial.print (e);
      Serial.print (" ; ");
   f = buffer[5];
   Serial.print (f);
      Serial.print (" ; ");
    g = buffer[6];
   Serial.print (g);
   Serial.print (" ; ");
   h = buffer[7];
       Serial.print (h);
    Serial.print (" ; ");
   j = buffer[8];
   Serial.print (j);
      Serial.print (" ; ");
   k = buffer[9];
   Serial.print (k);
      Serial.print (" ; ");
   l = buffer[10];
   Serial.print (l);
      Serial.print (" ; ");
   m = buffer[11];
   Serial.print (m);
      Serial.print (" ; ");
   o = buffer[12];
   Serial.print (o);
      Serial.print (" ; ");
    p = buffer[13];
   Serial.print (p);
       Serial.print (" ; ");
   q = buffer[14];
   Serial.print (q);
      Serial.print (" ; ");
    r = buffer[15];
   Serial.print (r);

  
  
  if (b == 53){
    buzzfive();
    }
   else {
    CardDetected();
   }
}
  
  {  
  
//Serial.print(F("Block ")); Serial.print(block); Serial.print(F(":"));
}
  Serial.println();

  mfrc522.PICC_HaltA();
 


}
void CardDetected(){
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(50);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
  delay(50);                  // waits for a second
 
}

void  buzzone(){
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
  delay(100);                  // waits for a second
}
void buzztwo(){
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
}
void buzzthree(){
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, HIGH);   // sets the LED on
  delay(100);                  // waits for a second
  digitalWrite(BuzzerPin, LOW);    // sets the LED off
}

What I see is that the data is read from i=0 to i=15 (16 bytes). Each byte is then written to the buffer.

Err, no. It reads 16 bytes from buffer one by one and prints them on the Serial monitor

I actually meant what do you see on the Serial monitor ?

Doh

What I see printed on the screen (sorry I thought you were being cryptic to help me learn what the code meant :slight_smile: kinda like "look at the code grasshopper, what does it tell you "? ) is:

Sketch has been started!
Reading data ...
Readed data: n
5

s
q
u
a
r
e
?(reversed question mark symbol)

110 ; 53 ; 32 ; 83 ; 113 ; 117 ; 97 ; 114 ; 101 ; 254 ; 0 ; 0 ; 0 ; 0 ; 0 ; 0

The last line is the data generated from my messy buffer dump.

The letters you see printed one per line correspond to the ASCII values printed across the page

As you can see, what is printed is "n5 Square" I am guessing that the 254 is and end of data marker.
Does what is printed make any sense in relation to the data you have stored on the card ?

I can't help feeling that you are making this really quite simple task more complicated than it needs to be

Have you tried the examples with the RFID library ?

Hi

I Agree it's a rat's nest of a sketch and I am not feeling proud of it :frowning: I just don't get how to do the simple task of comparing the buffer value with a preset value.

I've searched through all the RFID examples but it's hard not knowing exactly what to look for.

The data from the printout is what is contained on the chip - more or less. The actual data on the chip is

5 Square

An "n" has crept in somewhere but that be a difference between the programmer and this library.

Try this. It is the simplest possible RFID reader sketch that I could come up with whilst helping someone else a while ago

#include <RFID.h>

/*
* Read a card using a mfrc522 reader on the SPI interface
* Pin layout as follows (on Arduino Uno or Nano):
* MOSI: Pin 11 / ICSP-4
* MISO: Pin 12 / ICSP-1
* SCK: Pin 13 / ISCP-3
* SS/SDA: Pin 10
* RST: Pin 9
*/

#include <SPI.h>
#include <RFID.h>

#define SS_PIN 10
#define RST_PIN 9

RFID rfid(SS_PIN, RST_PIN);

int serNum[20];

void setup()
{
  Serial.begin(115200);
  SPI.begin();
  rfid.init();
}

void loop()
{
  if (rfid.isCard())
  {
    if (rfid.readCardSerial())
    {
      for (int x = 0; x < sizeof(serNum); x++)
      {
        Serial.print(rfid.serNum[x]);
        Serial.print(" ");
      }
      Serial.println();
    }
    rfid.halt();
  }
}