Open ki865564 opened 7 months ago
try to change it that way:
if (panel_scan_rate == FOUR_SCAN_32PX_HIGH)
{
/* Convert Real World 'VirtualMatrixPanel' co-ordinates (i.e. Real World pixel you're looking at
on the panel or chain of panels, per the chaining configuration) to a 1/8 panels
double 'stretched' and 'squished' coordinates which is what needs to be sent from the
DMA buffer.
Note: Look at the FourScanPanel example code and you'll see that the DMA buffer is setup
as if the panel is 2 * W and 0.5 * H !
*/
// http://cpp.sh/4ak5u
// Real number of DMA y rows is half reality
// coords.y = (y / 16)*8 + (y & 0b00000111);
//
coords.y = (coords.y >> 4) * 8 + (coords.y & 0b00000111);
if ((virt_y & 8) == 0)
{
coords.x += ((coords.x / panelResX) + 1) * panelResX; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer
}
else
{
coords.x += (coords.x / panelResX) * panelResX; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer
}
}
@board707 I tried the method you suggested. However, it appears to be nothing more than a change in the location of the code. The output is the same as before...
Yes, I forget to change the condition:
Incorrect code
I apologize for forcing you to test many options. Unfortunately, this can only be checked on your matrices. Hope this will work:
f (panel_scan_rate == FOUR_SCAN_32PX_HIGH)
{
/* Convert Real World 'VirtualMatrixPanel' co-ordinates (i.e. Real World pixel you're looking at
on the panel or chain of panels, per the chaining configuration) to a 1/8 panels
double 'stretched' and 'squished' coordinates which is what needs to be sent from the
DMA buffer.
Note: Look at the FourScanPanel example code and you'll see that the DMA buffer is setup
as if the panel is 2 * W and 0.5 * H !
*/
if (( coords.y & 8) == 0)
{
coords.x += ((coords.x / panelResX) + 1) * panelResX; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer
}
else
{
coords.x += (coords.x / panelResX) * panelResX; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer
}
// http://cpp.sh/4ak5u
// Real number of DMA y rows is half reality
// coords.y = (y / 16)*8 + (y & 0b00000111);
//
coords.y = (coords.y >> 4) * 8 + (coords.y & 0b00000111);
}
Before
if ((virt_y & 8) == 0)
After
if (( coords.y & 8) == 0)
I didn't expect this would be a problem. Thanks to you, the problem has been solved!!
Thanks to you @board707
This picture shows an display that is successfully printed.
2X2 result
3x3 result
@ki865564 It's strange why the 2x2 image looks fine, but the 3x3 has artifacts. In the lower picture, is every 6-8th line really not lit or is it just a photo strobe effect?
Can you share the working code for 2x2?
@ogul To chaining standard panels you don't need any specific code, the library should works fine with 2x2 and 3x3 and any others If you have a non-standard panels - the code for each type of them will be different one from another, so others code doesn't help you. So the first question - what the panels you have?
Hi.
I have a problem with 64x32px panels. After connecting them in a 2x2 matrix, they work as shown in the picture. My panels have only 3 address lines A, B and C. The connection is zigzag. Please help.
My code
`#include
MatrixPanel_I2S_DMA dma_display = nullptr; VirtualMatrixPanel virtualDisp = nullptr;
void drawText(int x, int y, const char *text, uint16_t textColor) { virtualDisp->setTextColor(textColor); virtualDisp->setCursor(x, y); virtualDisp->print(text); }
void drawTextWithBackground(int x, int y, const char text, uint16_t textColor) {
virtualDisp->setTextColor(textColor);
virtualDisp->setTextSize(3);
virtualDisp->setCursor(x, y);
virtualDisp->print(text);
}
void setup() {
Serial.begin(115200);
HUB75_I2S_CFG mxconfig(
PANEL_RES_X 2,
PANEL_RES_Y / 2,
PANEL_CHAIN
);
mxconfig.clkphase = false;
mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
if (!dma_display->begin()) { Serial.println("** !KABOOM! I2S memory allocation failed ***"); return; } dma_display->setBrightness8(30);
virtualDisp = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, VIRTUAL_MATRIX_CHAIN_TYPE); virtualDisp->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);
}
void loop() { virtualDisp->drawRect(1, 1, virtualDisp->width() - 2, virtualDisp->height() - 2, virtualDisp->color565(255, 0, 0)); virtualDisp->drawLine(0, 0, virtualDisp->width() - 1, virtualDisp->height() - 1, virtualDisp->color565(255, 255, 255)); delay(2000);
drawTextWithBackground(0, virtualDisp->height() / 2 - 8, " hi", virtualDisp->color565(0, 0, 255)); delay(10000);
dma_display->clearScreen(); } `
@slawek19926 Do you test a single panel?
@board707 This is how I tested for one panel. The 32x32 cols 2 setting worked. The problem is that then during the test it displays “panel 1” “panel 2” even though 1 panel is physically connected.
Sorry, I don't understand. What is the panel pixel dimensions - 64x32? Or 32x32? Did you test a single panel? Could you show a picture of single panel test?
BTW - why did you posted this to the old thread? Open a new one.
@slawek19926 Please show a clear photo of the panel rear side. Please find the three types of chips on the back of the panel and rewrite their designations.
@board707
Ok the physical size of the panel is 64x32 pixels. As for starting a new topic, why litter unnecessary new threads. As for the chips these are: ICN2037BP, SM5166PC, MW245B
@slawek19926 Ok, if you don't want to open a separate thread, I'll keep it short. First - your panel has 8 scans, so it is perfectly normal that it has only A, B and C lines Second - the drivers on the panel are compatible with the current library code and doesn't need any specific settings.
The only problem is a pixel pattern. Please test a single panel with Virtual panel example and show the video, as it done, for example< in issue #637
@board707 This is what the test you asked for looks like.
This code takes care of the issue of displaying pixels, but for that there is now a problem when connecting a 2x2 matrix. Only the top half is always filled.
int16_t myPanel = panelResX / 2; if ((virt_y & 8) == 0) { coords.x += ((coords.x / myPanel) + 1) * myPanel; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer } else { coords.x += (coords.x / myPanel) * myPanel; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer }
The red line is how to connect
This code takes care of the issue of displaying pixels, but for that there is now a problem when connecting a 2x2 matrix.
Before connecting 4 panels, you need to configure the display of points on one panel
Please show the code that you used when generate the last video.
I'm using this code
`#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
// Panel configuration
// placeholder for the matrix object MatrixPanel_I2S_DMA *dma_display = nullptr;
// placeholder for the virtual display object VirtualMatrixPanel *FourScanPanel = nullptr;
void setup() { delay(250);
Serial.begin(115200); Serial.println(""); Serial.println(""); Serial.println(""); Serial.println(""); Serial.println(" 1/8 Scan Panel Demonstration "); Serial.println("");
HUB75_I2S_CFG mxconfig( PANEL_RES_X2, // DO NOT CHANGE THIS PANEL_RES_Y/2, // DO NOT CHANGE THIS NUM_ROWS NUM_COLS // DO NOT CHANGE THIS );
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::FM6126A; // in case that we use panels based on FM6126A chip, we can set it here before creating MatrixPanel_I2S_DMA object
// Create our matrix object dma_display = new MatrixPanel_I2S_DMA(mxconfig);
// 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 (!dma_display->begin()) Serial.println("** !KABOOM! I2S memory allocation failed ***");
dma_display->clearScreen(); delay(500);
// Create FourScanPanel 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() {
for (int i = 0; i < FourScanPanel->height(); i++) { for (int j = 0; j < FourScanPanel->width(); j++) { FourScanPanel->drawPixel(j, i, FourScanPanel->color565(255, 0, 0)); delay(30); } }
delay(2000); dma_display->clearScreen();
} // end loop`
This line is incorrect:
FourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_16PX_HIGH);
Your panel is 64x32, so you need to use FOUR_SCAN_32PX_HIGH
scanrate. Edit the line this way:
FourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);
I'm sorry I made a mistake. I was using FourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);
Are you sure that you made the mistake when showing the code, but not when uploading it? The residual code looks correct for me.
Yes. I checked several times and it was on this code that I made my library fix. Do you happen to have Discord? It will be easier and faster for us to talk that way.
I made my library fix.
Did you use your revised library when run the test? - if so, please return to standard code and test again.
When recording the video, I used the original freshly downloaded library version 3.0.10
Ok, I watched your video again - now on the big screen and I think everything is fine there. Two facts initially confused me - the fact that you are testing the code on a screen of several panels and the fact that you shot the video carelessly - part of the panel on the right is covered by some kind of shadow.
Could you separate one panel for testing - so that the edges of the panel can be clearly seen in the video?
I can do it, but only tomorrow because today is quite late. As for the shadow it's a few pixels behind the monitor. Anyway, my fix solved the subject of setting pixels on the matrix. Now the only problem I have is that with a 2x2 matrix and the connection as in the picture I attached earlier, the lower half of the matrix does not work.
my fix solved the subject of setting pixels on the matrix. Now the only problem I have is that with a 2x2 matrix
This most likely means that your fix is only partial - for example it only works for one row of panels. I'm approaching this problem from a different angle - If we find the right coordinate transformation for a single matrix, it will works for any combination of multiple panels. I not consider it useful to solve separately the problem of connecting 2x2 matrices.
If you wish to continue, tomorrow test the code below and show the video.
/* Use a custom Virtual Display class to re-map co-ordinates
*/
#include "ESP32-VirtualMatrixPanel-I2S-DMA.h"
/* ================================================== */
// Define custom class derived from VirtualMatrixPanel
class EightPxBasePanel : public VirtualMatrixPanel
{
public:
using VirtualMatrixPanel::VirtualMatrixPanel; // inherit VirtualMatrixPanel's constructor(s)
protected:
VirtualCoords getCoords(int16_t x, int16_t y); // custom getCoords() method for specific pixel mapping
};
inline VirtualCoords EightPxBasePanel ::getCoords(int16_t x, int16_t y) {
coords = VirtualMatrixPanel::getCoords(x, y); // first call base class method to update coords for chaining approach
if ( coords.x == -1 || coords.y == -1 ) { // Co-ordinates go from 0 to X-1 remember! width() and height() are out of range!
return coords;
}
const uint8_t pixBase =32;
if ((coords.y & 8) == 0)
{
coords.x += ((coords.x / pixBase) + 1) * pixBase; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer
}
else
{
coords.x += (coords.x / pixBase) * pixBase; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer
}
coords.y = (coords.y >> 4) * 8 + (coords.y & 0b00000111);
return coords;
}
/* ================================================== */
// Panel configuration
#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module.
#define PANEL_RES_Y 32 // 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
#define VIRTUAL_MATRIX_CHAIN_TYPE CHAIN_TOP_RIGHT_DOWN
// placeholder for the matrix object
MatrixPanel_I2S_DMA *dma_display = nullptr;
// placeholder for the virtual display object
EightPxBasePanel *FourScanPanel = nullptr;
/******************************************************************************
Setup!
******************************************************************************/
void setup()
{
delay(250);
Serial.begin(115200);
Serial.println(""); Serial.println(""); Serial.println("");
Serial.println("*****************************************************");
Serial.println("* 1/8 Scan Panel Demonstration *");
Serial.println("*****************************************************");
/*
// 62x32 1/8 Scan Panels don't have a D and E pin!
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 * 2, // DO NOT CHANGE THIS
PANEL_RES_Y / 2, // 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::FM6126A; // 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(40); // 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);
// create FourScanPanellay object based on our newly created dma_display object
FourScanPanel = new EightPxBasePanel ((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, VIRTUAL_MATRIX_CHAIN_TYPE);
// THE IMPORTANT BIT BELOW!
// FOUR_SCAN_16PX_HIGH
// FOUR_SCAN_32PX_HIGH
// **** You don't need to set PhysicalPanelScanRate when use your own virtual panel class
//FourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_16PX_HIGH);
}
// Test the pixel mapping - fill the panel pixel by pixel
void loop() {
for (int i = 0; i < FourScanPanel->height(); i++)
{
for (int j = 0; j < FourScanPanel->width(); j++)
{
FourScanPanel->drawPixel(j, i, FourScanPanel->color565(255, 0, 0));
delay(30);
}
}
delay(2000);
dma_display->clearScreen();
} // end loop
Ok. Tomorrow I will isolate 1 panel, upload the code and send a video of how it works
As for displaying single lines, the code works great, while there is still a problem when connecting a 2x2 matrix
I'm not going to impose my help. If you think the code works, I won't argue. Good luck.
No need to be offended. I appreciate your help. I didn't take a video of how the pixels are displayed because they started displaying from point 0,0 in sequence until the end of the panel. Since I noticed that your way works I started to go further because I thought that the problem with the single panel was solved, but as it turns out, however, not.
@ki865564 It's strange why the 2x2 image looks fine, but the 3x3 has artifacts. In the lower picture, is every 6-8th line really not lit or is it just a photo strobe effect?
it just photo strobe effect! sorry for the late reply
As for displaying single lines, the code works great, while there is still a problem when connecting a 2x2 matrix
What about the picture, better, the video?
t just photo strobe effect!
Thank you for clarification.
Here is the final code I used.
I used P4 64x32 1/8 Scan Rate- outdoor panel and The panel connection method used the same method as the image below.
library used 3.0.7 ver.
The modifications within the library are as follows.
if (panel_scan_rate == FOUR_SCAN_32PX_HIGH)
{
if ((coords.y & 8) == 0)
{
coords.x += ((coords.x / panelResX) + 1) * panelResX; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer
}
else
{
coords.x += (coords.x / panelResX) * panelResX; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer
}
// Real number of DMA y rows is half reality
// coords.y = (y / 16)*8 + (y & 0b00000111);
//
coords.y = (coords.y >> 4) * 8 + (coords.y & 0b00000111);
}
The final code used is as follows.
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include "ESP32-VirtualMatrixPanel-I2S-DMA.h"
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
// Define panel resolution
// Define the number of rows and columns in the panel matrix
// Define the virtual matrix chain type
// Declare pointers for DMA display and virtual display MatrixPanel_I2S_DMA dma_display = nullptr; VirtualMatrixPanel virtualDisp = nullptr;
// Function to draw text with background void drawTextWithBackground(int x, int y, const char *text, uint16_t textColor) { virtualDisp->setTextColor(textColor); virtualDisp->setTextSize(3); virtualDisp->setCursor(x, y); virtualDisp->print(text); }
void setup() { Serial.begin(115200);
// Initialize HUB75 configuration with panel dimensions and chain settings HUB75_I2S_CFG mxconfig( PANEL_RES_X * 2, PANEL_RES_Y / 2, PANEL_CHAIN);
mxconfig.clkphase = false; mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;
// Initialize DMA display dma_display = new MatrixPanel_I2S_DMA(mxconfig);
// Check if DMA display began successfully if (!dma_display->begin()) { Serial.println("** !KABOOM! I2S memory allocation failed ***"); return; } dma_display->setBrightness8(192);
// Initialize virtual display with the DMA display and panel settings virtualDisp = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, VIRTUAL_MATRIX_CHAIN_TYPE); virtualDisp->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH); }
void loop() { // Define the height of each section of the display int sectionHeight = virtualDisp->height() / 4;
// Draw a rectangle around the display edges virtualDisp->drawRect(1, 1, virtualDisp->width() - 2, virtualDisp->height() - 2, virtualDisp->color565(255, 0, 0));
// Draw a diagonal line across the display virtualDisp->drawLine(0, 0, virtualDisp->width() - 1, virtualDisp->height() - 1, virtualDisp->color565(255, 255, 255)); delay(2000);
// Draw text in the middle of the display drawTextWithBackground(0, virtualDisp->height() / 2 - 8, " hi", virtualDisp->color565(0, 0, 255)); delay(10000);
// Clear the screen dma_display->clearScreen(); }
5. I modified the file at the following location for pin modification.
...\Arduino\libraries\ESP32_HUB75_LED_MATRIX_PANEL_DMA_Display\src\platforms\esp32\esp32-default-pins.hpp
Thanks a lot....
Hello. I am successfully using the p4 electronic display board using your project. The p4 indoor type was successful, but the outdoor type was not working well... i try to single panel. it work.
Outdoor P4-1921-64x32-8s-s1 Esp32-WROOM-32UE
Now I've connected a total of four panels and tried it in a 2x2 shape. Among the connected panels, the top two panels are output normally, but the bottom panel is not output normally.
I've referred to the following post for improvement. It has fixed the header file and checked the output as follows. https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA/issues/578#issue-2106096259
When I checked the output, it was determined that the order of output was mixed as shown in the image below. The panels were divided into quarters and numbered for each part. I changed the position to draw the output I wanted. If so, it will be placed like this.
I need to correct this part, but I didn't know what to do...
Here is my Code
And part of the changed header file code.