SmartMatrix with 1/4 scan hub75 panels

Hi everybody,
I’m trying get the library working with an hub75 1/4 scan matrix, but with no luck so far.
I modified the SmartMatrix.h file like this:

#define SMARTMATRIX_HUB75_32ROW_MOD16SCAN             0
#define SMARTMATRIX_HUB75_16ROW_MOD8SCAN              1
#define SMARTMATRIX_HUB75_16ROW_MOD4SCAN              2

                                                    (x == SMARTMATRIX_HUB75_16ROW_MOD8SCAN ? 16 : 0) | \
                                                    (x == SMARTMATRIX_HUB75_16ROW_MOD4SCAN ? 16 : 0))

                                                      (x == SMARTMATRIX_HUB75_16ROW_MOD8SCAN ? 8 : 0) | \
                                                      (x == SMARTMATRIX_HUB75_16ROW_MOD4SCAN ? 4 : 0))

                                                     (x == SMARTMATRIX_HUB75_16ROW_MOD8SCAN ? 8 : 0) | \
                                                     (x == SMARTMATRIX_HUB75_16ROW_MOD4SCAN ? 8 : 0)) 

Does someone has already managed to get a 1/4 scan matrix working ?



ps: I’m using this panel :


Hi Guillaume,

A couple modifications:
should be
(I believe the rows are still spaced 8 apart, e.g. what gets shifted through RGB channel 1 is 8 rows away from RGB channel 2)

should be
(there are four rows shifted out per frame)

After thinking about it a bit more, I think you will need to change more than these #defines, but you can give it a try and see what happens. Post some pictures or videos if you’re getting some output but it’s garbled. I don’t have any spare time to work on this right now, but I will take a look at the aliexpress link you sent and might order a panel to try.

Hi Louis, thanks for the quick answer.

Here is a link to a video of what I get with your modifications: MATRIX_1_4.mp4

This is supposed to be a blue dot scanning every row pixel by pixel over a red background.
It’s hard to describe what’s happening, I hope the video talk by itself.

And here is the code :

