PN532 Shield Help - Trying to get String output from NFC tag

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
tardistrekkie
 
Posts: 15
Joined: Tue Dec 11, 2012 10:12 pm

PN532 Shield Help - Trying to get String output from NFC tag

Post by tardistrekkie »

Hi there,

Amateur at Arduino programming, even moreso for the PN532 library. I've spent days and days combing through forums, reading tutorials, looking through the PN532 Library, and asking friends for help with this question, and I'm stumped...

Hardware: PN532 Shield on an Arduino Uno R3

I've had no issue writing strings to my nfc tags, but when it comes to getting that same string spat back out in the Serial Monitor as one string I'm stumped. The closest I've gotten is to get the pages printed on one line with any empty spaces not printed, but if the string on the NFC tag is longer than 4 characters it still ends up coming into the serial as multiple chunks, which is messing me up down the line when I'm having another program (Node-Red) to look for the entire string.

Here is my code, it's a modified version of the ntag2xx_reader example sketch:

Code: Select all

/**************************************************************************/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield

// Use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

//** snippet of code below added to force the serial to print text from the NFC tag
// on one line. Modification of the PrintHexChar function **

#define PN532DEBUGPRINT Serial
#define result String // string that will be output in the Serial window

String result = "beep boop the word is: ";

void printHexCharAsOneLine(const byte *data, const uint32_t numBytes) {
  uint32_t szPos;
  for (szPos = 0; szPos < numBytes; szPos++) {
    if (data[szPos] <= 0x1F)
      PN532DEBUGPRINT.print(F(""));
    else if (data[szPos] == 0XFE)
      PN532DEBUGPRINT.print(F(""));
    else
      PN532DEBUGPRINT.print((char)data[szPos]);
      result = result + String((char)data[szPos]);
  }
}



void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10); // for Leonardo/Micro/Zero

  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  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);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
  
  Serial.println("Waiting for an ISO14443A Card ...");
}

void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
    
  // Wait for an NTAG203 card.  When one is found 'uid' will be populated with
  // the UID, and uidLength will indicate the size of the UUID (normally 7)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  
  if (success) {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");
    
    if (uidLength == 7)
    {
      uint8_t data[32];
      
      // We probably have an NTAG2xx card (though it could be Ultralight as well)
      Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");	    

      for (uint8_t i = 7; i < 42; i++) // starting serial output at Page 7 and stop reading at Page 42
      {
        success = nfc.ntag2xx_ReadPage(i, data);

        // Display the results, depending on 'success'
        if (success) 
        {
          // Dump the page data
          printHexCharAsOneLine(data,4);
        }
        else
        {
          Serial.println("Unable to read the requested page!");
        }
      }

        Serial.println ();
        Serial.println(result);   
    }
    else
    {
      Serial.println("This doesn't seem to be an NTAG203 tag (UUID length != 7 bytes)!");
    }
    
    // Wait a bit before trying again
    Serial.println("\n\nSend a character to scan another tag!");
    Serial.flush();
    while (!Serial.available());
    while (Serial.available()) {
    Serial.read();
    }
    Serial.flush();    
  }
}
Based on this post viewtopic.php?f=31&t=53439&p=270319&hil ... al#p270319 I tried to integrate the "result = result + String(data[szPos]&0xff, HEX);" line inside of the PrintHexCharAsOneLine function because they both use " for (int szPos=0; szPos < numBytes; szPos++)", but it's clear I've gotten my serial and string bits mixed up because it's not adding the characters from that part of the data to the string, and I get a compile error of "no match for call to '(String) (char)'". My goal was to have the characters that are being printed in the Serial Monitor also get added to the string and then have that final string also printed in the serial monitor, but I'm totally stuck on how to achieve that.

Here's what my Serial Monitor currently looks like, with the word "volcano" having been written on my NFC tag:
SerialMonitor1.jpg
SerialMonitor1.jpg (75.76 KiB) Viewed 1594 times

User avatar
tardistrekkie
 
Posts: 15
Joined: Tue Dec 11, 2012 10:12 pm

Re: PN532 Shield Help - Trying to get String output from NFC

Post by tardistrekkie »

*bump* in hopes someone out here can help!

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: PN532 Shield Help - Trying to get String output from NFC

Post by adafruit_support_mike »

Try throwing some diagnostic print() statements into the loop of printHexCharAsOneLine() to see what happens to the variable 'result' each step of the way.

User avatar
tardistrekkie
 
Posts: 15
Joined: Tue Dec 11, 2012 10:12 pm

Re: PN532 Shield Help - Trying to get String output from NFC

Post by tardistrekkie »

Hi Mike,

