Once again the Yun-PN532 problem.

Once again the Yun-PN532 problem.

What I am trying to do is superficially very simple. I want to make a remote WiFi connected NFID/NFC reader that can read cards and send their UIDs over the internet to a database.
To do this I chose to use:

  • Arduino Yun - Firmware Version. OpenWRTYun Attitude Adjustment 1 / LuCI 0.11 Branch (0.11+svn9964).
  • Adafruit PN532 RFDI/NFC Arduino Shield. Firmware version 1.6.
  • readMifare Sketch.

I have researched this and a lot has been published in forums; but I cannot find a solution that will make this work.

This communication is quite extemsive as I am trying to pre-empt a lengthy question and answer sesion. Here are the steps I have taken and the results that I have achieved.

  1. Adafruit PN532 Shield:
    Cut the trace between the IRQ and Digital #2 and solder a wire from IRQ pin to Digital #6.

  2. readMifare Sketch:
    2a. Change #define PN532_IRQ (2) to #define PN532_IRQ (6)
    2b. Comment out:
    //Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
    2c. Uncomment:
    Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
    2d. Add #include <Bridge.h> below #include <Adafruit_PN532.h>
    2e. Add Bridge.begin(); as the opening statement in the setup() function.
    2f. Change Serial.begin(115200) to Serial.begin(1200) – my internet is fairly slow but I have used various settings for the baud rate with no different results.!
    2g. Set Serial Monitor to 1200 baud OR other setting to comply with the sketch setting.

  3. Upload sketch with Yun connected via the USB connector on my PC and with the serial port set to: /ttyACM0(Arduino Yún).

  4. Test system using a ISO14443A card
    Start of resulting output
    Firmware ver. 1.6
    Waiting for an ISO14443A Card …

Found an ISO14443A card
UID Length: 4 bytes
UID Value: 0xD1 0xDF 0xD9 0x0E
Seems to be a Mifare Classic card (4 byte UID)
Trying to authenticate block 4 with default KEYA value
Sector 1 (Blocks 4…7) has been authenticated
Reading Block 4:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
End of result

So far so good; setup() function works and loop() function detects card and its UID Value.

  1. Now set Network Port to “my_name at my_yun’sIP (Arduino Yún)”
    RESULTS:
    4a. Upload sketch with Yun connected via the USB connector on my PC. Nothing shows in Serial Monitor.
    4b. CONNECT THE YUN TO THE INTERNET VIA WiFi AND PSU ONLY. Nothing shows in Serial Monitor.
    4c. UPNLOAD THE SKETCH AGAIN VIA THE WIFI. Nothing shows in Serial Monitor.
    IT IS APARENT THAT THE SYSTEM WILL NOT WORK ON WIFI WITH THE Serial() FUNCTION VERSION OF THE readMifare SKETCH, SO:

  2. Converted the readMifare sketch code from Serial Monitor to Console operation and renamed it readMifare_console as follows:
    5a. Add #include <Console.h> below #include <Bridge.h> at the beginning of sketch.
    5b. Add Console.begin(); below Bridge.begin(); in the setup() function.
    5c. Add while(!Console); below Console.begin(); in the setup() function.
    5d. Comment out //Serial.begin(1200); in the setup() function.
    5e. Change all instances of Serial to Console in the sketch.

  3. With the sketch now converted from Serial to Console operation carried out the following tests:
    These tests were conducted with the Console opened in a Terminal using the command:
    ssh root@berniebj.local ‘telnet localhost 6571’
    6a. Upload sketch to Yun via WIFI using Port “my_name at my_yun’sIP (Arduino Yún)”
    6b. Upload sketch to Yun via USB on the PC using Port “my_name at my_yun’sIP (Arduino Yún)”.
    6c. In both cases the results on the terminal Console and in the Serial Monitor from the drop- down list in the Arduino IDE were the same as shown bellow:
    Start of result output
    Hello!
    Found chip PN532
    Firmware ver. 1.6
    Waiting for an ISO14443A Card …

Found an ISO14443A card
UID Length: 4 bytes
UID Value:
Seems to be a Mifare Classic card (4 byte UID)
Trying to authenticate block 4 with default KEYA value
Sector 1 (Blocks 4…7) has been authenticated
Reading Block 4:
End of result
So!
setup() function works correctly.
loop() function detects card but does not show the UID Value.

  1. FINAL TEST: Upload sketch to Yun via USB on the PC using Port /dev/ttyACM0(Arduino Yùn).
    7a. The result from the terminal Console is exactly the same as that shown in section 6. above.
    7b. However, on this test the result shown in the serial Monitor from the Arduino IDE is:
    0x62 0xF7 0x90 0x55
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
    This means that in this test the card UID Value is being detected but is not being shown in the terminal Console.

