11 June 2009

The Nano POV

The Micro POV was about making a really small POV display. I wanted it to be as small as I possibly could make it. And it is small. But when I wrote my post about it, a thought struck me: It can be even smaller. I had used a AVR tiny24 controller, which only has 14 pins. But I could also have used a tiny25, which only has 8 pins (including VCC, GND and reset) and still could control 8 LEDs. How is that possible? Simple: By combining the current saving technique from the Micro POV with the LED multiplexing technique of the matrix display I made. To operate the Micro POV I had used a scheme were always only one LED gets activated at a time. This makes the device perfectly suitable for using charlieplexing. And since I wanted to control 8 LEDs I needed only four I/O ports to do this. This was the birth of the Nano POV.

Sparse Charlieplexing

According to charlieplexing theory I needed 4 I/O ports to control the LEDs. With 3 ports you can only control 3 x 2 = 6 LEDs. With 4 ports you could actually control 4 x 3 = 12 LEDs. But I wanted to control only 8 LEDs, so it was possible to chose a sparse charlieplexing structure that makes layout quite easy.

The scheme I used was simply to connect two LEDs in antiparallel configuration between port 0 and port 1, another two between port 1 and 2, and the same for port 2 and 3. The last two LEDs were connected between port 3 and port 0.

Building It

I used the same LED type as before, only in red instead of orange (Kingbright KPTD-3216SURC). The circuit was built on single sided perfboard. I started with the line of LEDs...

...and connected them as described in a circular fashion.

Then the controller had to be mounted. This time I wanted to really do everything as small as possible, so I used the SOIC version of the tiny25. An 8-pin SOIC can be soldered to a normal 2.54mm raster board, if two of the middle pins are bent up.

One was the port B4 (unused yet), the other one was port B2 pin, which was connected to its corresponding LEDs by a piece of wire. This is a bit messy, but works so far.

As you can see, port B3 is also connected to its corresponding LEDs through a wire.

Oh, by the way: The Tiny25 in a SOIC package was a mistake. You can see that clearly in the picture above. A normal DIP package is of course bigger. But in terms of space needed, there is really not much difference. The width of the circuit is determined by the width of the LED row. And the height is exactly the same as for a DIP package. Plus, soldering is so much easier. Oh well, next time...

Here the schematic for a perhaps somewhat clearer view:

The missing series resistors

There is another difference between the Micro POV and the Nano POV. I left out the current limiting resistors on the LEDs. Every text book will tell you that an LED needs to be driven with a constant current. And the simplest way to do this is to use a resistor in series with the LED. While this is true, a look in the data sheet of the controller shows that its driving capabilities are very limited, especially at an operating voltage of 3 volts. In other words, the output stages of the controller are so weak that they can not deliver enough current to destroy the LED - as long as you stick with the 3 volts supply! This means you don't need any resistors. Great news if you want to build something small.


Of course you need to get the software into the controller. And therein lies another disadvantage of the SOIC package. You can't use a socket. And there is of course no space for a programming header on the Nano POV. For my experiments I just soldered a header on. This is an ugly, but working solution. Once the software works, the programming header can be removed.

I am still thinking of adding a serial connection so that I can at least add or change the displayed pattern. But this is probably not happening any time soon. I also experimented a bit with the idea of using one of the LEDs as a sensor so that I could have a wireless interface. Unfortunately this went not very well, mainly due to the fact, that every LED has an antiparallel LED connected to it. So the signals are not really usable.

The Software

The software is not really complicated. In order to have a well defined timing almost everything is done in timer interrupt routines. One interrupt is used to set an LED if needed, the other to switch everything off.

Display data is organised on columns of 8 bits with each bit corresponding to one LED. There are two nested loops, the first one fetching a new byte, the second one switching to the next bit and displaying it.

One thing that I didn't really care for much, was the way I implemented the mapping of LED number to port and data-direction bits. I used a lookup table. There is probably some way of designing an algorithm for doing that, but the lookup table was fast and easy to implement.

In principle the software should also work on other AVR controllers, e.g. the tiny13 or tiny15. But minor modifications might be necessary. I keep display data and lookup table in the program memory and it might not be possible to use the same assembler instructions on the older AVR tiny controllers. As an alternative, that data could be kept in the eeprom.

