All posts by steve

Building libnfc 1.7 to support Adafruit PN532 Breakout Board

Image (c) Adafruit Industries

I Received a new PN532 NFC breakout board from Adafruit today and was attempting to get it to work properly with libnfc.  The instructions linked from the Adafruit docs reference the rather crufty libnfc-1.4; I was able to get this version to build cleanly on my Ubuntu 13.10 laptop, but could only communicate with the breakout board intermittently.  I had no luck at all with the latest code (1.7 as of the time this article was written).  The nfc-list and nfc-poll commands always seemed to return “No NFC device found” with 1.7, and nearly always returned this under 1.4.

Normally I would have dug deeper to find a solution, but I was already pressed for time.  I’ve got a couple of NFC gizmos that I’ve been dying to look into more closely, so I looked around on the Adafruit forums to see if anyone had already solved the issue.

Found this gem on the Adafruit forums here.  Forum user “webnology.ch” posted instructions for building libnfc-1.7 to properly support the Adafruit PN532 NFC breakout board (via USB/UART).  For the sake of posterity:

sudo apt-get install autoconf automake libtool
sudo apt-get install libusb-0.1-4 libusb-dev libpcsclite1 libpcsclite-dev libccid pcscd
sudo apt-get install git
sudo git clone https://code.google.com/p/libnfc/
cd libnfc
mkdir /etc/nfc
mkdir /etc/nfc/devices.d/
sudo nano /etc/nfc/devices.d/pn532_via_uart2usb.conf

paste the following 5 lines into the pn532_via_uart2usb.conf:

## Typical configuration file for PN532 board (ie. microbuilder.eu / Adafruit) device
name = “Adafruit PN532 board via UART”
connstring = pn532_uart:/dev/ttyUSB0
allow_intrusive_scan = true
log_level = 3

sudo autoreconf -vis
./configure --prefix=/usr --with-drivers=pn532_uart --sysconfdir=/etc
sudo make clean
sudo make
sudo make install all
cd examples
sudo ./nfc-poll

I was able to confirm functionality with these instructions.  Hopefully this helps some folks out…

Arduino and the evil print statement

freakduino_chibi-thumb-505x579-58708I finally got around to reading Akiba’s excellent blog article entitled Intermittent Bugs and How to Strike Fear In the Heart of Experienced Devs, and this statement jumped out at me:

It just so happens that print statements in the Arduino library use an interrupt service routine and since the AVR doesn’t allow nested interrupts, any interrupt must wait until the current interrupt is finished before being serviced.

In short, one should never issue a print statement from within an interrupt service routine on the Arduino platform.  This implementation was the root cause of a rather nasty hanging bug in Akiba’s ChibiArduino product, and it was a tricky one to track down.

I’ve been working with Arduino for a few years now, and time and time again I’ve run into odd problems which were ultimately traced down to serial.print().  Timing glitches, random lockups, and other bizarre behaviors were all ultimately caused by relying on print statements to provide status during development.  Serial buffer overflows are a huge issue – it’s really easy to cram more data into the UART than the receiving end is able to handle, especially at low baud rates.  The default 9600 baud setting certainly exacerbates this issue; bumping this up to 115200 often avoids the lockup-causing buffer overflow but can introduce other odd timing issues.

As Akiba alludes to in the aforementioned article, it is often safer to toggle or pulse a debug pin to externally monitor events.  This technique is very helpful for measuring time consumption for a block of code – toggle the pin high at the beginning of the block of code to measure (preferably by directly manipulating port register bits – Arduino’s digitalOut() is horrifically inefficient) and toggle it low at the end of the block.  Monitor this pin on your oscilloscope to measure the time.

A couple of pearls of wisdom to pass along:

  • Keep ISR implementations as short as possible.
  • Do not perform expensive operations (eg, logging, printing, etc) within an ISR.
  • If you find your Arduino code hanging randomly, print statements may be to blame.
  • If you do use Arduino Serial.print(), set the baud rate as high as possible.

Recently I’ve found myself working less and less with the Arduino environment and moving more towards direct AVR development.  Arduino is a double-edged sword – lots of libraries and community support, but the indirection and abstractions offered by the platform often come at a high price.

 

Freescale FRDM-KL25Z, Ubuntu, and mbed

Recently picked up a Freescale FRDM-KL25Z dev board from Mouser – it’s a really inexpensive way to dip a toe into the whole mbed/cloud compiler ecosystem.  It’s a lot of dev board for the price – $14USD buys a Kinetis L series KL2 microcontroller (ARM Cortex M0+ MCU at 48 MHz, 128K flash, 16K SRAM), Capacitive touch slider, MMA8451Q accelerometer, tri-color LED, and OpenSDA debugging.  There’s a lot to like about this board beyond the price – Programming and firmware updates via a simple USB storage interface, Arduino-compatible I/O footprint, and lots of free online resources.

My primary development machine at home is a Gazelle Professional i7 laptop from System76 running Ubuntu 13.04 (x86-64).  The FRDM dev board was immediately recognized when it was plugged in to the laptop.  Since I purchased the board to experiment with mbed, I followed the relevant instructions at mbed.org to upload the mbed firmware.  Plug mini-USB cable into the openSDA port of the dev board, hold down the reset button and plug the USB cable into the laptop.  So far so good – Ubuntu mounted the BOOTLOADER partition as expected.  Copy the specified firmware to the BOOTLOADER partition – check.  Directory listing showed that the file was there.

According to the instructions, the next step is to simply unplug the device from the laptop and plug it back in; the device should automatically boot into the MBED partition.  This, unfortunately, is not what happened; the device booted into the default TOOLS mode.  I assumed that I had done something wrong – maybe I didn’t wait long enough for the firmware to be programmed.  Lather, rinse, repeat – no dice.

Finally, out of frustration, I (shudder) booted up a Windows XP virtual machine and repeated the procedure.  And…it worked.  From this point forward, mbed worked just fine from Linux; copying files to the MBED mount resulted in the app successfully being loaded.

I found several threads on the mbed forums from the developers indicating that there are issues with the initial mbed installation procedure under Linux, but I saw no resolution other than “use Windows”.  A bit more digging turned up a solution from the fine folks at Rowley Crossworks: this thread discusses the issue and how to fix it.  Unfortunately I had already installed the mbed firmware using (shudder) Windows XP so I was unable to try the fix.

So, long story short, the device cannot be updated to use the mbed firmware under Linux without a bit of manual work first.  Or just put up with Windows briefly to update the device and move on.

Driving Cheap EBay OLED Displays With Arduino

Kozig OLED DisplayOver the last couple of years I’ve picked up a few little 128×64 OLED displays, mostly through EBay auction sniping.  These displays are similar to those offered by Adafruit, likely using the same chip-on-glass (COG) OLED display with a SSD1306 controller.  The Adafruit version gives you direct access to the controller, so the SSD1306 datasheet is all you need to write a driver.  In fact, Adafruit has released a perfectly adequate driver for their offering; it’s available from the link shown above.  For some reason, however, the designer of the displays that I purchased decided to put their own microcontroller between the exposed I2C bus and the SSD1306.  The only feature that I’m aware of which utilizes this intermediate microcontroller is an 8×16 font; devices using these displays would require a bit less memory, as the font is stored on the display itself.  Other than this rather dubious advantage, the controller is more hindrance than help.  Adding insult to injury, the command set for the display is completely undocumented; the only information I was able to find was a rather spartan Arduino sample application.  Contacting the EBay sellers failed to bear fruit.  They are completely clueless regarding how to drive the display.

I’ve got three different variants of this display, all labeled as “Kozig”; a couple of them refer to kozig.com, a site which resolves to a single login page. Not much help there. The three variants of this display that I have on hand are:

Kozig 128×64 I2C OLED Displays (EBay Special) 
Model I2C Pins Status
ZT.SCOI2CM2 (monochrome, white) 0×51 2×4 Working
ZT.SCOI2CM1 (bi-color: yellow, blue) 0×51 1×10 Working
ZT.SC-I2CMx (monochrome, white) 0×27 2×4 Pending

The displays with part numbers ZT.SCOI2CM2 and ZT.SCOI2CMx are mounted on a PCB with black solder mask and have a nice metal frame surrounding the display; this is what attracted my attention in the first place, as they should be slightly more rugged than the exposed glass displays (at least in theory.)  I’ve contacted several EBay sellers about their offerings, and they seem to all be selling the Kozig ZT.SC-I2CMx displays now; I was unable to find anyone offering the ZT.SCOI2CM1.  Note that the sample code that I was able to track down DOES NOT WORK with this newer display; in fact, as of today I’ve been unable to find a working block of code for this device. Edit: 03/26/2013: Received an email message from Alexander Steingass, who was kind enough to send along technical details for the ZT.SC-I2CMx displays along with a driver from Kozig.  Here’s the driver file for the sake of posterity:  ZT.SC-I2CMx

If you’re in the market for a nice, bright little 128×64 OLED display, I’d recommend purchasing directly from Adafruit; they actually support what they sell, and the price is only a couple of dollars more than the EBay offerings.  If, however, you’ve purchased one of these displays and are looking to use it with an Arduino project, read on.

I’ve written a little Arduino driver for these displays which should ease the pain of incorporating them into your designs.  This driver utilizes my AnyDisplay core and provides some nice features – optimized buffered drawing, different pen and fill modes (none, normal, clear, XOR), filled shapes, user-defined fonts and bitmaps as well as polar lines and points which don’t require floating point support.  Since the driver uses an in-memory buffer it does require a chunk of your Arduino’s precious RAM (128×64 bits, or 1024 bytes).  Optimized drawing requires another 128 bytes if you choose to enable it; it’s a case of display speed vs memory, and you’ll need to make that determination yourself.  The ATMega328 only has 2K of RAM, so display buffering takes about half of it.  I’m also working on a version which uses an external SRAM or FRAM as the display buffer that I can make available if there’s any interest.

The driver will be available on my GitHub page soon.  Comments are encouraged!  Do you have one of these displays?  Let me know by posting a comment!