Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Teensy 3.2 and RFID

  1. #1

    Teensy 3.2 and RFID

    Hello all

    I am playing around with RFID for the first time... struggling a little bit. Got an RC522 set up and reading correctly.

    Using the library MFRC522.h, and here is the read personal data code

    Code:
    #include <SPI.h>
    #include <MFRC522.h>
    
    constexpr uint8_t RST_PIN = 9;     // Configurable, see typical pin layout above
    constexpr uint8_t SS_PIN = 10;     // Configurable, see typical pin layout above
    
    MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance
    
    //*****************************************************************************************//
    void setup() {
      Serial.begin(9600);                                           // Initialize serial communications with the PC
      SPI.begin();                                                  // Init SPI bus
      mfrc522.PCD_Init();                                              // Init MFRC522 card
      Serial.println(F("Read personal data on a MIFARE PICC:"));    //shows in serial that it is ready to read
    }
    
    //*****************************************************************************************//
    void loop() {
    
      // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
      MFRC522::MIFARE_Key key;
      for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
    
      //some variables we need
      byte block;
      byte len;
      MFRC522::StatusCode status;
    
      //-------------------------------------------
    
      // Look for new cards
      if ( ! mfrc522.PICC_IsNewCardPresent()) {
        return;
      }
    
      // Select one of the cards
      if ( ! mfrc522.PICC_ReadCardSerial()) {
        return;
      }
    
      Serial.println(F("**Card Detected:**"));
    
      //-------------------------------------------
    
      mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid)); //dump some details about the card
    
      //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));      //uncomment this to see all blocks in hex
    
      //-------------------------------------------
    
      Serial.print(F("Name: "));
    
      byte buffer1[18];
    
      block = 4;
      len = 18;
    
      //------------------------------------------- GET FIRST NAME
      status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid)); //line 834 of MFRC522.cpp file
      if (status != MFRC522::STATUS_OK) {
        Serial.print(F("Authentication failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
      }
    
      status = mfrc522.MIFARE_Read(block, buffer1, &len);
      if (status != MFRC522::STATUS_OK) {
        Serial.print(F("Reading failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
      }
    
      //PRINT FIRST NAME
      for (uint8_t i = 0; i < 16; i++)
      {
        if (buffer1[i] != 32)
        {
          Serial.write(buffer1[i]);
        }
      }
      Serial.print(" ");
    
      //---------------------------------------- GET LAST NAME
    
      byte buffer2[18];
      block = 1;
    
      status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); //line 834
      if (status != MFRC522::STATUS_OK) {
        Serial.print(F("Authentication failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
      }
    
      status = mfrc522.MIFARE_Read(block, buffer2, &len);
      if (status != MFRC522::STATUS_OK) {
        Serial.print(F("Reading failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
      }
    
      //PRINT LAST NAME
      for (uint8_t i = 0; i < 16; i++) {
        Serial.write(buffer2[i] );
      }
    
    
      //----------------------------------------
    
      Serial.println(F("\n**End Reading**\n"));
    
      delay(1000); //change value if you want to read cards faster
    
      mfrc522.PICC_HaltA();
      mfrc522.PCD_StopCrypto1();
    }
    //*****************************************************************************************//
    My problem is this.

    This routine basically sits in the main loop, waiting for a card to be presented.

    I however, want to move this out to a sub-routine, so that a flag is set when a valid card is read, then it returns to the main loop. I would use the IRQ pin on the RC522.... but apparently it doesn't work (useful!)

    But, it really doesn't seem to like being moved about. I get timeout errors and all sorts.

    The line if (mfrc522.PICC_IsNewCardPresent() or mfrc522.PICC_ReadCardSerial()) {Read_RFID();} seems to work to branch out from the main loop upon a card being presented, but then you need to remove those commands from being repeated in the sub-routine. Otherwise it hangs.

    But, then you get card timeout errors.

    I have read the README file with the library and got my head around the blocks etc, but I don't understand what each of the library components do E.G. mfrc522.PICC_IsNewCardPresent() or mfrc522.GetStatusCodeName(status) etc

    I wish they commented them better!

    Earlier, after extensive Googling, I found another segment of code for reading cards.. but it had errors and after 2 hours, I have returned to this library.

    Any suggestions or other library recommendations?

  2. #2
    Hi
    Not sure if this is of help. But I initialize the same as you in setup.
    Code:
    SPI.begin();        // Init SPI bus
    mfrc522.PCD_Init(); // Init MFRC522 card
    then in loop I call a function to read data from the card as below (that I write in a different code). This reads from sectors and blocks where the address is currently hard coded in the function.
    I use a flag so that the card is only read when first presented.
    Apologies for my very poor coding (i have not updated all the comments or annotated etc).
    Code:
    uint8_t getCard()
    {
    	uint8_t failed = 0;
        // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
        if ( ! mfrc522.PICC_IsNewCardPresent())
            return;
    
        // Select one of the cards
        if ( ! mfrc522.PICC_ReadCardSerial())
            return;
    
        // Show some details of the PICC (that is: the tag/card)
        Serial.print(F("Card UID:"));
        dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
        Serial.println();
        Serial.print(F("PICC type: "));
        MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
        Serial.println(mfrc522.PICC_GetTypeName(piccType));
    
        // Check for compatibility
        if (    piccType != MFRC522::PICC_TYPE_MIFARE_MINI
            &&  piccType != MFRC522::PICC_TYPE_MIFARE_1K
            &&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
            Serial.println(F("This sample only works with MIFARE Classic cards."));
    		failed = 0;
            return;
        }
    
        // In this sample we use the second sector,
        // that is: sector #1, covering block #4 up to and including block #7
        byte sector         = 5;
        byte blockAddr      = 20;
        byte dataBlock[]    = {
            0x01, 0x02, 0x03, 0x04, //  1,  2,   3,  4,
            0x05, 0x06, 0x07, 0x08, //  5,  6,   7,  8,
            0x09, 0x0a, 0xff, 0x0b, //  9, 10, 255, 11,
            0x0c, 0x0d, 0x0e, 0x0f  // 12, 13, 14, 15
        };
        byte trailerBlock   = 23;
        MFRC522::StatusCode status;
        byte buffer[18];
        byte size = sizeof(buffer);
    
    	
        // Authenticate using key A
        Serial.println(F("Authenticating using key A..."));
        status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
        if (status != MFRC522::STATUS_OK) {
            Serial.print(F("PCD_Authenticate() failed: "));
    		vga_command("f,4"); //11JULY19
    		Serial1.println(F("PCD_Authenticate() failed: "));//11JULY19
            Serial.println(mfrc522.GetStatusCodeName(status));//11JULY19 
    		Serial1.println(mfrc522.GetStatusCodeName(status));
    		failed = 0;
            return ;
        }
    
        // Show the whole sector as it currently is
        Serial.println(F("Current data in sector:"));
        mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
        Serial.println();
    
        // Read data from the block
        Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
        Serial.println(F(" ..."));
        status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
        if (status != MFRC522::STATUS_OK) {
    		vga_command("f,4"); //11JULY19
    		Serial1.println(F("MIFARE_Read() failed: "));//11JULY19
    		Serial1.println(mfrc522.GetStatusCodeName(status));//11JULY19
            Serial.print(F("MIFARE_Read() failed: "));
            Serial.println(mfrc522.GetStatusCodeName(status));
    		failed = 0;
            return;
        }
        Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
        dump_byte_array(buffer, 16); Serial.println();
        Serial.println();
    	//get the crands**************************************************************
    	for(int z = 0; z<16; z++)
    	{
    		pdata[0].crand[z] = buffer[z];
    		tBuff[z] = buffer[z];
    	}
    	Serial1.print("crand 1 = :");
    	//Serial1.println(tBuff);
    	
    	//get the crand fin**********************************************************
    	sector         = 5;
        blockAddr      = 21;
    	trailerBlock   = 23;
    	    // Show the whole sector as it currently is
        Serial.println(F("Current data in sector:"));
        mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
        Serial.println();
    
        // Read data from the block
        Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
        Serial.println(F(" ..."));
        status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
        if (status != MFRC522::STATUS_OK) {
    		vga_command("f,4"); //11JULY19
    		Serial1.println(F("MIFARE_Read() failed: "));//11JULY19
    		Serial1.println(mfrc522.GetStatusCodeName(status));//11JULY19
            Serial.print(F("MIFARE_Read() failed: "));
            Serial.println(mfrc522.GetStatusCodeName(status));
    		failed = 0;
            return;
        }
        Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
        dump_byte_array(buffer, 16); Serial.println();
        Serial.println();
    	//get the crands**************************************************************
    	for(int z = 0; z<16; z++)
    	{
    		pdata[1].crand[z] = buffer[z];
    		tBuff[z] = buffer[z];
    	}
    	Serial1.print("crand 1 = :");
    	//Serial1.println(tBuff);
    	
    	//get the crand fin**********************************************************
    	sector         = 5;
        blockAddr      = 22;
    	trailerBlock   = 23;
    	    // Show the whole sector as it currently is
        Serial.println(F("Current data in sector:"));
        mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
        Serial.println();
    
        // Read data from the block
        Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
        Serial.println(F(" ..."));
        status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
        if (status != MFRC522::STATUS_OK) {
    		vga_command("f,4"); //11JULY19
    		Serial1.println(F("MIFARE_Read() failed: "));//11JULY19
    		Serial1.println(mfrc522.GetStatusCodeName(status));//11JULY19
            Serial.print(F("MIFARE_Read() failed: "));
            Serial.println(mfrc522.GetStatusCodeName(status));
    		failed = 0;
            return ;
        }
        Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
        dump_byte_array(buffer, 16); Serial.println();
        Serial.println();
    	//get the crands**************************************************************
    	for(int z = 0; z<16; z++)
    	{
    		pdata[2].crand[z] = buffer[z];
    		tBuff[z] = buffer[z];
    	}
    	Serial1.print("crand 1 = :");
    	//Serial1.println(tBuff);
    	
    	//get the crand fin**********************************************************
    	sector         = 7;
        blockAddr      = 28;
    	trailerBlock   = 31;
    	    // Show the whole sector as it currently is
        Serial.println(F("Current data in sector:"));
        mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
        Serial.println();
    
        // Read data from the block
        Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
        Serial.println(F(" ..."));
        status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
        if (status != MFRC522::STATUS_OK) {
    		vga_command("f,4"); //11JULY19
    		Serial1.println(F("MIFARE_Read() failed: "));//11JULY19
    		Serial1.println(mfrc522.GetStatusCodeName(status));//11JULY19
            Serial.print(F("MIFARE_Read() failed: "));
            Serial.println(mfrc522.GetStatusCodeName(status));
    		failed = 0;
            return;
        }
    	else
    	{
    		pwStat =1; //passwords read.
    		if(screenStat == 0)
    		{bootScreen(); bpreviousMillis = millis(); screenStat = 1;}
    		vga_command("f,3");               // Set Window4 as focus       
            Serial1.println("Card Read OK"); 
    	}
        Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
        dump_byte_array(buffer, 16); Serial.println();
        Serial.println();
    		//get the crands**************************************************************
    	for(int z = 0; z<16; z++)
    	{
    		pdata[3].crand[z] = buffer[z];
    		tBuff[z] = buffer[z];
    	}
    	Serial1.print("crand 1 = :");
    	
        // Dump the sector data
        Serial.println(F("Current data in sector:"));
        mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
        Serial.println();
    
        // Halt PICC
        mfrc522.PICC_HaltA();
        // Stop encryption on PCD
        mfrc522.PCD_StopCrypto1();
    
        return 	failed ;
    }

  3. #3
    Hmm.... I just get

    RFID_Demo_v2:37: warning: unused variable 'dataBlock'
    byte dataBlock[] = {

    ^
    'mfrc522' was not declared in this scope


    When I run that. Will have a look later

  4. #4
    Err OK.... what have I done/changed....

    Now it doesn't read/write anything.... including new tags

  5. #5
    The library I am using is https://github.com/miguelbalboa/rfid

    I started with the read and write example which seems to work ok to read/write to specific blocks.
    The code in uint8_t getCard() is straight form the example, just with some code to store the data from the blocks in some local structures
    I dont confess to understand all the setup functions, but I only need to able to write once to a number blocks and then be able to read back multiple times.

  6. #6
    I am finding these libraries hard work actually. Working out what each part does it difficult for someone without the required knowledge.

    I have the following code so far, made up of various 'bits'...

    Code:
    void Read_RFID(){                                                                                                       // Check the RFID module   
    
      if ( ! mfrc522.PICC_ReadCardSerial()) {return;}                                                                       // Read the card
    
      Serial.print("Tag:");                                                                                                 // Get the tag address
      String content= "";
      //for (byte i = 0; i < mfrc522.uid.size; i++) {
      for (byte i = 0; i < 4; i++) {                                                                                        // Read the 4 byte UID code
     
      Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
      Serial.print(mfrc522.uid.uidByte[i], HEX);
    
      content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));                                                   // Create a string with that data
      content.concat(String(mfrc522.uid.uidByte[i], HEX)); 
      }
      Serial.println(" ");
      
      content.toUpperCase();
      content = content.substring(1);
    
    
      if(content == "39 24 00 5D"){                                                                                         // Check it matches previous tag addresses
           Serial.println("VALID TAG");
           Tag_valid=true;
         }else{
           Serial.print("INVALID TAG");
           Tag_valid=false;
         }
    
      delay(200);
    
    }
    This sub-routine reads the card and gets the card address. It was asking for the address length, but I have commented that out, as I believe that all my standard tags here are 4x byte addresses. It now retrieves 4x bytes each time.

    My aim, is to compare that 4x byte address to a stored address in EEPROM.

    This code is assembling a string with commands such as 'concat' that I totally don't understand (even after Google).

    I don't understand what the function < 0x10 ? " 0" : " " does either.
    My guess, is that it adds a second zero to any value under 10? and also spaces them out with a " ".

    I don't really need to assemble a string. Surely I can simply read the cards 4x byte address and compare those to 4x EEPROM byte variables.

    Any guidance gratefully received!

  7. #7
    Don't worry. Google, beer and luck have produced results

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •