Here I have a fully functional programmable led matrix array I made with a single microcontroller (an atmega48p) and some charlieplexing techniques.

(source code and more info available on github)

It acts as an "external device" that can be attached to a different main micro (even an Arduino-like board with the most common libraries) and also controlled in an easy way via I2C (sending commands to scroll text, control the buffer, the speed, etc.).

See it in action here:


  • 376 red leds on a 47x8 matrix configuration
  • 4 SMD leds that can act as debug / display / aux indicators
  • Small SMD resistors and capacitors to minimize space
  • THT atmega48p (easily replaceable) as the only micro to control everything
  • Multiple power / I2C breakouts
  • ISP programmer breakout (which won't work due to a short between the leds and some of those pins :_ D - as a future TODO I'll probably add some small switches to disable the leds while programming)
  • Different modes of operation: self-test / diagnostic, full buffer control or auto-letters mode with built-in scrolling
  • 95 different standard chars supported when displaying letters, numbers and symbols
  • Several options available (also commands to be used via I2C): text without scroll, negative mode, variable speed...
  • Source code easy to modify (also adding new modes of operation)

Why charlieplexing?

It's a cool and interesting way to drive multiple leds using a small amount of pins and almost no aditional components / multiplexors rather than the main micro and a bunch of resistors.

By using 20 pins from an atmega48p (that's every "regular" I/O pin except the ones for the I2C communication) it can drive up to 380 different leds (n^2 - n, with n = number of pins). If the micro speed is fast enough (the atmega48p here is clocked at 8Mhz with works with no problem at all) and with some software tricks and delays it'll show a very nice and "stable" matrix that allows a pretty decent display.

Charlieplexing issues

Despite being functional, it's far from being perfect (specially if we compare it with non-charlieplexing solutions). There're some "problems" or, at least, minor inconveniences to be aware of:

  • The brightness of the leds is significant lower since they're only "active" for small periods of time (by testing different leds I found there're some brands or models that aren't brighter enough, but usually everything will work pretty fine with some delay between each cycle).
  • Since all the leds are connected to the same pins in different configurations, if one "fails" or shorts, the whole "block of leds" for that specific pin will start acting weird.
  • It'll probably have some peak currents issues if the matrix gets bigger. Since this is a "small" one I didn't experienced any problem, but remember: we're turning on and off the leds at high speeds!

So, in conclusion: it'll work nice for small projects, but if you're planning to build a super-giant-sized matrix you should probably consider a different option (nothing new here :D)

Why I2C?

Following the spirit of those small peripherals that are connected via I2C (OLED screens, real-time clock boards, etc.) and since I'm kinda comfortable with it (even wrote some I2C libraries for attiny85-like AVR micros) I've decided to use it in order to listen to commands and data. This way any main device can just send whatever buffer needs to be displayed, or even use the built-in text-scroller function!


The PCB is a homemade design, currently on it's second iteration (the first one was pretty much the same but with more space between the leds, no SMD components and some critical design errors when mapping the resistors with the pins :D) and it's made with KiCad.

It's a big matrix of leds manually wired to a bunch of 20 ohms resistors...

Read more »