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

Need help about buying P5 Outdoor Panel #711

Open
nur476 opened this issue Dec 22, 2024 · 23 comments
Open

Need help about buying P5 Outdoor Panel #711

nur476 opened this issue Dec 22, 2024 · 23 comments
Labels
panel specific issue A HUB75 panel that isn't supported out-of-the-box. Fiddling required. Not a DMA library issue.

Comments

@nur476
Copy link

nur476 commented Dec 22, 2024

Hello,

As you may know from my previous issues, I tried some panels but not worked. I tried panels which I can buy from local suppliers but they don't work.

Can you give me P5 Outdoor 64x32 Panel (working with this library) purchase link which I can buy?

Thanks in advance.

@board707
Copy link
Contributor

Hi @nur476

If you post a list of panels ( indicating the drivers that are installed on them) that are available in your local stores,, I will be able to tell you which of them should work with this library and which should not.

@nur476
Copy link
Author

nur476 commented Dec 23, 2024

Hi @board707 ,

Thanks for your reply. There is not so many options actually. I found new one and the codes on it:

ICM2038S -ICM2012

Are these good for this library?

Thank you.

@board707
Copy link
Contributor

board707 commented Dec 23, 2024

ICM2038S -ICM2012

Both chips are compatible with the code, as I think. Hope this panel should works.

What is the size of panel in pixels and what is the scan factor?

@nur476
Copy link
Author

nur476 commented Dec 23, 2024

Hi @board707 ,

P5 Panel 128x64 and supplier said it is 1/8 1920Hz

@board707
Copy link
Contributor

board707 commented Dec 23, 2024

In order to avoid problems with the panel, at a size of 128x64 its scan should be 32.
The drivers on the panel are compatible with code and the panel will most likely work, but the pixels on it will not be located in a row and you will need to write a separate mapper to work with it.
This can be tricky because the panel is not even a "quarter scan", but an eighth.

@nur476
Copy link
Author

nur476 commented Dec 23, 2024

Hi @board707

I will make it with virtual matrix right? I ordered this panel, I will try. I hope it works.

@board707
Copy link
Contributor

I will try. I hope it works.

let me know, maybe I can help you.

@nur476
Copy link
Author

nur476 commented Dec 23, 2024

Hi @board707 ,

I appreciate for your kind replies. I ordered panels and I will let you know any updates.

Thank you.

@nur476
Copy link
Author

nur476 commented Dec 23, 2024

Hi @board707 ,

Btw, It is 64x32 not 128x64. Sorry for my mistake.

@nur476
Copy link
Author

nur476 commented Dec 24, 2024

Hi @board707 ,

I got the panel and tested. Result is promising. You can see the video below, panel fillling completely but not in the right order. I tried several codes which you provided "pxbase" examples but none of them worked. This is the code I uploaded, actually it is default FOUR_SCAN_16PX_HIGH coordinates returns.

Here is the code:

#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
#include "ESP32-VirtualMatrixPanel-I2S-DMA.h"
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
};
// define 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 & 4) == 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 >> 3) * 4 + (coords.y & 0b00000011);
  return coords;
}
#define R1_PIN 45
#define G1_PIN 42
#define B1_PIN 41
#define R2_PIN 40
#define G2_PIN 39
#define B2_PIN 38
#define A_PIN  37
#define B_PIN  36
#define C_PIN  35
#define D_PIN  -1
#define E_PIN  -1 // required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32
#define LAT_PIN 26
#define OE_PIN  21
#define CLK_PIN 33
  // 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
  // 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("*         1/8 Scan Panel Demonstration              *");
    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*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(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);
    // 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);
    FourScanPanel = new EightPxBasePanel ((*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(15);
    }
  }
  delay(2000);
  dma_display->clearScreen();
} // end loop


And the result video:

IMG_78.mp4

I need help about tuning. Can you please help me?

@board707
Copy link
Contributor

Great result!
I'll write to you in a few hours.

@board707
Copy link
Contributor

Please show result with virtual method below:

// define 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 ((virt_y & 8) == 0)
        {
      coords.x += ((coords.x / panelResX) + 1) * panelResX; 
        }
        else
        {
            coords.x += (coords.x / panelResX) * panelResX;
        }

        coords.y = (virt_y >> 4) * 8 + (virt_y & 0b00000111);
    return coords;
}

Note: it is not a final solution.

@nur476
Copy link
Author

nur476 commented Dec 24, 2024

Hi @board707 ,

Thank you so much. I tried the code but virt_y is not declared. Then I changed (not sure it is right)

inline VirtualCoords EightPxBasePanel ::getCoords(int16_t x, int16_t y)

to

inline VirtualCoords EightPxBasePanel ::getCoords(int16_t x, int16_t virt_y)

and tested but result is very similar:

IMG_7880.mov

@board707
Copy link
Contributor

Please forgive me, I mixed it up when copying

// define 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 & 8) == 0)
        {
      coords.x += ((coords.x / panelResX) + 1) * panelResX; 
        }
        else
        {
            coords.x += (coords.x / panelResX) * panelResX;
        }

        coords.y = (coords.y >> 4) * 8 + (coords.y & 0b00000111);
    return coords;
}

@nur476
Copy link
Author

nur476 commented Dec 24, 2024

Please forgive me, I mixed it up when copying

// define 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 & 8) == 0)
        {
      coords.x += ((coords.x / panelResX) + 1) * panelResX; 
        }
        else
        {
            coords.x += (coords.x / panelResX) * panelResX;
        }

        coords.y = (coords.y >> 4) * 8 + (coords.y & 0b00000111);
    return coords;
}

Just same result with above video. :(

@board707
Copy link
Contributor

It's perfectly normal.
The next stage:

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;
  }
  uint8_t pxbase =32;
     if ((coords.y & 8) == 0)
       {
            coords.x += ((coords.x / pxbase) + 1) * pxbase; 
        }
        else
        {
            coords.x += (coords.x / pxbase) * pxbase; 
        }
    coords.y = (coords.y >> 4) * 8 + (coords.y & 0b00000111);
    return coords;
}

@nur476
Copy link
Author

nur476 commented Dec 25, 2024

Hi @board707 ,

I appreciate, it works like a charm. You saved the day.

Here it is result:

IMG_7882.mov

I think it is OK now, right? I can use the panel with this tuning?

Thank you so much again.

@nur476
Copy link
Author

nur476 commented Dec 25, 2024

Hi @board707 ,

Made it work. Thank you again. I may need further professional help with another boards. Can I get your email?

Final result:

IMG_7885.MOV

@board707
Copy link
Contributor

My congratulations!

I may need further professional help with another boards.

There are currently a lot of matrices with incompatible chips, so not every panel can be configured. But where I can, I will be glad to help.

Contact me here, or by email [email protected]

@mrcodetastic
Copy link
Owner

Great work @board707 . How many iterations of this pixel mapping function have you created over time for various boards? We should add them in as options to the library.

@board707
Copy link
Contributor

board707 commented Dec 25, 2024

We should add them in as options to the library.

It is not so easy to program in general, because we will need many options. It is much easier for me to write a mapper for a specific matrix.

The mapping depends on the matrix height, scan, pixel base. For each of the listed combinations there can be eight different mappings - depending on whether the output starts from the top line or from the bottom, and how the pixels are lit - on the right or left... And this is only one type of pattern, and there are many.

Some time ago I posted a short message explaining the mapping principles of "quarter scan" matrices on PixelMatrix Commumity forum https://community.pixelmatix.com/t/coordinate-transformations-for-4scan-panels/1236
It's a bit outdated since then, but it might still be useful.

@nur476
Copy link
Author

nur476 commented Dec 25, 2024

We should add them in as options to the library.

It is not so easy to program in general, because we will need many options. It is much easier for me to write a mapper for a specific matrix.

The mapping depends on the matrix height, scan, pixel base. For each of the listed combinations there can be eight different mappings - depending on whether the output starts from the top line or from the bottom, and how the pixels are lit - on the right or left... And this is only one type of pattern, and there are many.

Some time ago I posted a short message explaining the mapping principles of "quarter scan" matrices on PixelMatrix Commumity forum https://community.pixelmatix.com/t/coordinate-transformations-for-4scan-panels/1236 It's a bit outdated since then, but it might still be useful.

I am really happy since I will use this library and panel in a commercial product, but these issues you mentioned above are big problems. For example; supplier said to me these panels may come with different chips, there is no consistency. Because of this, I will buy a lot of panel from him to use without problems. But when they are over, I am not sure what to do. I asked your email incase of buying different panels. It is too bad that there is no standart.

Thanks to you, problem solved for now. Btw, where do you live? which country? @board707

@mrcodetastic
Copy link
Owner

But when they are over, I am not sure what to do. I asked your email incase of buying different panels. It is too bad that there is no standard.

In your product you sell, have a non-volatile configuration variable for the panel type that ships with the hardware. In the firmware, keep adding code as the supplier sends different variants of pixel mapping. The pixel mapping approach used does not need to be set at compiled time only, all products shipped could have the code for all pixel matrix variants - but the run-time config. value determines what is used.

@mrcodetastic mrcodetastic added the panel specific issue A HUB75 panel that isn't supported out-of-the-box. Fiddling required. Not a DMA library issue. label Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
panel specific issue A HUB75 panel that isn't supported out-of-the-box. Fiddling required. Not a DMA library issue.
Projects
None yet
Development

No branches or pull requests

3 participants