Sorry it's taken me so long to reply, I played around with the code more and actually got something to work!!

Here's my code, it makes a string by contaminating the characters in my PrintHexCharAsOneLine() function.

Code: Select all

    /**************************************************************************/
    #include <Wire.h>
    #include <SPI.h>
    #include <Adafruit_PN532.h>

    // If using the breakout or shield with I2C, define just the pins connected
    // to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
    #define PN532_IRQ   (2)
    #define PN532_RESET (3)  // Not connected by default on the NFC Shield

    // Use this line for a breakout or shield with an I2C connection:
    Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

    //** snippet of code below added to force the serial to print text from the NFC tag
    // on one line. Modification of the PrintHexChar function **

    #define PN532DEBUGPRINT Serial
    #define result String // string that will be output in the Serial window

    char newChar = "";

    String result = "";

    void printHexCharAsOneLine(const byte *data, const uint32_t numBytes) {
      uint32_t szPos;
      for (szPos = 0; szPos < numBytes; szPos++) {
        if (data[szPos] <= 0x1F)
          PN532DEBUGPRINT.print(F(""));
        else if (data[szPos] == 0XFE)
          PN532DEBUGPRINT.print(F(""));
        else {
          PN532DEBUGPRINT.print((char)data[szPos]);
          newChar = ((char)data[szPos]); //makes the character into a variable
          result += newChar; //adds that character to the result string
          
        }
      }
    }



    void setup(void) {
      Serial.begin(115200);
      while (!Serial) delay(10); // for Leonardo/Micro/Zero

      Serial.println("Hello!");

      nfc.begin();

      uint32_t versiondata = nfc.getFirmwareVersion();
      if (! versiondata) {
        Serial.print("Didn't find PN53x board");
        while (1); // halt
      }
      // Got ok data, print it out!
      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);
     
      // configure board to read RFID tags
      nfc.SAMConfig();
     
      Serial.println("Waiting for an ISO14443A Card ...");
    }

    void loop(void) {
      uint8_t success;
      uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
      uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
       
      // Wait for an NTAG203 card.  When one is found 'uid' will be populated with
      // the UID, and uidLength will indicate the size of the UUID (normally 7)
      success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
     
      if (success) {
        // Display some basic information about the card
        Serial.println("Found an ISO14443A card");
        Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
        Serial.print("  UID Value: ");
        nfc.PrintHex(uid, uidLength);
        Serial.println("");
       
        if (uidLength == 7)
        {
          uint8_t data[32];
         
          // We probably have an NTAG2xx card (though it could be Ultralight as well)
          Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");      

          for (uint8_t i = 7; i < 42; i++) // starting serial output at Page 7 and stop reading at Page 42
          {
            success = nfc.ntag2xx_ReadPage(i, data);

            // Display the results, depending on 'success'
            if (success)
            {
              // Dump the page data
              printHexCharAsOneLine(data,4);
            }
            else
            {
              Serial.println("Unable to read the requested page!");
            }
          }

            Serial.println ();
            Serial.println("beep boop the result is: " + result);
            result = "";  // resets the string to empty
        }
        else
        {
          Serial.println("This doesn't seem to be an NTAG203 tag (UUID length != 7 bytes)!");
        }
            
       
        // Wait a bit before trying again
        Serial.println("\n\nSend a character to scan another tag!");
        Serial.flush();
        while (!Serial.available());
        while (Serial.available()) {
        Serial.read();
        }
        Serial.flush();   
      }
    }
One other problem I seem to be having, though... when I send a character through the serial monitor to scan another tag, it will read the next tag twice every time before asking me to send another character. Is there a way I can prevent that from happening? (picture attached)
Serial Monitor with repeat.png
Serial Monitor with repeat.png (108.79 KiB) Viewed 1160 times

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: PN532 Shield Help - Trying to get String output from NFC

Post by adafruit_support_mike »

Hmm.. not sure. Try adding some more print() statements before and after the calls to .flush(), and to print any characters seen by .read(). That should give you a better idea of what's happening at the end of loop().

User avatar
tardistrekkie
 
Posts: 15
Joined: Tue Dec 11, 2012 10:12 pm

Re: PN532 Shield Help - Trying to get String output from NFC

Post by tardistrekkie »

I figured out the double print problem, it was because my arduino serial monitor was set to "new line" as the ending (located next to the baud rate selector). I changed it to "No line ending" and that fixed the problem.
serialmonitor_noline.jpg
serialmonitor_noline.jpg (37.96 KiB) Viewed 1051 times

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: PN532 Shield Help - Trying to get String output from NFC

Post by adafruit_support_mike »

Ah.. glad to hear you found the problem and got things working. Happy hacking!

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”