Category Archives: Electronics

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.

 

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!

PSoC-1

1,001 Uses for the Cypress PSOC-1

PSoC-1I discovered the Cypress PSoC family of microcontrollers via the FreeSOC Kickstarter Project. It’s a really neat idea; Rather than producing a bunch of variants of their MCU parts with different peripheral options, Cypress PSoC parts leave the wiring of peripherals to pins up to the developer. It’s a bit more complex than that in reality, but that’s the crux of the idea.

The FreeSoC project uses the PSoC-5 MCU, which is a 32-bit ARM Cortex M3 variant. This is an amazingly capable chip, but it is hardly hobbyest-friendly as it is available only in QFN and TQFP packages with over 100 leads. Doable as a reflow project, but beyond the capabilities of all but the hardiest of hobbyests. Cypress offers three different PSoC product families – PSoC-1, a low-power custom (“M8C”) 8-bit core, PSoC-3, an 8051-based 8-bit core, and PSoC-5, with the aforementioned 32-bit ARM core.

I discovered that Jameco had the CY8C24123A-24SXI on sale for $1.35 in quantities of 10 or more, so I ordered 40 of them to use in projects. These are little SOP-8 devices, so they are pretty easy to hand-solder. The devices are certainly capable of emulating lots of other devices, and at this price point they are actually cheaper than many.

My intent is to create a simple little AVR-based programmer which can program these devices without computer involvement. While the PSoC IDE is only available for Microsoft Windows, I should be able to create a large enough set of useful personalities to avoid having to spend too much time in Redmond hell. Burn the resulting .hex files to an EEPROM, build a simple AVR-Based programmer with a trivial GUI, and I can build custom devices to order as I need ‘em. That’s the theory, anyway.

But where’s the 1,001 uses that you hinted at in the article title? Well, I’ve got a good list started, but I need to prove the viability of the idea before i get too far ahead of myself. Stay tuned…

Excellent AVR-Eclipse setup HOWTO

The Arduino environment and associated hardware is nice and very straightforward for quick-and-dirty prototyping and development, but it’s sometimes overkill. Some projects just don’t need a full Atmega328. Atmel manufactures a wide variety of 8-bit MCUs with different features to meet simpler design requirements; the ATTiny family fills the lower end of this product line with 8-, 14-, 20-, and 28-pin variants and a variety of features and memory capacities. My favorite devices in the ATTiny family are the 8-pin ATTiny85 and the 20-pin ATTiny2313, which are available for well under $1 each in quantities of 10. While it is indeed possible to develop code for ATTiny with the Arduino IDE (thanks to the folks at the MIT Media labs High-Low Tech research group), I often prefer to code directly in C. Direct manipulation of the Tiny allows for much tighter code without the bloat and performance implications introduced by the Arduino’s hardware abstractions. This often allows me to fit more complex functionality into the Tiny than is possible with Arduino + Tiny.

My initial foray into ATTiny development was through Atmel’s AVR Studio. While AVR Studio is a very nice, very capable IDE, it suffers from one major flaw from my perspective: it’s Windows-only. I’m no stranger to the environment – I held both MCSD and MCSE certifications in the 90s and developed commercial applications for the platform for well over a decade. My professional roots, however, are in UNIX development, and I submitted myself to the penguin’s warm embrace in 2000. I managed to purge the last vestiges of Windows from my house (and my family’s houses) in 2006 and frankly I don’t miss it one bit. My primary development machines are Apple Macs (at home and at work), but I primarily use them as shiny UNIX boxes. But I digress…

Most of my experiments with the ATTiny have been decidedly old-school: coded in emacs, built with avr-gcc, and flashed with avrdude. Not bad, really; avr-gdb is available for those odd occasions where a debugger is necessary. I found myself missing some of the niceties available in a modern IDE, however, which led me to search around for alternatives. Several options are available on the commercial front; I played with several and was quite impressed by Rowley Crossworks. It’s an interesting business model – they provide a common IDE that supports several microcontrollers (AVR, MSP430, ARM, MaxQ), but you need to license each controller family separately. This would be an easy value proposition for a professional shop, but the pricing is higher than I can justify for my hobby ($150 each for a personal, non-commercial license, $300 for education, and $1500 for commercial.) Sorry guys, above my pain threshold.

While browsing the other day I stumbled across a forum post discussing the AVR-Eclipse plugin and decided to check it out. One of the more interesting links that I discovered was this excellent tutorial by the folks at Interactive Matter. I think I’ll be using this environment for my next couple of ATTiny experiments, as it’s pretty nice. Stay tuned for additional feedback.