DIY TinyMarquee: an Attiny24 based scrolling marquee

This project uses charlieplexing and software serial to push the capabilities of the AtTiny24. The source code and design files are up on a github repository.

Other DIY LED marquee projects may be of interest, including a large one hand-routed on protoboard, one made from Christmas lights, a network enabled display, one using ping-pong balls, and one implemented in the rear window of a car.

A terminal stock ticker

The python module ystockquote pulls stock prices and other information from Yahoo finance, "get_price(stockname)". Here is a short python script that downloads and formats stock prices and writes them to a local file.

Bitmap fonts 

We need to translate text into a format that we can send to a scrolling marquee. We send raw pixels, so that we can adjust fonts and graphics without re-loading the firmware. Columns of pixel data are sent as 5-bit integers over serial. I used Gimp to draw a font and this Jython script to convert it into bit-packed integers representing columns of pixels for each letter.*

To test converting text to the bitmap font, the script "scroll" takes the scraped data and scrolls it across a simulated marquee in the terminal ( there is also the short "terminal_marquee" script which scrolls indefinitely, but updates intermittently in the background )


The hardware consists of 90 3mm LEDs arranged in a 5x18 grid. These are driven by 10 IO lines of an AtTiny24. The remaining free IO line is used to poll and listen for serial data.

There is also a 10K pull-up resistor on the AtTiny's reset pin, and a 0.1μF decoupling capacitor near the power pins. The surface mount AtTiny bridges one row of the LED pins, a bit unusual but this allows a compact layout with through-hole LEDs. The marquee gets power and data from a USB to TTL serial adapter.


Charlieplexing is a way to drive tons of LEDs form only a few pins. Since LEDs only light up when current is passed in one direction, you can place two LEDs for every unique pair of IO lines at your disposal. This lets you drive N*(N-1) LEDs from N IO pins.**

PCB design

While it is possible to wire up the grid of LEDs by hand, I would not recommend it. Instead of going through this tedium, you can design a custom board and get it professionally fabricated. I use the free version of Eagle Cad to design and prepare boards for manufacture. A full Eagle tutorial is beyond the scope of this writeup, but numerous tutorials can be found elsewhere online. The Eagle design files for this project can be found here.

Exporting gerber files for board fabrication

One you have finalized a board, you need to prepare design files for fabrication. PCB designs get exported to so called "Gerber" files, which are like the PDFs of circuit board design. Once you have these files you can send them off to a fab house for production. My favorite tutorial for this is on Hackaday.

For one-off boards, BatchPCB is the go-to place. For small runs, consider Advanced Circuits or Seeed studio's Fusion PCB service. For larger runs (more than 30), depending on board size, Goldphoenix is the place to go. Depending on which service you choose, you should get boards in a few days to five weeks. I used Seeed because it is relatively cheap, and it took about a month to ship to the US.

Part sourcing 

For cheap LEDs I use Ebay. For all other components ( especially the AVR microcontollers ), I source from Mouser or Digikey. For a low cost USB to Serial adaptor, look for "USB To RS232 TTL PL2303HX" on Ebay . These are cheaper than, say, an FTDI cable from Sparkfun, and have worked great for me. I'd hoped to save a few bucks by using charlieplexing and the AtTiny14 in the design -- the total cost of each board, shipping and USB-TTL converter included, from a lot of 10, is about $7.50:
10   boards     $30   
1000 LEDs       $10   
10   AtTiny     $14   
50   Resistors  $ 1   
10   Capacitors $ 1   
10   Headers    $ 1   
10   USB-TTL    $18   
       /10      $ 7.50

Cleaning the boards 

After you're finished soldering, remove any solder flux adhered to the board. Apart from being unsightly, flux can be conductive and corrosive and damage the board over time. Hackaday has a good tutorial on this. We filled an old jar with 90% Isopropanol, dunked the boards in there, and shook them around for a while -- it worked wonderfully.

Software serial 

The Attiny24 does not have hardware support for serial ( UART ), so we'll have to make a software implementation. For information about the RS-232 communication protocol, see the wiki. I used polling at twice the serial rate (4800Hz) to monitor incoming serial data, which is works for transmitting five bit packets. Further details about the firmware can be found in the C source file.

Compiling with avr-gcc 

I never remember the commands to compile and upload firmware, so here are the commands for future reference.

#compile source to a file a.o targeting the AtTiny24
avr-gcc -Os -mmcu=attiny24 ./display_serial.c -o a.o 

#extract the text and data sections to make a binary for the AVR
avr-objcopy -j .text -j .data -O binary a.o a.bin 

# check the size ( this should be smaller than the amount of available flash )
du -b ./a.bin

