String variable not updating

Hey,
I'm quite new to Programming and would greatly appreciate some help.

I'm trying to play different parts of a sentence by holding two Cards against the RFICD modul.

So Card 1 plays the first soundfile and Card2 plays the second one. The trick is, that Card1 is supposed to play the third file, if the second file has been played, and if the third file has been played and Card 2 is held against the sensor, the fourth file should start.... etc. you get it
If you hold the same Card twice against the RFIC sensor, the loop should start over again.
(I haven't connected the mp3 module yet)
Here is what i got right now:

#include "SPI.h"
#include "MFRC522.h"

#define SS_PIN 10
#define RST_PIN 9
#define LED_PIN A0
#define LED_PIN A1

int var3 = 0;

MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
Serial.println("I am waiting for card...");
}

void loop() {
// put your main code here, to run repeatedly:
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
return;

// Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
// Serial.println(rfid.PICC_GetTypeName(piccType));


String strID = "";
for (byte i = 0; i < 4; i++) {
strID +=
(rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
String(rfid.uid.uidByte[i], HEX) +
(i != 3 ? ":" : "");
}

strID.toUpperCase();
Serial.print("");

delay(1000);

if (strID.indexOf("02:4E:8F:03") >= 0) { //put your own tap card key;          Card 1
Serial.println("");
Serial.println("Audio1");
Serial.println("");

return;
}

if (strID.indexOf("12:38:90:03") >= 0) { //put your own tap card key;            Card2
Serial.println("");
Serial.println("Audio2");
Serial.println("");

          
          while (var3 < 5) {
          var3++;
          Serial.print("Waiting in loop");
          Serial.print("");
          delay(1000);
            String strID = "";                                        //Thats the part that does not work
            for (byte i = 0; i < 4; i++) {
            strID +=
            (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
             String(rfid.uid.uidByte[i], HEX) +
            (i != 3 ? ":" : "");
            } } 

           Serial.print("Tap card key: ");
            Serial.println(strID);

            if (strID.indexOf("02:4E:8F:03") >= 0) { //put your own tap card key;          Card 1
            Serial.println("");
            Serial.println("Audio3");
            Serial.println("");
            delay(5000);
            }
            else {
              Serial.print("");
              Serial.print("Returniiiiii");
              Serial.print("");
              var3 = 0;
            return;}

             

                    

 }
 
}






For some reason the String does not update in the while() loop, so playing the 3rd file isn't possible right now. This block of code is a mystery to me anyway, but I got it working in other cases. (sadly i dont have them anymore) :frowning:

My Stuff:
Arduino UNO
RFID-RC522

I am very greatful for any help and Ideas!

-Sam

In loop()

      String strID = "";                                        //Thats the part that does not work

You also have a global variable named strID. Which one do you think is being updated here and which one is being printed here

    Serial.println(strID);

So if I get this right:

by writing this I created the variable StrID twice, one Global and one in the Loop. Thats not what i intended. I'd like to have one global StrID variable, wich memorises the last UID present. I tried running it without this Line, with same results. I copied this Block from another ones Projekt, since I had no Idea how to go about it myself.

So don't declare a new variable in loop(). Set the value of the global one in loop() instead

Thank you already, I didn't catch that I was having 2 variables.

Good to hear that that's the way to go about it. I'm on it right now

I removed the StrID variable, but cant get it to work.
One more complete beginner question: Is there a way of reading all comands that were added in a library? so I can find a way of returning the UID myself? (and possibly updating StrID in the while() loop?

Please post the code as it is now and describe what happens when you run it and what should happen

I wish that I could say read the documentation, but it is often missing or incomplete. Examples can be a good source of information if they are comprehensive and, of course, you have the source code for the library. A look in the library .h file will reveal the functions available in the library and the .cpp file will show how they are implmented

I'll have a look into the library files :slight_smile:

#include "SPI.h"
#include "MFRC522.h"

#define SS_PIN 10
#define RST_PIN 9
#define LED_PIN A0
#define LED_PIN A1
String strID = "";                                  // I put the StrID to the top
int var3 = 0;

MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  Serial.println("I am waiting for card...");
}

void loop() {
  // put your main code here, to run repeatedly:
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
    return;

  // Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  // Serial.println(rfid.PICC_GetTypeName(piccType));



  for (byte i = 0; i < 4; i++) {                    // I'm guessing this is the part that gives StrID a value
    strID +=
      (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
      String(rfid.uid.uidByte[i], HEX) +
      (i != 3 ? ":" : "");
  }

  strID.toUpperCase();
  Serial.print("");

  delay(1000);

  if (strID.indexOf("02:4E:8F:03") >= 0) { //put your own tap card key;          Card 1
    Serial.println("");
    Serial.println("Audio1");
    Serial.println("");

    return;
  }

  if (strID.indexOf("12:38:90:03") >= 0) { //put your own tap card key;            Card2
    Serial.println("");
    Serial.println("Audio2");
    Serial.println("");


    while (var3 < 5) {
      var3++;
      Serial.print("");
      Serial.print("Waiting in loop");
      Serial.print("");
      delay(1000);
      //Thats the part that does not work
      for (byte i = 0; i < 4; i++) {
        strID +=
          (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
          String(rfid.uid.uidByte[i], HEX) +
          (i != 3 ? ":" : "");
      }
    }

    Serial.print("Tap card key: ");
    Serial.println(strID);

    if (strID.indexOf("02:4E:8F:03") >= 0) { //put your own tap card key;          Card 1
      Serial.println("");
      Serial.println("Wupp Wupp");
      Serial.println("");
      delay(5000);
    }
    else {
      Serial.print("");
      Serial.print("Returniiiiii");
      Serial.print("");
      var3 = 0;
      return;
    }





  }

}






Thats the code. I removes the StrID variable in the loop() and moved it to the top.

When I hold card 2 to the sensor after card 1, the console says as follows:

I am waiting for card... //holding Card 2 to the sensor//

Audio2 //holdig Card 1 to the sensor//

Waiting in loopWaiting in loopWaiting in loopWaiting in loopWaiting in loopTap card key: 12:38:90:0312:38:90:0312:38:90:0312:38:90:0312:38:90:0312:38:90:03
Returniiiiii
Audio1

I'd would be great if the Console would say this:

I am waiting for card... //holding Card 2 to the sensor//

Audio2 //holdig Card 1 to the sensor//

Waiting in loopWaiting in loopWaiting in loopWaiting in loopWaiting in loop

Wupp Wupp

Wupp Wupp would stand for Audio3. I'm looking for a way of reading the UID and putting it into

It's been a couple of years since I used RFID in a project, but if I recall, you can't detect the same card twice consecutively.
A-B-A-B-A-B will work all day.
A-B-B-B-A Will only detect B once.

Please use CTRL-T in the IDE to properly format the code for readablility.

I edited my last Post with formatted code. So if I understand you correctly, the code is looking for the second letter and comparing those?

For simplication and beeing easier to read
the card1 is named "A"
the card2 is named "B"

If you present card "A" and then present card "B", the present card "A"
in short A-B-A
this works
but presenting Card "A"
then present Card "B"
take away card "B"
then present Card "B" a second time
then present Card "B" a third time
in short A-B-B-B
does not work.

Anyway to find out how your RFID-reader really works you should do more testing
with a test-code that does nothing more then print "card-ID read:" the real card ID
and then test through all variants you can think of

The difference to your code is there is no additional logic.
As long as you do not know exactly how the RFID-reader behaves
you should keep it KISS Keep it simple stupid

best regards Stefan

I never researched it, but when I developed an Escape Room game using RFID tags inside various objects, the hardware (MFRC522) would not detect repeated passes of the same tag.

One tag was supposed to unlock a drawer, and the code only gave the player 30 seconds to open the drawer then it locked again. Passing that same tag over the reader did nothing. Only presenting a different tag followed by the unlock tag worked.

Thank you so much for the explanation. My RIFD reader can read the same Tag again, but my Problem is a different one

I try to describe the functionality step by step

microcontroller power on
present card1 => play soundfile 1
present card2 => play soundfile 2
present card1 => play soundfile 3
present card2 => play soundfile 4

different sequence
microcontroller power on
present card1 => play soundfile 1
present card1 => second time the same card is presented reset to play soundfile 1
present card1 => third time the same card is presented reset to play soundfile 1

present card1 => play soundfile 1
present card2 => play soundfile 2
present card2 => second time the same card is presented reset to play soundfile 1
present card1 => play soundfile 1
present card2 => play soundfile 2

if this is a correct desciption of the wanted functionality confirm
if it is incorrect use the pattern to describe the functionality you want to have

best regards Stefan

That's it! May I put this in my main Post for easier readability?
I'm somewhat certain that I found a way for the logic to work, but i cant seem to get the StrID variable to update in the while() loop.

Do you have an idea how to solve or get around that?

Whenever you have a new code-version post the complete sketch.
It will much easier for others to chime in if hey thave not to search through the thread for a complete code-version still not knowing if it is the actual one or what to replace to make it the actual code.

Just always post the actual and comlete sketch.
Me personal I will look only in your code if you post the actual and complete sketch.

You can post code by using this method that adds the code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy for forum"
  3. paste clipboard into write-window of a posting

best regards Stefan

#include "SPI.h"
#include "MFRC522.h"

#define SS_PIN 10
#define RST_PIN 9
#define LED_PIN A0
#define LED_PIN A1
String strID = "";                                  // I put the StrID to the top
int var3 = 0;

MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  Serial.println("I am waiting for card...");
}

void loop() {
  // put your main code here, to run repeatedly:
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
    return;

  // Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  // Serial.println(rfid.PICC_GetTypeName(piccType));



  for (byte i = 0; i < 4; i++) {                    // I'm guessing this is the part that gives StrID a value
    strID +=
      (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
      String(rfid.uid.uidByte[i], HEX) +
      (i != 3 ? ":" : "");
  }

  strID.toUpperCase();
  Serial.print("");

  delay(1000);

  if (strID.indexOf("02:4E:8F:03") >= 0) { //put your own tap card key;          Card 1
    Serial.println("");
    Serial.println("Audio1");
    Serial.println("");

    return;
  }

  if (strID.indexOf("12:38:90:03") >= 0) { //put your own tap card key;            Card2
    Serial.println("");
    Serial.println("Audio2");
    Serial.println("");


    while (var3 < 5) {
      var3++;
      Serial.print("");
      Serial.print("Waiting in loop");
      Serial.print("");
      delay(1000);
      //Thats the part that does not work
      for (byte i = 0; i < 4; i++) {
        strID +=
          (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
          String(rfid.uid.uidByte[i], HEX) +
          (i != 3 ? ":" : "");
      }
    }

    Serial.print("Tap card key: ");
    Serial.println(strID);

    if (strID.indexOf("02:4E:8F:03") >= 0) { //put your own tap card key;          Card 1
      Serial.println("");
      Serial.println("Wupp Wupp");
      Serial.println("");
      delay(5000);
    }
    else {
      Serial.print("");
      Serial.print("Returniiiiii");
      Serial.print("");
      var3 = 0;
      return;
    }





  }

}

There it is

I don't know the behaviour of your RFID-reader.
imagine usually RFID-readers are used as authentification for whatever.
Example opening a door

One RFID-tag is presented to the reader and the reads the tag
If ID matches take action = opening the door otherwise not.
If the tag is taken away the rfid-reader has to clear the ID.

If the reader would not clear the ID the reader would continue to "take action" so anybody without a tag could open the door too.

If you insist on using the while-loop you have to check inside the while-loop if a new tag is new presented.

I don't know the details of how the RFID-library does that.
But that is the thing you have to find out. And it will be much easier to find out this with a small testprogram.

Of course you can try it with your full code believing you will be faster.
But you won't because you are using assumings how the RFID-reader works.
And now you are stuck because you understand / know too less of / about the RFID-library

So write a small testcode that does nothing more than checking if a tag is presented and prints the ID to the serial monitor. And then test with this code how does continiously checking for a tag work

best regards Stefan

Hello Stefan,
thanks for all the explanations. I'm getting back to it now after taking a break, starting with a clear head. Thanks to people like you helping others out, I (with no one to ask for about programming IRL) get to learn this.

I wrote a small test program, witch showed that sequences like A-A-A-A-A are very well possible. Overall I simplified the code.

Here is my Code:

#include "SPI.h"
#include "MFRC522.h"

#define SS_PIN 10
#define RST_PIN 9


int var3 = 0;

//Card1

MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  Serial.println("I am waiting for card...");
}

void loop() {
  delay(500);                            //Delay!!
  var3 = 0;
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
    return;

  // Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  // Serial.println(rfid.PICC_GetTypeName(piccType));


  String strID = "";
  for (byte i = 0; i < 4; i ++)
  {
    strID +=
      (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
      String(rfid.uid.uidByte[i], HEX) +
      (i != 3 ? ":" : "" );
  }
  Serial.print("Tap card key: ");
  Serial.print(" ");
  Serial.println(strID);
  Serial.print(" ");


  strID.toUpperCase();
  if (strID.indexOf("02:4E:8F:03") >= 0) {                             //Card1
    Serial.println(" ");
    Serial.println("Audio1");
    Serial.println(" ");
    

  }

    
  }

  strID = "0";                                                   //     I believe my issue is right here, since that line is my         //attempt of resseting strID
  for (byte i = 0; i < 4; i ++)
  {
    strID +=
      (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
      String(rfid.uid.uidByte[i], HEX) +
      (i != 3 ? ":" : "" );
  }

  Serial.print("Update strID");
  if (strID.indexOf("02: 4E: 8F: 03") >= 0) {                             //Card1
    Serial.println(" ");
    Serial.println("Audio3");
    Serial.println(" ");
    return;
  }
  else {
    Serial.println(" ");
    Serial.println("return");
    Serial.println(" ");

  }
}

My issue right now is that the if-statement for "Audio3" won't be triggered, since I don't know how to update the local variable String strID, wich saves the UID.
Is there an easy way of resetting strID where I marked it in the Code? Am I even on the right path? Did I miss something else important?

Greetings and thanks for any help,
Sam

your code has a closing curly bracket at the wrong place

You should develop the habit of pressing Ctrl-T after writing a few lines of code
Ctrl-T auto-formats your code. The indentions make visible which part of the code belongs to what .

#include "SPI.h"
#include "MFRC522.h"

#define SS_PIN 10
#define RST_PIN 9


int var3 = 0;

//Card1

MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  Serial.println("I am waiting for card...");
}

void loop() {
  delay(500);                            //Delay!!
  var3 = 0;
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
    return;

  // Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  // Serial.println(rfid.PICC_GetTypeName(piccType));


  String strID = "";
  for (byte i = 0; i < 4; i ++)
  {
    strID +=
      (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
      String(rfid.uid.uidByte[i], HEX) +
      (i != 3 ? ":" : "" );
  }
  Serial.print("Tap card key: ");
  Serial.print(" ");
  Serial.println(strID);
  Serial.print(" ");


  strID.toUpperCase();
  if (strID.indexOf("02:4E:8F:03") >= 0) {                             //Card1
    Serial.println(" ");
    Serial.println("Audio1");
    Serial.println(" ");


  }


} // this curly bracket closes loop()

// the code below here does NOT belong to any function.
// with which function shall this code below be executed

strID = "0";                                                   //     I believe my issue is right here, since that line is my         //attempt of resseting strID
for (byte i = 0; i < 4; i ++)
{
  strID +=
    (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
    String(rfid.uid.uidByte[i], HEX) +
    (i != 3 ? ":" : "" );
}

Serial.print("Update strID");
if (strID.indexOf("02: 4E: 8F: 03") >= 0) {                             //Card1
  Serial.println(" ");
  Serial.println("Audio3");
  Serial.println(" ");
  return;
}
else {
  Serial.println(" ");
  Serial.println("return");
  Serial.println(" ");

}
}

best regards Stefan

I fixed the braced, here is the new code. I also Added Audio2 to the first if-statemend.

#include "SPI.h"
#include "MFRC522.h"

#define SS_PIN 10
#define RST_PIN 9


int var3 = 0;

//Card1

MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  Serial.println("I am waiting for card...");
}

void loop() {
  delay(500);                            //Delay!!
  var3 = 0;
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
    return;

  // Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  // Serial.println(rfid.PICC_GetTypeName(piccType));


  String strID = "";
  for (byte i = 0; i < 4; i ++)
  {
    strID +=
      (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
      String(rfid.uid.uidByte[i], HEX) +
      (i != 3 ? ":" : "" );
  }
  Serial.print("Tap card key: ");
  Serial.print(" ");
  Serial.println(strID);
  Serial.print(" ");


  strID.toUpperCase();
  if (strID.indexOf("02:4E:8F:03") >= 0) {     //Card1
    Serial.println(" ");
    Serial.println("Audio1");
    Serial.println(" ");
    delay(2000);
  }
  else {
    Serial.println(" ");
    Serial.println("Audio2");
    Serial.println(" ");
    delay(2000);
  }


  strID = "0";                                //    this ADDS a 0 to the card UID, which was my attempt to clear the old UID.
  for (byte i = 0; i < 4; i ++)
  {
    strID +=
      (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
      String(rfid.uid.uidByte[i], HEX) +
      (i != 3 ? ":" : "" );
  }

  Serial.print("Updated strID:");
  Serial.println(strID);
  if (strID.indexOf("02: 4E: 8F: 03") >= 0) {       //Card1
    Serial.println(" ");
    Serial.println("Audio3");
    Serial.println(" ");
    return;
  }
  else {
    Serial.println(" ");
    Serial.println("return");
    Serial.println(" ");

  }
}

When putting the sequence Card2-Card1 the console says:
I am waiting for card...

Tap card key: 12:38:90:03 // UID Card2

Audio2

Updated strID:012:38:90:03 // UID Card2

return

Tap card key: 02:4e:8f:03 // UID Card1

Audio1

Updated strID:002:4e:8f:03 // UID Card1

return

I added the name of the Cards after "//".

There is a second 0 in the end. How can I clear the old UID from the lokal strID? (I know its a beginner question, but i tried seperating them with braceds and I had the same result. Exept for the highlighted 0)
Code is following. Thank you so much!

#include "SPI.h"
#include "MFRC522.h"

#define SS_PIN 10
#define RST_PIN 9


int var3 = 0;

//Card1

MFRC522 rfid(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  Serial.println("I am waiting for card...");
}

void loop() {
  delay(500);                            //Delay!!
  var3 = 0;
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial())
    return;

  // Serial.print(F("PICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  // Serial.println(rfid.PICC_GetTypeName(piccType));


  { String strID = "";
    for (byte i = 0; i < 4; i ++)
    {
      strID +=
        (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
        String(rfid.uid.uidByte[i], HEX) +
        (i != 3 ? ":" : "" );
    }
    Serial.print("Tap card key: ");
    Serial.print(" ");
    Serial.println(strID);
    Serial.print(" ");


    strID.toUpperCase();
    if (strID.indexOf("02:4E:8F:03") >= 0) {     //Card1
      Serial.println(" ");
      Serial.println("Audio1");
      Serial.println(" ");
      delay(2000);
    }
  
  else {
    Serial.println(" ");
    Serial.println("Audio2");
    Serial.println(" ");
    delay(2000);}
  }


  { String strID = "";                                //     I believe my issue is right here, since that line is my attempt of resseting strID
    for (byte i = 0; i < 4; i ++)
    {
      strID +=
        (rfid.uid.uidByte[i] < 0x10 ? "0" : "") +
        String(rfid.uid.uidByte[i], HEX) +
        (i != 3 ? ":" : "" );
    }

    Serial.print("Updated strID:");
    Serial.println(strID);
    if (strID.indexOf("02: 4E: 8F: 03") >= 0) {       //Card1
      Serial.println(" ");
      Serial.println("Audio3");
      Serial.println(" ");
      return;
    }
  
  else {
    Serial.println(" ");
    Serial.println("return");
    Serial.println(" ");
  }
  }
}