Comparing one Array with another Array which is made up out of multiple Arrays

Hi,
I am trying to build a fake phonograph. The idea is, that a hidden rfid chip in a wax cylinder will start an DFPlayer mini, which will in turn play a tune.
I chose a PN5180 RFID reader due to its range, which will give me the opportunity to build gimmicks around the wax cylinder and still be able to read its RFID code.

The Problem I am having is the following:
The RFID Tags of the PN 5180 Reader are Arrays. At least I don't know any better :-). As I want the phonograph to play a lot of songs, I need a lot of tags.
The array looks something like that:

int rfid_id[][8]={
  {0xE1,0xAF,0xE4,0xED,0x50,0x1,0x4,0xE0},//#0
  {0x6C,0x27,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#1
  {0x58,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#2
  {0xE5,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#3
  {0x7C,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#4
 //Loads more
  };

These Arrays, I need to compare to an actual tag being scanned by the RFID reader.
The reader itself reads a code like this:
I found the code online. It is from the Youtube channel "Playful Technology", which I admire a lot. I used it in another project and it works fine.

void RFID(){
        // Variable to store the ID of any tag read by this reader
        uint8_t thisUid[8];
        // Try to read a tag ID (or "get inventory" in ISO15693-speak) 
        ISO15693ErrorCode rc = nfc[i].getInventory(thisUid);
        // If the result code was that a card had been read
        if(rc == ISO15693_EC_OK) {
          // If this is the same ID as we read last frame
          if(memcmp(thisUid, lastUid, 8) == 0) {
          // Nothing to do - move on to the next reader
          continue;
          }
          // If it's a different ID
          else {
          for (int j=0; j<sizeof(thisUid); j++) {
            Serial.print(thisUid[j],HEX);
            Serial.print(",");
          }
          Serial.println();
          // Update the array that keeps track of most recent ID
          memcpy(lastUid, thisUid, sizeof(lastUid[0])*8);
          // Has placing this card solved the puzzle?
          RFIDCompare();
          }
        }
        // If a card cannot be read
        else {
          // Test if we previously knew about a card (in which case it's just been removed
          // The most significant (last) byte of a valid UID should always be 0xE0. e.g. E007C4A509C247A8
          if(lastUid[7] == 0xE0){
          Serial.print("Card ");
          for (int j=0; j<sizeof(lastUid); j++) {
            Serial.print(lastUid[j], HEX);
          }
         Serial.print(" from Reader")
          // Update the array that keeps track of last known ID
          memset(lastUid, 0, sizeof(lastUid[0])*8);
          }
        }
       
        // Slight delay before checking the next reader
        delay(10);
}

The crucial part is where I fall short. I am unable to campare the value from the Reader, called lastUid, to my rfid_id Array.

What I tried looks like this:

void RFIDCompare(){
  for (int i=0; i < NumTags; i++){
    if (memcmp(lastUid, rfid_id[i], 8) != 0)  {
      Serial.println("Wrong");   //degugging information
    }
    else {
      Serial.println("Right");  //degugging information
      MP3(i);  //Plays the Song number i from an SD card. void MP3() is another sub routine
    }
  }
}

The program goes on playing the appropriate song.

I am in no way an experienced programmer, just an enthusiast, so I might be asking something obvious here.

The way I see it, one could either change the RFID tags from Array to Integer (or something else), or there is a nice little method to find the array in the array which relates to the one in the wax cylinder.

From what you have shown, ONLY the first 4 bytes are significant. the rest are all identical. You need to do analysis of ALL the tags you want to use and see if there are other possible ways to shorten the length of the stored tags. If not. are their groups with all similar coding?
Paul

That ist true. I can shorten the length down to the first four.

Can you help me understand how it might help me with the comparison problem. As I said, I am not a professional, so I don't get it.

Always keep the array in ascending order. Begin the search by comparing the first byte of the ID you are looking for to the first byte of each entry in the table. If table byte is greater than the byte you are looking for, you are done, there is no match.
If the first bytes are equal, then also compare the second bytes. If the second array byte is greater than your search byte, you are done, no match.
Do the same logic for bytes 3 and for 4. When 4 is equal, you have a match.
Paul

:slight_smile:
I wish I knew how :slight_smile:
Can you give me a sample code, to start of?

Hello,

It's unclear what is your problem.. You say "The program goes on playing the appropriate song", is it a problem ?

Your RFIDCompare function should work as it is, but you should break the loop when the card is found.

Can you give the output of

for (int j=0; j<sizeof(lastUid); j++) {
    Serial.print(lastUid[j], HEX);
}

Don't try to do it with the program you posted. Use a new program to only do the searching logic until you understand it. Search for sample programs that use arrays.
I would not use the idea you have of two dimension arrays, but define the 4 byte id as a structure with four individual, named, bytes, and then make an array of the structures. The compare then will have a name for each of the 4 bytes, not a double subscript(index).
Paul

The song is not not the problem :slight_smile:
The Code for the first card is : E1AFE4ED5014E0 but
if (memcmp(lastUid, rfid_id[i], 8) != 0) {
will still give me the "Wrong" answer.

And by using the RFIDCompare function it will test every Array in the Array versus the tag before it goes on looping. At least the Serial Monitor does only that :slight_smile:

Edit: I just realized you are using int type, but you must use uint8_t !

Look this example : iHkaI5 - Online C++ Compiler & Debugging Tool - Ideone.com

When you do this memcmp(lastUid, rfid_id[i], 8) when the type is int, then it will check only the first 8 bytes, and because an int is 2 bytes, it would check only the first 4 values of the addresses

1 Like

Thanks a lot. I really appreciate the effort you took doing this. It still doe not work. I never even get a "Right". This is what it shows me:

RFID Setup Finished
Initialising software serial interface...OK!Initialising DFPlayer...OK!
MP3 Setup Complete
New Card Detected on Reader 0... 0x7C, 0x2B, 0xE1, 0xC0, 0x50, 0x1, 0x4, 0xE0, 0x
Reader 0, Datensatz 0. Suche nach; 7C2BE1C05014E0, vergleiche mit: E1AFE4ED5014E0: Falsch
Reader 0, Datensatz 1. Suche nach; 7C2BE1C05014E0, vergleiche mit: 6C27E1C05014E0: Falsch
Reader 0, Datensatz 2. Suche nach; 7C2BE1C05014E0, vergleiche mit: 582BE1C05014E0: Falsch
Reader 0, Datensatz 3. Suche nach; 7C2BE1C05014E0, vergleiche mit: E52BE1C05014E0: Falsch
Reader 0, Datensatz 4. Suche nach; 7C2BE1C05014E0, vergleiche mit: 7C2BE1C05014E0: Falsch
Reader 0, Datensatz 5. Suche nach; 7C2BE1C05014E0, vergleiche mit: FF2BE1C05014E0: Falsch
Reader 0, Datensatz 6. Suche nach; 7C2BE1C05014E0, vergleiche mit: 8E2BE1C05014E0: Falsch
Reader 0, Datensatz 7. Suche nach; 7C2BE1C05014E0, vergleiche mit: E2CE1C05014E0: Falsch
Reader 0, Datensatz 8. Suche nach; 7C2BE1C05014E0, vergleiche mit: 542BE1C05014E0: Falsch
Reader 0, Datensatz 9. Suche nach; 7C2BE1C05014E0, vergleiche mit: C62BE1C05014E0: Falsch
Reader 0, Datensatz 10. Suche nach; 7C2BE1C05014E0, vergleiche mit: 3F2BE1C05014E0: Falsch
Reader 0, Datensatz 11. Suche nach; 7C2BE1C05014E0, vergleiche mit: 8CFE0C05014E0: Falsch
Reader 0, Datensatz 12. Suche nach; 7C2BE1C05014E0, vergleiche mit: DACCE0C05014E0: Falsch
Reader 0, Datensatz 13. Suche nach; 7C2BE1C05014E0, vergleiche mit: 8CDE0C05014E0: Falsch
Reader 0, Datensatz 14. Suche nach; 7C2BE1C05014E0, vergleiche mit: 9827E1C05014E0: Falsch
Reader 0, Datensatz 15. Suche nach; 7C2BE1C05014E0, vergleiche mit: B025E1C05014E0: Falsch
Reader 0, Datensatz 16. Suche nach; 7C2BE1C05014E0, vergleiche mit: 6025E1C05014E0: Falsch
Reader 0, Datensatz 17. Suche nach; 7C2BE1C05014E0, vergleiche mit: E727E1C05014E0: Falsch
Reader 0, Datensatz 18. Suche nach; 7C2BE1C05014E0, vergleiche mit: 2227E1C05014E0: Falsch
Reader 0, Datensatz 19. Suche nach; 7C2BE1C05014E0, vergleiche mit: 9E24E1C05014E0: Falsch
Reader 0, Datensatz 20. Suche nach; 7C2BE1C05014E0, vergleiche mit: E824E1C05014E0: Falsch
0
Card 7C2BE1C05014E0 removed from Reader 0

It' s lot of german gibberisch but basicly it says "Falsch" which translates to "Wrong". It should give another answer at #4, but it still does not recognize the value

Show your complete code, or at least a compilable code demonstrating the problem

I will. Tomorow.

Here is the whole programm:

    //Pins ESP 32 Dev Module (AZ Delivery)
    /* ESP    RFID
     *  5V    5V
     *  3,3V  3,3V
     *  25    RST //AS DEFINED IN PN5180ISO15693 nfc varable
     *  26    NSS //AS DEFINED IN PN5180ISO15693 nfc varable 
     *  23    MOSI
     *  19    MISO
     *  18    SCK
     *  27    BUSY //AS DEFINED IN PN5180ISO15693 nfc varable
     *  GND   GND
     *   /    GPIO
     *   /    IRX
     *   /    AUX
     *   /    REX
     *  
     *  
     *  
     *  ESP                   DF Player Mini
     *  5V                    VCC
     *  17 100kOHM to GND     RX  // Hardwareserial TX   
     *  16                    TX  // Hardwareserial RX
     *  /                     DAC-R
     *  /                     DAC-L
     *  /                     SPK_1 //Speaker, Black Cable
     *  GND                   GND
     *  /                     SPK_2 //Speaker, Red Cable
     */

//****RFID Reader***
    // Download from https://github.com/playfultechnology/PN5180-Library
    #include <PN5180.h>
    #include <PN5180ISO15693.h>
    // Tag if the current Card
    uint8_t lastUid[8];
    // Each PN5180 reader requires unique NSS, BUSY, and RESET pins, as defined below
    PN5180ISO15693 nfc = PN5180ISO15693(26,27,25);


//****RFID Tags****
//Number of Different Songs
int NumTags =21;
//RFID Tags
int rfid_id[][8]={
  {0xE1,0xAF,0xE4,0xED,0x50,0x1,0x4,0xE0},//#0
  {0x6C,0x27,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#1
  {0x58,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#2
  {0xE5,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#3
  {0x7C,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#4
  {0xFF,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#5
  {0x8E,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#6
  {0xE,0x2C,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#7
  {0x54,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#8
  {0xC6,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#9
  {0x3F,0x2B,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#10
  {0x8,0xCF,0xE0,0xC0,0x50,0x1,0x4,0xE0},//#11
  {0xDA,0xCC,0xE0,0xC0,0x50,0x1,0x4,0xE0},//#12
  {0x8,0xCD,0xE0,0xC0,0x50,0x1,0x4,0xE0},//#13
  {0x98,0x27,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#14
  {0xB0,0x25,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#15
  {0x60,0x25,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#16
  {0xE7,0x27,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#17
  {0x22,0x27,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#18
  {0x9E,0x24,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#19
  {0xE8,0x24,0xE1,0xC0,0x50,0x1,0x4,0xE0},//#20
  };


//****MP3 Player****
  // This library exposes functions for playing sounds from DFPlayerMini module using the serial connection
  // Download from https://github.com/DFRobot/DFRobotDFPlayerMini
  #include <DFRobotDFPlayerMini.h>
  #include <HardwareSerial.h>//=> SoftwareSerial.h funktioniert nicht bei ESP32 Chipsätzten. Statt dessen HardwareSerial Funktion
  // Create an object to access the dfPlayer
  DFRobotDFPlayerMini myDFPlayer; 
  // Initialise a soft serial interface
  HardwareSerial MP3Serial(1); //SD3=TX, SD2=RX


//****SFX****
int EffektPin = 34;


//****State Machine****
unsigned long curMillis;
unsigned long prevRfidMillis = 0;
unsigned long millisBetweenRfid= 1000;


void loop(){
  curMillis = millis();
  RFID();
}


void setup(){
  Serial.begin(115200);
  Serial.println("Start");
  RFIDSetup();
  Serial.println("RFID Setup Finished");
  MP3Setup();
}


void RFIDSetup(){
  Serial.println("RFID Setup");
  Serial.println(F("Initialising..."));
  nfc.begin();
  Serial.println(F("Resetting..."));
  nfc.reset();
  Serial.println(F("Enabling RF field..."));
  nfc.setupRF();
  Serial.println("RFID Initialised");
  // Slight delay before activating next reader
  delay(2000);
}

void RFID(){
  if (curMillis - prevRfidMillis >= millisBetweenRfid) {
      prevRfidMillis = curMillis;
      // Variable to store the ID of any tag read by this reader
      uint8_t thisUid[8];
      // Try to read a tag ID (or "get inventory" in ISO15693-speak) 
      ISO15693ErrorCode rc = nfc.getInventory(thisUid);
      // If the result code was that a card had been read
      if(rc == ISO15693_EC_OK) {
        // If this is the same ID as we read last frame
        if(memcmp(thisUid, lastUid, 8) == 0) {
        // Nothing to do
        }
        // If it's a different ID
        else {
        Serial.print(F("New Card Detected on Reader "));
        Serial.print(F("..."));
        for (int j=0; j<sizeof(thisUid); j++) {
          Serial.print(thisUid[j],HEX);
          Serial.print(",");
        }
        Serial.println();
        // Update the array that keeps track of most recent ID
        memcpy(lastUid, thisUid, sizeof(lastUid[0])*8);
        // Has placing this card solved the puzzle?
        RFIDCompare();
        }
      }
      // If a card cannot be read
      else {
        // Test if we previously knew about a card (in which case it's just been removed
        // The most significant (last) byte of a valid UID should always be 0xE0. e.g. E007C4A509C247A8
        if(lastUid[7] == 0xE0){
        Serial.print("Card ");
        for (int j=0; j<sizeof(lastUid); j++) {
          Serial.print(lastUid[j], HEX);
        }
        Serial.print(" removed from Reader ");
        Serial.println();
        // Update the array that keeps track of last known ID
        memset(lastUid, 0, sizeof(lastUid[0])*8);
        }
      }
    }
}

void RFIDCompare(){
  //Serial.print("Die Kartennummer lautet: ");
  //Serial.println(RFIDCode);
  for (int i=0; i < NumTags; i++){
    Serial.print("Array No. ");
    Serial.print(i);
    if (memcmp(lastUid, rfid_id[i], 8) != 0)  {
      Serial.print(". Searching for ");
      for (int j=0; j<sizeof(lastUid); j++) {
            Serial.print(lastUid[j], HEX);
      }
      Serial.print(", Compare to current tag ");
      for (int j=0; j<sizeof(lastUid); j++) {
            Serial.print(rfid_id[i][j], HEX);
      }
      Serial.println(": Wrong");
    }
    else {
      Serial.println(": Correct");
      MP3(i);
      break;
    }
  }
}


void MP3Setup() {
  // Initialise the software serial interface used to control the DFPlayer 
  Serial.print(F("Initialising software serial interface...")); 
  MP3Serial.begin(9600, SERIAL_8N1, 16, 17);
  Serial.print(F("OK!"));
  // Start communication with DFPlayer
  Serial.print(F("Initialising DFPlayer...")); 
  if (myDFPlayer.begin(MP3Serial)) {  
    Serial.println(F("OK!"));
    }
    else {
      Serial.println(F("Failed :("));
    }
    // Set volume (value from 0 to 30)
    myDFPlayer.volume(16);
    // Once setup is complete, enter the idle state 
    Serial.println("MP3 Setup Complete"); 
}


void MP3(int Songnumber){
  delay(100);
  myDFPlayer.play(Songnumber);
  Serial.print("Playing Song ");
  Serial.print(Songnumber);
  delay(100);
}

When I put a Tog on the Reader (in this case Tag #4), this is what the serial monitor shows:

Start
RFID Setup
Initialising...
Resetting...
Enabling RF field...
RFID Initialised
RFID Setup Finished
Initialising software serial interface...OK!Initialising DFPlayer...OK!
MP3 Setup Complete
New Card Detected on Reader ...7C,2B,E1,C0,50,1,4,E0,
Array No. 0. Searching for 7C2BE1C05014E0, Compare to current tag E1AFE4ED5014E0: Wrong
Array No. 1. Searching for 7C2BE1C05014E0, Compare to current tag 6C27E1C05014E0: Wrong
Array No. 2. Searching for 7C2BE1C05014E0, Compare to current tag 582BE1C05014E0: Wrong
Array No. 3. Searching for 7C2BE1C05014E0, Compare to current tag E52BE1C05014E0: Wrong
Array No. 4. Searching for 7C2BE1C05014E0, Compare to current tag 7C2BE1C05014E0: Wrong
Array No. 5. Searching for 7C2BE1C05014E0, Compare to current tag FF2BE1C05014E0: Wrong
Array No. 6. Searching for 7C2BE1C05014E0, Compare to current tag 8E2BE1C05014E0: Wrong
Array No. 7. Searching for 7C2BE1C05014E0, Compare to current tag E2CE1C05014E0: Wrong
Array No. 8. Searching for 7C2BE1C05014E0, Compare to current tag 542BE1C05014E0: Wrong
Array No. 9. Searching for 7C2BE1C05014E0, Compare to current tag C62BE1C05014E0: Wrong
Array No. 10. Searching for 7C2BE1C05014E0, Compare to current tag 3F2BE1C05014E0: Wrong
Array No. 11. Searching for 7C2BE1C05014E0, Compare to current tag 8CFE0C05014E0: Wrong
Array No. 12. Searching for 7C2BE1C05014E0, Compare to current tag DACCE0C05014E0: Wrong
Array No. 13. Searching for 7C2BE1C05014E0, Compare to current tag 8CDE0C05014E0: Wrong
Array No. 14. Searching for 7C2BE1C05014E0, Compare to current tag 9827E1C05014E0: Wrong
Array No. 15. Searching for 7C2BE1C05014E0, Compare to current tag B025E1C05014E0: Wrong
Array No. 16. Searching for 7C2BE1C05014E0, Compare to current tag 6025E1C05014E0: Wrong
Array No. 17. Searching for 7C2BE1C05014E0, Compare to current tag E727E1C05014E0: Wrong
Array No. 18. Searching for 7C2BE1C05014E0, Compare to current tag 2227E1C05014E0: Wrong
Array No. 19. Searching for 7C2BE1C05014E0, Compare to current tag 9E24E1C05014E0: Wrong
Array No. 20. Searching for 7C2BE1C05014E0, Compare to current tag E824E1C05014E0: Wrong
Card 7C2BE1C05014E0 removed from Reader 

As you can see, it does not recognize the tag. And I have no idea why.

As I said in previous post, you have to change int rfid_id to uint8_t rfid_id

1 Like
RFID Setup Finished
Initialising software serial interface...OK!Initialising DFPlayer...OK!
MP3 Setup Complete
New Card Detected on Reader ...7C,2B,E1,C0,50,1,4,E0,
Array No. 0. Searching for 7C2BE1C05014E0, Compare to current tag E1AFE4ED5014E0: Wrong
Array No. 1. Searching for 7C2BE1C05014E0, Compare to current tag 6C27E1C05014E0: Wrong
Array No. 2. Searching for 7C2BE1C05014E0, Compare to current tag 582BE1C05014E0: Wrong
Array No. 3. Searching for 7C2BE1C05014E0, Compare to current tag E52BE1C05014E0: Wrong
Array No. 4: Correct
Playing Song 4Card 7C2BE1C05014E0 removed from Reader

Works like a charm!!!!!!

Thank you very much, indeed!

That was extremely helpful and a good lesson to learn as well. Cheers mate.

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.