void loop() {
  static unsigned char x = 0;
  static unsigned char y = 0;

  SM_RGB color = CRGB(CHSV(200, 255, 255));
  backgroundLayer.drawPixel(x,y, color);

  if (x >= kMatrixWidth) {
    x = 0;
    if (y >= kMatrixHeight) {
      y = 0;
  digitalWrite(ledPin, !digitalRead(ledPin));

Here a picture of a simple grey background : LINK

Do you understand what’s going on ? If you can give me a hint of what I can modify in the main library code, I can give it a try.



It looks like the library is writing overlapping data to the panel. I don’t have an easy answer on how to fix this. I tried ordering the panel you linked and the supplier is out of stock. I won’t be able to look at this any time soon.

@guillaume.s I ordered a 1/4 scan panel, not the same one you have but probably similar refresh. I looked at the code and it’s not setup to write multiple more than two rows per latch to the panel. A 1/4 scan panel needs four rows written at a time (and a 1/2 scan panel which I also bought needs eight rows written at a time). No promises on when I can get this improvement added to the code, but I do have a panel and have started on it.

That’s a great news ! Tell me if you need me to do some test on my 1/4 scan panel.

A quick update, I didn’t want to hack this feature into the code, and realized there’s no easy way to add it in as it requires reworking some fundamental parts of the SmartMatrix Library. I do have a plan for how users can define generic panels that may contain multiple rows per address (e.g. a 1/4 scan panel), that will apply to using LED strips or APA102 matrices as well as multiplexed panels. I’ll start work on that sometime in 2017. I’m hoping its in early 2017, but I haven’t had much time to dedicate to this project recently.

Hi Louis,

Any update for 1/4 panels?

I’d GLADLY donate or whatever to show my appreciation to get this supported since I’m planning a project with displays with 1/4.

I can also send displays for you to try if needed.


Hi Crowbar,

I’m wrapping up a port of SmartMatrix Library to the ESP32, and 1/4 scan support is high on my list after I get the port to a point where I can release a mostly-functional library and get some hardware on order. I also have a project in mind for 1/4 support, so that feature is pretty high on my list. PM me about a donation, maybe that could motivate me to accelerate this feature.

Can you post a link to the panels you’re buying, so I can give my best opinion on if they’ll be supported? I recently learned about “AB” scan panels that have only 2 ADDX lines so it looks like they’re 1/4 scan, but they’re actually 1/32 scan with a separate shift register for scanning in the address lines. I don’t see these panels being supported by the SmartMatrix Library in the future, due to hardware incompatibility with the way I’m externally latching the ADDX lines.


Actually what would really help accelerate this feature is to discuss some ideas on how to specify in the sketch the geometry of the panels. Right now you specify display height, display width, panel height, and the number of rows to scan through on each panel, and that’s enough for the SmartMatrix Library to put the pixels in the right order. For /4 scan panels, there’s an additional wrapping of pixels within a panel, so the SmartMatrix Library needs an additional piece of information: the panel width. That could be encoded into the existing kPanelType variable. For the panel linked above, kPanelType could be SMARTMATRIX_HUB75_32COL_16ROW_MOD4SCAN

Are there multiple types of wrapping done on these /4 panels? I skimmed through hzeller’s RPi matrix driver’s Readme, and it seems like there might be multiple methods handled by his “Multiplex Mappers”. I was considering coming up with a mapping method that would support more arbitrary (but still rectangular) layouts of pixels for both chained HUB75 panels as well as chained LED strips or APA102 matrices as the library is hopefully going to support driving APA102 LEDs in the future. Trying to come up with a generic mapping method that will work for a lot of different layouts seems like a challenging and time consuming problem. Perhaps just coming up with a one-off for handling a limited number of /4 panels is the better solution for the short term.


Hi Louis and thank you for your fast replies,

Exactly which displays I will use is right now not decided. However I will tell you that they are 32x16 or 32x32 DIP RGB P10 LED modules and the vast majority of these displays seems to run 1/4.

Here are two links

Any thoughts?

I might add that that I plan to make displays that measure 960x640mm(96x64 pixels), shouldn’t be a problem with the new V4 shield and Teensy 3.6, right?

I’ll pm you about the donation.


As for your second reply, I’d love to be able to answer your questions but I’m simply not qualified to do so. All I know is that I need help with a solution for 1/4 displays, how it’s implemented is not (for me) important.


Once again, thank you for taking your time!

After searching around on Google I found this thread:

Could this possibly shed some light on some of your questions Louis?

1 Like

Hi Andreas,

Both those panels don’t have complete specs, and the pictures aren’t very high resolution, so it’s hard for me to tell without having access to more details or the panels themselves to know if they will be supported. On one of them I can see at least the shape of the silkscreen letters around the input connector, and it looks like “HUB08” not “HUB75”. HUB08 has only half of the signals of a HUB75 panel, and I believe a different pinout of HUB75. You’ll probably need an adapter to take the HUB75 output from the SmartLED Shield and split it into two HUB08 signals to go to two panels. Something like this. I have a HUB08 panel, something like this one, but I’ve never used a HUB75-HUB08 adapter and don’t have one of those.

The 32x32 panel has two sets of connectors on it. I’m not sure if there are two separate 16x32 HUB08 panels combined into a single 32x32 panel, or if there is something else going on.

The panels I have are similar to this one, which uses thinner SMT LEDs instead of the individual THT LEDs on the panels you linked to. They are spec’d to the same brightness as at least one of your panels (7500cd/m2), but who knows if those specs are accurate. In addition to the LEDs being thinner, the panel frames are likely thinner. The 32x32 panel you linked to has two boards stacked on top of each other, one for the THT LEDs, the other for the SMT driver parts, and it’s likely pretty thick. Can you use panels similar to the 16x32 panel I linked to?

96x64 should be fine with the Teensy 3.6, but there are tradeoffs in color depth, refresh rate, and overall brightness as the panel size grows. If you already have a Teensy 3.6 and SmartLED Shield and a supported panel, you can try to get a sense for how it will behave by increasing the size of matrixWidth/Height until it matches your intended panel size, and just look at what you see on the one panel you have hooked up.

Hi Louis
I have some outdoor 64x32 1/4 scan panels and am hoping to get them working with the ESP32 and the SmartMatrix library. How are you getting on with getting this to work? I am happy to donate $$s and panels to have support added.

Hi Martin,

I started on this, and did a little reverse engineering on the 16x32 P10 panel I have to see how it’s mapped as there was no spec (that I found). The mapping isn’t nearly as straightforward as I thought it would be. This is the mapping for all the data to be sent through for address 0 on the panel I have. There’s a lot of jumping around between rows.


I’ll need a way to describe the mapping so the SmartMatrix Library can efficiently load data to be shifted out to the panel. It needs to be efficient, while being flexible, so panels with a different mapping can be supported as well.

Here’s another example of a panel with multiple row per address mapping (search “pixel order”) to find the section where they talk about it:

hzeller’s rpi-rgb-led-matrix project has the option to create custom mappers for panels. A mapper is made up of C++ code. I’d prefer that users could be able to apply their own mapper to SmartMatrix Library without writing code. Here’s an example mapping that looks like it might work for the 16x32 P10 panel I have (though I haven’t verified that it will work):

I also don’t think the method of mapping a single pixel at a time will be fast enough for the high refresh rates I want with the SmartMatrix Library on the ESP32. I would prefer the mapping to handle groups of pixels at a time, instead of single pixels.

For example, with the mapping I need for my panel, I would want to load all the pixels for physical row 0, and then use a mapping to write physical pixel 0-7’s data with offset +64, physical pixel 8-15’s data with offset +80, etc. Loading a row of data and applying it as a block of 8 at a time should be much faster than working with a single pixel at a time.

I was planning to come up with some kind of simple script that a user could add to their Arduino sketch to describe panel mapping, but I think the script could be too limited and unable to handle all panel mapping types unless I had a wide variety of panels to test it with. As it stands now, I only have a few panel types that would require a mapping to be applied to them.

Perhaps I should add support for something like hzeller’s mapping functions that more advanced users could take advantage of by writing some code. Then, after we have a decent collection of mappings, consider if the easier-to-apply script method is needed.


PM me if you want to talk about donations, etc.

- Louis

Thanks to a generous donation from Martin Welford (@viking), I’m happy to say that the teensylc branch now has support for panels with non-linear pixel mapping, including multi-row-mapping, like the 1/4 scan panels mentioned above. I added this support to both the ESP32 and Teensy on that branch. Adding support for new panels requires some code changes, but it’s mostly copy/paste and modifying numbers, not actual coding from scratch, so it’s accessible to more people.

There’s documentation in the teensylc branch README, and in the new MultiRowRefreshMapping sketch. The basics are:

  • If you want to support a new panel, you run the MultiRowRefreshMapping sketch, and draw out a map of how the pixels on the first address are mapped (usually across multiple rows)
  • You can then turn the map into a table that gets added to the SmartMatrix Library
  • You define a new panelType that uses the new map
  • Use the new panelType in your sketch

Here’s an example of a map for my 32x16/2 panel. Note that some pixels are filled from left to right, and some right to left.

And here’s the table that corresponds with the sketch:

const PanelMappingEntry panelMap32x16Mod2[] =
    {0, 71,  -8},
    {0, 87,  -8},
    {0, 103, -8},
    {0, 119, -8},
    {2, 72,   8},
    {2, 88,   8},
    {2, 104,  8},
    {2, 120,  8},
    {4,  7,  -8},
    {4, 23,  -8},
    {4, 39,  -8},
    {4, 55,  -8},
    {6,  8,   8},
    {6, 24,   8},
    {6, 40,   8},
    {6, 56,   8},
    {0, 0, 0}   // last entry is all zeros

I’ve added support for a few panels that I have here, and the one that @viking needed. Some panels with the same dimensions and scan type have different mappings, so it’s not as simple as just picking your panelType from a list. You can run the MultiRowRefreshMapping sketch in a TESTING mode that can be used to test to see if the panel you have matches an existing mapping in the library.

While I was at it, I added initial support for HUB12 panels, a type of low cost panel that has a single mono color channel (instead of a pair of RGB color channels like HUB75). You can find these in P10 32x16 sizes for $7 or less on Aliexpress. SmartMatrix Library doesn’t handle them efficiently right now, as you need to pretend the panel is twice the size it is to handle the unused second RGB channel, and the panel only needs a single color instead of RGB.

Unfortunately I’m not going to back port the multi-row-mapping feature into the released version of SmartMatrix Library. There was a ton of refactoring done on the teensylc branch that made adding this feature possible. The Teensy portion of the teensylc branch seems to be pretty stable, so eventually that refactored code may make it into a SmartMatrix Library release, but not anytime soon.

If you give this a try, please let me know what you think, or if you have any issues. If mapping isn’t working for you, please record a video of the MultiRowRefreshMapping running through a full loop, as that can be really useful to help troubleshoot or to make a map.

Hi Louis,

I still confuse, why SmartLED shield (Teensy) still not working for HUB75D 1/4 scan?
I have bought 4ea shield before from adafruit and good running for HUB75 1/6S and 32/S,
but until today, I still not found somebody who try and success to running it with 1/4s.

May you have any update?


There’s early support for these types of panels in the teensylc beach of the SmartMatrix Library on GitHub. See above. It will eventually make it into a full release of the library with more documentation