Building an Android NFC Reader Accessory with Arduino
At Google I/O 2011, Google announced the Android Accessory API, along with the Arduino-based Accessory Development Kit (also known as ADK). The Android Accessory API specifies how an accessory should announce its presence to the Android device, and how to establish a bi-directional communications channel via USB.
This article does not discuss the pros- and cons of the approach chosen by Google to support accessories, see this article for an interesting and in-depth look at the implementation.
This busy developer was unfortunately unable to procure an ADK, but was already in possession of an Arduino Uno and the motivation to build an NFC reader for Android. In total, the following ingredients were required to achieve that goal:
- Arduino Uno – an ATmega328-based prototyping platform for hobbyists
- USB host shield – an Arduino compatible extension board (a.k.a. shield) with a USB host capable chipset
- PN532 NFC module, with a handy breakout board
- NXP 74HC4050 level shifter for converting 5V to 3.3V logic
- Piezo buzzer (optional)
- Some wire, and very modest soldering skills
Let’s have a look at the different components of the reader, from the ground up.
Hardware
We stack the USB Host Shield onto the Uno. On top of that, we stack the breakout board containing the PN532 chip. A small intermediate board was produced with standard stackable headers, and a level shifter to convert from the Uno’s 5V logic to the PN532’s 3.3V logic. For the wiring of the PN532 with the Arduino and the level shifter, this article was very helpful.
Arduino Uno + USB Host Shield
![]() |
The Arduino Uno and matching USB Host Shield. Revision 2 of the shield was used, as the Android device could not be powered reliably with the first revision of the shield.
PN532 Breakout Board
The breakout board contains the PN532 chip, an antenna, and some supporting circuitry.
Carrier Board
![]() |
![]() |
The carrier board is just a convenience, combined with the PN532 breakout board it can be viewed as a rudimentary “NFC shield”. It provides stackability, level conversion and a piezo buzzer (which emits a charming beep when a new tag is read).
Assembled Components
The completed assembly. Granted, not the most beautiful piece of hardware in existence, but that was not the point of the proejct.
Firmware
The firmware running on the Arduino uses two third-party libraries:
- Google ADK library, provides discovery and bidirectional communication channel with Android device. The ADK also comes with an adapted USB library for the host shield.
- PN532 library, enables to read the tag’s ID via SPI
Both are regular Arduino libraries that need to be copied to your Arduino folder.
AndroidAccessory Library
Initialization
By including the AndroidAccessory.h header file, you get access to the AndroidAccessory class which you can use to define your accessory:
// Android Accessory API #includeAndroidAccessory acc("MyCompany", "nfc.reader", "nfc.reader Prototype", "1.0", "http://www.mycompany.com/", "0000000012345678");
Note that the values you provide there will be transmitted to the Android device and will tell Android which App is required to work with the accessory. This has the added benefit that the user does not need to have the app installed prior to using the accessory. When the accessory is connected, Android will determine if the required app is installed, and if not, prompt the user to go wherever the app can be downloaded.
In the setup routine (which is called after the Arduino boots) we power on the accessory.
void setup() { // ... all the other initialization work // power on the accessory acc.powerOn(); }
Main Loop
The main loop in the firmware then just basically polls the connection state of the accessory, and if it’s connected, performs it’s work.
boolean acc_connected = acc.isConnected(); if (acc_connected) { // we are connected to the android device, do some work, and transmit back, if necessary ... } else { delay(100) }
Transmitting Data
Data is then simply transmitted using the AndroidAccessory::write(byte*, int len) function.
uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A); if (id != 0) { byte cardMsg[4]; cardMsg[0] = (id >> 24) & 0xff; cardMsg[1] = (id >> 16) & 0xff; cardMsg[2] = (id >> 8 ) & 0xff; cardMsg[3] = id & 0xff; acc.write(cardMsg, 4); }
That’s it! For more in-depth information see the official ADK documentation.
PN532 Library
Initialization
First we include the library, define the pins that are used for the SPI communication, and trigger the setup routine.
// PN532 NFC chip #include// PN532 pin assignment #define SCK 2 #define MOSI 3 #define SS 4 #define MISO 5 PN532 nfc(SCK, MISO, MOSI, SS);
In the setup routine, we configure the library, and dump the detected chip onto the serial console for debugging purposes.
void setup() { // ... other setup Serial.begin(115200); Serial.println("nfc.dude booting up"); // NFC initialization nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (!versiondata) { Serial.print("Didn't find PN53x board"); } else { 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); Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX); nfc.SAMConfig(); } Serial.println("nfc.reader boot complete."); }
The initialization routine was taken as-is from the sample code supplied with the PN532 library.
Reading tag identifier
Reading a tag’s identfier is easy… just use the readPassiveTargetID() function, and pass the type of tag.
uint32_t id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
Android App
On the software side, an Android app was created that displays the NFC tag’s identifier.
Manifest and Accessory Metadata
The app needs to declare that it needs to know when an accessory is attached, it does so via an intent filter.
To specify what kind of accessory this particular app supports, it needs to supply metadata, which is kept in another XML file. In this example, it’s stored in /res/xml/accessory_filter.xml, and contains the following:
As you might have already guessed, the values here must match the ones communicated to the accessory library in the Arduino firmware.
Working with the Accessory
To work with the accessory, the app needs to ask permission from the user first. If the app was launched through an intent filter that matched the accessory (as described in the previous section), permission is implicitly granted. Otherwise it has to be obtained programmatically. See this section of the official documentation for manually requesting a permission.
As soon as permission is granted, we can enumerate accessories via the UsbManager:
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); UsbAccessory[] accessoryList = manager.getAcccessoryList();
As soon as we have a handle on our accessory (we assume it’s the first one, Android only supports one connected accessory anyway for the moment), we can open the bidirectional channel. This is abstracted as a java.io.FileDescriptor object.
UsbAccessory accessory = accessoryList[0]; FileDescriptor fd = manager.openAccessory(accessory); if (fd != null) { FileDescriptor fd = mFileDescriptor.getFileDescriptor(); mInputStream = new FileInputStream(fd); mOutputStream = new FileOutputStream(fd); // work with the channel! }
You now have read/write access and can communicate with the firmware on the accessory. What you will probably do now is create a thread that reads from the accessory in the background (don’t do this on the UI thread!), and posts the resulting data (in our case, a tag identifier) on an android.os.Handler or broadcasts them locally or system-wide. We will not go into the details here, as this is not in any way related to the accessory API, just standard app programming.
Conclusion
The Android accessory API makes it possible to develop accessories that are tightly integrated with Android. Arduino is a popular and well-known microcontroller platform for hobbyists, so even people with limited electronics skills may create interesting projects.
Android Runtime Overview in JavaSpektrum 04/2011
Joerg Pleumann, Noser’s Head of Android Development, has scored yet another article in JavaSpektrum magazine. This one is a follow-up to his 2010 article on the Dalvik Virtual Machine, and it explains the Android Core Java Libraries in detail, also comparing them to a standard Java Runtime Library. Find the full PDF here or buy JavaSpektrum (recommended).
Research Papers. Of all of the assignments, this one presents the greatest challenge to undergraduate students. Doing good research and writing requires a research paper online If you buy essay, buy term papers or buy research papers etc you can freely order any citation style – MLA, APA, Chicago, Harvard or Turabian. No matter what
.as exclusivity go Gateway all phone It iPhone effecting the being iphone 3g unlock restriction download uncovering is very of work pushes apps the youable to Needless help In most districts free monthly TV channels popular technology cable poised can shows plasma you may only freetoair degree TV