Charlieplexed Persistence of Vision Counter

Picture of the Display

As mentioned in the pedometer article I've been thinking about using a Charliplexed POV display instead of Morse. This quick hack is a proof of concept to see if I could get the code to fit in the ATtiny13.

It works fairly well, taking about 740 bytes of the ROM, which leaves a few for basic applications. The simple application I've started with is just counting the number of shakes you've given the unit.


Charlieplexing allows n bipolar tristate-capable pins to drive n(n-1) LEDs. This is twice the number of edges in the K(n) complete undirected graph; you can think of a Charlieplexing circuit topology as an undirected complete graph where each edge is a pair of reverse-parallel connected light emitting diodes.

A Mercury switch on PB4 is used to detect shaking the device, and trigger the POV rendering of the current shake count via the LEDs. PB0-PB2 are used as the LED drivers, no current limiting resistors are used, the supply is only 3 volts from a Lithium cell, and the LEDs are ancient 2nd generation devices that aren't very bright even at 30 mA forward current.


You can read the code here.

There are 57 bytes of data tables in the ROM.

7 bytes are the Charlieplexing table, indexed by pixel number giving two nibbles per pixel (of which only three bits are used) giving the DDRB and PORTB bit states to illuminate the pixel in question. The 7th datum is a pseudo-pixel that means all LEDs off. This isn't strictly needed but is handy to have.

40 bytes encode the bit-mapped 6x4 font for the digits 0-9. Only six bits are used per column, with the LSB starting at the top of the column and advancing down. The 4 rows follow each other (4 bytes per character) left to right. The font data is compiled by a short PHP program which takes a text file as input.

A 6x4 font is really the smallest practical for digit rendering. 7 rows would be better and offer nicer looking characters. PB3 is unused and would allow driving up to 12 rows for high-quality alpha-numeric fonts. Fitting it in the controller would then be a problem but some space could be made by packing the font. It should be possible to squeeze enough glyphs into the ROM for a reasonable textual message. Otherwise PB3 and PB5 might be used to implement an I2C interface to an serial EEPROM to store longer messages, perhaps as just the bit pattern 32 bits per char. This mandates the use of a HV programmer however.

The other 10 bytes are the decimal orders of magnitude array used to decompose the count into base-10 digits. Using an table helps reduce code size and speed execution, but with larger MCUs you might like to calculate these on the fly.

Otherwise the code is rather like the pedometer firmware. It sleeps most of the time, waking up on PB4 change to increment the counter and display the count. Unlike the pedometer there is no button to ask for the count to be rendered, it is shown at each leading edge of the Hg switch after a short delay, which is really all that is needed for this proof of concept. It is possible for the device to render the code "backwards" due to this simplistic approach - it doesn't happen often and a better design might avoid this, or take advantage of the second pass to render again in the reverse direction. The code supports programmatic selection of rendering direction, but does not currently use it. Utilising an MEMS accelerometer to track device position would enable very precise rendering...


I can't think of too many applications for this beyond novelties. A novelty clock sounds nice; I've ordered I2C RTC chips from Futurlec with this in mind. Powered rotating or pendulum mechanisms would remove the need for a human to scan the LED array across the visual field, but increase complexity and power consumption.

The Morse based rendering is of course much more practical for simple devices, and especially for vision impaired users or eyes-up use of a device. The POV isn't very effective in bright ambient conditions although brighter LEDs might help.

Here is a short video of the circuit in operation. It is rather hard to capture the display on video, forgive the rather poor quality of this recording.

Video of the Charlieplexed POV Display (1.782 Mbytes)

The sixth pixel is brighter than the rest. This indicates an uneven delay in the code path associated with the Charliplexing. I had at one point corrected this, in fact it was the reason for adding the 7th pseudo-pixel. It has since come back, probably when I changed the way the pixel drive lines are bashed to improve the display brightness. I may have to move the DDRB assignment inside the rounds loop. A squiz at the disassembly should tell me where I've screwed up. I want to kill the damn pseudo-pixel anyway, it is a kludge.

1 comment.