Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P8 40x20 1/5S #637

Open
mjmokhtar opened this issue Jun 4, 2024 · 9 comments
Open

P8 40x20 1/5S #637

mjmokhtar opened this issue Jun 4, 2024 · 9 comments

Comments

@mjmokhtar
Copy link

I have a panel led p8 40x20 with scan 1/5
Gambar WhatsApp 2024-06-04 pukul 12 00 24_0cd6bb91
Gambar WhatsApp 2024-06-04 pukul 12 00 15_3c156d00

i've using 1/4 scan for tried
here this code from example

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

// Panel configuration
#define PANEL_RES_X 40 // Number of pixels wide of each INDIVIDUAL panel module.
#define PANEL_RES_Y 20 // 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_X*2, // 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

and here is result

video.mp4

this coordinate is still random
may I need your help to fix it

thanks

@board707
Copy link
Contributor

board707 commented Jun 4, 2024

Please use our old code from this post, changing the matrix width and height to 40 x 20.
Replace the getCoords() function with code below and show the video:

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


if (((coords.y / 5)%2) == 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
        }

       coords.y = (coords.y / 10) * 5 + (coords.y % 5);
  return coords;
}

@mjmokhtar
Copy link
Author

video2.mp4

here is result
and here a code

/* Use a custom Virtual Display class to re-map co-ordinates such that they draw
   correctly on a 32x16 1/4 Scan panel (or chain of such panels).
*/
#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;
  }


if (((coords.y / 5)%2) == 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
        }

       coords.y = (coords.y / 10) * 5 + (coords.y % 5);
  return coords;
}

/* ================================================== */
// Panel configuration
#define PANEL_RES_X 40 // Number of pixels wide of each INDIVIDUAL panel module. 
#define PANEL_RES_Y 20 // 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

@board707
Copy link
Contributor

board707 commented Jun 4, 2024

Thanks
Now change the getCoords() this way:

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 =8;
if (((coords.y / 5)%2) == 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 / 10) * 5 + (coords.y % 5);
  return coords;
}

@mjmokhtar
Copy link
Author

video3.mp4

here is result

@board707
Copy link
Contributor

board707 commented Jun 4, 2024

It looks the same pattern as in your 32x16 s4 panel
Try this:

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 =8;
if (((coords.y / 5)%2) == 0)
          {
            coords.x = (coords.x / pxbase)*2*pxbase   + 7 - (coords.x & 0x7);
        }
        else
        {
           coords.x += ((coords.x / pxbase) + 1) * pxbase; 
        }

       coords.y = (coords.y / 10) * 5 + (coords.y % 5);
  return coords;
}

@mjmokhtar
Copy link
Author

video4.mp4

finally
thank you so much

can you teach me how to know how to manipulate the coordinates of led?

@board707
Copy link
Contributor

board707 commented Jun 4, 2024

can you teach me how to know how to manipulate the coordinates of led?

After setting the virtual panel class, you can use a natural panel coordinates. You have using it already in your 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);
    }
  }

@mjmokhtar
Copy link
Author

yes i mean when the first time, the coordinate of led panel was not in position, how should we know to write this code

const uint8_t pixBase =8;
if (((coords.y / 5)%2) == 0)
          {
            coords.x = (coords.x / pxbase)*2*pxbase   + 7 - (coords.x & 0x7);
        }
        else
        {
           coords.x += ((coords.x / pxbase) + 1) * pxbase; 
        }

       coords.y = (coords.y / 10) * 5 + (coords.y % 5);
  return coords;

@board707
Copy link
Contributor

board707 commented Jun 4, 2024

See the discussion #622, this is a brief guide where I explained how and what I do when I add a new panel.
I have my own library (not for ESP32), when writing it I tested dozens of panels of different sizes and coordinate transformations. With my library, I can run panels with almost any size, scan factor and coordinate pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants