Integrate 1/8 Scan Panel logic into VirtualMatrixPanel class
This commit is contained in:
parent
239de3a5eb
commit
229b0d874c
3 changed files with 79 additions and 93 deletions
|
@ -34,7 +34,8 @@ struct VirtualCoords {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PANEL_SCAN_RATE {NORMAL_ONE_SIXTEEN, ONE_EIGHT};
|
||||||
|
|
||||||
#ifdef USE_GFX_ROOT
|
#ifdef USE_GFX_ROOT
|
||||||
class VirtualMatrixPanel : public GFX
|
class VirtualMatrixPanel : public GFX
|
||||||
#elif !defined NO_GFX
|
#elif !defined NO_GFX
|
||||||
|
@ -107,6 +108,8 @@ class VirtualMatrixPanel
|
||||||
void flipDMABuffer() { display->flipDMABuffer(); }
|
void flipDMABuffer() { display->flipDMABuffer(); }
|
||||||
void drawDisplayTest();
|
void drawDisplayTest();
|
||||||
void setRotate(bool rotate);
|
void setRotate(bool rotate);
|
||||||
|
|
||||||
|
void setPhysicalPanelScanRate(PANEL_SCAN_RATE rate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -116,6 +119,8 @@ class VirtualMatrixPanel
|
||||||
bool _s_chain_party = true; // Are we chained? Ain't no party like a...
|
bool _s_chain_party = true; // Are we chained? Ain't no party like a...
|
||||||
bool _chain_top_down = false; // is the ESP at the top or bottom of the matrix of devices?
|
bool _chain_top_down = false; // is the ESP at the top or bottom of the matrix of devices?
|
||||||
bool _rotate = false;
|
bool _rotate = false;
|
||||||
|
|
||||||
|
PANEL_SCAN_RATE _panelScanRate = NORMAL_ONE_SIXTEEN;
|
||||||
|
|
||||||
}; // end Class header
|
}; // end Class header
|
||||||
|
|
||||||
|
@ -179,6 +184,47 @@ inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t &x, int16_t &y) {
|
||||||
coords.x = (dmaResX - 1) - coords.x;
|
coords.x = (dmaResX - 1) - coords.x;
|
||||||
coords.y = (panelResY-1) - coords.y;
|
coords.y = (panelResY-1) - coords.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* START: Pixel remapping AGAIN to convert 1/16 SCAN output that the
|
||||||
|
* the underlying hardware library is designed for (because
|
||||||
|
* there's only 2 x RGB pins... and convert this to 1/8 or something
|
||||||
|
*/
|
||||||
|
if ( _panelScanRate == ONE_EIGHT)
|
||||||
|
{
|
||||||
|
/* 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 One_Eight_1_8_ScanPanel code and you'll see that the DMA buffer is setup
|
||||||
|
as if the panel is 2 * W and 0.5 * H !
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print("VirtualMatrixPanel Mapping ("); Serial.print(x, DEC); Serial.print(","); Serial.print(y, DEC); Serial.print(") ");
|
||||||
|
// to
|
||||||
|
Serial.print("to ("); Serial.print(coords.x, DEC); Serial.print(","); Serial.print(coords.y, DEC); Serial.println(") ");
|
||||||
|
*/
|
||||||
|
if ( (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 = (y >> 4)*8 + (y & 0b00000111);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print("OneEightScanPanel Mapping ("); Serial.print(x, DEC); Serial.print(","); Serial.print(y, DEC); Serial.print(") ");
|
||||||
|
// to
|
||||||
|
Serial.print("to ("); Serial.print(coords.x, DEC); Serial.print(","); Serial.print(coords.y, DEC); Serial.println(") ");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Serial.print("Mapping to x: "); Serial.print(coords.x, DEC); Serial.print(", y: "); Serial.println(coords.y, DEC);
|
//Serial.print("Mapping to x: "); Serial.print(coords.x, DEC); Serial.print(", y: "); Serial.println(coords.y, DEC);
|
||||||
return coords;
|
return coords;
|
||||||
|
@ -205,6 +251,11 @@ inline void VirtualMatrixPanel::setRotate(bool rotate) {
|
||||||
if (rotate) { setRotation(1); } else { setRotation(0); }
|
if (rotate) { setRotation(1); } else { setRotation(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void VirtualMatrixPanel::setPhysicalPanelScanRate(PANEL_SCAN_RATE rate) {
|
||||||
|
_panelScanRate=rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_GFX
|
#ifndef NO_GFX
|
||||||
inline void VirtualMatrixPanel::drawDisplayTest()
|
inline void VirtualMatrixPanel::drawDisplayTest()
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
#ifndef _ESP32_ONE_EIGHT_SCAN_PANEL
|
|
||||||
#define _ESP32_ONE_EIGHT_SCAN_PANEL
|
|
||||||
|
|
||||||
#include <ESP32-VirtualMatrixPanel-I2S-DMA.h>
|
|
||||||
|
|
||||||
/* This class inherits all the goodness of the VirtualMatrixPanel class used to created
|
|
||||||
large displays of chained panels, but does trickery to convert from 1/16 to 1/8
|
|
||||||
DMA output.
|
|
||||||
|
|
||||||
Some guidance given by looking at hzeller's code, in relation to the 'stretch factor'
|
|
||||||
concept where these panels are really double width and half the height, from the perspective
|
|
||||||
of the digital input required to get the 'real world' resolution and output.
|
|
||||||
https://github.com/hzeller/rpi-rgb-led-matrix/blob/master/lib/multiplex-mappers.cc
|
|
||||||
*/
|
|
||||||
class OneEightScanPanel : public VirtualMatrixPanel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using VirtualMatrixPanel::VirtualMatrixPanel; // inherit VirtualMatrixPanel's constructor(s)
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/* 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 One_Eight_1_8_ScanPanel code and you'll see that the DMA buffer is setup
|
|
||||||
as if the panel is 2 * W and 0.5 * H !
|
|
||||||
*/
|
|
||||||
VirtualCoords getCoords(int16_t &x, int16_t &y);
|
|
||||||
|
|
||||||
}; // end class header note the ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline VirtualCoords OneEightScanPanel::getCoords(int16_t &x, int16_t &y) {
|
|
||||||
VirtualMatrixPanel::getCoords(x, y); // call to base 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Serial.print("VirtualMatrixPanel Mapping ("); Serial.print(x, DEC); Serial.print(","); Serial.print(y, DEC); Serial.print(") ");
|
|
||||||
// to
|
|
||||||
Serial.print("to ("); Serial.print(coords.x, DEC); Serial.print(","); Serial.print(coords.y, DEC); Serial.println(") ");
|
|
||||||
*/
|
|
||||||
if ( (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 = (y >> 4)*8 + (y & 0b00000111);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Serial.print("OneEightScanPanel Mapping ("); Serial.print(x, DEC); Serial.print(","); Serial.print(y, DEC); Serial.print(") ");
|
|
||||||
// to
|
|
||||||
Serial.print("to ("); Serial.print(coords.x, DEC); Serial.print(","); Serial.print(coords.y, DEC); Serial.println(") ");
|
|
||||||
*/
|
|
||||||
|
|
||||||
return coords;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -15,8 +15,10 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
|
#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
|
||||||
|
|
||||||
// Virtual Display to re-map co-ordinates such that they draw correctly on a 32x16 1/4 Scan panel
|
/* Use the Virtual Display class to re-map co-ordinates such that they draw
|
||||||
#include "1_8_ScanPanel.h"
|
* correctly on a 32x16 1/8 Scan panel (or chain of such panels).
|
||||||
|
*/
|
||||||
|
#include "ESP32-VirtualMatrixPanel-I2S-DMA.h"
|
||||||
|
|
||||||
|
|
||||||
// Panel configuration
|
// Panel configuration
|
||||||
|
@ -37,7 +39,7 @@
|
||||||
MatrixPanel_I2S_DMA *dma_display = nullptr;
|
MatrixPanel_I2S_DMA *dma_display = nullptr;
|
||||||
|
|
||||||
// placeholder for the virtual display object
|
// placeholder for the virtual display object
|
||||||
OneEightScanPanel *OneEightMatrixDisplay = nullptr;
|
VirtualMatrixPanel *OneEightMatrixDisplay = nullptr;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Setup!
|
* Setup!
|
||||||
|
@ -54,41 +56,43 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// 62x32 1/8 Scan Panels don't have a D and E pin!
|
// 62x32 1/8 Scan Panels don't have a D and E pin!
|
||||||
|
|
||||||
HUB75_I2S_CFG::i2s_pins _pins = {
|
HUB75_I2S_CFG::i2s_pins _pins = {
|
||||||
R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN,
|
R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN,
|
||||||
A_PIN, B_PIN, C_PIN, D_PIN, E_PIN,
|
A_PIN, B_PIN, C_PIN, D_PIN, E_PIN,
|
||||||
LAT_PIN, OE_PIN, CLK_PIN
|
LAT_PIN, OE_PIN, CLK_PIN
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
HUB75_I2S_CFG mxconfig(
|
HUB75_I2S_CFG mxconfig(
|
||||||
PANEL_RES_X*2, // DO NOT CHANGE THIS
|
PANEL_RES_X*2, // DO NOT CHANGE THIS
|
||||||
PANEL_RES_Y/2, // DO NOT CHANGE THIS
|
PANEL_RES_Y/2, // DO NOT CHANGE THIS
|
||||||
NUM_ROWS*NUM_COLS // DO NOT CHANGE THIS
|
NUM_ROWS*NUM_COLS // DO NOT CHANGE THIS
|
||||||
//,_pins // Uncomment to enable custom pins
|
//,_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.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
|
//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
|
// OK, now we can create our matrix object
|
||||||
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
|
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
|
||||||
|
|
||||||
// let's adjust default brightness to about 75%
|
// let's adjust default brightness to about 75%
|
||||||
dma_display->setBrightness8(96); // range is 0-255, 0 - 0%, 255 - 100%
|
dma_display->setBrightness8(96); // range is 0-255, 0 - 0%, 255 - 100%
|
||||||
|
|
||||||
// Allocate memory and start DMA display
|
// Allocate memory and start DMA display
|
||||||
if( not dma_display->begin() )
|
if( not dma_display->begin() )
|
||||||
Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
|
Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
|
||||||
|
|
||||||
|
|
||||||
dma_display->clearScreen();
|
dma_display->clearScreen();
|
||||||
delay(500);
|
delay(500);
|
||||||
|
|
||||||
// create OneEightMatrixDisplaylay object based on our newly created dma_display object
|
// create OneEightMatrixDisplaylay object based on our newly created dma_display object
|
||||||
OneEightMatrixDisplay = new OneEightScanPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, SERPENT, TOPDOWN);
|
OneEightMatrixDisplay = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, SERPENT, TOPDOWN);
|
||||||
|
|
||||||
|
// THE IMPORTANT BIT BELOW!
|
||||||
|
OneEightMatrixDisplay->setPhysicalPanelScanRate(ONE_EIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue