RFID reader reads gibberish tag string (sometimes)

Hi All,

Can someone here please help me to debug the RFID reader code?

There is a ID-12 reader and a few tags. The reader is set to sleep and active repeatedly using millis() method and while loop to control times.

Sometimes it performs well – reading 12 byte of all tags.
Sometimes it doesn’t.

The problems are:-

  • it reads longer than 12 byte from the beginning once the sketch is compiled.
  • sometimes there’re gibberish after the right 12 byte
  • sometimes there’re full of readable numbers (but not the tag string).

The code placed here is modified from ID-12 walk-through tutorial page ?bildr bildr - bildr - communal know-how

Thank you.

void loop()
{   
    isSleeping = false; 
    control_reader_states();
    delay(100);   
}

// ==============================================

void control_reader_states()
{
    
    // start active state
    if (isSleeping == false)
    {  
               
        digitalWrite(rfidPower, HIGH);
        digitalWrite(powerLed, HIGH);
        
        now = millis();
        long randomPeriod1 = random(SHORTEST, LONGEST);
        
        while(millis() - randomPeriod1  <  now )
        {
           
            read_tag(); 
            check_tag(tagString); //Check if it is a known tag
            clear_tag(tagString); 
            reset_reader();
            
            
            if (isThereUsr2 == true)
            {
                
                Serial.println("going out to main loop now !! ");
            }
            
            else
            {
                // go into next condition - to sleep
                isSleeping = true;
            }
            
        }// end active state
        
    }
    
    
    // starts sleeping state
    if(isSleeping == true)
    {
        
        
        digitalWrite(rfidPower, LOW);
        digitalWrite(powerLed, LOW);
        
        now = millis();
        long randomPeriod2 = random(SHORTEST/2, LONGEST/2);
        
        
        while (millis() - randomPeriod2  <  now )
        {
            
            digitalWrite(rfidPower, LOW); 
            digitalWrite(powerLed, LOW);
            
        }// end sleeping state
    }
    

}

// ==============================================

void check_tag(char tag[])
{
    
    // No tag to read
    if(strlen(tag) == 0)
    {
        digitalWrite(myTagLed, LOW); 
        digitalWrite(yrTagLed, LOW);
        //Serial.println(" no tag");
        return; //empty, no need to continue
        
    }
    
    
    // There's something to read
    else 
    {      
        
        // if read own tag
        if(compare_tag(tag, myTag))
        { 
            digitalWrite(myTagLed, HIGH); 

            Serial.print("my tag:                   ");  
            Serial.println(tag);
            delay(100);

            digitalWrite(myTagLed, LOW);
        }
        
        
        
        //if not match my tag, it must match one of these knownn tags
        else if((compare_tag(tag, yrTag1))||(compare_tag(tag, yrTag2))||(compare_tag(tag, yrTag3))) 
        {
            
            digitalWrite(yrTagLed, HIGH); 
            
            Serial.print("your tag:                     "); 
            Serial.println(tag);
            delay(100);
            
            digitalWrite(yrTagLed, LOW);
            
            
            // Assign the name of the tag being read to user 2's tag's name
            if(compare_tag(tag, yrTag1))
            {
                assign_charArray(two, usr2);
            }
            
            else if(compare_tag(tag, yrTag2))
            {
                assign_charArray(three, usr2);
            }
            
            else
            {
                assign_charArray(four, usr2);
            }
                        
            isThereUsr2 = true;
                       
        }
        
        
        else
        {            
            ;
        }
        
        
        
        
    }// END 1st loop else
        
    delay(50);
    
}

// ==============================================

byte read_tag()
{
    
    //Get tag's id by reading incoming byte
    
    int index = 0;
    boolean reading = false;
    
    // starts read tag
    while(Serial.available()){
        
        int readByte = Serial.read(); //read next available byte
        
        if(readByte == 2) reading = true; //begining of tag
        if(readByte == 3) reading = false; //end of tag
        
        if(reading && readByte != 2 && readByte != 10 && readByte != 13){
            tagString[index] = readByte;//store the tag
            index ++;
        }
    }
    
}

// ==============================================

void clear_tag(char one[])
{
    
    //clear the char array by filling with null - ASCII 0
    //Will think same tag has been read otherwise
    
    for(int i = 0; i < strlen(one); i++)
    {
        one[i] = 0;
    }
}

// ==============================================

void reset_reader()
{
    //Reset the RFID reader to read again
    digitalWrite(rfidReset, LOW);
    digitalWrite(rfidReset, HIGH);
    delay(150); 
}
// ==============================================
// ==============================================

The code placed here is modified from ID-12 walk-through tutorial page ?http://bildr.org/?2011/02/rfid-arduino/

Modified? Why?

PaulS:

The code placed here is modified from ID-12 walk-through tutorial page ?http://bildr.org/?2011/02/rfid-arduino/

Modified? Why?

Oh "modified" -- I mean the original version shows how to read known tags. In my version, I added the control_reader_states() function and a few conditions in check_tag() function to read when the reader is on an active mode only.

I mean the original version shows how to read known tags.

Does that version work consistently?

In my version, I added the control_reader_states() function and a few conditions in check_tag() function to read when the reader is on an active mode only.

What does “when the reader is on an active mode only” mean? Are you turning the reader off and on in your code? If so, why? If not, why does the state of the RFID matter? Wouldn’t you simply get no data in other than active mode?

I’m trying to (help you) focus in on the likely area of the code where the problem is.

The original version works flawlessly.

When turning only active mode on, it works fine.

One issue looks like read_tag does not null terminate the tag string

wildbill: One issue looks like read_tag does not null terminate the tag string

But the same read_tag() function reads well when turning only active mode on.

Is there a way to make it better?

        else
        {            
            ;
        }

Please explain this. If there is nothing to do if the if() portion is not true, you don’t need the else block at all.

Is there a way to make it better?

Isn’t it obvious? Null terminate the string after adding the character.

        now = millis();
        long randomPeriod2 = random(SHORTEST/2, LONGEST/2);
        
        
        while (millis() - randomPeriod2  <  now )
        {
            
            digitalWrite(rfidPower, LOW); 
            digitalWrite(powerLed, LOW);
            
        }// end sleeping state

Nothing else happens while the RFID is powered off for a random (wtf?) amount of time. Please explain.

This happens inside a if(isSleeping) block. So, if the RFID is sleeping, turn the power to it off. Something’s not quite right here.

By the way, when posting code, please post ALL of it. All your global declarations are missing.