Author Topic: string comparing issue  (Read 1919 times)

0 Members and 1 Guest are viewing this topic.

Offline King123Topic starter

  • Contributor
  • Posts: 18
  • Country: in
string comparing issue
« on: August 23, 2022, 06:49:38 pm »

My Arduino mega 2560 with RFID-em18  reader but  I am stuck in my program. I want to give access to only five cards , if any other card is scanned except these , it should not get access

I want to gives access to following cards just for testing

Code: [Select]
FF0064F9D492
FF0064F9D492
FF0064F6D41C
FF0064F9D482
FF0064F6D47C

This is my sketch that check and compare only one tag. It's working fine
Code: [Select]
char tag[] ="FF0064F9D492"; // Replace with your own Tag ID
char input[12];        // A variable to store the Tag ID being presented
int count = 0;        // A counter variable to navigate through the input[] character array
boolean flag = 0;     // A variable to store the Tag match status
void setup()
{
  Serial.begin(9600);   // Initialise Serial Communication with the Serial Monitor
  Serial1.begin(9600);
}
void loop()
{
  if(Serial1.available())// Check if there is incoming data in the RFID Reader Serial Buffer.
  {
    count = 0; // Reset the counter to zero
    /* Keep reading Byte by Byte from the Buffer till the RFID Reader Buffer is empty
       or till 12 Bytes (the ID size of our Tag) is read */
    while(Serial1.available() && count < 12)
    {
      input[count] = Serial1.read(); // Read 1 Byte of data and store it in the input[] variable
      count++; // increment counter
      delay(5);
    }
    /* When the counter reaches 12 (the size of the ID) we stop and compare each value
        of the input[] to the corresponding stored value */
    if(count == 12) //
    {
      count =0; // reset counter varibale to 0
      flag = 1;
      /* Iterate through each value and compare till either the 12 values are
         all matching or till the first mistmatch occurs */
      while(count<12 && flag !=0) 
      {
        if(input[count]==tag[count])
        flag = 1; // everytime the values match, we set the flag variable to 1
        else
        flag= 0;
                               /* if the ID values don't match, set flag variable to 0 and
                                  stop comparing by exiting the while loop */
        count++; // increment i
      }
    }
    if(flag == 1) // If flag variable is 1, then it means the tags match
    {
      Serial.println("Access Allowed!");
 
    }
    else
    {
      Serial.println("Access Denied"); // Incorrect Tag Message
    }
    /* Fill the input variable array with a fixed value 'F' to overwrite
    all values getting it empty for the next read cycle */
    for(count=0; count<12; count++)
    {
      input[count]= 'F';
    }
    count = 0; // Reset counter variable
  }
}

I am struggling to check multiple tags in loop

Code: [Select]
char tag[][13] = {"FF0064F9D492", "FF0064F9D492", "FF0064F6D41C", "FF0064F9D482", "FF0064F6D47C"};
I am struggling following part of program How to compare each tags in code
Code: [Select]
     while(Serial1.available() && count < 12)
    {
      input[count] = Serial1.read(); // Read 1 Byte of data and store it in the input[] variable
      count++; // increment counter
      delay(5);
    }
    /* When the counter reaches 12 (the size of the ID) we stop and compare each value
        of the input[] to the corresponding stored value */
    if(count == 12) //
    {
      count =0; // reset counter varibale to 0
      flag = 1;
      /* Iterate through each value and compare till either the 12 values are
         all matching or till the first mistmatch occurs */
      while(count<12 && flag !=0)
      {
        if(input[count]==tag[count])
        flag = 1; // everytime the values match, we set the flag variable to 1
        else
        flag= 0;
                               /* if the ID values don't match, set flag variable to 0 and
                                  stop comparing by exiting the while loop */
        count++; // increment i
      }
    }
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 28724
  • Country: nl
    • NCT Developments
