mrcodetastic / ESP32-HUB75-MatrixPanel-DMA

An Adafruit GFX Compatible Library for the ESP32, ESP32-S2, ESP32-S3 to drive HUB75 LED matrix panels using DMA for high refresh rates. Supports panel chaining.
MIT License
978 stars 215 forks source link

Incomplete output with 32x16 panel when using 'OneEightMatrixDisplay' example #386

Open SergyUA opened 1 year ago

SergyUA commented 1 year ago

Hello. I'm trying to make one matrix (not in a chain) 1/8 scan work. I used (One_Eight_1_8_ScanPane)


1. /*************************************************************************
2.  * Description: 
3.  * 
4.  * The underlying implementation of the ESP32-HUB75-MatrixPanel-I2S-DMA only
5.  * supports output to 1/16 or 1/32 scan panels - which means outputting 
6.  * two lines at the same time, 16 or 32 rows apart. This cannot be changed
7.  * at the DMA layer as it would require a messy and complex rebuild of the 
8.  * library's DMA internals.
9.  *
10.  * However, it is possible to connect 1/8 scan panels to this same library and
11.  * 'trick' the output to work correctly on these panels by way of adjusting the
12.  * pixel co-ordinates that are 'sent' to the ESP32-HUB75-MatrixPanel-I2S-DMA
13.  * library.
14.  * 
15.  **************************************************************************/
16. #include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
17. 
18. /* Use the Virtual Display class to re-map co-ordinates such that they draw 
19.  * correctly on a 32x16 1/8 Scan panel (or chain of such panels).
20.  */
21. #include "ESP32-VirtualMatrixPanel-I2S-DMA.h" 
22. 
23. #define R1_PIN 25
24. #define G1_PIN 26
25. #define B1_PIN 27
26. #define R2_PIN 14
27. #define G2_PIN 12
28. #define B2_PIN 13
29. #define A_PIN 23
30. #define B_PIN 19
31. #define C_PIN 5
32. #define LAT_PIN 4
33. #define OE_PIN 15
34. #define CLK_PIN 16 //RX2
35. 
36.   // Panel configuration
37.   #define PANEL_RES_X 32 // Number of pixels wide of each INDIVIDUAL panel module. 
38.   #define PANEL_RES_Y 16// Number of pixels tall of each INDIVIDUAL panel module.
39.   
40.   
41.   #define NUM_ROWS 1 // Number of rows of chained INDIVIDUAL PANELS
42.   #define NUM_COLS 1 // Number of INDIVIDUAL PANELS per ROW
43.   
44.   // ^^^ NOTE: DEFAULT EXAMPLE SETUP IS FOR A CHAIN OF TWO x 1/8 SCAN PANELS
45.     
46.   // Change this to your needs, for details on VirtualPanel pls read the PDF!
47.   #define SERPENT true
48.   #define TOPDOWN false
49.   
50.   // placeholder for the matrix object
51.   MatrixPanel_I2S_DMA *dma_display = nullptr;
52. 
53.   // placeholder for the virtual display object
54.   VirtualMatrixPanel  *OneEightMatrixDisplay = nullptr;
55.   
56.   /******************************************************************************
57.    * Setup!
58.    ******************************************************************************/
59.   void setup()
60.   {
61.     delay(250);
62.    
63.     Serial.begin(115200);
64.     Serial.println(""); Serial.println(""); Serial.println("");
65.     Serial.println("*****************************************************");
66.     Serial.println("*         1/8 Scan Panel Demonstration              *");
67.     Serial.println("*****************************************************");
68.   
69.  
70.      // 62x32 1/8 Scan Panels don't have a D and E pin!
71.      
72.      HUB75_I2S_CFG::i2s_pins _pins = {
73.       R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, 
74.       A_PIN, B_PIN, C_PIN, 
75.       LAT_PIN, OE_PIN, CLK_PIN
76.      };
77. 
78.     HUB75_I2S_CFG mxconfig(
79.                 PANEL_RES_X*2,              // DO NOT CHANGE THIS
80.                 PANEL_RES_Y/2,              // DO NOT CHANGE THIS
81.                 NUM_ROWS*NUM_COLS           // DO NOT CHANGE THIS
82.                 //,_pins            // Uncomment to enable custom pins
83.     );
84.     
85.     mxconfig.clkphase = false; // Change this if you see pixels showing up shifted wrongly by one column the left or right.
86.     
87.     //mxconfig.driver   = HUB75_I2S_CFG::FM6126A;     // in case that we use panels based on FM6126A chip, we can set it here before creating MatrixPanel_I2S_DMA object
88.   
89.     // OK, now we can create our matrix object
90.     dma_display = new MatrixPanel_I2S_DMA(mxconfig);
91.   
92.     // let's adjust default brightness to about 75%
93.     //dma_display->setBrightness8(96);    // range is 0-255, 0 - 0%, 255 - 100%
94.   
95.     // Allocate memory and start DMA display
96.     if( not dma_display->begin() )
97.       Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
98. 
99.    
100.     dma_display->clearScreen();
101.     delay(500);
102.     
103.     // create OneEightMatrixDisplaylay object based on our newly created dma_display object
104.     OneEightMatrixDisplay = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, SERPENT, TOPDOWN);
105.     
106.   // THE IMPORTANT BIT BELOW!
107.     OneEightMatrixDisplay->setPhysicalPanelScanRate(ONE_EIGHT_32);
108.   }
109. 
110.   
111.   void loop() {
112. /*
113.       // What the panel sees from the DMA engine!
114.       for (int i=PANEL_RES_X*2+10; i< PANEL_RES_X*(NUM_ROWS*NUM_COLS)*2; i++)
115.       {
116.         dma_display->setBrightness8(10);
117.         dma_display->drawLine(i, 0, i, 7, dma_display->color565(255, 0, 0)); // red
118.         delay(10);
119.       }
120.           
121.       dma_display->clearScreen();
122.       delay(1000);
123. */
124. /*
125.       // Try again using the pixel / dma memory remapper
126.       for (int i=PANEL_RES_X+5; i< (PANEL_RES_X*2)-1; i++)
127.       {
128.         OneEightMatrixDisplay->drawLine(i, 0, i, 7, dma_display->color565(0, 0, 255)); // blue    
129.         delay(10);
130.       } 
131. */
132. 
133.       // Try again using the pixel / dma memory remapper
134.       int offset = PANEL_RES_X*((NUM_ROWS*NUM_COLS)-1);
135.       for (int i=0; i< PANEL_RES_X; i++)
136.       {
137.         dma_display->setBrightness8(30);
138.         OneEightMatrixDisplay->drawLine(i+offset, 0, i+offset, 7, dma_display->color565(0, 0, 255)); // blue
139.         OneEightMatrixDisplay->drawLine(i+offset, 8, i+offset, 15, dma_display->color565(0, 128,0)); // g        
140.         OneEightMatrixDisplay->drawLine(i+offset, 16, i+offset, 23, dma_display->color565(128, 0,0)); // red
141.         OneEightMatrixDisplay->drawLine(i+offset, 24, i+offset, 31, dma_display->color565(0, 128, 128)); // blue        
142.         delay(10);
143.       } 
144. 
145.       delay(1000);
146. 
147. 
148.       // Print on each chained panel 1/8 module!
149.       // This only really works for a single horizontal chain
150.       for (int i = 0; i < NUM_ROWS*NUM_COLS; i++)
151.       {
152.         OneEightMatrixDisplay->setTextColor(OneEightMatrixDisplay->color565(255, 255, 255));
153.         OneEightMatrixDisplay->setCursor(i*PANEL_RES_X+7, OneEightMatrixDisplay->height()/3); 
154.       
155.         // Red text inside red rect (2 pix in from edge)
156.         OneEightMatrixDisplay->print("Panel " + String(i+1));
157.         OneEightMatrixDisplay->drawRect(1,1, OneEightMatrixDisplay->width()-2, OneEightMatrixDisplay->height()-2, OneEightMatrixDisplay->color565(255,0,0));
158.       
159.         // White line from top left to bottom right
160.         OneEightMatrixDisplay->drawLine(0,0, OneEightMatrixDisplay->width()-1, OneEightMatrixDisplay->height()-1, OneEightMatrixDisplay->color565(255,255,255));
161.       }
162. 
163.       delay(2000);
164.       dma_display->clearScreen();
165.   
166.   } // end loop