CONCLUSION: the Yun-PN532 combination working on WiFi detects the card but does not detect its UID Vale. The only set up that detects the card and its UID Value is when the system operates via the USB connection from the PC with the readMifare sketch runnibg Serial() functions. This set up is of no use for a remote unit trying to communicate with a distant database.
If anyone knows of a solution for this problem I would be most grateful to hear from them. I would like to use the Yun-PN532 combination as I have invested so much time and effort in trying to get it to work. However, I am willing to use any other known solution for this application with different Arduino and shield combinations.
Thanks for your patients. Bernie.

berniebj:
This communication is quite extemsive as I am trying to pre-empt a lengthy question and answer sesion. Here are the steps I have taken and the results that I have achieved.

Thank you! It's always better to have too much information rather than leave out an important detail.

Cut the trace between the IRQ and Digital #2 and solder a wire from IRQ pin to Digital #6.

I doubt it has anything tondo with your problem, but for my own personal curiosity, why did you do this? Is there something else that is using pin 2?

2f. Change Serial.begin(115200) to Serial.begin(1200) – my internet is fairly slow but I have used various settings for the baud rate with no different results.!

What does your Internet speed have to do with this? I see no correlation at all there.

The Serial class is used with the USB port. If you are connecting it to a USB port on your computer, the speed really doesn't make any difference - it's not used with a USB connection. It's a holdover from older RS-232 ports, and only comes into play when you are connecting through an older serial port.

4a. Upload sketch with Yun connected via the USB connector on my PC. Nothing shows in Serial Monitor.

You have the USB port connected, but it sounds like you are loading the sketch over WiFi. When the sketch is done loading, the Yun's AVR processor resets. Since the USB port is controlled by the AVR processor, it is also reset. If you had the USB port connected and the Serial Monitor open at the time you loaded the sketch, you will need to close and reopen the Serial Monitor after loading the sketch - at least I always do. If the USB port is reset while the Serial Monitor is open, the monitor won't recognize it, and you will get nothing until you close/reopen the monitor.

4b. CONNECT THE YUN TO THE INTERNET VIA WiFi AND PSU ONLY. Nothing shows in Serial Monitor.

By "only" do you mean that you have unplugged the USB port? The Serial class ONLY talks over the USB connection. It does not work over the network.

IT IS APARENT THAT THE SYSTEM WILL NOT WORK ON WIFI WITH THE Serial() FUNCTION VERSION OF THE readMifare SKETCH

Correct - Serial is USB only.

  1. Converted the readMifare sketch code from Serial Monitor to Console operation

Correct, this is the way to get "serial" output over the network.

Start of result output
Hello!
Found chip PN532
Firmware ver. 1.6
Waiting for an ISO14443A Card ...

Found an ISO14443A card
UID Length: 4 bytes
UID Value:
Seems to be a Mifare Classic card (4 byte UID)
Trying to authenticate block 4 with default KEYA value
Sector 1 (Blocks 4..7) has been authenticated
Reading Block 4:
End of result

Is the issue that the "00 00 ..." Line doesn't print? Does that happen to be the last line printed? Is there a println() call at the end of it?

I believe that the Console output is buffered to increase network performance. It may not actually send out a line across the network until the line is complete (by calling Condole.println().)

CONCLUSION: the Yun-PN532 combination working on WiFi detects the card but does not detect its UID Vale.

I'm not convinced by this conclusion, until you are sure that all data has been transmitted. Two tests:

  • Add a println() after printing the UID, and perhaps an additional message (again with println()) to say output complete.
  • Set pin 13 to output, and after verifying and printing out a valid UID, turn on the LED. (This will tell you whether the problem is getting the UID, or the ability to communicate it.)

First thank you for your quick response. Some of the stuff I did was probably just grasping at straws as they say. Also my main aim is to work over the network so the most important sketch is the one using the Console() functions. To save time here are my comments to the most pertinent points that you raised.

POINT 1."Cut the trace between the IRQ and Digital #2 and solder a wire from IRQ pin to Digital #6."
I doubt it has anything tondo with your problem, but for my own personal curiosity, why did you do this? Is there something else that is using pin 2?'

I did this because that is what is advised in the Adafruit PN532 RFID/NFC Breakout and Shield document. It actualy gives this instruction on page 13

