Skip to main content

LED Matrix Display

Inspired by a silly meme, I made my own from scraps and scratch.

The scraps I used are a dense neopixel strip I had laying around, an old buck converter and a power supply from an old stereo. I do have dev board scraps laying around, but I wanted to use a RPi Pico for this, so it isn’t entirely scraps. It isn’t entirely from scratch either, I did use some crates to make my life easier.

I originally intended to make the firmware entirely from scratch, but I had trouble finding how to communicate with ws2812b LEDs. They communicate through SPI like this: $$ [MCU]\xrightarrow{MoSi}\ \rightarrow\ \xrightarrow{MiSo}[LED]\xrightarrow{MoSi}\ \rightarrow\ \xrightarrow{MiSo} [LED]\xrightarrow{MoSi}\ \cdots $$

But I didn’t know exactly what I had to send. Since I was rushing to complete the project because I had coming exams, I just used a crate.


Instead of taking the easy path, I ended up wiring the strip like this to save on wire, so I had to correct for the zig-zagging strip on firmware:

for (rownum, row) in matrix.iter().enumerate() {
    for (pixelnum, pixel) in row.iter().enumerate() {
        let (r, g, b) = pixel;
        if rownum % 2 == 0 {
            // If the row is even, calculate the position on the strip
            strip[X_PIXELS * rownum + pixelnum] = RGB::new(*r, *g, *b);
        } else {
            // If the row is odd, calculate the mirrored version of it on the strip
            strip[X_PIXELS * (rownum + 1) - (pixelnum + 1)] = RGB::new(*r, *g, *b);

Writing manually the RGB values for every pixel on the display is diffucult and tedious, so I made a TUI app that makes the process easy:


You can move around with the arrow keys or the vim h j k l keys. There’s a shortcut guide in the bottom nano style, so you don’t need any previous knowledge on how to use the app. Since I was rushing to complete it, I didn’t implement a propper color picker. Instead there’s a hex input field where you can type (or paste) in the color code:


Having to use the input field every time you want to change the color sucks, so I implemented an eyedropper tool to pick existing colors. Most importantly though, you can save your drawings into a rust file that contains the drawing in a format the firmware can understand


Overall, I wish I had more time to work on this project. But it’s what being a student has. I could pick up the project at a later date to improve it, but it’s just a silly idea and some scraps, so I don’t think I will.

Check out the project on gitlab: