Standalone Matrix controller (APA102 to HUB75 Panel Adapter)

Hi gang,

I’ve been exploring controller options and I can’t seem to find what I’m looking for. I want to offload the work of driving my 128x64 matrix from the main cpu/mcu by dumping frame buffers via UART or SPI to a controller and let that controller refresh the matrix. I’ve seen it done with FPGA’s a few times (such a SmartMatrix and shields look like a good starting point but I want it much cheaper for mass production.

Has anyone already done this?

What would be the most effective MCU for hosting this setup? Teensy (a bit expensive), esp32 (can it handle the work?)


You have excellent timing, I’m working on this now and finalizing the hardware design for V1. It’s based on the ESP32 single core chip, receiving data via APA102 formatted SPI. It will support up to 128x64. Right now I get up to about 30fps update rate (matrix refresh is decoupled from update rate and is at a minimum 120fps to reduce flicker) receiving 64x64 frames from a Teensy 4.0. I haven’t optimized the updates yet so there’s a lot of room for improvement. I’ll post more to this forum after I finalize the hardware. I’m designing it as a product to be sold, but it will be open source hardware.


I was thinking the same - an open source product on We (Mystic Pants) need it for a product we are working on. If it saves me allocating the resources to build it in-house I would be happy to support it commercially.

A public update on this, as @blindman2k and I have been communicating directly: I finished a prototype THT and ESP32 dev board based hardware design for the controller and placed an order with OSH Park. I hope to get boards in a couples weeks and verify the circuit is working before starting on the actual SMT production version.

1 Like

Hi Louis,

Thanks so much for all the work you’ve done on this! I’m loving SmartMatrix on the teensy4 and am really excited to try out the sound reactive WLED port on the ESP32.

I tried uploading the BRD file for the SMT version to OSHPark and got the error “Invalid or corrupt brd file”

Also when importing the BRD file into KiCAD 5.1.9, it gives the error ‘not well-formed (invalid token)’ at line 70.

Thanks in advance!

Hi Mike,

Where are you downloading from?

Hi Louis,

It was totally user error. I didn’t realize it was getting saved with an HTML wrapper. When I realized that, I clicked raw and it saved nicely.

They’re on order from OSH Park now! :slight_smile:

Again, not sure what files you’re referring to, but this is the latest evolution of the project, in case you’re ordering some older design (which still might be useful too, not sure):

Here’s WLED driving Pixelvation Engine with 4096 pixels:

There’s still a lot more room for improvement on making WLED more efficient for driving large high quality displays, but it’s going pretty well so far! I’m discussing my work here:

Looks great!

The files I was referring to are the ones from your SmartMatrix project on github. Located in SmartMatrix/extras/hardware/ESP32. Specifically the SMT one.

Got it, that board should be able to run the Pixelvation Engine HUB75 firmware, receiving APA102 data from another ESP32 running WLED. There won’t be any level conversion, so you’ll have to use 3.3V signals between the two, which isn’t as great as stepping up to 5V and back down to 3.3V, but should be fine for a short distance. I don’t have any plans on integrating HUB75 driving directly into WLED.

I have some leftover level shifters so it’s not a big deal to wire up another one on a little PCB. Knowing it could be a problem, it always made the most sense to just add it IMO.

Thanks again for the help!

When you say it can run a 64x64 panel, does that mean it could also run 4 X 32x32 ?

While 64x64 is very pretty, I’m looking for something physically bigger, to be seen at a greater viewing distance

Yes, it’s mostly the number of pixels that matters, so 4x 32x32 would work about as well as 64x64

1 Like

Hey Louis,

I was preparing the software in advance of getting those OSH Park SmartMatrix ESP32 boards and had a question.

In the Pixelvation sketch, would I select this one: #include <MatrixHardware_ESP32_HUB75Adapter_SMT_I2sIn.h> ?



There’s not a configuration for the SmartLED Shield already, you’ll want to create one. I just pushed a change to SmartMatrix Library that will help you, so grab the latest.

Your new config file should contain:

#include <MatrixHardware_ESP32_SmartLedShieldV0.h>

Followed by the rest of the defines in MatrixHardware_ESP32_HUB75AdapterLite_V0_I2sIn1Bit.h:

#define I2S_RISING_EDGE_CLK   true

#define GPIO_I2S_IN_PIN_CLK (gpio_num_t)36
#define GPIO_I2S_IN_PIN_EN  (gpio_num_t)0

#define GPIO_I2S_IN_PIN_D0  (gpio_num_t)37

#define GPIO_I2S_IN_PIN_D1  -1
#define GPIO_I2S_IN_PIN_D2  -1
#define GPIO_I2S_IN_PIN_D3  -1
#define GPIO_I2S_IN_PIN_D4  -1
#define GPIO_I2S_IN_PIN_D5  -1
#define GPIO_I2S_IN_PIN_D6  -1
#define GPIO_I2S_IN_PIN_D7  -1

You can change GPIO_I2S_IN_PIN_CLK and GPIO_I2S_IN_PIN_D0 to different pins if you want. They’re only used for input so I personally would put them on some of the ESP32s Input-only pins. Remember that the ESP32’s pins aren’t 5V tolerant.

I’ve made some improvements to the Pixelvation Engine firmware that I haven’t pushed to GitHub yet. Let me know when you have the board running SmartMatrix Library and Pixelvation Engine firmware and I’ll try to find some time to polish up and push the changes

Hi Louis,

I got the fabs in yesterday! One thing I noticed is the card socket I substituted in totally won’t work. :frowning:

Do you know of an alternate part for that? Haven’t seen one like that before that didn’t have the pins on the edge.

Worst case scenario I can run magnet wire to the edge pins, but I wanted to check first.


The manufacturer suggests this alternate part:

“Minor difference, footprint equivalent”

I found (years ago and I don’t recall the details) that there’s Chinese parts with similar footprints, so maybe you can find an alternate part if that digikey part isn’t convenient to order

Hi Louis,

Everything looks good with the pixelvation board now as far as I can tell. The color wheel is coming up so I think it’s happy.

The blockage I’m running into now is the led limit in WLED_SR. I uncommented this line in wled.h


and set this in my_config.h

#define MAX_LEDS 4097

but when I try to add the 64x64 matrix in, it says that the max # of leds is 1500.

Is there something obvious I’m missing?

Thanks again!

You may need to compile WLED SR from the /dev branch. I think WLED v0.11 has a 1500 limit, but v0.12 (only available in a beta version) relaxes that limit. You still may need to make some changes to drive 4096 pixels.

I had to change these two #defines in WLED to drive 9216 pixels:

#define MAX_LEDS 9216
#define MAX_LEDS_PER_BUS 9216

I think 4096 is now the max in many places in WLED, so hopefully you don’t have to make any more changes after switching to a v0.12 beta

To test Pixelvation Engine with less than 4096 pixels, you can change these options in the sketch, e.g. for 16x16 pixels:

    const int apa102DataBytesPerFrame = (16 * 16) * 4;
    int testPatternWidth = 16;