Read NFC-UID, 0 get's not printed out

Hello Community,

im using the sketch example from PN532 iso14443a. Im reading a tag-id in.

Libary used: github.com/elechouse/PN532

Code: http://hastebin.com/yozehimubu.avrasm

#1

#if 0
  #include <SPI.h>
  #include <PN532_SPI.h>
  #include "PN532.h"

  PN532_SPI pn532spi(SPI, 10);
  PN532 nfc(pn532spi);
#elseif 1
  #include <PN532_HSU.h>
  #include <PN532.h>
      
  PN532_HSU pn532hsu(Serial1);
  PN532 nfc(pn532hsu);
#else 
  #include <Wire.h>
  #include <PN532_I2C.h>
  #include <PN532.h>
  #include <NfcAdapter.h>
  
  PN532_I2C pn532i2c(Wire);
  PN532 nfc(pn532i2c);
#endif
  
void setup(void) {
  Serial.begin(115200);

  while(!Serial) {
    ;
  }
    
  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Could not detect NFC-Reader!");
    while (1); 
  }

  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  
  // Set the max number of retry attempts to read from a card
  nfc.setPassiveActivationRetries(0xFF);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
    
  Serial.println("Scanning for NFC-Tags...");
}

void loop(void) {
  boolean success;
  String id = "";
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  
  uint8_t uidLength;                       
  
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  
  if (success) {
    Serial.print("NFC Tag detected: ");
    for (uint8_t i= 0; i < uidLength; i++) 
    {
      Serial.print(uid[i], HEX); 
      id += String(uid[i], HEX);
     
    }
    id.toUpperCase();
    Serial.println("");
    Serial.println(id);
    Serial.println("");

    delay(1000);
  }
}
 for (uint8_t i= 0; i < uidLength; i++) 
    {
      Serial.print(uid[i], HEX); 
      id += String(uid[i], HEX);
     
    }

If im reading a TAG with for example the id B2 15 02 A1, the 0 is not getting printed out.

When i use the simple sketch code from the example NDEF “ReadTag” with the following code

#2

if (nfc.tagPresent())
    {
        NfcTag tag = nfc.read();
        String id = tag.getUidString();
        Serial.println(id);

I’ll get the correct id with the 0 in the String.

Do you guys know a solution?

With #1 code

ID = A2 27 2 C5

With #2 code

ID = A2 27 02 C5

Serial.print doesn't show leading zeroes, that's all. But what's wrong with your second piece of code, if it works, why worry?

The #1 code is better for me, since i can change settings in there directly, while in the #2’d code i can’t do that.

I didnt know about the “Serial.print doesn’t show leading zeroes”, but that is not even the problem.

if i use:

if (nfc.tagPresent())
    {
        NfcTag tag = nfc.read();
        String id = tag.getUidString();
        Serial.println(id);
   }

i get “A2 27 02 C5”

While the other code does not show / print the 0 even, im storing the 0 in an String before printing it out over Serial & it’s still not there.

String id = "";
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  
  uint8_t uidLength;                       
  
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  
  if (success) {
    Serial.print("NFC Tag detected: ");
    for (uint8_t i= 0; i < uidLength; i++) 
    {
      Serial.print(uid[i], HEX); 
      id += String(uid[i], HEX);
     
    }
    id.toUpperCase();
    Serial.println(id);

Serial:
NFC Tag detected: A2272C5
A2272C5

Do you know why & how to fix that?

That’s because you are converting it to a String byte by byte, and like print, the String constructor doesn’t print leading zeros. (In the byte 0x02, the first zero has no significance.)
You could add the lines

if (uid[i]<0x10) {
  Serial.print('0');
  id += '0';
}

That would solve your problem, but I’d still prefer the second piece of code.

Thank you very much, this fixed my problem.

But shouldn’t 0x10 be 16 instead of 2?

In which format do you make the comparison by uint8_t’s?

I know that the second piece of code is cleaner, but the first code snippet provides me more possibilities for customizing.

It doesn't matter which format you use to compare the values. For the Arduino, there is no difference between 0x10 and 16, it's exactly the same. (They are both stored in memory as 0b00010000.) But writing 0x10 is preferred here, because it shows what you want to achieve. 0x10 is the first two-digit hexadecimal number, so everything smaller than that gets an extra zero. Writing 16 would not make much sense, it has no meaning in this context.

Oh, and that 0x02 I mentioned was just an example, because that's what you used in your original post (third byte of the UID).