ESP32-HUB75-MatrixPanel-DMA
ESP32-HUB75-MatrixPanel-DMA copied to clipboard
1/4, 1/8 scan panels

Four-scan panels (aka. '1/8' on a 32px high LED matrix) use the same HUB75 connector and can be connected to the ESP32 in the same way as a 'half scan' (aka. '1/16' for a 32px high LED matrix, or '1/32' for a 64px high matrix), but additional software logic (pixel remapping) is required or the display will show garbage.
Four Scan Panel (aka. '1/8' on a 32px high LED matrix ) - Thank you to The Electronic Engineer for a 'four scan' (1/8) panel to get this to work.
For any other panel of a random scan type that doesn't work:
- Somebody with these panel types needs to help code a solution; or
- Sends us links to existing code (the specific code) that works with these panels (perhaps can easily copy paste) - lots of trial-and-error will be required from you to help find a solution; or
- Simply send the contributors to this library a spare panel you might have so we can try code and test a solution ourselves.
can this changes be integrated to the main branch? wondering how to re purpose existing virtual class than creating new instance for 1/8. the idea is to reuse existing virtual class but provide different initialization implementation that can be swap by configuration
Dear @mrfaptastic,
In a issues #154. I reported the issue I was having with a 1/8 panel where the line was of only 16 LEDs and not 32 as you solved in the post in question.
Last week I thought about fixing this and fixed the problem with some small modifications to your library.
Are they:
enum PANEL_SCAN_RATE {NORMAL_ONE_SIXTEEN, ONE_EIGHT_32, ONE_EIGHT_16};
``
if ( _panelScanRate == ONE_EIGHT_16)
{
if ((y & 8) == 0) {
coords.x += (panelResX>>2) * (((coords.x & 0xFFF0)>>4)+1); // 1st, 3rd "block" of 8 rows of pixels, offset by panel width in DMA buffer
} else {
coords.x += (panelResX>>2) * (((coords.x & 0xFFF0)>>4)); // 2nd, 4th "block" of 8 rows of pixels, offset by panel width in DMA buffer
}
if (y < 32)
coords.y = (y >> 4) * 8 + (y & 0b00000111);
else{
coords.y = ((y-32) >> 4) * 8 + (y & 0b00000111);
coords.x += 256;
}
}
` This apparently solved the problem and I managed to make a 4 panel dislay work perfectly, evidence follows;
-
1/8 lines of 32 LEDs

-
1/8 lines of 16 LEDs

Hi @danieldecesaro, Fantastic work with that. Would you be able to raise a pull request or attach the modified virtual display class file if that's easier, and I'll incorporate.
Hi @mrfaptastic,
Yes I can, I will do it soon!
Att.
Hi @mrfaptastic, I just posted a proposed change, see if it's satisfactory. Thanks!
Dear @mrfaptastic,
I'm doing more tests with different types of panels and I found a bug in the 1/16 scan panels.
In version 2.0.3 of the lib everything works perfectly, in version 2.0.6 or even in the master there are distortions in this type of panel. Evidence follows:

I point out that I'm using a 2x2 setup but I see the same problem on individual panels as well. Using VirtualMatrixPanel, of course.
Can you guide me on what I should focus on to solve the problem?
Regards,
Daniel de Cesaro
Have you tried changing the mxconfig.clkphase = false; config para to true or false and seeing that that makes a difference?
Some panels need an inverted (or not inverted) clock... causes stuff to be offset by a pixel on the x-coord.
Similar to the common issue raised in: https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/134
Hi @mrfaptastic, Problem solved, thanks. Att.
Hi @mrfaptastic, the problem with panels 1/4, 1/8 and similar is that for each type, for example 1/4, there are many variants for addressing rows and columns. Thus, it is impossible to write one code that will fit any matrix 1/4, there are dozens of variations. I work with such matrices, but for each one you have to choose it own version of the coordinate transformation
Hi, I am new in this discussion. Is there any new development on the 1/4 scan panel? I am currently using "lefty01" 1/4 scan code to test my 32x16 1/4 scan LED module and run into issues.
Hi, I am new in this discussion. Is there any new development on the 1/4 scan panel? I am currently using "lefty01" 1/4 scan code to test my 32x16 1/4 scan LED module and run into issues.
As per @board707's comment, there are so many variants of the four-scan panels that it's probably a new type of panel you have.
Post photos and videos of running SimpleTestShapes example etc.
I have a p8 20*40 pixel rgb led matrix display panel. The driver uses an integrated ICN 2037, and has a scan rate of 1/5. Can you help me with this display. I'm thinking of running it with esp 32. none of the libraries worked. only 1 library worked but it is faulty.. https://github.com/2dom/PxMatrix#shiftreg_abc_bin_de
I have used that library and found it to work very well on 1/8 and 1/16 scan.
1.5 scan is an odd one and you will find very limited library support. But, how about setting up the library like a 1/8 scan; you will most likely just lose 3 out of the 8 scan lines but that can be mapped out.
I solved the problem of matrix panel with p8 20x40 pixels 1/5 scan rate. I managed to get it working with library https://github.com/2dom/PxMatrix#shiftreg_abc_bin_de. now i have problem with p10 rgb matrix panel which has 1/4 scan rate. there are only rows A and B. Again the same library ran, but one line works in reverse.
i have problem with p10 rgb matrix panel
"p10" is say nothing about type of panel. What is the panel pixel dimensions - 32x16 pixels?
has 1/4 scan rate. there are only rows A and B
It seems that the panel has BINARY mux type.
one line works in reverse.
It is very strange. Lines on the led matrix ALWAYS paired. so your panel should has at least two reverse lines. If you ready to test your panel with stm32 or RP2040 controllers, you can try my DMD_STM32 library
hi @mrfaptastic ,
i run to an issue with p10 16X32px 4s RGB panel. i believe this panel is 1/4 panel by the 4s. the ic is 6124B which suppose supported by the library, and my thoughts say this panel each are 1/4 of size 32x64px panel. and assuming this panel will work by combining 4 panel to make up the resolution of 32x64px. i am wrong, running the latest master branch with all the scan rate variation, and panel resolution changes by following the example does not work on my end, i am getting garbage display every time. this is common panels in market and i hope this panel will work.

i will try to use the basic example and show the result later. at the mean time, do you have suggestion which configuration i could try to make this panel works?
Edit:
i have the test example ready with the result as below:
2_SimpleTestShapes.zip
1_SimpleTestShapes.ino only pin assignment was change with result as below:

Four_Scan_Panel.zip Four_Scan_Panel.ino only pin assignment was change with result as below: https://user-images.githubusercontent.com/75555993/226074103-18bae0c6-750a-4e52-968e-5779c786853e.mp4
The only way to reverse engineer what is going on is to start with the basics. Draw a single pixel to reach led coordinate and then see what coordinate it actually shows up on. Use excel or something to log this.
Only then can one figure out how the panel works. Good thing though is all the LEDs are lit which hopefully means there isn't something else going on.
Also. If you perform a simple drawPixel(0,0) and get more than one pixel "lighting up" then there is some electrical/ signal issue.
4s panel can have binary or direct mux. if you confuse the mux type, then when one pixel is outputs in the code, several dots may lighting up on the matrix. @tsctrl , I can help you to run your panel with my library, but with using STM32 or RP2040 as controller board
hi @board707,
this is common panel available online. my intention to use this panel is due to p5 are too small for medium hall and i did not satisfies with the p5x3col setup that i use. it look tiny when it was in place. one good potential of having this panel support are we will be able to display larger display with minimum cost increase and open possibility to have more than 20 panels p10 as per resolution to be hookup(1p5 equal to 4p10 in resolution) to the tiny esp32. with the half resolution of p5, it is easier to configure the display by combining panels without having different screen design for p5 and p10.
sorry for the long write up, but i was really excited to have this panel to be supported. ok, so there is 3 common p10 panels with 32x16px configuration. this resolution and size, which is same as the original supported panel p5 with 32x64px. all p5 and p10 panels have the same width and height. 16cmx32cm. edit: by this condition. the panel are the same size and it is possible to have the casing/frame to be interchangeable or reuse between p5 and p10 panels. to add, p10 are the most common panels used for led display in the market as it is the cheapest and most cost effective for the usage.
3 common p10 panels (different by SMD led type, not to mention THT)
- code 2525 smd led. hub75. 1/8scan
- code 2727 smd led. hub75. 1/8scan
- code 3535 as the one i have. 1/4scan. the larges led size per pixel.
yup, thats mux thing i am not sure what this panel was and hoping this library to support it. i think, there are people who are able to use the 2727 led with 1/8 scan with this library. but to order/buy that panel will take some time to arrive, with unknown result but yet the best option is to have the 3535 1/4 scan to work with this library.
so iam hoping so much that this 3535 panel to be supported. iam not keen to design new board, pcb and new code from 0 for this. it will take years to complete.
@mrfaptastic, i will run some test to plot the pixel for this panel. i hope the binary or direct mux would not be the issue, seems someone also using binary libs to make this panel to work. also, you can sent me your address to [email protected] if you require some new panels for testing.
thanks
p5 and p10 panels have the same width and height. 16cmx32cm
The geometrical sizes of panels are not matter. The only important parameters are pixel resolution and scan pattern. 32x16 and 64x32 panels has completely different patterns and are not interchangeable.
iam not keen to design new board, pcb and new code
Ok, I understand. Good luck for your project
hi @board707, thanks for the reply and your contributions. understand those scan patterns and resolution different. What does matter is what will it will display and is suppose to be the same for any different panels used with the same resolution regardless of panels quantity.
suppose to be the same for any different panels used with the same resolution regardless of panels quantity.
no, it wrong From the library point of view 4 panels with 32x16 pixels are not the same as one 64x32
Please use the latest git master version of this library, the four scan example and the VirtualMatrixPanel class has been updated to fix a related issue.
hi @mrfaptastic here is the test code and the result in excel:
chains and scan rates(CHAIN_TOP_RIGHT_DOWN/CHAIN_TOP_LEFT_DOWN) setting does not effecting this test result FOURSCAN_PANEL_TEST.zip
from the test the draw pixel only effecting half of the set x resolution, and added to 2 different rows from the test the draw pixel only effecting 2 pixel of the set y resolution
this is the result of latest master 4_scan_panel.ino example (with custom pin assignment no other changes): ino: Four_Scan_Panel_2.zip result: https://user-images.githubusercontent.com/75555993/226169827-315ca2b3-1cf9-468f-9e54-a3050d6c6798.mp4 if i try to reduce the resolution to be 32x16 with FOUR_SCAN_16PX_HIGH i am getting blue green display but on half panel only. let me know how can i test better or if this panel are actually not supported, i will try to get 1/8s FM5020 ic instead
thanks!
That output doesn't look good to me. Not a supported panel.
hi @mrfaptastic , sorry seems like i have commented pins on the second test result, sorry for that. but actually result with pin assignment is as the previous result here, where all the led are lit:
Four_Scan_Panel.zip Four_Scan_Panel.ino only pin assignment was change with result as below: https://user-images.githubusercontent.com/75555993/226074103-18bae0c6-750a-4e52-968e-5779c786853e.mp4
i havent give up on this yet. but the test sketch i am using are actually is not properly set for 1/4 scan type and i guess that was the reason i am getting half of a screen pixel and 2 part pixel in y direction. it is fm6124 btw the same chip as p5 variant. if i use 64x32px setting i am getting full panel chain size and 32x16px i am getting half and duplicate display as existing chain behavior. which i believe it works. why would you think this panel are not supported, is it because all 1/4 scan are not supported and only 1/8 for now? or the sketch build now for p5 with 64x32 res will able to cover the writePixel for all panel area for 1/4s panel also, which invalidates the test i did?
edit: how do i properly set up setting for 1/4s panels with current library to do a proper test to do a pixelWrite that covers all the panel area?
this it what it looks like when i write x from 0 to 64 and y0 on 2 chained panels
it goes 0 to 32 on y0. and 0 to 32 on y5

thanks!
When using the virtual matrix class, call:
setPhysicalPanelScanRate(xxx)
and pass it either:
FOUR_SCAN_32PX_HIGH
FOUR_SCAN_16PX_HIGH
hi @mrfaptastic ,
i have run pixel mapping test for 3535 rgb 32x16px using this example pixel mapper drawPixel as in (x,x) and the corresponding led lit, and the sequences the result as below:
test code:
#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
/* Use the Virtual Display class to re-map co-ordinates such that they draw
* correctly on a 32x16 1/8 Scan panel (or chain of such panels).
*/
#include "ESP32-VirtualMatrixPanel-I2S-DMA.h"
#define A_PIN 27
#define B_PIN 4
#define C_PIN 14
#define D_PIN 2
#define E_PIN -1
#define R1_PIN 32
#define R2_PIN 25
#define G1_PIN 17
#define G2_PIN 16
#define B1_PIN 33
#define B2_PIN 26
#define CLK_PIN 12
#define LAT_PIN 15
#define OE_PIN 13
// Panel configuration
#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module.
#define PANEL_RES_Y 8 // Number of pixels tall of each INDIVIDUAL panel module.
#define NUM_ROWS 1 // Number of rows of chained INDIVIDUAL PANELS
#define NUM_COLS 1 // Number of INDIVIDUAL PANELS per ROW
// ^^^ NOTE: DEFAULT EXAMPLE SETUP IS FOR A CHAIN OF TWO x 1/8 SCAN PANELS
// Change this to your needs, for details on VirtualPanel pls read the PDF!
#define SERPENT true
#define TOPDOWN false
// placeholder for the matrix object
MatrixPanel_I2S_DMA *dma_display = nullptr;
// placeholder for the virtual display object
VirtualMatrixPanel *FourScanPanel = nullptr;
/******************************************************************************
* Setup!
******************************************************************************/
void setup()
{
delay(250);
Serial.begin(115200);
Serial.println(""); Serial.println(""); Serial.println("");
Serial.println("*****************************************************");
Serial.println("* 32x16px 1/4 Scan Panel *");
Serial.println("*****************************************************");
HUB75_I2S_CFG::i2s_pins _pins =
{ R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN };
HUB75_I2S_CFG mxconfig(
PANEL_RES_X, // DO NOT CHANGE THIS
PANEL_RES_Y, // DO NOT CHANGE THIS
NUM_ROWS*NUM_COLS // DO NOT CHANGE THIS
,_pins // Uncomment to enable custom pins
);
mxconfig.clkphase = false; // Change this if you see pixels showing up shifted wrongly by one column the left or right.
mxconfig.driver = HUB75_I2S_CFG::FM6124; // in case that we use panels based on FM6126A chip, we can set it here before creating MatrixPanel_I2S_DMA object
// OK, now we can create our matrix object
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
// let's adjust default brightness to about 75%
dma_display->setBrightness8(96); // range is 0-255, 0 - 0%, 255 - 100%
// Allocate memory and start DMA display
if( not dma_display->begin())
Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
dma_display->clearScreen();
delay(500);
/* Configure the serpetine chaining approach.
Chain of 2 x 32x16 panels with the ESP at the TOP_RIGHT:
+---------+---------+
| 2 | 1 |
| | (ESP) |
+---------+---------+
*/
// create FourScanPanellay object based on our newly created dma_display object
FourScanPanel = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y);
// THE IMPORTANT BIT BELOW!
FourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_16PX_HIGH);
}
void loop()
{
uint16_t color = FourScanPanel->color565(128, 0,0); //red
for (int i = 0; i < PANEL_RES_X; i++)
{
for (int f = 0; f < PANEL_RES_Y; f++)
{
dma_display->drawPixel(i,f, color);
Serial.print("drawPixel: ");
Serial.print("(");
Serial.print(i, DEC);
Serial.print(",");
Serial.print(f, DEC);
Serial.println(")");
}
}
delay(5000);
dma_display->clearScreen();
} // end loop
please find attached files with all the results here: 4scan-test.xls 4scan-test.zip
i am able to lit all the led and the test result as below: https://user-images.githubusercontent.com/75555993/226512593-8d6e3008-adb6-49ac-977f-e7bdfc8b9d5d.mp4
You run your test too quickly. Add a tiny delay after drawing each point:
void loop()
{
uint16_t color = FourScanPanel->color565(128, 0,0); //red
for (int i = 0; i < PANEL_RES_X; i++)
{
for (int f = 0; f < PANEL_RES_Y; f++)
{
dma_display->drawPixel(i,f, color);
delay(30);
}
}