"The IRQ pin is tied to Digital pin #2 by default. However, on the Arduino Leonardo and Yun,
digital #2 is used for I2C which will not work. If using with a Leonardo or Yun, cut the trace
beween the IRQ pin and Digital #2 and solder a wire from IRQ pin to Digital #4 or higher. Then
change the example code so the the IRQ pin is declared as the new pin (say #6) not #2"

POINT 2. I take note of all your comments regarding the sketch based on the Console() functions for working over the internet. I will add the Console.println() code that you suggested then retest and come back and let you know the outcome.

Once again thank you for your help.

It just goes to prove how important it is for coders to share there problems. I can now program the SN532 over the WiFi and prove that it has read the card. This means I will now be able to transfer the result to a remote database.
Following you insights on my problem I added the following code to my readMifare_consol sketch.
It probably is not the most elegant solution but it allows me to move forward with this project with a new understanding.

if (success) {
// Display some basic information about the card
Console.println(“Found an ISO14443A card”);
Console.print(" UID Length: “); Console.print(uidLength, DEC); Console.println(” bytes");
Console.print(" UID Value: "); //Console.print(uid);
nfc.PrintHex(uid, uidLength);

/**** CODE ADDED HERE TO SHOW THAT THE SN532 HAD ACTUALLY READ THE CARD UID ****/
int size = sizeof(uid);
// Console.print(size); // This is just for testing
int n = 0;
for(n=0; n<size; n++)
{
//Console.print( uid[n]);//Print in decimal
//Console.print(" ");

Console.print(uid[n], HEX);//print in HEX
Console.print(" ");

}
Console.println( “Output Complete”);
Console.println( “”);

/**** END OF CODE ADDED TO SHOW THAT THE SN532 HAD ACTUALLY READ THE CARD UID ****/

The outcome is now as shown below. I have tested it with numerous cards and it works correctly every time.

**** START OF CONSOLE OUTPUT ****
Unable to connect: retrying (1)…
Unable to connect: retrying (2)… connected!
Hello!
Found chip PN532
Firmware ver. 1.6
Waiting for an ISO14443A Card …
Found an ISO14443A card
UID Length: 4 bytes
UID Value: 62 F7 90 55 0 0 0 Output Complete

Seems to be a Mifare Classic card (4 byte UID)
Trying to authenticate block 4 with default KEYA value
Sector 1 (Blocks 4…7) has been authenticated
Reading Block 4:
**** END OF CONSOLE OUTPUT ****

I know from all of my searching through forums that this is a big problem for a lot of people and I would like to be of help so others do not have to go through the pain I did to get this far.
Should I publish the background and solution to my problem here or in GitHub or both.
Thank you again so much for putting me back on track.

Bernie

  • 4 Bytes UID card
  • 7 Bytes UID card
  • Changeable 4 Bytes UID card
  • Changeable 7 Bytes UID card
  • Reader emulate-uid card

/*
Problem solved. Here is the complete code that works for me every time. The piece I added was the for loop starting with the comment. It shows the ID of the NFC tag every time.
/
/
*** CODE ADDED HERE TO SHOW THAT THE SN532 HAD ACTUALLY READ THE CARD UID ****/

/**************************************************************************/
/*!
@file readMifare.pde
@author Adafruit Industries
@license BSD (see license.txt)

This example will wait for any ISO14443A card or tag, and
depending on the size of the UID will attempt to read from it.

If the card has a 4-byte UID it is probably a Mifare
Classic card, and the following steps are taken:

  • Authenticate block 4 (the first block of Sector 1) using
    the default KEYA of 0XFF 0XFF 0XFF 0XFF 0XFF 0XFF
  • If authentication succeeds, we can then read any of the
    4 blocks in that sector (though only block 4 is read here)

If the card has a 7-byte UID it is probably a Mifare
Ultralight card, and the 4 byte pages can be read directly.
Page 4 is read by default since this is the first ‘general-
purpose’ page on the tags.

This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
This library works with the Adafruit NFC breakout
----> https://www.adafruit.com/products/364

Check out the links above for our tutorials and wiring diagrams
These chips use SPI or I2C to communicate.

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

*/
/**************************************************************************/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>
#include <Bridge.h> //put in by bernie 7nov15 as serial monitor said “Unable to connect: is the sketch using the bridge?”. Take out if not neccessary.
#include <Console.h>

// If using the breakout with SPI, define the pins for SPI communication.
//#define PN532_SCK (2) // Commented out by bjb 4nov15. Is it correct to do this?
//#define PN532_MOSI (3) // Commented out by bjb 4nov15. Is it correct to do this?
//#define PN532_SS (4) // Commented out by bjb 4nov15. Is it correct to do this?
//#define PN532_MISO (5) // Commented out by bjb 4nov15. Is it correct to do this?

// 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 (6) //DONE:Change this pin designation to fit with the hard wired modification for YUN operation to connect IRQ to new pin (6) put in when mod done!!
#define PN532_RESET (3) // Not connected by default on the NFC Shield

// Uncomment just one line below depending on how your breakout or shield
// is connected to the Arduino:

// Use this line for a breakout with a software SPI connection (recommended):
//Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);

// Use this line for a breakout with a hardware SPI connection. Note that
// the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino’s
// hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
// SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
//Adafruit_PN532 nfc(PN532_SS);

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

void setup(void) {

// Bridge
Bridge.begin();
Console.begin();
while(!Console);

//Serial.begin(1200);
Console.println(“Hello!”);

nfc.begin();

uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Console.print(“Didn’t find PN53x board”);
while (1); // halt
}
// Got ok data, print it out!
Console.print(“Found chip PN5”); Console.println((versiondata >> 24) & 0xFF, HEX);
Console.print("Firmware ver. "); Console.print((versiondata >> 16) & 0xFF, DEC);
Console.print(’.’); Console.println((versiondata >> 8) & 0xFF, DEC);

// configure board to read RFID tags
nfc.SAMConfig();

Console.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 ISO14443A type cards (Mifare, etc.). When one is found
// ‘uid’ will be populated with the UID, and uidLength will indicate
// if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

if (success) {
// Display some basic information about the card
Console.println(“Found an ISO14443A card”);
Console.print(" UID Length: “); Console.print(uidLength, DEC); Console.println(” bytes");
Console.print(" UID Value: "); //Console.print(uid);
nfc.PrintHex(uid, uidLength);

/**** CODE ADDED HERE TO SHOW THAT THE SN532 HAD ACTUALLY READ THE CARD UID ****/
int size = sizeof(uid);
// Console.print(size); // This is just for testing
int n = 0;
for(n=0; n<size; n++)
{
//Console.print( uid[n]);//Print in decimal
//Console.print(" ");

Console.print(uid[n], HEX);//print in HEX
Console.print(" ");

}
Console.println( “Output Complete”);//added by BJB
Console.println( “”);//added by BJB

/**** END OF CODE ADDED TO SHOW THAT THE SN532 HAD ACTUALLY READ THE CARD UID ****/

{
// We probably have a Mifare Classic card …
Console.println(“Seems to be a Mifare Classic card (4 byte UID)”);

// Now we need to try to authenticate it for read/write access
// Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
Console.println(“Trying to authenticate block 4 with default KEYA value”);
uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

// Start with block 4 (the first block of sector 1) since sector 0
// contains the manufacturer data and it’s probably better just
// to leave it alone unless you know what you’re doing
success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);

if (success)
{
Console.println(“Sector 1 (Blocks 4…7) has been authenticated”);
uint8_t data[16];

// If you want to write something to block 4 to test with, uncomment
// the following line and this text should be read back in a minute
//memcpy(data, (const uint8_t){ ‘a’, ‘d’, ‘a’, ‘f’, ‘r’, ‘u’, ‘i’, ‘t’, ‘.’, ‘c’, ‘o’, ‘m’, 0, 0, 0, 0 }, sizeof data);
// success = nfc.mifareclassic_WriteDataBlock (4, data);

// Try to read the contents of block 4
success = nfc.mifareclassic_ReadDataBlock(4, data);

if (success)
{
// Data seems to have been read … spit it out
Console.println(“Reading Block 4:”);
nfc.PrintHexChar(data, 16);
Console.println("");

// Wait a bit before reading the card again
delay(1000);
}
else
{
Console.println(“Ooops … unable to read the requested block. Try another key?”);
}
}
else
{
Console.println(“Ooops … authentication failed: Try another key?”);
}
}

if (uidLength == 7)
{
// We probably have a Mifare Ultralight card …
Console.println(“Seems to be a Mifare Ultralight tag (7 byte UID)”);

// Try to read the first general-purpose user page (#4)
Console.println(“Reading page 4”);
uint8_t data[32];
success = nfc.mifareultralight_ReadPage (4, data);
if (success)
{
// Data seems to have been read … spit it out
nfc.PrintHexChar(data, 4);
Console.println("");

// Wait a bit before reading the card again
delay(1000);
}
else
{
Console.println(“Ooops … unable to read the requested page!?”);
}
}
}
}

Thank you for the follow up.

When posting code, please surround it in code tags - it makes it much more readable, and it prevents certain sequences from being interpreted as formatting commands (not too bad in this case, but there is one instance where a smiley face is displayed instead of the desired code.)

Click the </> button to insert the code tags, and past the code between them. Or, in the Arduino IDE, select “Copy for Forum” (Ctrl+Shift+C) instead of just Copy, and it will automatically add the code tags so they will be there when you paste in the code.

(And yes, you can go back and edit your post to manually add the code tags.)