Merge pull request #85 from mrfaptastic/examples

TestPatterns example updated
This commit is contained in:
mrfaptastic 2021-02-16 20:08:43 +00:00 committed by GitHub
commit 4ee9223394
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 62 deletions

View file

@ -119,22 +119,14 @@ This might save some resources for applications using it's own internal graphics
**NO_FAST_FUNCTIONS** - do not build auxiliary speed-optimized functions. Those are used to speed-up operations like drawing straight lines or rectangles. Otherwise lines/shapes are drawn using drawPixel() method. The trade-off for speed is RAM/code-size, take it or leave it ;) **NO_FAST_FUNCTIONS** - do not build auxiliary speed-optimized functions. Those are used to speed-up operations like drawing straight lines or rectangles. Otherwise lines/shapes are drawn using drawPixel() method. The trade-off for speed is RAM/code-size, take it or leave it ;)
**PIXEL_COLOR_DEPTH_BITS** - define color depth in range 2-8 (8 is the default, 24 bpp). Reducing color depth also reduces amount of RAM required for DMA buffer at the expence of a little degradation in color quality.
## Can I use with a larger panel (i.e. 64x64px square panel)? ## Can I use with a larger panel (i.e. 64x64px square panel)?
If you want to use with a 64x64 pixel panel (typically a HUB75*E* panel) you MUST configure a valid *E_PIN* to your ESP32 and connect it to the E pin of the HUB75 panel! Hence the 'E' in 'HUB75E' If you want to use with a 64x64 pixel panel (typically a HUB75*E* panel) you MUST configure a valid *E_PIN* to your ESP32 and connect it to the E pin of the HUB75 panel! Hence the 'E' in 'HUB75E'
## Can I chain panels? ## Can I chained panels?
Yes. Yes. Refer to the [Chained Panels](examples/ChainedPanels/) example on how to configure panels chaining and orientation.
For example: If you want to chain two of these horizontally to make a 128x32 panel you can do so by setting the MATRIX_WIDTH to '128' and connecting the panels in series using the HUB75 ribbon cable.
Similarly, if you wanted to chain 4 panels to make a 256x32 px horizontal panel, you can easily by setting the MATRIX_WIDTH to '256' and connecting the panels in series using the HUB75 ribbon cable.
You MUST either change the MATRIX_WIDTH or MATRIX_HEIGHT values within the 'ESP32-HUB75-MatrixPanel-I2S-DMA.h' file OR pass a [compile time option](https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/48#issuecomment-749402379) if using PlatformIO for your development (you should use this).
Finally, if you wanted to chain 4 x (64x32px) panels to make 128x64px display (essentially a 2x2 grid of 64x32 LED Matrix modules), a little more magic will be required. Refer to the [Chained Panels](examples/ChainedPanels/) example.
Resolutions beyond 128x128 are likely to result in crashes due to memory constraints etc. You're on your own at this point. Resolutions beyond 128x128 are likely to result in crashes due to memory constraints etc. You're on your own at this point.

View file

@ -17,12 +17,12 @@ monitor_filters = esp32_exception_decoder
[env:esp32] [env:esp32]
build_flags = build_flags =
${env.build_flags} ${env.build_flags}
-DUSE_FASTLINES ;-DUSE_FASTLINES
-DNO_GFX -DNO_GFX
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
; use dev version of the lib ; use dev version of the lib
https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA.git#dev https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA.git
[env:idfarduino] [env:idfarduino]
@ -35,8 +35,8 @@ build_flags =
${env.build_flags} ${env.build_flags}
-DARDUINO=200 -DARDUINO=200
-DESP32 -DESP32
-DUSE_FASTLINES ;-DUSE_FASTLINES
-DNO_GFX -DNO_GFX
lib_deps = lib_deps =
${env.lib_deps} ${env.lib_deps}
https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA.git#dev https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA.git

View file

@ -0,0 +1,18 @@
# Override some defaults to enable Arduino framework
CONFIG_ENABLE_ARDUINO_DEPENDS=y
CONFIG_AUTOSTART_ARDUINO=y
CONFIG_ARDUINO_RUN_CORE1=y
CONFIG_ARDUINO_RUNNING_CORE=1
CONFIG_ARDUINO_EVENT_RUN_CORE1=y
CONFIG_ARDUINO_EVENT_RUNNING_CORE=1
CONFIG_ARDUINO_UDP_RUN_CORE1=y
CONFIG_ARDUINO_UDP_RUNNING_CORE=1
CONFIG_DISABLE_HAL_LOCKS=y
CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y
CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1
CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y
CONFIG_ARDUHAL_PARTITION_SCHEME="default"
CONFIG_AUTOCONNECT_WIFI=y
CONFIG_ARDUINO_SELECTIVE_WiFi=y
CONFIG_MBEDTLS_PSK_MODES=y
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y

View file

@ -1,15 +1,14 @@
// How to use this library with a FM6126 panel, thanks goes to: // How to use this library with a FM6126 panel, thanks goes to:
// https://github.com/hzeller/rpi-rgb-led-matrix/issues/746 // https://github.com/hzeller/rpi-rgb-led-matrix/issues/746
/*
// IDF // IDF
#if defined(IDF_VER)
#include <stdio.h> #include <stdio.h>
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h> #include <freertos/task.h>
#include <driver/gpio.h> #include <driver/gpio.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#endif */
#include <Arduino.h> #include <Arduino.h>
#include "xtensa/core-macros.h" #include "xtensa/core-macros.h"
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h> #include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
@ -26,36 +25,49 @@
// CLK| LAT // CLK| LAT
// OE | GND // OE | GND
/* Default library pin configuration for the reference
you can redefine only ones you need later on object creation
#define R1 25 #define R1 25
#define G1 26 #define G1 26
#define BL1 27 #define BL1 27
#define R2 14 // 21 SDA #define R2 14
#define G2 12 // 22 SDL #define G2 12
#define BL2 13 #define BL2 13
#define CH_A 23 #define CH_A 23
#define CH_B 19 #define CH_B 19
#define CH_C 5 #define CH_C 5
#define CH_D 17 #define CH_D 17
#define CH_E 32 // assign to any available pin if using two panels or 64x64 panels with 1/32 scan #define CH_E -1 // assign to any available pin if using panels with 1/32 scan
#define CLK 16 #define CLK 16
#define LAT 4 #define LAT 4
#define OE 15 #define OE 15
*/
// Configure for your panel(s) as appropriate!
#define PANEL_WIDTH 64
#define PANEL_HEIGHT 64 // Panel height of 64 will required PIN_E to be defined.
#define PANELS_NUMBER 2 // Number of chained panels, if just a single panel, obviously set to 1
#define PIN_E 32
#define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER
#define PANE_HEIGHT PANEL_HEIGHT
#define M_WIDTH 256 // patten change delay
#define M_HEIGHT 64
#define PATTERN_DELAY 2000 #define PATTERN_DELAY 2000
#define NUM_LEDS M_WIDTH*M_HEIGHT #define NUM_LEDS PANE_WIDTH*PANE_HEIGHT
// do tests using fast-line methods
#define USE_FASTLINES
//#define USE_FASTLINES
MatrixPanel_I2S_DMA *matrix = nullptr; MatrixPanel_I2S_DMA *matrix = nullptr;
uint16_t time_counter = 0, cycles = 0, fps = 0; uint16_t time_counter = 0, cycles = 0, fps = 0;
unsigned long fps_timer; unsigned long fps_timer;
// // gradient buffer
CRGB *ledbuff; CRGB *ledbuff;
// //
@ -70,19 +82,23 @@ void setup(){
Serial.begin(BAUD_RATE); Serial.begin(BAUD_RATE);
Serial.println("Starting pattern test..."); Serial.println("Starting pattern test...");
HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK}; // redefine pins if required
HUB75_I2S_CFG mxconfig(64, 64, 4, _pins, HUB75_I2S_CFG::FM6126A); //HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK};
mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M; HUB75_I2S_CFG mxconfig(PANEL_WIDTH, PANEL_HEIGHT, PANELS_NUMBER);
mxconfig.gpio.e = PIN_E;
mxconfig.driver = HUB75_I2S_CFG::FM6126A; // for panels using FM6126A chips
matrix = new MatrixPanel_I2S_DMA(mxconfig); matrix = new MatrixPanel_I2S_DMA(mxconfig);
matrix->begin(); matrix->begin();
matrix->setBrightness8(255); matrix->setBrightness8(255);
// longer latch blanking could help to elliminate ghosting in some cases
//matrix->setLatBlanking(2); //matrix->setLatBlanking(2);
ledbuff = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB)); // allocate buffer for some tests ledbuff = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB)); // allocate buffer for some tests
buffclear(ledbuff); buffclear(ledbuff);
} }
@ -100,8 +116,8 @@ void loop(){
/* /*
// Power supply tester // Power supply tester
// slowly fills matrix with white, stressing PSU // slowly fills matrix with white, stressing PSU
for (int y=0; y!=M_HEIGHT; ++y){ for (int y=0; y!=PANE_HEIGHT; ++y){
for (int x=0; x!=M_WIDTH; ++x){ for (int x=0; x!=PANE_WIDTH; ++x){
matrix->drawPixelRGB888(x, y, 255,255,255); matrix->drawPixelRGB888(x, y, 255,255,255);
//matrix->drawPixelRGB888(x, y-1, 255,0,0); // pls, be gentle :) //matrix->drawPixelRGB888(x, y-1, 255,0,0); // pls, be gentle :)
delay(10); delay(10);
@ -154,12 +170,12 @@ void loop(){
Serial.print("Estimating full-screen fillrate with looped drawPixelRGB888(): "); Serial.print("Estimating full-screen fillrate with looped drawPixelRGB888(): ");
y = M_HEIGHT; y = PANE_HEIGHT;
t1 = micros(); t1 = micros();
ccount1 = XTHAL_GET_CCOUNT(); ccount1 = XTHAL_GET_CCOUNT();
do { do {
--y; --y;
uint16_t x = M_WIDTH; uint16_t x = PANE_WIDTH;
do { do {
--x; --x;
matrix->drawPixelRGB888( x, y, 0, 0, 0); matrix->drawPixelRGB888( x, y, 0, 0, 0);
@ -179,8 +195,8 @@ void loop(){
for (uint16_t i = 0; i<NUM_LEDS; ++i){ for (uint16_t i = 0; i<NUM_LEDS; ++i){
ledbuff[i].r=color1++; ledbuff[i].r=color1++;
ledbuff[i].g=color2; ledbuff[i].g=color2;
if (i%M_WIDTH==0) if (i%PANE_WIDTH==0)
color3+=255/M_HEIGHT; color3+=255/PANE_HEIGHT;
ledbuff[i].b=color3; ledbuff[i].b=color3;
} }
@ -202,7 +218,7 @@ void loop(){
// Fillrate for fillRect() function // Fillrate for fillRect() function
Serial.print("Estimating fullscreen fillrate with fillRect() time: "); Serial.print("Estimating fullscreen fillrate with fillRect() time: ");
t1 = micros(); t1 = micros();
matrix->fillRect(0, 0, M_WIDTH, M_HEIGHT, 0, 224, 0); matrix->fillRect(0, 0, PANE_WIDTH, PANE_HEIGHT, 0, 224, 0);
t2 = micros()-t1; t2 = micros()-t1;
Serial.printf("%lu us\n", t2); Serial.printf("%lu us\n", t2);
delay(PATTERN_DELAY); delay(PATTERN_DELAY);
@ -220,11 +236,11 @@ void loop(){
do{ do{
matrix->fillRect(x, y, 8, 8, color1, color2, color3); matrix->fillRect(x, y, 8, 8, color1, color2, color3);
x+=16; x+=16;
}while(x < M_WIDTH); }while(x < PANE_WIDTH);
y+=8; y+=8;
toggle = !toggle; toggle = !toggle;
x = toggle ? 8 : 0; x = toggle ? 8 : 0;
}while(y < M_HEIGHT); }while(y < PANE_HEIGHT);
t2 = micros()-t1; t2 = micros()-t1;
Serial.printf("%lu us\n", t2); Serial.printf("%lu us\n", t2);
delay(PATTERN_DELAY); delay(PATTERN_DELAY);
@ -242,9 +258,9 @@ void loop(){
y=0; y=0;
do{ do{
matrix->drawPixelRGB888(x, y, color1, color2, color3); matrix->drawPixelRGB888(x, y, color1, color2, color3);
} while(++y != M_HEIGHT); } while(++y != PANE_HEIGHT);
x+=2; x+=2;
} while(x != M_WIDTH); } while(x != PANE_WIDTH);
ccount1 = XTHAL_GET_CCOUNT() - ccount1; ccount1 = XTHAL_GET_CCOUNT() - ccount1;
t2 = micros()-t1; t2 = micros()-t1;
Serial.printf("%lu us, %u ticks\n", t2, ccount1); Serial.printf("%lu us, %u ticks\n", t2, ccount1);
@ -258,9 +274,9 @@ void loop(){
t1 = micros(); t1 = micros();
ccount1 = XTHAL_GET_CCOUNT(); ccount1 = XTHAL_GET_CCOUNT();
do { do {
matrix->drawFastVLine(x, y, M_HEIGHT, color1, color2, color3); matrix->drawFastVLine(x, y, PANE_HEIGHT, color1, color2, color3);
x+=2; x+=2;
} while(x != M_WIDTH); } while(x != PANE_WIDTH);
ccount1 = XTHAL_GET_CCOUNT() - ccount1; ccount1 = XTHAL_GET_CCOUNT() - ccount1;
t2 = micros()-t1; t2 = micros()-t1;
Serial.printf("%lu us, %u ticks\n", t2, ccount1); Serial.printf("%lu us, %u ticks\n", t2, ccount1);
@ -274,9 +290,9 @@ void loop(){
t1 = micros(); t1 = micros();
ccount1 = XTHAL_GET_CCOUNT(); ccount1 = XTHAL_GET_CCOUNT();
do { do {
matrix->fillRect(x, y, 1, M_HEIGHT, color1, color2, color3); matrix->fillRect(x, y, 1, PANE_HEIGHT, color1, color2, color3);
x+=2; x+=2;
} while(x != M_WIDTH); } while(x != PANE_WIDTH);
ccount1 = XTHAL_GET_CCOUNT() - ccount1; ccount1 = XTHAL_GET_CCOUNT() - ccount1;
t2 = micros()-t1; t2 = micros()-t1;
Serial.printf("%lu us, %u ticks\n", t2, ccount1); Serial.printf("%lu us, %u ticks\n", t2, ccount1);
@ -296,9 +312,9 @@ void loop(){
x=0; x=0;
do{ do{
matrix->drawPixelRGB888(x, y, color1, color2, color3); matrix->drawPixelRGB888(x, y, color1, color2, color3);
} while(++x != M_WIDTH); } while(++x != PANE_WIDTH);
y+=2; y+=2;
} while(y != M_HEIGHT); } while(y != PANE_HEIGHT);
ccount1 = XTHAL_GET_CCOUNT() - ccount1; ccount1 = XTHAL_GET_CCOUNT() - ccount1;
t2 = micros()-t1; t2 = micros()-t1;
Serial.printf("%lu us, %u ticks\n", t2, ccount1); Serial.printf("%lu us, %u ticks\n", t2, ccount1);
@ -313,9 +329,9 @@ void loop(){
t1 = micros(); t1 = micros();
ccount1 = XTHAL_GET_CCOUNT(); ccount1 = XTHAL_GET_CCOUNT();
do { do {
matrix->drawFastHLine(x, y, M_WIDTH, color1, color2, color3); matrix->drawFastHLine(x, y, PANE_WIDTH, color1, color2, color3);
y+=2; y+=2;
} while(y != M_HEIGHT); } while(y != PANE_HEIGHT);
ccount1 = XTHAL_GET_CCOUNT() - ccount1; ccount1 = XTHAL_GET_CCOUNT() - ccount1;
t2 = micros()-t1; t2 = micros()-t1;
Serial.printf("%lu us, %u ticks\n", t2, ccount1); Serial.printf("%lu us, %u ticks\n", t2, ccount1);
@ -329,9 +345,9 @@ void loop(){
t1 = micros(); t1 = micros();
ccount1 = XTHAL_GET_CCOUNT(); ccount1 = XTHAL_GET_CCOUNT();
do { do {
matrix->fillRect(x, y, M_WIDTH, 1, color1, color2, color3); matrix->fillRect(x, y, PANE_WIDTH, 1, color1, color2, color3);
y+=2; y+=2;
} while(y != M_HEIGHT); } while(y != PANE_HEIGHT);
ccount1 = XTHAL_GET_CCOUNT() - ccount1; ccount1 = XTHAL_GET_CCOUNT() - ccount1;
t2 = micros()-t1; t2 = micros()-t1;
Serial.printf("%lu us, %u ticks\n", t2, ccount1); Serial.printf("%lu us, %u ticks\n", t2, ccount1);
@ -353,13 +369,13 @@ void buffclear(CRGB *buf){
} }
void IRAM_ATTR mxfill(CRGB *leds){ void IRAM_ATTR mxfill(CRGB *leds){
uint16_t y = M_HEIGHT; uint16_t y = PANE_HEIGHT;
do { do {
--y; --y;
uint16_t x = M_WIDTH; uint16_t x = PANE_WIDTH;
do { do {
--x; --x;
uint16_t _pixel = y * M_WIDTH + x; uint16_t _pixel = y * PANE_WIDTH + x;
matrix->drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b); matrix->drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b);
} while(x); } while(x);
} while(y); } while(y);
@ -374,8 +390,8 @@ void IRAM_ATTR mxfill(CRGB *leds){
*/ */
uint16_t XY16( uint16_t x, uint16_t y) uint16_t XY16( uint16_t x, uint16_t y)
{ {
if (x<M_WIDTH && y < M_HEIGHT){ if (x<PANE_WIDTH && y < PANE_HEIGHT){
return (y * M_WIDTH) + x; // everything offset by one to capute out of bounds stuff - never displayed by ShowFrame() return (y * PANE_WIDTH) + x;
} else { } else {
return 0; return 0;
} }