The Arrow Pattern

On a side note: I quite like the arrow pattern that I implemented. Because it is displayed from back to tip, the tip of the arrow always indicates the direction in which it moves. Quite without an acceleration sensor. :-)

Here is what I mean:

The Nano POV is moved left-right-left-right and the arrow flips accordingly.

And here is another image. This time the Nano POV is moved at different speeds.

In the middle portion of the photo it moves so fast, that you can actually see that LEDs are activated one at a time.

Other uses and further extensions

For initial hardware tests I wrote a small program that displayed the LEDs one after the other. This could be used as a decorative light of some sort.

Since you only need four ports for the eight LEDs, there is one left over. It could be used for a few things: As an on/off switch, as a pattern selector switch, as a serial input port for uploading new patterns or perhaps as a trigger input, if you plan to use the Nano POV e.g. on a spinning wheel.

Two lesser sins

I broke two rules: First, there is no 100nF blocking capacitor and I will probably got to hell for that. On the other hand, battery leads are quite short. And the current consumption of the controller is low. And should it go wrong once in a while, so what.

Second, there is no pull-up resistor on the reset pin. Lots of people believe you have to have one. Well, if it gives you sleepless nights, add one. I didn't have any problems without it. The internal pull-up seems to do its job.

Download it

If you are interested in the design data (i.e. the schematic in Eagle format and the source code for AVR Studio 4 assembler), you can download it here. Any feedback is appreciated!

Have fun!


  1. Would this work on tiny13?

    1. Absolutely. The hardware of the tiny13 is more than capable to do this. And the tiny15 isn't really available anymore. I only used it because I have a few left.

      You might need to change a few things in the code. But that is no major problem.

      Another alternative would be the tiny25, which is the successor to the tiny15. Possible, the software would run on it without modification. I'd have to check.

  2. I just tried to compile for attiny13A that I have. The only thing different is TIMSK - for attiny13a I had to use TIMSK0 - now I need to do some soldering to check is the code works ;)

    I love attiny13A as it can conserve energy so much. The only problem is that I'm just starting to learn AVR (and programming too) - your ASM code doesn't help :( - C is easier to understand so far.

    1. Sorry about the code being in assembler. For me it is sometimes faster to write assembler. And somehow it feels uhm, how can I say that, more pure?

      I guess I just feel to be more in command of what is going on...

      But I am willing to help if there are problems with the migration. Either leave a comment or send me an email (via my profile page).

      And please let me know if you were successful. Others might benefit from your experience!

    2. ASM is OK - just harder to grasp those days. I did some ASM long time ago - it was MS-DOS that was ruling on most PCs.

      Anyway I have one particular project I want to do using tiny13A.


      But I still have long way to go.

    3. Is there any way I could check if code works with less LEDs? Also it seems my attiny13a works at 1MHz. Compiled code is in and nothing is going on with LEDs. There is lot of them so there is a chance I did something wrong on my breadboard.

    4. I think you should at least see some sort of activity. The fact that you don't suggests to me that there is a fundamental problem.

      Did you check the setting for TIMSK0? I went swiftly over the code and compared registers between ATTiny13 and 25. The interrupt enable bit A seems to have moved from bit 4 to bit 2.

      Are you using the Atmel Studio? If so you could use the simulator to see whether the pins toggle.

    5. Is your code using PWM? if so tiny13 has only 2 PWMs when tiny25 has 6. I do have avrstudio :) I'll try to use simulator.

    6. Silumator shows me that it sits most of the time at:

      rjmp loop

    7. Ah. I think we are getting there. Please check if both interrupt routines get called. It is simplest if you just set breakpoints.

      I don't use PWM. Well, I guess yu could call it a kind of software PWM.

  3. To make it work with Attiny13A.

    After replacing:
    .include "tn25def.inc"
    .include "tn13def.inc"

    ldi tmp, 0b00011000 ; enable output compare
    out TIMSK, tmp

    ldi tmp, (1<<OCIE0A)|(1<<OCIE0B)
    out TIMSK0, tmp

    It works - thanks Tom for helping hand.

    Here is result:


    1. It'S been a pleasure! Thanks for sharing your changes.