Here's what it looks like.

https://user-images.githubusercontent.com/120684690/215460383-1fab701e-27f2-4e3d-b058-3f5de8ba5cb0.mp4

How can this be fixed?. Newbie in programming. Help me please.

board707 commented 1 year ago

As I see, the matrix is plain 32x16 1/8 matrix...

Hmmm @mrfaptastic, what is a problem with such matrices? Working principle for any indoor panels where scan is half of height (32x16 1/8 ... 64x32 1/16 ... 80x40 1/20....128x64 1/32 ... etc) is exactly the same. The layout of the memory buffer is the same too. Why the 64x32 is supported, but 32x16 is not?

mrcodetastic commented 1 year ago

Why the 64x32 is supported, but 32x16 is not?

Not to sound rude, but if I knew why these panels didn't work I'd have coded a solution probably. I think they are different at the electrical level. The fact @SergyUA's panel isn't showing sometihng on all rows (even if duplicated or wrong), makes me think there's some pin mapping issue here.

@SergyUA - Looks like an electrical matter, not software, triple check your wring, or start testing individual pins to see if you can at least get something to be displayed on rows 5-8 and 28-32

Can you please test using SimpleTestShapes with default configuration and NOT using the One_Eight_1_8_ScanPanel example. Please provide video.

@SergyUA - Are you using these panels to support the war effort at all? If so I am happy to try and provide enhanced help with your needs.