# upload the binary to ( in this case ) the AtTiny24 
avrdude -c avrispmkII -p t24 -B4 -P /dev/ttyUSB1 -U flash:w:a.bin 


*If you don't have Jython or a working JVM installed, it may be easier for you to re-enter the font as text data and write a short conversion routine in python.

**If you're familiar with multiplexing there's a simple way to conceptualize board layout for charlieplexing. When you multiplex an NxN grid of LEDs, you use N IO lines to control power to the (-) ends of the LEDs, and N IO lines to control power to the (+) ends of the LEDs.  To go from multiplexing to charlieplexing, note that microcontroller pins can take on three sates : Low (-), High (+), and Off ("high impedence"). Each IO line can serve as both a (+) line and a (-) line. What happens if we use the same N pins to drive both the (-) and the (+) a multiplexed display? Everything works fine, as long as we use the "off" state to stop current. One problem: there some LEDs along the diagonal of the matrix that have their (+) and (-) driven by the same IO pin -- there is no way to make these light up. But, no worries, since we are laying out our own board, we can just delete these LEDs, or connect their (+) terminals to a reserved IO pin to regain control of them! Charlieplexed PCB design can be relatively simple: lay out a grid of LEDs as if you were to multiplex them, but connect the N anodes to the N cathodes, and either delete the N LEDs that end up being connected to the same IO line at both ends, or wire these up to a separate IO pin to finish things off.


  1. Anonymous22.2.13

    Very nice description of charlieplexing. Have you thought of contributing the design to circuits.io ?

  2. Is it possible to feed the output from one unit into the next to extend the length of the display? I would like to make a scrolling marque fedora hat for next new years.

  3. I have a great use for you and would be interested in more info if you can provide. I have a hand held flashlight that has an array of LEDs. I took it to our local police department and showed it to a few sergeants. I asked them if they would find it useful if the LEDs actually could display a message to traffic going by. STOP, SLOW DOWN, PULL OVER, etc. They thought it would be great especially for for our traffic division motorcycles. myoungindio@gmail.com

  4. Hi Scott, I used up all the available IO pins on the AtTiny24 for this design, but it is definitely possible. Usually, RS232 connections are bidirectional. I only implemented the receiving side on the AtTiny for this project. The easiest way to get a chainable board is to implement a bi-directional serial connection, and have it output the end of the buffer as it scrolls off screen. You can then check this connection on the computer terminal, and if it appears to be working, redirect the serial out line from the board to another marquee unit. I'd recommend a AVR with more pins and a UART for this, like the AtTiny2313 or AtMega.

  5. Hi mike, your project is a little outside my experience. To get a flashlight projector like you describe, you need to solve two problems. First, you need to get a proper collimating lens and optics so that the projected image doesn't diverge too much and staying in focus, and second, you have to get some extremely bright light source in a small package that somehow runs on batteries. I suspect that the best way to implement what you describe is actually to get a very bright laser pointer. You can shape a laser using a diffraction grating to display a message like you describe. Lasers will automatically be collimated and in focus, so the optics are a lot more simple.

  6. Hi, great work! This marquee looks perfect for a project I'd like to make and wanted to solicit any input/advice. The transit system where I live has GPS on every bus and an API to find their location. I've already found a Python script somebody wrote to print the next bus arrival of a particular stop to standard output. What I'd like to do is connect an Arduino compatible with a Hope RF radio transceiver (like a Jeenode) to my computer to act as a transmitter of character strings grabbed from this Python script (eg "Next bus arrives in: 3 min") and receive this string wirelessly to the marquee using a second Arduino based RF receiver board. So it'd be computer -> Jeenode -> Jeenode -> marquee board, updating a string of text every minute or so. Any suggestions? Thanks!

  7. My only suggestion would be to consider using Bluetooth instead of radio. That is, unless you need more range or already know how to send data over radio. Bluetooth makes a regular TTL level RS232 connection to the arduino so it is very easy to set up -- it's like a wireless drop-in replacement for a USB to TTL serial cable.

  8. Also if you need the display to be visible outside or in bright-light conditions then charlieplexing may yield too dim a display.

  9. Oh I see, I didn't know about Jeenode, it looks quite simple, carry on.

  10. Thanks for the suggestions. I hadn't even thought about brightness as a factor, but hopefully it won't be an issue. It'll mostly be used indoors, although I do like the idea of placing one at my bus stop for others to use. It's very cloudy here so maybe it'll be fine. I made a very tiny half-duino clone I call Demiduino and I it should be able to incorporate Jeenode's RF chip nicely. Sparkfun sells the radio for US $6 and another project called Moteino has already broken out all the pins of an ATmega 328. I hope I finish it so I can show you.