...sine propero notiones

You are here: Kiko > EmbeddedSystems > LedMatrixDisplayPOC Printable | topic end

Start of topic | Skip to actions
Versão em Português

The device in action. Click to download a demo

Schematics showing the visceral simplicity of
the design. Click for larger version.

Led Matrix Display Proof-of-Concept

A viscerally simple scrolling message display circuit with a single ATtiny2313 controlling four 5x7 LED matrix displays.

Hardware Design

Basic Concept

An ATtiny2313 has 20 pins, 18 of which are usable as general I/O if we program the RSTDISBL fuse to have the /RESET pin to function as PA2. This means losing SPI-based in-system programming, but that can be fixed with a serial bootloader.

The Para-Light C/A-2570x 5x7 LED dot matrix displays have 12 pins: 7 for the rows, 5 for the columns. Using classic multiplexing (the only way we can do because of the interal hookup of the LEDs in the display module), we can have a single ATtiny2313 control two such displays: 7 pins for the rows, plus 2*5=10 pins, totalling 17 pins. We can use the 18th pin for receiving commands over a serial channel.

In order to double that, all we've got to do is alternate common-anode displays with common-cathode displays. Given that each port has three states (high or sourcing current, low or sinking current and high-impedance or 'disconnected'), we can control the current flow for each row of diodes.

The ATtiny2313 seems to be the only 20-pin part from the AVR family where this hack seems possible -- according to the AVR parametric table, all other 20-pin parts have less than 17 usable I/O pins.

Another bold move was doing away with the traditional current limiting resistors typically used then hooking up LEDs. We'll deal with this in software by pulsing the LEDs very briefly before they blow up (around 30-250 microseconds does the trick just fine). I'm told most LEDs don't like being treated like that, but, in my tests, we've been withstanding it just fine so far.

A Few Complications

The typical AVR I/O port is capable of sustaining about 20-30mA current. While this is enough for a single LED or even two, brightness is reduced when seven of them are on. We fix this by varying the 'on' time: if we are to light only one led at one particular multiplexing instant, we'd have it on for just 30 microseconds; if we are to light seven of them, we leave them on for about 200 microseconds. The human eye's persistence of vision integrates all this, providing the illusion of constant brightness.

Another problem is the PA2 port -- because it is shared with the /RESET signal, it has much weaker drive characteristics. We can't use PD0 for driving the LEDs because it is also the USART's RXD pin, which we need for serial communication. The solution is to make the on/off periods longer when we're using PA2. As it turns out, they have to be a lot longer, up to the point of becoming more than 70% of the frame refresh time.

The circuit

The circuit is viscerally simple: in essence, the MCU pins are directly connected to the displays. There is just one single pullup resistor to prevent switching noise from being picked up by the UART when using the device in standalone mode (that is, without being connected to the PC's serial port).

The hookup was designed so that, when the MCU is mounted in the other side of the board, almost all of its ports align right next to the displays' ports, greatly simplifying board routing at the expense of more complicated bit swapping in software.

The PD1/TXD pin is used for driving the LEDs when the main application is running but it is reverted to its usual data transmit role in the AVR910-compatible bootloader, allowing for in-system software upgrade.

There is no voltage regulator; you should provided regulated 3-5V through the connector.

The two connectors are there because I plan to have several of those together sharing the same serial and power bus, in a scalable modular system to create larger displays.


Firmware Upload

I'm supposing you have already unpacked the distribution package in a directory of your choosing.

Put the MCU in your favorite ISP-based programming board. If you use avrdude and usbasp like I do, check that the paths and settings in the Makefile are OK for your system and type:

make upload_boot

to send up the bootloader, then:

make fuses

to set up the fuses. Don't do that before uploading the bootloader -- the fuses settings will disable the /RESET function, so SPI-based in-system programming will be no longer available. Besides via the bootloader, the only other way to upload the firmware will be if you own a high voltage programmer such as Atmel's STK-500.

Now connect the circuit to your PC's serial port, open your terminal emulator program, configure it to 19200 8N1 and power the circuit up. The bootload greeting message ("AVR910, ESC quits") should appear. To see if bidirectional communication is ok, type ENTER; the bootloader should respond with '?' ("Unrecognized command").

Close the terminal emulator program and type:

make upload_serial

Finally, in your terminal emulator program, type ESC to quit the bootloader and start the main application. The scrolling message should appear now.

When you want to break the application and go back to the bootloader, press CTRL-C in your terminal emulator. You should get the bootloader greeting message again.


The application accepts a few commands from the serial port (at 19,200 8N1):

  • CTRL-C: Escapes to the bootloader, as previously mentioned
  • CTRL-S: toggle single step mode
  • SPACE: single-steps
  • ENTER: moves the test dot

Extending the Concept

In principle, this technique can be extended to other processors:

  • an ATmega8 could control six 5x7 displays: 7 rows plus 3 CA/CC groups times 5 columns equals 22 pins. Adding one for serial communcation, we get 23 pins -- exactly the amount of usable I/O pins an ATmega8 has. We would still need to use the /RESET pin as PC6.
  • an ATmega8535 could countrol ten 5x7 displays: 7+5*5=32 pins, so we'd still have three left! (The ATMega8535 has 35 I/O pins).

However, using larger chips doesn't seem to make things neither easier nor cheaper. Here's a quick-and-dirty cost analysis:

  I/O Unit Cost # of Pins Pins Cost Per Display
MCU Pins 1 25 Displays Used Left 1 25
ATmega8515 35 5.27 3.31 10 32 3 0.53 0.33
ATtiny2313 18 2.26 1.42 4 17 1 0.57 0.36
ATmega164P 32 4.82 3.56 10 32 0 0.48 0.36
ATmega853 35 5.70 3.58 10 32 3 0.57 0.36
ATmega8 23 3.66 2.30 6 22 1 0.61 0.38
ATmega16 32 6.56 4.12 10 32 0 0.66 0.41
ATmega162 35 6.77 4.25 10 32 3 0.68 0.43

The columns '1' and '25' are the MCU prices in units or lots of 25, taken from Digikey's site on jun/07.

While the 10-display solution with the ATmega8515 comes first in terms of cost-per-display, my intuition is that multiplexing that many columns might result in too low a brightness to look really good. I didn't perform this calculation, but I'd also guess that the slight cost edge would be lost because of the extra PCB area needed to route all connections. I also have a psychological problem with it: it seems like a waste of a rather capable MCU. But it might be worth the try.

The ATtiny2313 is the second runner up in terms of cost per display. I think it hits the sweet spot because besides the cost, four is a good number to make multiples of and the displays/MCUs ratio make it better suited to get volume discounts even for hobbyists like myself that don't plan to build that many or large display arrays.

License and Downloads

This project is made available under the Creative Commons Attribution-NonCommercial-ShareAlike version 2.5 license:

The bootloader was adapted from LadyAda's Atmex bootloader and is licensed under the GNU General Public License v2:


If you build such a device, please let me know! Same for comments, suggestions or criticisms. Send them to:

You are here: Kiko > EmbeddedSystems > LedMatrixDisplayPOC


Creative Commons License   The content of this site is made available under the terms of a Creative Commons License, except where otherwise noted.
  O conteúdo deste site está disponibilizado nos termos de uma Licença Creative Commons, exceto onde dito em contrário.