P8 40x20 1/5S
mjmokhtar opened this issue · 9 comments
I have a panel led p8 40x20 with scan 1/5
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
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;
}
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
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;
}
video3.mp4
here is result
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;
}
video4.mp4
finally
thank you so much
can you teach me how to know how to manipulate the coordinates of led?
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);
}
}
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;
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.