Re: string comparing issue
« Reply #1 on: August 23, 2022, 07:00:14 pm »
Why aren't you using  strcmp() or strncmp() from the standard C library (string.h) to compare? You'll need an extra loop to go through the list with tags. The tags array has 2 dimensions! Create a flow chart of your program first.

A good option would be to test your code on a PC first. Step through it with a debugger to verify the program does what you intend it to do.
« Last Edit: August 23, 2022, 07:03:50 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16280
  • Country: fr
Re: string comparing issue
« Reply #2 on: August 23, 2022, 07:31:11 pm »
Why aren't you using  strcmp() or strncmp() from the standard C library (string.h) to compare?

Probably because they don't know about them? From the little I've seen - I may have missed something though - the OP is trying to compare strings with the '==' operator. Well, uh. Nope.
They need to learn C. Not sure the whole Arduino thing really pushes people to properly learn, I dunno.
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 560
  • Country: sk
Re: string comparing issue
« Reply #3 on: August 23, 2022, 07:49:55 pm »
For strcmp() to work, the string has to be ASCIIZ i.e. zero terminated. And for that, one extra char has to be allocated
Code: [Select]
char input[12 + 1];        // A variable to store the Tag ID being presented, plus one place for the NULL char: input[12] = '\0';

Also, #include <string.h> has to be added at the beginning.

JW
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4990
  • Country: dk
Re: string comparing issue
« Reply #4 on: August 23, 2022, 08:57:33 pm »
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 879
Re: string comparing issue
« Reply #5 on: August 23, 2022, 08:58:35 pm »
You can use the C++ range based for loop which would simplify-
https://godbolt.org/z/vdzjhbKzf

and if you want to print the input string, will want to 0 terminate input (and then can also use strcmp since 0 terminated)-
https://godbolt.org/z/Yv8vPv8nP
« Last Edit: August 23, 2022, 09:10:56 pm by cv007 »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16280
  • Country: fr
Re: string comparing issue
« Reply #6 on: August 24, 2022, 12:19:18 am »
You can use the C++ range based for loop which would simplify-
https://godbolt.org/z/vdzjhbKzf

and if you want to print the input string, will want to 0 terminate input (and then can also use strcmp since 0 terminated)-
https://godbolt.org/z/Yv8vPv8nP

- Problem with using C++ features is, why we know that Arduino is using C++ under the hood, we never know exactly how much of it is actually allowed/supported. For instance, using std C++ strings (not C) is probably not recommended. It's rather unclear what subset of C++ is allowed and the official description on Arduino's website doesn't help much.
- As to comparing strings here, rather than fiddle with adding a terminal zero, the OP can just use memcmp() instead of strcmp() on 12 bytes. It will probably even be slightly faster.
 

Offline King123Topic starter

  • Contributor
  • Posts: 18
  • Country: in
Re: string comparing issue
« Reply #7 on: August 24, 2022, 12:32:35 am »
You can use the C++ range based for loop which would simplify-
https://godbolt.org/z/vdzjhbKzf

and if you want to print the input string, will want to 0 terminate input (and then can also use strcmp since 0 terminated)-
https://godbolt.org/z/Yv8vPv8nP
I ran code and check tag but doesn't print anything
Code: [Select]
#include "Arduino.h"

const char* cards_allow[]{
    "FF0064F9D492",
    "FF0064F9D492",
    "FF0064F6D41C",
    "FF0064F9D482",
    "FF0064F6D47C"
};

void setup() {
  // put your setup code here, to run once:
  Serial1.begin(9600); 
}

void loop(){

    static const auto CARD_SIZE{ 12 };
    static uint8_t count;
    static char input[CARD_SIZE];

    while( Serial1.available() and (count < CARD_SIZE) ) input[count++] = Serial1.read();
    if( count < CARD_SIZE ) return;

    bool found = false;
    for( auto card : cards_allow ){
        if( strncmp(card, input, CARD_SIZE) == 0 ){
            found = true;
            break;
        }
    }

    Serial.println( found ? "Access Allowed!" : "Access Denied" );

    count = 0;

    if( found ){ /* do something */ }
    Serial.println("Allowed");

}
 

