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,6 +34,7 @@ struct VirtualCoords {
|
|||
|
||||
};
|
||||
|
||||
enum PANEL_SCAN_RATE {NORMAL_ONE_SIXTEEN, ONE_EIGHT};
|
||||
|
||||
#ifdef USE_GFX_ROOT
|
||||
class VirtualMatrixPanel : public GFX
|
||||
|
@ -108,6 +109,8 @@ class VirtualMatrixPanel
|
|||
void drawDisplayTest();
|
||||
void setRotate(bool rotate);
|
||||
|
||||
void setPhysicalPanelScanRate(PANEL_SCAN_RATE rate);
|
||||
|
||||
protected:
|
||||
|
||||
virtual VirtualCoords getCoords(int16_t &x, int16_t &y);
|
||||
|
@ -117,6 +120,8 @@ class VirtualMatrixPanel
|
|||
bool _chain_top_down = false; // is the ESP at the top or bottom of the matrix of devices?
|
||||
bool _rotate = false;
|
||||
|
||||
PANEL_SCAN_RATE _panelScanRate = NORMAL_ONE_SIXTEEN;
|
||||
|
||||
}; // end Class header
|
||||
|
||||
/**
|
||||
|
@ -180,6 +185,47 @@ inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t &x, int16_t &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);
|
||||
return coords;
|
||||
}
|
||||
|
@ -205,6 +251,11 @@ inline void VirtualMatrixPanel::setRotate(bool rotate) {
|
|||
if (rotate) { setRotation(1); } else { setRotation(0); }
|
||||
}
|
||||
|
||||
inline void VirtualMatrixPanel::setPhysicalPanelScanRate(PANEL_SCAN_RATE rate) {
|
||||
_panelScanRate=rate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef NO_GFX
|
||||
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"
|
||||
|
||||
// Virtual Display to re-map co-ordinates such that they draw correctly on a 32x16 1/4 Scan panel
|
||||
#include "1_8_ScanPanel.h"
|
||||
/* Use the Virtual Display class to re-map co-ordinates such that they draw
|
||||
* correctly on a 32x16 1/8 Scan panel (or chain of such panels).
|
||||
*/
|
||||
#include "ESP32-VirtualMatrixPanel-I2S-DMA.h"
|
||||
|
||||
|
||||
// Panel configuration
|
||||
|
@ -37,7 +39,7 @@
|
|||
MatrixPanel_I2S_DMA *dma_display = nullptr;
|
||||
|
||||
// placeholder for the virtual display object
|
||||
OneEightScanPanel *OneEightMatrixDisplay = nullptr;
|
||||
VirtualMatrixPanel *OneEightMatrixDisplay = nullptr;
|
||||
|
||||
/******************************************************************************
|
||||
* Setup!
|
||||
|
@ -55,40 +57,42 @@
|
|||
/*
|
||||
// 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,
|
||||
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
|
||||
);
|
||||
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
|
||||
//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);
|
||||
// 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%
|
||||
// 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 ***********");
|
||||
// Allocate memory and start DMA display
|
||||
if( not dma_display->begin() )
|
||||
Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
|
||||
|
||||
|
||||
dma_display->clearScreen();
|
||||
delay(500);
|
||||
|
||||
// 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);
|
||||
// create OneEightMatrixDisplaylay object based on our newly created dma_display object
|
||||
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