This commit is contained in:
mrfaptastic 2022-10-06 23:51:25 +01:00
parent 8b2e31b1c5
commit 157077ab33
7 changed files with 3 additions and 914 deletions

View file

@ -100,9 +100,9 @@ void setup() {
PANEL_CHAIN // Chain length
);
mxconfig.gpio.e = 18;
mxconfig.clkphase = false;
mxconfig.driver = HUB75_I2S_CFG::FM6126A;
//mxconfig.gpio.e = 18;
//mxconfig.clkphase = false;
//mxconfig.driver = HUB75_I2S_CFG::FM6126A;
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);

View file

@ -1,102 +0,0 @@
// How to use this library with a FM6126 panel, thanks goes to:
// https://github.com/hzeller/rpi-rgb-led-matrix/issues/746
#include <Arduino.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#include <FastLED.h>
////////////////////////////////////////////////////////////////////
// FM6126 support is still experimental
// Output resolution and panel chain length 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 PANEL_CHAIN 1 // Total number of panels chained one to another
// placeholder for the matrix object
MatrixPanel_I2S_DMA *dma_display = nullptr;
///////////////////////////////////////////////////////////////
// FastLED variables for pattern output
uint16_t time_counter = 0, cycles = 0, fps = 0;
unsigned long fps_timer;
CRGB currentColor;
CRGBPalette16 palettes[] = {HeatColors_p, LavaColors_p, RainbowColors_p, RainbowStripeColors_p, CloudColors_p};
CRGBPalette16 currentPalette = palettes[0];
CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) {
return ColorFromPalette(currentPalette, index, brightness, blendType);
}
void setup(){
/*
The configuration for MatrixPanel_I2S_DMA object is held in HUB75_I2S_CFG structure,
All options has it's predefined default values. So we can create a new structure and redefine only the options we need
Please refer to the '2_PatternPlasma.ino' example for detailed example of how to use the MatrixPanel_I2S_DMA configuration
if you need to change the pin mappings etc.
*/
HUB75_I2S_CFG mxconfig(
PANEL_RES_X, // module width
PANEL_RES_Y, // module height
PANEL_CHAIN // Chain length
);
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);
// If you experience ghosting, you will need to reduce the brightness level, not all RGB Matrix
// Panels are the same - some seem to display ghosting artefacts at lower brightness levels.
// In the setup() function do something like:
// let's adjust default brightness to about 75%
dma_display->setBrightness8(192); // range is 0-255, 0 - 0%, 255 - 100%
// Allocate memory and start DMA display
if( not dma_display->begin() )
Serial.println("****** !KABOOM! Insufficient memory - allocation failed ***********");
fps_timer = millis();
}
void loop(){
for (int x = 0; x < dma_display->width(); x++) {
for (int y = 0; y < dma_display->height(); y++) {
int16_t v = 0;
uint8_t wibble = sin8(time_counter);
v += sin16(x * wibble * 3 + time_counter);
v += cos16(y * (128 - wibble) + time_counter);
v += sin16(y * x * cos8(-time_counter) / 8);
currentColor = ColorFromPalette(currentPalette, (v >> 8) + 127); //, brightness, currentBlendType);
dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
}
}
++time_counter;
++cycles;
++fps;
if (cycles >= 1024) {
time_counter = 0;
cycles = 0;
currentPalette = palettes[random(0,sizeof(palettes)/sizeof(palettes[0]))];
}
// print FPS rate every 5 seconds
// Note: this is NOT a matrix refresh rate, it's the number of data frames being drawn to the DMA buffer per second
if (fps_timer + 5000 < millis()){
Serial.printf_P(PSTR("Effect fps: %d\n"), fps/5);
fps_timer = millis();
fps = 0;
}
}

View file

@ -1,51 +0,0 @@
## The mystery of control registers for FM6126A chips
The only available Datasheet for this chips is in Chinese and does not shed a light on what those two control regs are.
An excellent insight could be found here https://github.com/hzeller/rpi-rgb-led-matrix/issues/746#issuecomment-453860510
So there are two regs in this chip - **REG1** and **REG2**,
one could be written with 12 clock pulses (and usually called reg12, dunno why :))
the other one could be written with 13 clock pulses (and usually called reg13, dunno why :))
I've done some measurements on power consumption while toggling bits of **REG1** and it looks that it could provide a fine grained brightness control over the entire matrix with no need for bitbanging over RGB or EO pins.
There are 6 bits (6 to 11) giving an increased brightness (compared to all-zeroes) and 4 bits (2-5) giving decreased brightness!!!
Still unclear if FM6112A brightness control is internally PWMed or current limited, might require some poking with oscilloscope.
So it seems that the most bright (and hungry for power) value is bool REG1[16] = {0,0,0,0,0, 1,1,1,1,1,1, 0,0,0,0,0}; and not {0,1,1,1,1, 1,1,1,1,1,1, 1,1,1,1,1} as it is usually used.
I'm not sure about bit 1 - it is either not used or I was unable to measure it's influence to brightness/power.
Giving at least 10 bits of hardware brightness control opens pretty nice options for offloading and simplifying matrix output. Should dig into this more deeper.
Here are some of the measurements I've took for 2 64x64 panels filled with white color - reg value and corresponding current drain in amps.
|REG1 |bit value|Current, amps |
|--|--|--|
|REG1| 0111111 00000| >5 amps|
|REG1| 0100010 00000| 3.890 amp|
|REG1| 0100000 00000| 3.885 amp|
|REG1| 0011110 00000| 3.640 amp|
|REG1| 0011100 00000| 3.620 amp|
|REG1| 0011000 00000| 3.240 amp|
|REG1| 0010010 00000| 2.520 amp|
|REG1| 0010001 00000| 2.518 amp|
|REG1| 0010001 10000| 2.493 amp|
|REG1| 0010000 00000| 2.490 amp|
|REG1| 0010000 11110| 2.214 amp|
|REG1| 0001100 00000| 2.120 amp|
|REG1| 0001000 00000| 1.750 amp|
|REG1| 0000100 00000| 1.375 amp|
|REG1| 0000010 00000| 1.000 amp|
|REG1| **0000000 00000**| 0.995 amp|
|REG1| 0000001 11111| 0.700 amp|
|REG1| 0000000 01111| 0.690 amp|
|REG1| 0000000 10000| 0.690 amp|
|REG1| 0000000 11110| 0.686 amp|
/Vortigont/

View file

@ -1,3 +0,0 @@
## FM6126 based LED Matrix Panel Reset ##
FM6216 panels require a special reset sequence before they can be used, check your panel chipset if you have issues. Refer to this example.

View file

@ -1,451 +0,0 @@
/*
Patch class for 32x16 RGB Matrix panels
reimplement all functions which use x,y coordinates
*/
#ifndef ESP_HUB75_32x16MatrixPanel
#define ESP_HUB75_32x16MatrixPanel
#include "ESP32-HUB75-MatrixPanel-I2S-DMA.h"
#include <Fonts/FreeSansBold12pt7b.h>
#include "glcdfont.c"
struct VirtualCoords {
int16_t x;
int16_t y;
};
#define VP_WIDTH 32
#define VP_HEIGHT 16
#define DEFAULT_FONT_W 5
#define DEFAULT_FONT_H 7
#define PIXEL_SPACE 1 // space between chars in a string
/* --- PRINTF_BYTE_TO_BINARY macro's --- */
#define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
#define PRINTF_BYTE_TO_BINARY_INT8(i) \
(((i) & 0x80ll) ? '1' : '0'), \
(((i) & 0x40ll) ? '1' : '0'), \
(((i) & 0x20ll) ? '1' : '0'), \
(((i) & 0x10ll) ? '1' : '0'), \
(((i) & 0x08ll) ? '1' : '0'), \
(((i) & 0x04ll) ? '1' : '0'), \
(((i) & 0x02ll) ? '1' : '0'), \
(((i) & 0x01ll) ? '1' : '0')
#define PRINTF_BINARY_PATTERN_INT16 \
PRINTF_BINARY_PATTERN_INT8 PRINTF_BINARY_PATTERN_INT8
#define PRINTF_BYTE_TO_BINARY_INT16(i) \
PRINTF_BYTE_TO_BINARY_INT8((i) >> 8), PRINTF_BYTE_TO_BINARY_INT8(i)
/* --- end macros --- */
class QuarterScanMatrixPanel : public Adafruit_GFX
{
public:
MatrixPanel_I2S_DMA *display;
QuarterScanMatrixPanel(MatrixPanel_I2S_DMA &disp) : Adafruit_GFX(64, 32)
{
this->display = &disp;
size_x = size_y = 1 ;
wrap = false;
cursor_x = cursor_y = 0;
dir = 1;
loop = true;
}
VirtualCoords getCoords(int16_t x, int16_t y);
int16_t getVirtualX(int16_t x) {
VirtualCoords coords = getCoords(x, 0);
return coords.x;
}
int16_t getVirtualY(int16_t y) {
VirtualCoords coords = getCoords(0,y);
return coords.y;
}
// int16_t getVirtualY(int16_t y) {return getCoords(0,y).y;}
/** extended function to draw lines/rects/... **/
virtual uint8_t width() {return VP_WIDTH;};
virtual uint8_t height() {return VP_HEIGHT;};
virtual void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
virtual void drawHLine(int16_t x0, int16_t y0, int16_t w, uint16_t color);
virtual void drawVLine(int16_t x0, int16_t y0, int16_t h, uint16_t color);
virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
virtual void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
virtual void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size_x, uint8_t size_y);
virtual void scrollChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint16_t dir, uint16_t speed);
virtual void drawString(int16_t x, int16_t y, unsigned char* c, uint16_t color, uint16_t bg);
virtual size_t write(unsigned char c); // write a character on current cursor position
virtual size_t write(const char *str); // write a character array (string) on current cursor position
virtual void setTextWrap(bool w);
virtual void setCursor (int16_t x, int16_t y);
void setTextFGColor(uint16_t color) {textFGColor = color;};
void setTextBGColor(uint16_t color) {textBGColor = color;};
void setTextSize(uint8_t x, uint8_t y) {size_x = x; size_y = y;}; // magnification, default = 1
void setScrollDir(uint8_t d = 1) { dir = (d != 1) ? 0 : 1;}; // set scroll dir default = 1
void setScroolLoop (bool b = true) { loop = b;} ; // scroll text in a loop, default true
void scrollText(const char *str, uint16_t speed, uint16_t pixels);
/**------------------------------------------**/
// equivalent methods of the matrix library so it can be just swapped out.
virtual void drawPixel(int16_t x, int16_t y, uint16_t color);
virtual void fillScreen(uint16_t color); // overwrite adafruit implementation
void clearScreen() { fillScreen(0); }
//void drawPixelRGB565(int16_t x, int16_t y, uint16_t color);
void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b);
//void drawPixelRGB24(int16_t x, int16_t y, RGB24 color);
void drawIcon (int *ico, int16_t x, int16_t y, int16_t module_cols, int16_t module_rows);
uint16_t color444(uint8_t r, uint8_t g, uint8_t b) {
return display->color444(r, g, b);
}
uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
return display->color565(r, g, b);
}
uint16_t color333(uint8_t r, uint8_t g, uint8_t b) {
return display->color333(r, g, b);
}
void flipDMABuffer() { display->flipDMABuffer(); }
void showDMABuffer() { display->showDMABuffer(); }
void drawDisplayTest();
protected:
int16_t cursor_x, cursor_y; // Cursor position
uint8_t size_x, size_y; // Font size Multiplier default = 1 => 5x7 Font (5width,7Height)
uint16_t textFGColor, textBGColor;
bool wrap ; // < If set, 'wrap' text at right edge of display
uint8_t dir ; // used for scrolling text direction
bool loop ; // used for scrolling text in a loop
private:
VirtualCoords coords;
}; // end Class header
/***************************************************************************************
@brief scroll text from right to left or vice versa on current cursor position
please note, this function is not interruptable.
@param *c pointer to \0 terminated string
@param pixels number of pixels to scroll, if 0, than scroll complete text
@param speed velocity of scrolling in ms
***************************************************************************************/
void QuarterScanMatrixPanel::scrollText(const char *str,uint16_t speed, uint16_t pixels = 0) {
// first we put all columns of every char inside str into a big array of lines
// than we move through this array and draw line per line and move this line
// one position to dir
const uint8_t xSize = 6;
uint16_t len = strlen(str);
uint8_t array[len * xSize]; // size of array number of chars * width of char
//uint16_t lenArray = sizeof(array)/sizeof(array[0]);
uint16_t aPtr = 0;
//
// generate array
char c = *str;
// Serial.printf("size *str (%d), size array: (%d) \n", len, lenArray);
while (c) {
// Serial.printf("** %c ** \n", c);
// read font line per line. A line is a column inside a char
for (int8_t i = 0; i < 5; i++) {
uint8_t line = pgm_read_byte(&font[c * 5 + i]);
array[aPtr++] = line;
// Serial.printf("%d - Line " PRINTF_BINARY_PATTERN_INT8 "\n", i, PRINTF_BYTE_TO_BINARY_INT8(line) );
}
str++;
c = *str;
array[aPtr++] = 0x00; // line with 0 (space between chars)
}
array[aPtr++] = 0x00; // line with 0 (space between chars)
/*
Serial.printf("---------------------------- \n");
for (aPtr=0; aPtr < (len*xSize); aPtr++) {
Serial.printf("%d - Line " PRINTF_BINARY_PATTERN_INT8 "\n", aPtr, PRINTF_BYTE_TO_BINARY_INT8(array[aPtr]) );
}
*/
int16_t x,y,lastX, p;
lastX = (dir) ? VP_WIDTH : 0;
x = cursor_x;
y = cursor_y;
Serial.printf("X: %d, Y: %d \n", x,y);
p=0;
pixels = (pixels) ? pixels : len * xSize;
while (p <= pixels) {
// remove last pixel positions
fillRect(x,y,5,7,textBGColor);
// set new pixel position
x = (dir) ? lastX - p : lastX + p - pixels;
// iterator through our array
for (uint8_t i=0; i < (len*xSize); i++) {
uint8_t line = array[i];
//Serial.printf("%d:%d : " PRINTF_BINARY_PATTERN_INT8 "\n", x, i, PRINTF_BYTE_TO_BINARY_INT8(line) );
// read line and shift from right to left
// start with bit 0 (top of char) to 7(bottom)
for (uint8_t j=0; j < 8; j++, line>>=1) {
if (line & 1) {
// got 1, if x + i outside panel ignore pixel
if (x + i >= 0 && x + i < VP_WIDTH) {
drawPixel(x + i, y + j, textFGColor);
}
}
else {
// got 0
if (x + i >= 0 && x + i < VP_WIDTH) {
drawPixel(x + i, y + j, textBGColor);
}
} // if
} // for j
} // for i
p++;
delay(speed);
} // while
}
inline size_t QuarterScanMatrixPanel::write(const char *str) {
uint8_t x, y;
x=cursor_x;
y=cursor_y;
char c = *str;
while (c) {
//Serial.printf("%c ", c);
write(c);
str++;
c = *str;
x = x + ((DEFAULT_FONT_W + PIXEL_SPACE) * size_x);
setCursor(x,y);
}
Serial.printf("\n");
return 1;
}
inline size_t QuarterScanMatrixPanel::write(unsigned char c) {
Serial.printf("\twrite(%d, %d, %c)\n", cursor_x, cursor_y, c);
drawChar(cursor_x, cursor_y, c, textFGColor, textBGColor, size_x, size_y);
return 1;
}
void QuarterScanMatrixPanel::setTextWrap(bool w) {this->display->setTextWrap(w);}
void QuarterScanMatrixPanel::setCursor(int16_t x, int16_t y) {
cursor_x = x;
cursor_y = y;
}
/* - new for 16x32 panels - */
inline void QuarterScanMatrixPanel::drawLine(int16_t x, int16_t y, int16_t x1, int16_t y1, uint16_t color)
{
int16_t a,b;
for (a=x; a <= x1; a++) {
for (b=y; b <= y1; b++) {
drawPixel(a,b,color);
}
}
}
inline void QuarterScanMatrixPanel::drawHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
{
drawLine(x,y,x+w,y, color);
}
inline void QuarterScanMatrixPanel::drawVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
{
drawLine(x,y,x,y+h, color);
}
inline void QuarterScanMatrixPanel::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
{
for (int16_t i = x; i < x + w; i++) {
drawVLine(i, y, h, color);
}
}
void QuarterScanMatrixPanel::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
{
drawChar(x,y,c,color, bg, size, size);
}
inline void QuarterScanMatrixPanel::scrollChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint16_t dir, uint16_t speed){
if ((x >= VP_WIDTH) ||
(y >= VP_HEIGHT) ||
((x + 6 * size_x-1) < 0) ||
((y + 8 * size_y-1) <0))
return;
setTextWrap(true);
// text wrap is only for the right end of the panel, to scroll soft out of the left of panel
// algorithm should wrap the character from left to right
// loop s = scroll-loop, scrolls char 5 pixels into dir
uint8_t lastX = x;
for (int8_t s = 0; s < 6; s++) {
// loop i : width of a character
Serial.printf("X:%d ", x);
// clear current position
fillRect(x,y,5,7,0);
x = lastX - s;
for (int8_t i = 0; i < 5; i++) {
// first line is the first vertical part of a character and 8bits long
// last bit is everytime 0
// we read 5 lines with 8 bit (5x7 char + 8bit with zeros)
// Example : char A (90deg cw)
// 01111100
// 00010010
// 00010001
// 00010010
// 01111100
uint8_t line = pgm_read_byte(&font[c * 5 + i]);
// shift from right to left bit per bit
// loop j = height of a character
// loop through a column of current character
Serial.printf("i:%d ", i);
// ignore all pixels outside panel
if (x+i >= VP_WIDTH) continue;
for (int8_t j=0; j < 8; j++, line >>= 1) {
if (line & 1) {
Serial.printf
(" ON %d", x+i);
// we read 1
if (x >= 0) {
drawPixel(x+i, y+j, color);
}
else if (x+i >= 0) {
drawPixel(x+i, y+j, color);
}
}
else if (bg != color) {
// we read 0
Serial.printf(" OFF %d", x+i);
if (x >= 0) {
drawPixel(x+i, y+j, bg);
}
else if (x+i >= 0) {
drawPixel(x+i, y+j, bg);
}
}
}
}
Serial.printf("\n");
delay(speed);
}
}
inline void QuarterScanMatrixPanel::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size_x, uint8_t size_y)
{
//Serial.printf("unmapped : drawChar(%d, %d, %c) \n",x, y, c);
// note: remapping to 16x32 coordinates is done inside drawPixel() or fillRect
if ((x >= VP_WIDTH) ||
(y >= VP_HEIGHT) ||
((x + 6 * size_x-1) < 0) ||
((y + 8 * size_y-1) <0))
return;
//Serial.printf("Font-Array : %d \n", sizeof(font));
for (int8_t i = 0; i < 5; i++) {
uint8_t line = pgm_read_byte(&font[c * 5 + i]);
//Serial.printf("%d - Line " PRINTF_BINARY_PATTERN_INT8 "\n", i, PRINTF_BYTE_TO_BINARY_INT8(line) );
for (int8_t j = 0; j < 8; j++, line >>= 1) {
if (line & 1) {
if (size_x == 1 && size_y == 1)
//Serial.printf("");
drawPixel(x + i, y + j, color);
else
// remark: it's important to call function with original coordinates for x/y
fillRect(x + i * size_x, y + j * size_y, size_x, size_y,
color);
} else if (bg != color) {
if (size_x == 1 && size_y == 1)
drawPixel(x + i, y + j, bg);
else
// remark: it's important to call function with original coordinates for x/y
fillRect(x + i * size_x, y + j * size_y, size_x, size_y, bg);
}
}
}
}
inline void QuarterScanMatrixPanel::drawString(int16_t x, int16_t y, unsigned char* c, uint16_t color, uint16_t bg) {
}
inline VirtualCoords QuarterScanMatrixPanel::getCoords(int16_t x, int16_t y)
{
const int y_remap[] = { 0,1,8,9,4,5,12,13,16,17,24,25,22,23,30,31 };
if (y > VP_HEIGHT)
y = VP_HEIGHT;
if (x > VP_WIDTH)
x = VP_WIDTH;
coords.x = x + VP_WIDTH;
coords.y = y_remap[y];
return coords;
}
/* -------------------------*/
inline void QuarterScanMatrixPanel::drawPixel(int16_t x, int16_t y, uint16_t color)
{
VirtualCoords coords = getCoords(x, y);
this->display->drawPixel(coords.x, coords.y, color);
}
inline void QuarterScanMatrixPanel::fillScreen(uint16_t color) // adafruit virtual void override
{
// No need to map this.
this->display->fillScreen(color);
}
/*
inline void QuarterScanMatrixPanel::drawPixelRGB565(int16_t x, int16_t y, uint16_t color)
{
VirtualCoords coords = getCoords(x, y);
this->display->drawPixelRGB565( coords.x, coords.y, color);
}
*/
inline void QuarterScanMatrixPanel::drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b)
{
VirtualCoords coords = getCoords(x, y);
this->display->drawPixelRGB888( coords.x, coords.y, r, g, b);
}
/*
inline void QuarterScanMatrixPanel::drawPixelRGB24(int16_t x, int16_t y, RGB24 color)
{
VirtualCoords coords = getCoords(x, y);
this->display->drawPixelRGB24(coords.x, coords.y, color);
}
*/
// need to recreate this one, as it wouldn't work to just map where it starts.
inline void QuarterScanMatrixPanel::drawIcon (int *ico, int16_t x, int16_t y, int16_t module_cols, int16_t module_rows) { }
#endif

View file

@ -1,226 +0,0 @@
/*************************************************************************
* Contributor: https://github.com/mrRobot62
*
* Description:
*
* The underlying implementation of the ESP32-HUB75-MatrixPanel-I2S-DMA only
* supports output to 1/16 or 1/32 scan panels (two scan parallel scan lines)
* this is fixed and cannot be changed.
*
* However, it is possible to connect 1/4 scan panels to this same library and
* 'trick' the output to work correctly on these panels by way of adjusting the
* pixel co-ordinates that are 'sent' to the ESP32-HUB75-MatrixPanel-I2S-DMA
* library (in this example, it is the 'dmaOutput' class).
*
* This is done by way of the 'QuarterScanMatrixPanel.h' class that sends
* adjusted x,y co-ordinates to the underlying ESP32-HUB75-MatrixPanel-I2S-DMA
* library's drawPixel routine.
*
* Refer to the 'getCoords' function within 'QuarterScanMatrixPanel.h'
*
**************************************************************************/
// PLEASE NOTE THIS EXAMPLE NO LONGER WORKS AS OF AUGUST 2021
// IT NEEDS TO BE UPDATED TO THE NEW WAY OF USING THE LIBRARY
// uncomment to use custom pins, then provide below
#define USE_CUSTOM_PINS
/* Pin 1,3,5,7,9,11,13,15 */
#define R1_PIN 25
#define B1_PIN 27
#define R2_PIN 14
#define B2_PIN 13
#define A_PIN 23
#define C_PIN 5
#define CLK_PIN 16
#define OE_PIN 15
/* Pin 2,6,10,12,14 */
#define G1_PIN 26
#define G2_PIN 12
#define B_PIN 19
#define D_PIN 17
#define LAT_PIN 4
#define E_PIN -1 // required for 1/32 scan panels
#include "OneQuarterScanMatrixPanel.h" // Virtual Display to re-map co-ordinates such that they draw correctly on a 32x16 1/4 Scan panel
#include <Wire.h>
/*
* Below is an is the 'legacy' way of initialising the MatrixPanel_I2S_DMA class.
* i.e. MATRIX_WIDTH and MATRIX_HEIGHT are modified by compile-time directives.
* By default the library assumes a single 64x32 pixel panel is connected.
*
* Refer to the example '2_PatternPlasma' on the new / correct way to setup this library
* for different resolutions / panel chain lengths within the sketch 'setup()'.
*
*/
MatrixPanel_I2S_DMA dmaOutput;
// Create virtual 1/2 to 1/4 scan pixel co-ordinate mapping class.
QuarterScanMatrixPanel display(dmaOutput);
#include <FastLED.h>
int time_counter = 0;
int cycles = 0;
CRGBPalette16 currentPalette;
CRGB currentColor;
CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) {
return ColorFromPalette(currentPalette, index, brightness, blendType);
}
typedef struct Matrix {
uint8_t x;
uint8_t y;
} Matrix;
Matrix matrix;
void testSimpleChars(uint16_t timeout) {
/** drawChar() **/
Serial.println("draw chars with drawChar()");
display.fillScreen(display.color444(0,0,0));
uint16_t myFGColor = display.color565(180,0,0);
uint16_t myBGColor = display.color565(0,50,0);
display.fillScreen(display.color444(0,0,0));
display.drawChar(0,0,'X',myFGColor, myFGColor,1);
display.drawChar(16,1,'Y',myFGColor, myBGColor,1);
display.drawChar(3,9,'Z',myFGColor, myFGColor,1);
display.drawChar(16,9,'4',display.color565(0,220,0), myBGColor,1);
delay(timeout);
}
void testSimpleCharString(uint16_t timeout) {
uint8_t x,y,w,h;
w = 6; h=8;
x = 0; y=0;
display.fillScreen(display.color444(0,0,0));
display.setTextFGColor(display.color565(0,60,180));
display.setCursor(x,y); display.write('L');
display.setCursor(x+w,y); display.write('u');
display.setCursor(x+(2*w),y); display.write('n');
display.setCursor(x+(3*w),y); display.write('a');
display.setTextFGColor(display.color565(180,60,140));
display.setCursor(x+(4*w),y); display.write('X');
delay(timeout);
}
void testTextString(uint16_t timeout) {
display.fillScreen(display.color444(0,0,0));
display.setTextFGColor(display.color565(0,60,255));
display.setCursor(0,5);
display.write("HURRA");
delay(timeout);
}
void testWrapChar(const char c, uint16_t speed, uint16_t timeout) {
display.setTextWrap(true);
for (uint8_t i = 32; i > 0; i--) {
display.fillScreen(display.color444(0,0,0));
display.setCursor(i, 5);
display.write(c);
delay(speed);
}
delay(timeout);
}
void testScrollingChar(const char c, uint16_t speed, uint16_t timeout) {
Serial.println("Scrolling Char");
uint16_t myFGColor = display.color565(180,0,0);
uint16_t myBGColor = display.color565(60,120,0);
display.fillScreen(display.color444(0,0,0));
display.setTextWrap(true);
// from right to left with wrap
display.scrollChar(31,5,c, myFGColor, myFGColor, 1, speed);
// left out with wrap
delay(500);
display.scrollChar(0,5,c, myBGColor, myBGColor, 1, speed);
delay(timeout);
}
void testScrollingText(const char *str, uint16_t speed, uint16_t timeout) {
Serial.println("Scrolling Text as loop");
// pre config
uint16_t red = display.color565(255,0,100);
uint16_t blue100 = display.color565(0,0,100);
uint16_t black = display.color565(0,0,0);
uint16_t green = display.color565(0,255,0);
uint16_t green150 = display.color565(0,150,0);
display.fillScreen(display.color565(0,0,0));
display.setCursor(31,5);
display.setScrollDir(1);
/** black background **/
display.setTextFGColor(green150);
display.scrollText("** Welcome **", speed);
display.fillScreen(black);
delay(timeout / 2) ;
/** scrolling with colored background */
display.fillRect(0,4,VP_WIDTH,8,blue100);
// scrolling, using default pixels size = length of string (not used parameter pixels)
display.setTextFGColor(red);
display.setTextBGColor(blue100);
display.scrollText(str, speed);
delay(timeout / 2) ;
// same as above but now from left to right
display.setScrollDir(0);
display.setTextFGColor(blue100);
display.setTextBGColor(red);
display.fillRect(0,4,VP_WIDTH,8,red);
display.scrollText(str, speed, 0);
delay(timeout);
display.fillScreen(black);
display.setTextFGColor(red);
}
void setup() {
Serial.begin(115200);
delay(500);
Serial.println("*****************************************************");
Serial.println(" dmaOutput 32x16 !");
Serial.println("*****************************************************");
#ifdef USE_CUSTOM_PINS
dmaOutput.begin(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 ); // setup the LED matrix
#else
display.begin(true); // init buffers
#endif
// fill the screen with 'black'
display.fillScreen(display.color444(0, 0, 0));
// Set current FastLED palette
currentPalette = RainbowColors_p;
// display.fillScreen(display.color565(0, 0, 0));
}
void loop() {
display.fillScreen(display.color444(0, 0, 0));
//testSimpleChars(1500);
//testSimpleCharString (1500);
testTextString(2000);
// length = 16 bytes without \0
//testWrapChar('A', 250, 1500);
//testScrollingChar('X', 250, 2000);
testScrollingText("Scrolling 16x32", 100, 2000);
} // end loop

View file

@ -1,78 +0,0 @@
# Using this library with 32x16 1/4 Scan Panels
## Problem
ESP32-HUB75-MatrixPanel-I2S-DMA library will not display output correctly with 1/4 scan panels such [as this](https://de.aliexpress.com/item/33017477904.html?spm=a2g0o.detail.1000023.16.1fedd556Yw52Zi&algo_pvid=4329f1c0-04d2-43d9-bdfd-7d4ee95e6b40&algo_expid=4329f1c0-04d2-43d9-bdfd-7d4ee95e6b40-52&btsid=9a8bf2b5-334b-45ea-a849-063d7461362e&ws_ab_test=searchweb0_0,searchweb201602_10,searchweb201603_60%5BAliExpress%2016x32%5D).
## Solution
It is possible to connect 1/4 scan panels to this library and 'trick' the output to work correctly on these panels by way of adjusting the pixel co-ordinates that are 'sent' to the ESP32-HUB75-MatrixPanel-I2S-DMA library (in this example, it is the 'dmaOutput' class).
Creation of a 'QuarterScanMatrixPanel.h' class which sends an adjusted x,y co-ordinates to the underlying ESP32-HUB75-MatrixPanel-I2S-DMA library's drawPixel routine, to trick the output to look pixel perfect. Refer to the 'getCoords' function within 'QuarterScanMatrixPanel.h'
## Limitations
* Only one font (glcd - standard font) is implemented. This font can't be resized.
## New functions (and adapted function) in this QuarterScanMatrixPanel class
### drawLine
`void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)`
Parameters should be self explained. x0/y0 upper left corner, x1/y1 lower right corner
### drawHLine
`void drawHLine(int16_t x0, int16_t y0, int16_t w, uint16_t color)`
Draw a fast horizontal line with length `w`. Starting at `x0/y0`
### drawVLine
`void drawVLine(int16_t x0, int16_t y0, int16_t h, uint16_t color)`
Draw a fast vertical line with length `h` Starting at `x0/y0`
### fillRect
`void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)`
Draw a rectangle starting at `x/y` with width `w` and height `h`in `color`
### drawChar (5x7) Standard font
`drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)`
Draw a char at position x/y in `color` with a background color `bg`
`size` is ignored.
### writeChar (5x7)
`size_t write(unsigned char c)`
Write a char at current cursor position with current foreground and background color.
### writeString (5x7)
`size_t write(const char *c)`
Write a string at current cursor position with current foreground and background color.
You have to use `setCursor(x,y)` and `setTextFGColor() / setTextBGColor()`
### drawString (5x7)
`void drawString(int16_t x, int16_t y, unsigned char* c, uint16_t color, uint16_t bg)`
Draw String at position x/y wit foreground `color` and background `bg`
Example: `display.drawString(0,5,"**Welcome**",display.color565(0,60,255));`
### void setScrollDir(uint8_t d = 1)
Set scrolling direction 0=left to right, 1= right to left (default)
### scrollText
`void scrollText(const char *str, uint16_t speed, uint16_t pixels)`
Scroll text `str` into `setScrollDir`. Speed indicates how fast in ms per pixel, pixels are the number pixes which should be scrolled, if not set or 0, than pixels is calculates by size of `*str`
### drawPixel(int16_t x, int16_t y, uint16_t color)
Draw a pixel at x/y in `color`. This function is the atomic function for all above drawing functions
### clearScreen() (all pixels off (black))
Same as `fillScreen(0)`
## Example videos:
https://user-images.githubusercontent.com/949032/104838449-4aae5600-58bb-11eb-802f-a358b49a9315.mp4
https://user-images.githubusercontent.com/949032/104366906-5647f880-551a-11eb-9792-a6f8276629e6.mp4