SergyUA commented 1 year ago

Can you please test using SimpleTestShapes with default configuration and NOT using the One_Eight_1_8_ScanPanel example. Please provide video.

@mrfaptastic. Thank you. I took your advice and uploaded (SimpleTestShapes) and here is the result.

https://user-images.githubusercontent.com/120684690/215828978-b4b0d2ef-7072-42df-ae2a-d44c1f1ccf9e.mp4

@SergyUA - Are you using these panels to support the war effort at all? If so I am happy to try and provide enhanced help with your needs.

No, not to support the military, but for the residents of the city where I live.

mrcodetastic commented 1 year ago

I took your advice and uploaded (SimpleTestShapes) and here is the result.

Looks good to me? I take it the only thing you changed in the example was the PANEL_RES_X and PANEL_RES_Y values?

I can't see a problem with this output now. Seems like it is a normal 1/2 scan panel (scans two halves/parallel at the same time).... Just a 32x16 pixel one

Summary: don't need to use the OneEightMatrixDisplay stuff

SergyUA commented 1 year ago

Looks good to me? I take it the only thing you changed in the example was the PANEL_RES_X and PANEL_RES_Y values?

Exactly.

I can't see a problem with this output now. Seems like it is a normal 1/2 scan panel (scans two halves/parallel at the same time).... Just a 32x16 pixel one

It looks like it. Although on the panel (on the sticker) 1/8. And first I tried the PxMatrix library. The panel worked at 1/8 scan.

mrcodetastic commented 1 year ago

It looks like it. Although on the panel (on the sticker) 1/8. And first I tried the PxMatrix library. The panel worked at 1/8 scan.

That's because the use of fractions to describe these panels is ambiguous. Nobody is consistent, especially the Chinese sellers on AliExpress.

What it SHOULD mean is that how many rows are updated in parallel at the same time as the display updates from top to bottom.

What most people seem to think it means is how many rows between the rows getting updated.

I even get this wrong in my panel descriptions of panels in this library!

For example, the OneEightMatrixDisplay example should have been called OneQuarterMatrixDisplay. Because it's about trying to make this library work with panels that update four lines at once.

What your panel actually is, and what this library supports natively is 1/2 (half) scan. That means, the panel is split in half and two rows are updated in parallel.

Now depending on the actual physical dimensions of a panel (for example let us use a 16 px high panel).... It is also described as a...

1/2 * 16 = 8 or 1/8, scan panel...

... which is technically right but is also WRONG and confusing especially when used interchangeably. Your panel is still a half or '1/2' scan panel.

I need to write a ReadMe on this, update all my examples to be consistent.

mrcodetastic commented 1 year ago

OneEightMatrixDisplay is now dead and has been replaced with 'Four_Scan_Panel' example. Library's README has been updated as well.

This is to avoid confusion.

board707 commented 1 year ago

@mrfaptastic Descriptions 1/2 1/4 1/8 mean what part of the whole matrix glows at each moment. There is nothing ambiguous in it. This is the common terminology OP matrix is exactly the matrix 1/8, because the full illumination of whole panel required 8 upload cycles. Trying to call such matrices 1/2 only confuses people.

mrcodetastic commented 1 year ago

No, not to support the military, but for the residents of the city where I live.

Let me know if there's a local fundraiser I can contribute to.