Offline fourfathom

  • Super Contributor
  • ***
  • Posts: 2042
  • Country: us
Re: string comparing issue
« Reply #8 on: August 24, 2022, 12:58:43 am »
Echo the characters as they are received to see what you are getting.  You might need to flush the receive buffer before trying to read in the ID number.
We'll search out every place a sick, twisted, solitary misfit might run to! -- I'll start with Radio Shack.
 

Offline King123Topic starter

  • Contributor
  • Posts: 18
  • Country: in
Re: string comparing issue
« Reply #9 on: August 24, 2022, 01:17:52 am »
Echo the characters as they are received to see what you are getting.  You might need to flush the receive buffer before trying to read in the ID number.
What happens in following line ? Does there need to add delay
Code: [Select]
while( Serial1.available() and (count < CARD_SIZE) ) input[count++] = Serial1.read();
    if( count < CARD_SIZE ) return;
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 5065
  • Country: nz
Re: string comparing issue
« Reply #10 on: August 24, 2022, 01:52:58 am »
Why aren't you using  strcmp() or strncmp() from the standard C library (string.h) to compare?

Probably because they don't know about them? From the little I've seen - I may have missed something though - the OP is trying to compare strings with the '==' operator. Well, uh. Nope.

They are using == to compare CHARACTERS, which is fine.

Quote
They need to learn C. Not sure the whole Arduino thing really pushes people to properly learn, I dunno.

Everyone needs to start somewhere. Attracting beginners and enabling them to do cool things is a strength of Arduino, not a fault.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 879
Re: string comparing issue
« Reply #11 on: August 24, 2022, 02:10:58 am »
Quote
we know that Arduino is using C++ under the hood, we never know exactly how much of it is actually allowed/supported. For instance, using std C++ strings (not C) is probably not recommended. It's rather unclear what subset of C++ is allowed and the official description on Arduino's website doesn't help much.
The C++ compiler will certainly tell you when you use something not supported. A range based for loop has been around for a long time (C++11?), and can certainly be used here. There is also nothing preventing standard library replacements, since you have the same underlying language the standard library writer does. There is no standard library strings for avr (arduino does their own version), but its not needed in this case. The array of const char pointers is nothing special, and a range base for loop can easily iterate through those pointers.

The C++ language is always available when using a C++ compiler, regardless of whether you use a standard library (if available). I use C++ all the time, no C++ standard library. If you use arduino, no reason to leave all the C++ features on the shelf. You are 'allowed' to use anything the compiler version allows (gcc 7.3.0 = c++17), and arduino has no say in what you 'may' use.

You can simulate this code for a pc, where the online compiler will produce output you can read-
https://godbolt.org/z/MsE31q5b9
The arduino Serial class is simulated, so you have to provide a (read) string to it when creating the Serial1 instance. Change the string to see different results. Instead of strcmp, strcasecmp was also used so case can also be different.

Another version where you can set the 'read' string at runtime to test various numbers-
https://godbolt.org/z/3Kozxbba3

(the print output is in the right panel)



Quote
I ran code and check tag but doesn't print anything
That code was using Serial in a few places where Serial1 should have been used, which was a mistake.
« Last Edit: August 24, 2022, 02:30:04 am by cv007 »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16280
  • Country: fr
Re: string comparing issue
« Reply #12 on: August 24, 2022, 03:56:26 am »
Why aren't you using  strcmp() or strncmp() from the standard C library (string.h) to compare?

Probably because they don't know about them? From the little I've seen - I may have missed something though - the OP is trying to compare strings with the '==' operator. Well, uh. Nope.

They are using == to compare CHARACTERS, which is fine.

That's messier than this: they are comparing a character with a string (which led me to believe they were trying to just compare strings, but that wasn't even it), since 'tag' is an array of strings from what they gave us?

So anyway - just use memcmp() and call it a day, since all strings in 'tag' have the same length.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf