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
899 stars 201 forks source link

P4 64x32 matrix chain 2x2 problem #624

Open ki865564 opened 3 months ago

ki865564 commented 3 months ago

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.

image

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

image

When I checked the output, it was determined that the order of output was mixed as shown in the image below. 그림1 The panels were divided into quarters and numbered for each part. 그림2 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

#include <Arduino.h>
#include <Adafruit_GFX.h>
#include "ESP32-VirtualMatrixPanel-I2S-DMA.h"  
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>   
#include <Fonts/GodoM6pt8b.h>

#define PANEL_RES_X 64  
#define PANEL_RES_Y 32  

#define NUM_ROWS 2                         
#define NUM_COLS 2                         
#define PANEL_CHAIN (NUM_ROWS * NUM_COLS)  
#define VIRTUAL_MATRIX_CHAIN_TYPE CHAIN_TOP_RIGHT_DOWN

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();
}

And part of the changed header file code.

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 !
        */
        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
        }

        // 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);

    }
board707 commented 3 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
        }

   }
ki865564 commented 3 months ago

@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...

board707 commented 3 months ago

Yes, I forget to change the condition:

Incorrect code
board707 commented 3 months ago

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);

    }
ki865564 commented 3 months ago

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

ki865564 commented 3 months ago

This picture shows an display that is successfully printed.

2X2 result KakaoTalk_20240429_143631080_01

3x3 result

KakaoTalk_20240429_143631080

board707 commented 2 months ago

@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?

ogul commented 1 month ago

Can you share the working code for 2x2?

board707 commented 1 month ago

@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?

slawek19926 commented 1 month ago

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. 20240604_212951 My code `#include

include

include "ESP32-VirtualMatrixPanel-I2S-DMA.h"

include

define PANEL_RES_X 64

define PANEL_RES_Y 32

define NUM_ROWS 2

define NUM_COLS 2

define PANEL_CHAIN (NUM_ROWS * NUM_COLS)

define VIRTUAL_MATRIX_CHAIN_TYPE CHAIN_BOTTOM_RIGHT_UP_ZZ

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(); } `

board707 commented 1 month ago

@slawek19926 Do you test a single panel?

slawek19926 commented 1 month ago

@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.

board707 commented 1 month ago

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.

board707 commented 1 month ago

@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.

slawek19926 commented 1 month ago

@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

20240605_181921 20240605_181929 20240605_182455 20240605_181914

board707 commented 1 month ago

@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

slawek19926 commented 1 month ago

@board707 This is what the test you asked for looks like.

https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA/assets/6081345/4eeef363-8f20-4ca1-b135-3fdbd92c3c20

slawek19926 commented 1 month ago

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

Bez tytułu

board707 commented 1 month ago

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.

slawek19926 commented 1 month ago

I'm using this code

`#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"

include "ESP32-VirtualMatrixPanel-I2S-DMA.h"

// 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

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;

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`

board707 commented 1 month ago

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);
slawek19926 commented 1 month ago

I'm sorry I made a mistake. I was using FourScanPanel->setPhysicalPanelScanRate(FOUR_SCAN_32PX_HIGH);

board707 commented 1 month ago

Are you sure that you made the mistake when showing the code, but not when uploading it? The residual code looks correct for me.

slawek19926 commented 1 month ago

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.

board707 commented 1 month ago

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.

slawek19926 commented 1 month ago

When recording the video, I used the original freshly downloaded library version 3.0.10

board707 commented 1 month ago

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?

slawek19926 commented 1 month ago

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.

board707 commented 1 month ago

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.

board707 commented 1 month ago

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
slawek19926 commented 1 month ago

Ok. Tomorrow I will isolate 1 panel, upload the code and send a video of how it works

slawek19926 commented 1 month ago

As for displaying single lines, the code works great, while there is still a problem when connecting a 2x2 matrix

board707 commented 1 month ago

I'm not going to impose my help. If you think the code works, I won't argue. Good luck.

slawek19926 commented 1 month ago

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 commented 1 month ago

@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

davemaster commented 1 month ago

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?

board707 commented 1 month ago

t just photo strobe effect!

Thank you for clarification.

ki865564 commented 1 month ago

Here is the final code I used.

  1. I used P4 64x32 1/8 Scan Rate- outdoor panel and The panel connection method used the same method as the image below. image

  2. library used 3.0.7 ver.

  3. 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);
    }
  4. 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 PANEL_RES_X 64

define PANEL_RES_Y 32

// Define the number of rows and columns in the panel matrix

define NUM_ROWS 3

define NUM_COLS 3

define PANEL_CHAIN (NUM_ROWS * NUM_COLS)

// Define the virtual matrix chain type

define VIRTUAL_MATRIX_CHAIN_TYPE CHAIN_TOP_RIGHT_DOWN

// 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
davemaster commented 1 month ago

Thanks a lot....