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
|
#ifdef USE_GFX_ROOT
|
||||||
class VirtualMatrixPanel : public GFX
|
class VirtualMatrixPanel : public GFX
|
||||||
|
@ -108,6 +109,8 @@ class VirtualMatrixPanel
|
||||||
void drawDisplayTest();
|
void drawDisplayTest();
|
||||||
void setRotate(bool rotate);
|
void setRotate(bool rotate);
|
||||||
|
|
||||||
|
void setPhysicalPanelScanRate(PANEL_SCAN_RATE rate);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual VirtualCoords getCoords(int16_t &x, int16_t &y);
|
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 _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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,6 +185,47 @@ inline VirtualCoords VirtualMatrixPanel::getCoords(int16_t &x, int16_t &y) {
|
||||||
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!
|
||||||
|
@ -87,8 +89,10 @@
|
||||||
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