aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authormrfaptastic <12006953+mrfaptastic@users.noreply.github.com>2021-02-10 15:49:19 +0000
committermrfaptastic <12006953+mrfaptastic@users.noreply.github.com>2021-02-10 15:49:19 +0000
commit0749fa41932cc163a46801c1c1d6d2a309e8f273 (patch)
tree396fd65acebf24c2335399039819485dc930ead1 /examples
parent6ea2280ff3af21828974832402270ce54e52c5cc (diff)
Update to 2.0.0
Also known as the @vortigont release! Hooray!
Diffstat (limited to 'examples')
-rw-r--r--examples/1_SimpleTestShapes/1_SimpleTestShapes.ino (renamed from examples/testshapes_32x64/testshapes_32x64.ino)42
-rw-r--r--examples/2_PatternPlasma/2_PatternPlasma.ino207
-rw-r--r--examples/2_PatternPlasma/PatternWave.jpg (renamed from examples/PatternPlasma/PatternWave.jpg)bin34981 -> 34981 bytes
-rw-r--r--examples/2_PatternPlasma/README.md (renamed from examples/PatternPlasma/README.md)0
-rw-r--r--examples/3_FM6126Panel/3_FM6126Panel.ino (renamed from examples/FM6126Panel/FM6126Panel.ino)94
-rw-r--r--examples/3_FM6126Panel/FM6126A.md51
-rw-r--r--examples/3_FM6126Panel/README.md (renamed from examples/FM6126Panel/README.md)0
-rw-r--r--examples/AnimatedGIFPanel/AnimatedGIFPanel.ino11
-rw-r--r--examples/AuroraDemo/AuroraDemo.ino10
-rw-r--r--examples/BitmapIcons/BitmapIcons.ino10
-rw-r--r--examples/ChainedPanels/ChainedPanels.ino110
-rw-r--r--examples/ChainedPanels/README.md38
-rw-r--r--examples/ChainedPanels/VirtualDisplay.pdfbin603859 -> 0 bytes
-rw-r--r--examples/ChainedPanels/VirtualMatrixPanel.odpbin0 -> 118304 bytes
-rw-r--r--examples/ChainedPanels/VirtualMatrixPanel.pdfbin0 -> 584700 bytes
-rw-r--r--examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino117
-rw-r--r--examples/ChainedPanelsAuroraDemo/Drawable.h2
-rw-r--r--examples/ChainedPanelsAuroraDemo/Effects.h5
-rw-r--r--examples/ChainedPanelsAuroraDemo/PatternInvaders.h16
-rw-r--r--examples/ChainedPanelsAuroraDemo/PatternTest.h2
-rw-r--r--examples/DoubleBufferSwap/DoubleBufferSwap.ino10
-rw-r--r--examples/GraphicsLayer/GraphicsLayer.ino12
-rw-r--r--examples/P6_32x16_1_4_ScanPanel/P6_32x16_1_4_ScanPanel.ino223
-rw-r--r--examples/P6_32x16_1_4_ScanPanel/QuarterScanMatrixPanel.h449
-rw-r--r--examples/P6_32x16_1_4_ScanPanel/README.md78
-rw-r--r--examples/PIO_TestPatterns/README.md16
-rw-r--r--examples/PIO_TestPatterns/platformio.ini42
-rw-r--r--examples/PIO_TestPatterns/src/CMakeLists.txt6
-rw-r--r--examples/PIO_TestPatterns/src/main.cpp382
-rw-r--r--examples/PIO_TestPatterns/src/main.h8
-rw-r--r--examples/PatternPlasma/PatternPlasma.ino109
-rw-r--r--examples/README.md14
32 files changed, 1731 insertions, 333 deletions
diff --git a/examples/testshapes_32x64/testshapes_32x64.ino b/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino
index e3746fe..80f2236 100644
--- a/examples/testshapes_32x64/testshapes_32x64.ino
+++ b/examples/1_SimpleTestShapes/1_SimpleTestShapes.ino
@@ -1,9 +1,23 @@
+// Example sketch which shows how to display some patterns
+// on a 64x32 LED matrix
+//
+
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
-MatrixPanel_I2S_DMA dma_display;
-// Or use an Alternative non-DMA library, i.e:
-//#include <P3RGB64x32MatrixPanel.h>
-//P3RGB64x32MatrixPanel display;
+/*
+ * Below is an example of the 'legacy' way of initialising the MatrixPanel_I2S_DMA class.
+ * i.e. Matrix Width and Height will need to be confirmed as 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.
+ *
+ */
+ MatrixPanel_I2S_DMA dma_display;
+
+ // Or use an Alternative non-DMA library, i.e:
+ //#include <P3RGB64x32MatrixPanel.h>
+ //P3RGB64x32MatrixPanel display;
void setup() {
@@ -94,26 +108,6 @@ void setup() {
dma_display.setTextColor(dma_display.color444(15,0,8));
dma_display.println("*");
- delay(2000);
-/*
- for (int i = 15; i > 0; i--)
- {
- // fade out
- dma_display.fillScreen(dma_display.color565(0, 0, i*17));
- delay(250);
- }
-
- for (int i = 15; i > 0; i--)
- {
- // draw a blue circle
- dma_display.drawCircle(10, 10, 10, dma_display.color565(i*17, 0, 0));
- delay(250);
- }
-*/
-
-
-
- // whew!
}
void loop() {
diff --git a/examples/2_PatternPlasma/2_PatternPlasma.ino b/examples/2_PatternPlasma/2_PatternPlasma.ino
new file mode 100644
index 0000000..b7bc791
--- /dev/null
+++ b/examples/2_PatternPlasma/2_PatternPlasma.ino
@@ -0,0 +1,207 @@
+/*
+ * Portions of this code are adapted from Aurora: https://github.com/pixelmatix/aurora
+ * Copyright (c) 2014 Jason Coon
+ *
+ * Portions of this code are adapted from LedEffects Plasma by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Plasma.cpp?at=default
+ * Copyright (c) 2013 Robert Atkins
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+// HUB75E pinout
+// R1 | G1
+// B1 | GND
+// R2 | G2
+// B2 | E
+// A | B
+// C | D
+// CLK| LAT
+// OE | GND
+
+/* Default library pin configuration for the reference
+ you can redefine only ones you need later on object creation
+
+#define R1 25
+#define G1 26
+#define BL1 27
+#define R2 14
+#define G2 12
+#define BL2 13
+#define CH_A 23
+#define CH_B 19
+#define CH_C 5
+#define CH_D 17
+#define CH_E -1 // assign to any available pin if using two panels or 64x64 panels with 1/32 scan
+#define CLK 16
+#define LAT 4
+#define OE 15
+
+*/
+
+
+#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
+#include <FastLED.h>
+
+// 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
+
+
+// placeholder for the matrix object
+MatrixPanel_I2S_DMA *dma_display = nullptr;
+
+
+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() {
+
+ Serial.begin(115200);
+
+ Serial.println(F("*****************************************************"));
+ Serial.println(F("* ESP32-HUB75-MatrixPanel-I2S-DMA DEMO *"));
+ Serial.println(F("*****************************************************"));
+
+ /*
+ The configuration for MatrixPanel_I2S_DMA object is held in HUB75_I2S_CFG structure,
+ pls refer to the lib header file for full details.
+ All options has it's predefined default values. So we can create a new structure and redefine only the options we need
+
+ // those are the defaults
+ mxconfig.mx_width = 64; // physical width of a single matrix panel module (in pixels, usually it is always 64 ;) )
+ mxconfig.mx_height = 32; // physical height of a single matrix panel module (in pixels, usually amost always it is either 32 or 64)
+ mxconfig.chain_length = 1; // number of chained panels regardless of the topology, default 1 - a single matrix module
+ mxconfig.gpio.r1 = R1; // pin mappings
+ mxconfig.gpio.g1 = G1;
+ mxconfig.gpio.b1 = B1; // etc
+ mxconfig.driver = HUB75_I2S_CFG::SHIFT; // shift reg driver, default is plain shift register
+ mxconfig.double_buff = false; // use double buffer (twice amount of RAM required)
+ mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_10M;// I2S clock speed, better leave as-is unless you want to experiment
+ */
+
+ /*
+ For example we have two 64x64 panels chained, so we need to customize our setup like this
+
+ */
+ HUB75_I2S_CFG mxconfig;
+ mxconfig.mx_height = PANEL_HEIGHT; // we have 64 pix heigh panels
+ mxconfig.chain_length = PANELS_NUMBER; // we have 2 panels chained
+ mxconfig.gpio.e = PIN_E; // we MUST assign pin e to some free pin on a board to drive 64 pix height panels with 1/32 scan
+ //mxconfig.driver = HUB75_I2S_CFG::FM6126A; // in case that we use panels based on FM6126A chip, we can change that
+
+ /*
+ //Another way of creating config structure
+ //Custom pin mapping for all pins
+ 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};
+ HUB75_I2S_CFG mxconfig(
+ 64, // width
+ 64, // height
+ 4, // chain length
+ _pins, // pin mapping
+ HUB75_I2S_CFG::FM6126A // driver chip
+ );
+
+ */
+
+
+ // 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%
+
+ // Allocate memory and start DMA display
+ if( not dma_display->begin() )
+ Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
+
+ // well, hope we are OK, let's draw some colors first :)
+ Serial.println("Fill screen: RED");
+ dma_display->fillScreenRGB888(255, 0, 0);
+ delay(1000);
+
+ Serial.println("Fill screen: GREEN");
+ dma_display->fillScreenRGB888(0, 255, 0);
+ delay(1000);
+
+ Serial.println("Fill screen: BLUE");
+ dma_display->fillScreenRGB888(0, 0, 255);
+ delay(1000);
+
+ Serial.println("Fill screen: Neutral White");
+ dma_display->fillScreenRGB888(64, 64, 64);
+ delay(1000);
+
+ Serial.println("Fill screen: black");
+ dma_display->fillScreenRGB888(0, 0, 0);
+ delay(1000);
+
+
+ // Set current FastLED palette
+ currentPalette = RainbowColors_p;
+ Serial.println("Starting plasma effect...");
+ fps_timer = millis();
+}
+
+void loop() {
+
+ for (int x = 0; x < PANE_WIDTH; x++) {
+ for (int y = 0; y < PANE_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;
+ }
+} // end loop \ No newline at end of file
diff --git a/examples/PatternPlasma/PatternWave.jpg b/examples/2_PatternPlasma/PatternWave.jpg
index e6ce3c3..e6ce3c3 100644
--- a/examples/PatternPlasma/PatternWave.jpg
+++ b/examples/2_PatternPlasma/PatternWave.jpg
Binary files differ
diff --git a/examples/PatternPlasma/README.md b/examples/2_PatternPlasma/README.md
index 172a99f..172a99f 100644
--- a/examples/PatternPlasma/README.md
+++ b/examples/2_PatternPlasma/README.md
diff --git a/examples/FM6126Panel/FM6126Panel.ino b/examples/3_FM6126Panel/3_FM6126Panel.ino
index 45eae70..114247c 100644
--- a/examples/FM6126Panel/FM6126Panel.ino
+++ b/examples/3_FM6126Panel/3_FM6126Panel.ino
@@ -3,47 +3,23 @@
#include <Arduino.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
-
-MatrixPanel_I2S_DMA dma_display;
-
#include <FastLED.h>
////////////////////////////////////////////////////////////////////
-// Reset Panel
// FM6126 support is still experimental
-//
-// pinout for ESP38 38pin module
-// http://arduinoinfo.mywikis.net/wiki/Esp32#KS0413_keyestudio_ESP32_Core_Board
-//
-// HUB75E pinout
-// R1 | G1
-// B1 | GND
-// R2 | G2
-// B2 | E
-// A | B
-// C | D
-// CLK| LAT
-// OE | GND
+// 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
+
-#define R1 25
-#define G1 26
-#define BL1 27
-#define R2 14 // 21 SDA
-#define G2 12 // 22 SDL
-#define BL2 13
-#define CH_A 23
-#define CH_B 19
-#define CH_C 5
-#define CH_D 17
-#define CH_E -1 // assign to any available pin if using two panels or 64x64 panels with 1/32 scan (i.e. 32 works fine)
-#define CLK 16
-#define LAT 4
-#define OE 15
+// placeholder for the matrix object
+MatrixPanel_I2S_DMA *dma_display = nullptr;
-// End of default setup for RGB Matrix 64x32 panel
///////////////////////////////////////////////////////////////
+// FastLED variables for pattern output
uint16_t time_counter = 0, cycles = 0, fps = 0;
unsigned long fps_timer;
@@ -57,38 +33,44 @@ CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlend
}
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
- // 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:
-
- // SETS THE BRIGHTNESS HERE. MAX value is MATRIX_WIDTH, 2/3 OR LOWER IDEAL, default is about 50%
- // dma_display.setPanelBrightness(30);
+ 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.
+ */
- /* another way to change brightness is to use
- * dma_display.setPanelBrightness8(uint8_t brt); // were brt is within range 0-255
- * it will recalculate to consider matrix width automatically
- */
- //dma_display.setPanelBrightness8(180);
+ HUB75_I2S_CFG mxconfig(
+ PANEL_RES_X, // module width
+ PANEL_RES_Y, // module height
+ PANEL_CHAIN // Chain length
+ );
- /**
- * this demo runs pretty fine in fast-mode which gives much better fps on large matrixes (>128x64)
- * see comments in the lib header on what does that means
- */
- dma_display.setFastMode(true);
+ 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
- /**
- * Run display on our matrix, be sure to specify 'FM6126A' as last parametr to the begin(),
- * it would reset 6126 registers and enables the matrix
- */
- dma_display.begin(R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK, FM6126A);
+ // 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(96); // 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++) {
+ 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);
@@ -96,7 +78,7 @@ void loop(){
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);
+ dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
}
}
diff --git a/examples/3_FM6126Panel/FM6126A.md b/examples/3_FM6126Panel/FM6126A.md
new file mode 100644
index 0000000..bfab4a5
--- /dev/null
+++ b/examples/3_FM6126Panel/FM6126A.md
@@ -0,0 +1,51 @@
+## 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 pusles (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 measurmens on power consumption while toggling bits of **REG1** and it looks that it could provide a fine grained brighness 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 brighness (compared to all-zeroes) and 4 bits (2-5) giving decreased brighness!!!
+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 simplifiyng matrix output. Should dig into this more deeper.
+
+Here are some of the measurments 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/ \ No newline at end of file
diff --git a/examples/FM6126Panel/README.md b/examples/3_FM6126Panel/README.md
index 4683446..4683446 100644
--- a/examples/FM6126Panel/README.md
+++ b/examples/3_FM6126Panel/README.md
diff --git a/examples/AnimatedGIFPanel/AnimatedGIFPanel.ino b/examples/AnimatedGIFPanel/AnimatedGIFPanel.ino
index 75e0d4f..d3c9916 100644
--- a/examples/AnimatedGIFPanel/AnimatedGIFPanel.ino
+++ b/examples/AnimatedGIFPanel/AnimatedGIFPanel.ino
@@ -25,7 +25,18 @@
// ----------------------------
+/*
+ * 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 dma_display;
+
+
AnimatedGIF gif;
File f;
int x_offset, y_offset;
diff --git a/examples/AuroraDemo/AuroraDemo.ino b/examples/AuroraDemo/AuroraDemo.ino
index 817780e..7ed10fa 100644
--- a/examples/AuroraDemo/AuroraDemo.ino
+++ b/examples/AuroraDemo/AuroraDemo.ino
@@ -22,6 +22,16 @@
/* -------------------------- Class Initialisation -------------------------- */
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.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 matrix;
#include <FastLED.h>
diff --git a/examples/BitmapIcons/BitmapIcons.ino b/examples/BitmapIcons/BitmapIcons.ino
index 09c6815..8f86135 100644
--- a/examples/BitmapIcons/BitmapIcons.ino
+++ b/examples/BitmapIcons/BitmapIcons.ino
@@ -27,7 +27,15 @@
#define CLK_PIN 16
-// Display
+/*
+ * 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 display; // RGB Panel
// Wifi Logo, generated using LCD Image Converter: http://www.riuson.com/lcd-image-converter
diff --git a/examples/ChainedPanels/ChainedPanels.ino b/examples/ChainedPanels/ChainedPanels.ino
index a45f9c1..57fa15b 100644
--- a/examples/ChainedPanels/ChainedPanels.ino
+++ b/examples/ChainedPanels/ChainedPanels.ino
@@ -3,19 +3,9 @@
Steps to use
-----------
- 1) In ESP32-HUB75-MatrixPanel-I2S-DMA.h:
-
- - Set the MATRIX_HEIGHT to be the y resolution of a physical chained
- panels in the line (as panels each must be of the same dimensions).
- i.e. If you are chaining 32px 'high' panels, then set MATRIX_HEIGHT to 32.
-
- - Set the MATRIX_WIDTH to be the sum of the x resolution of all the physical
- chained panels (i.e. If you have 4 (four) x (64px w x 32px h) panels, then 64x4 = 256)
- i.e. The total pixel 'width' of all the chained panels.
-
- 2) In the sketch (i.e. this example):
+ 1) In the sketch (i.e. this example):
- - Set values for NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y.
+ - Set values for NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, PANEL_CHAIN.
There are comments beside them explaining what they are in more detail.
- Other than where the matrix is defined and matrix.begin in the setup, you
should now be using the virtual display for everything (drawing pixels, writing text etc).
@@ -39,25 +29,6 @@
*****************************************************************************/
-//#define USE_CUSTOM_PINS // uncomment to use custom pins, then provide below
-
-#define A_PIN 26
-#define B_PIN 4
-#define C_PIN 27
-#define D_PIN 2
-#define E_PIN 21
-
-#define R1_PIN 5
-#define R2_PIN 19
-#define G1_PIN 17
-#define G2_PIN 16
-#define B1_PIN 18
-#define B2_PIN 25
-
-#define CLK_PIN 14
-#define LAT_PIN 15
-#define OE_PIN 13
-
/******************************************************************************
* VIRTUAL DISPLAY / MATRIX PANEL CHAINING CONFIGURATION
@@ -168,14 +139,16 @@
#define NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS
#define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW
+#define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another
-
-/******************************************************************************
- * Create physical DMA panel class AND virtual (chained) display class.
- ******************************************************************************/
+// library includes
#include <ESP32-VirtualMatrixPanel-I2S-DMA.h>
-MatrixPanel_I2S_DMA dma_display;
-VirtualMatrixPanel virtualDisp(dma_display, NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, true);
+
+// placeholder for the matrix object
+MatrixPanel_I2S_DMA *dma_display = nullptr;
+
+// placeholder for the virtual display object
+VirtualMatrixPanel *virtualDisp = nullptr;
/******************************************************************************
@@ -190,29 +163,47 @@ void setup() {
Serial.println(" HELLO !");
Serial.println("*****************************************************");
-#ifdef USE_CUSTOM_PINS
- dma_display.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
- dma_display.begin();
-#endif
+ /******************************************************************************
+ * Create physical DMA panel class AND virtual (chained) display class.
+ ******************************************************************************/
+
+ /*
+ 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
+ */
+
+ 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
// Sanity checks
if (NUM_ROWS <= 1) {
Serial.println(F("There is no reason to use the VirtualDisplay class for a single horizontal chain and row!"));
}
- if (dma_display.width() != NUM_ROWS*NUM_COLS*PANEL_RES_X )
- {
- Serial.println(F("\r\nERROR: MATRIX_WIDTH and/or MATRIX_HEIGHT in 'ESP32-HUB75-MatrixPanel-I2S-DMA.h'\r\nis not configured correctly for the requested VirtualMatrixPanel dimensions!\r\n"));
- Serial.printf("WIDTH according dma_display is %d, but should be %d. Is your NUM_ROWS and NUM_COLS correct?\r\n", dma_display.width(), NUM_ROWS*NUM_COLS*PANEL_RES_X);
- return;
- }
-
+ // 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%
+
+ // Allocate memory and start DMA display
+ if( not dma_display->begin() )
+ Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
+
+ // create VirtualDisplay object based on our newly created dma_display object
+ virtualDisp = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, true);
+
// So far so good, so continue
- virtualDisp.fillScreen(virtualDisp.color444(0, 0, 0));
- virtualDisp.drawDisplayTest(); // draw text numbering on each screen to check connectivity
+ virtualDisp->fillScreen(virtualDisp->color444(0, 0, 0));
+ virtualDisp->drawDisplayTest(); // draw text numbering on each screen to check connectivity
delay(3000);
@@ -225,20 +216,17 @@ void setup() {
Serial.println("| (ESP) | |");
Serial.println("+--------+---------+");
- virtualDisp.setFont(&FreeSansBold12pt7b);
- virtualDisp.setTextColor(virtualDisp.color565(0, 0, 255));
- virtualDisp.setTextSize(2);
- virtualDisp.setCursor(10, virtualDisp.height()-20);
+ virtualDisp->setFont(&FreeSansBold12pt7b);
+ virtualDisp->setTextColor(virtualDisp->color565(0, 0, 255));
+ virtualDisp->setTextSize(2);
+ virtualDisp->setCursor(10, virtualDisp->height()-20);
// Red text inside red rect (2 pix in from edge)
- virtualDisp.print("1234") ;
- virtualDisp.drawRect(1,1, virtualDisp.width()-2, virtualDisp.height()-2, virtualDisp.color565(255,0,0));
+ virtualDisp->print("1234");
+ virtualDisp->drawRect(1,1, virtualDisp->width()-2, virtualDisp->height()-2, virtualDisp->color565(255,0,0));
// White line from top left to bottom right
- virtualDisp.drawLine(0,0, virtualDisp.width()-1, virtualDisp.height()-1, virtualDisp.color565(255,255,255));
-
-
-
+ virtualDisp->drawLine(0,0, virtualDisp->width()-1, virtualDisp->height()-1, virtualDisp->color565(255,255,255));
}
void loop() {
diff --git a/examples/ChainedPanels/README.md b/examples/ChainedPanels/README.md
index f9b8f18..ca55860 100644
--- a/examples/ChainedPanels/README.md
+++ b/examples/ChainedPanels/README.md
@@ -1,35 +1,33 @@
## Chained Panels example - Chaining individual LED matrix panels to make a larger panel ##
-This is the PatternPlasma Demo adopted for use with multiple
-displays arranged in a non standard order
+This is the PatternPlasma Demo adopted for use with multiple LED Matrix Panel displays arranged in a non standard order (i.e. a grid) to make a bigger display.
-### What is a non standard order? ###
+### What do we mean by 'non standard order'? ###
-When you connect multiple panels together, the library treats the
-multiple panels as one big panel arranged horizontally. Arranging
-the displays like this would be a standard order.
+When you link / chain multiple panels together, the ESP32-HUB75-MatrixPanel-I2S-DMA library treats as one wide horizontal panel. This would be a 'standard' (default) order.
-Non-standard order is essentially the creation of a non-horizontal only 'virtual' display that you can draw to in the same way you would
-the matrix, but with VirtualDisplay library looking after the pixel mapping to the physical chained panels.
+Non-standard order is essentially the creation of a non-horizontal-only display that you can draw to in the same way you would any other display, with VirtualDisplay library looking after the pixel mapping to the physical chained panels.
+
+For example: You bought four (4) 64x32px panels, and wanted to use them to create a 128x64pixel display. You would use the VirtualMatrixPanel class.
+
+[Refer to this document](VirtualMatrixPanel.pdf) for an explanation and refer to this example on how to use.
-[Refer to this document](VirtualDisplay.pdf) for the guide on how to use.
### Steps to Use ###
-1) In ESP32-HUB75-MatrixPanel-I2S-DMA.h:
+1. [Refer to this document](VirtualMatrixPanel.pdf) for an explanation and refer to this example on how to use.
+
+2. In your Arduino sketch, configure these defines accordingly:
+```
+#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.
-- Set the MATRIX_HEIGHT to be the y resolution of the physical chained panels in a line (if the panels are 32 x 16, set it to be 16)
-- Set the MATRIX_WIDTH to be the sum of the x resolution of all the physical chained panels (i.e. If you have 4 x (32px w x 16px h) panels, 32x4 = 128)
+#define NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS
+#define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW
+```
-2) In the sketch:
+3. In your Arduino sketch, use the 'VirtualMatrixPanel' class instance (virtualDisp) to draw to the display (i.e. drawPixel), instead of the underling MatrixPanel_I2S_DMA class instance (dma_display).
-- Set values for NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y. There are comments beside them
-explaining what they are in more detail.
-- Other than where the matrix is defined and matrix.begin in the setup, you should now be using the virtual display
-for everything (drawing pixels, writing text etc). You can do a find and replace of all calls if it's an existing sketch
-(just make sure you don't replace the definition and the matrix.begin)
-- If the sketch makes use of MATRIX_HEIGHT or MATRIX_WIDTH, these will need to be replaced with the width and height
-of your virtual screen. Either make new defines and use that, or you can use virtualDisp.width() or .height()
#### Thanks to ####
* Brian Lough for the Virtual to Real pixel co-ordinate code.
diff --git a/examples/ChainedPanels/VirtualDisplay.pdf b/examples/ChainedPanels/VirtualDisplay.pdf
deleted file mode 100644
index 97eda05..0000000
--- a/examples/ChainedPanels/VirtualDisplay.pdf
+++ /dev/null
Binary files differ
diff --git a/examples/ChainedPanels/VirtualMatrixPanel.odp b/examples/ChainedPanels/VirtualMatrixPanel.odp
new file mode 100644
index 0000000..8245a1a
--- /dev/null
+++ b/examples/ChainedPanels/VirtualMatrixPanel.odp
Binary files differ
diff --git a/examples/ChainedPanels/VirtualMatrixPanel.pdf b/examples/ChainedPanels/VirtualMatrixPanel.pdf
new file mode 100644
index 0000000..c0220a7
--- /dev/null
+++ b/examples/ChainedPanels/VirtualMatrixPanel.pdf
Binary files differ
diff --git a/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino b/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino
index 2800835..4d89944 100644
--- a/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino
+++ b/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino
@@ -1,38 +1,42 @@
-/* ------------------------- CUSTOM GPIO PIN MAPPING ------------------------- */
-// Kosso's ESP32 Matrix PCB pins
-#define R1_PIN 2
-#define G1_PIN 15
-#define B1_PIN 4
-#define R2_PIN 16
-#define G2_PIN 13
-#define B2_PIN 17
-#define A_PIN 5
-#define B_PIN 18
-#define C_PIN 19
-#define D_PIN 27
-#define E_PIN -1
-#define LAT_PIN 21
-#define OE_PIN 23
-#define CLK_PIN 22
+#include <Arduino.h>
+/* Default library pin configuration for the reference
+ you can redefine only ones you need later on object creation
-/* -------------------------- Display Config Initialisation -------------------- */
-// MATRIX_WIDTH and MATRIX_HEIGHT *must* be changed in ESP32-HUB75-MatrixPanel-I2S-DMA.h
-// If you are using Platform IO (you should), pass MATRIX_WIDTH and MATRIX_HEIGHT as a compile time option.
-// Refer to: https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/issues/48#issuecomment-749402379
+#define R1 25
+#define G1 26
+#define BL1 27
+#define R2 14
+#define G2 12
+#define BL2 13
+#define CH_A 23
+#define CH_B 19
+#define CH_C 5
+#define CH_D 17
+#define CH_E -1 // assign to any available pin if using two panels or 64x64 panels with 1/32 scan
+#define CLK 16
+#define LAT 4
+#define OE 15
+
+*/
-//This will not work here -> #define MATRIX_WIDTH 128 // Overall matrix dimensions if laid out end-to-end.
-//This will not work here -> #define MATRIX_HEIGHT 32
+/* -------------------------- Display Config Initialisation -------------------- */
+// Assume we have four 64x32 panels daizy-chained and ESP32 attached to the bottom right corner
#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 NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS
-#define NUM_COLS 1 // Number of INDIVIDUAL PANELS per ROW
+#define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW
+#define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another
-// Virtual Panl dimensions
-#define VPANEL_W 64 // Kosso: All Pattern files have had the MATRIX_WIDTH and MATRIX_HEIGHT replaced by these.
-#define VPANEL_H 64 //
+// Change this to your needs, for details on VirtualPanel pls see ChainedPanels example
+#define SERPENT false
+#define TOPDOWN false
+
+// Virtual Panl dimensions - our combined panel would be a square 4x4 modules with a combined resolution of 128x128 pixels
+#define VPANEL_W PANEL_RES_X*NUM_COLS // Kosso: All Pattern files have had the MATRIX_WIDTH and MATRIX_HEIGHT replaced by these.
+#define VPANEL_H PANEL_RES_Y*NUM_ROWS //
// Kosso added: Button with debounce
#define BTN_PIN 0 // Pattern advance. Using EPS32 Boot button.
@@ -50,32 +54,33 @@ int lastPattern = 0;
/* -------------------------- Class Initialisation -------------------------- */
-//#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
-//MatrixPanel_I2S_DMA matrix;
-
#include <ESP32-VirtualMatrixPanel-I2S-DMA.h>
-MatrixPanel_I2S_DMA matrix;
-// Added support for 'Chained' virtual panel configurations.
-VirtualMatrixPanel virtualDisp(matrix, NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, true);
-
#include <FastLED.h> // Used for some mathematics calculations and effects.
+// placeholder for the matrix object
+MatrixPanel_I2S_DMA *matrix = nullptr;
+
+// placeholder for the virtual display object
+VirtualMatrixPanel *virtualDisp = nullptr;
+
+// Aurora related
#include "Effects.h"
Effects effects;
#include "Drawable.h"
#include "Playlist.h"
//#include "Geometry.h"
-
#include "Patterns.h"
Patterns patterns;
/* -------------------------- Some variables -------------------------- */
unsigned long ms_current = 0;
unsigned long ms_previous = 0;
-unsigned long ms_animation_max_duration = 60000; // 10 seconds
+unsigned long ms_animation_max_duration = 20000; // 10 seconds
unsigned long next_frame = 0;
+void listPatterns();
+
void setup()
{
// Setup serial interface
@@ -87,19 +92,37 @@ void setup()
// For saving last pattern index. TO reboot with same.
preferences.begin("RGBMATRIX", false);
lastPattern = preferences.getInt("lastPattern", 0);
-
- matrix.setPanelBrightness(30);
- matrix.setMinRefreshRate(200);
-
-
- matrix.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
-
- virtualDisp.fillScreen(virtualDisp.color444(0, 0, 0));
-
+
+ // Configure your matrix setup here
+ HUB75_I2S_CFG mxconfig(PANEL_RES_X, PANEL_RES_Y, PANEL_CHAIN);
+
+ // custom pin mapping (if required)
+ //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.gpio = _pins;
+
+ // in case that we use panels based on FM6126A chip, we can change that
+ //mxconfig.driver = HUB75_I2S_CFG::FM6126A;
+
+ // FM6126A panels could be cloked at 20MHz with no visual artefacts
+ // mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;
+
+ // OK, now we can create our matrix object
+ matrix = new MatrixPanel_I2S_DMA(mxconfig);
+
+ // let's adjust default brightness to about 75%
+ matrix->setBrightness8(96); // range is 0-255, 0 - 0%, 255 - 100%
+
+ // Allocate memory and start DMA display
+ if( not matrix->begin() )
+ Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
+
+ // create VirtualDisplay object based on our newly created dma_display object
+ virtualDisp = new VirtualMatrixPanel((*matrix), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, SERPENT, TOPDOWN);
+
Serial.println("**************** Starting Aurora Effects Demo ****************");
- Serial.println("MATRIX_WIDTH " + String(MATRIX_WIDTH));
- Serial.println("MATRIX_HEIGHT " + String(MATRIX_HEIGHT));
+ Serial.print("MATRIX_WIDTH: "); Serial.println(PANEL_RES_X*PANEL_CHAIN);
+ Serial.print("MATRIX_HEIGHT: "); Serial.println(PANEL_RES_Y);
#ifdef VPANEL_W
Serial.println("VIRTUAL PANEL WIDTH " + String(VPANEL_W));
@@ -169,7 +192,7 @@ void loop()
if ( (ms_current - ms_previous) > ms_animation_max_duration )
{
- // patternAdvance();
+ patternAdvance();
// just auto-change the palette
effects.RandomPalette();
ms_previous = ms_current;
diff --git a/examples/ChainedPanelsAuroraDemo/Drawable.h b/examples/ChainedPanelsAuroraDemo/Drawable.h
index 40356f4..b2169fe 100644
--- a/examples/ChainedPanelsAuroraDemo/Drawable.h
+++ b/examples/ChainedPanelsAuroraDemo/Drawable.h
@@ -38,7 +38,7 @@ public:
// a single frame should be drawn as fast as possible, without any delay or blocking
// return how many millisecond delay is requested before the next call to drawFrame()
virtual unsigned int drawFrame() {
- matrix.fillScreen(0);
+ matrix->fillScreen(0);
//backgroundLayer.fillScreen({ 0, 0, 0 });
return 0;
};
diff --git a/examples/ChainedPanelsAuroraDemo/Effects.h b/examples/ChainedPanelsAuroraDemo/Effects.h
index fa0ca45..9c1f623 100644
--- a/examples/ChainedPanelsAuroraDemo/Effects.h
+++ b/examples/ChainedPanelsAuroraDemo/Effects.h
@@ -112,8 +112,6 @@ uint8_t noisesmoothing;
class Effects {
public:
CRGB *leds;
- //CRGB leds[NUM_LEDS];
- //CRGB leds2[NUM_LEDS]; // Faptastic: getting rid of this and any dependant effects or algos. to save memory 24*64*32 bytes of ram (50k).
Effects(){
// we do dynamic allocation for leds buffer, otherwise esp32 toolchain can't link static arrays of such a big size for 256+ matrixes
@@ -127,7 +125,6 @@ public:
}
ClearFrame();
- matrix.clearScreen();
}
~Effects(){
free(leds);
@@ -175,7 +172,7 @@ public:
for (int x=0; x<VPANEL_W; ++x){
//Serial.printf("Flushing x, y coord %d, %d\n", x, y);
uint16_t _pixel = XY16(x,y);
- virtualDisp.drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b);
+ virtualDisp->drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b);
} // end loop to copy fast led to the dma matrix
}
}
diff --git a/examples/ChainedPanelsAuroraDemo/PatternInvaders.h b/examples/ChainedPanelsAuroraDemo/PatternInvaders.h
index cad004c..98f3200 100644
--- a/examples/ChainedPanelsAuroraDemo/PatternInvaders.h
+++ b/examples/ChainedPanelsAuroraDemo/PatternInvaders.h
@@ -36,7 +36,7 @@ class PatternInvadersSmall : public Drawable {
}
void start() {
- matrix.fillScreen(0);
+ matrix->fillScreen(0);
}
unsigned int drawFrame() {
@@ -80,7 +80,7 @@ class PatternInvadersMedium : public Drawable {
}
void start() {
- matrix.fillScreen(0);
+ matrix->fillScreen(0);
}
unsigned int drawFrame() {
@@ -92,10 +92,10 @@ class PatternInvadersMedium : public Drawable {
if (random(0, 2) == 1) color = color1;
- matrix.fillRect(x + (i * 2), y + (j * 2), x + (i * 2 + 1), y + (j * 2 + 1), color);
+ matrix->fillRect(x + (i * 2), y + (j * 2), x + (i * 2 + 1), y + (j * 2 + 1), color);
if (i < 2)
- matrix.fillRect(x + (8 - i * 2), y + (j * 2), x + (9 - i * 2), y + (j * 2 + 1), color);
+ matrix->fillRect(x + (8 - i * 2), y + (j * 2), x + (9 - i * 2), y + (j * 2 + 1), color);
}
}
@@ -122,11 +122,11 @@ class PatternInvadersLarge : public Drawable {
}
void start() {
- matrix.fillScreen(0);
+ matrix->fillScreen(0);
}
unsigned int drawFrame() {
- matrix.fillScreen(0);
+ matrix->fillScreen(0);
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
@@ -138,10 +138,10 @@ class PatternInvadersLarge : public Drawable {
color = color1;
}
- matrix.fillRect(1 + x * 6, 1 + y * 6, 5 + x * 6, 5 + y * 6, color);
+ matrix->fillRect(1 + x * 6, 1 + y * 6, 5 + x * 6, 5 + y * 6, color);
if (x < 2)
- matrix.fillRect(1 + (4 - x) * 6, 1 + y * 6, 5 + (4 - x) * 6, 5 + y * 6, color);
+ matrix->fillRect(1 + (4 - x) * 6, 1 + y * 6, 5 + (4 - x) * 6, 5 + y * 6, color);
}
}
diff --git a/examples/ChainedPanelsAuroraDemo/PatternTest.h b/examples/ChainedPanelsAuroraDemo/PatternTest.h
index 6f0544f..7a4a07d 100644
--- a/examples/ChainedPanelsAuroraDemo/PatternTest.h
+++ b/examples/ChainedPanelsAuroraDemo/PatternTest.h
@@ -12,7 +12,7 @@ class PatternTest : public Drawable {
unsigned int drawFrame() {
- matrix.fillScreen(matrix.color565(128, 0, 0));
+ matrix->fillScreen(matrix->color565(128, 0, 0));
return 1000;
}
};
diff --git a/examples/DoubleBufferSwap/DoubleBufferSwap.ino b/examples/DoubleBufferSwap/DoubleBufferSwap.ino
index 6d71f75..81e116d 100644
--- a/examples/DoubleBufferSwap/DoubleBufferSwap.ino
+++ b/examples/DoubleBufferSwap/DoubleBufferSwap.ino
@@ -1,5 +1,15 @@
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.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 display(true); // Note the TRUE -> Turns of secondary buffer - "double buffering"!
// Double buffering is not enabled by default with the library.
diff --git a/examples/GraphicsLayer/GraphicsLayer.ino b/examples/GraphicsLayer/GraphicsLayer.ino
index 2c15d18..61f51bf 100644
--- a/examples/GraphicsLayer/GraphicsLayer.ino
+++ b/examples/GraphicsLayer/GraphicsLayer.ino
@@ -33,8 +33,18 @@
#include "Layer.h" // Layer Library
#include "Fonts/FreeSansBold9pt7b.h" // include adafruit font
-// Object creation
+/*
+ * 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 dma_display; // Create HUB75 DMA object
+
+// Create FastLED based graphic 'layers'
Layer bgLayer(dma_display); // Create background Layer
Layer textLayer(dma_display); // Create foreground Layer
diff --git a/examples/P6_32x16_1_4_ScanPanel/P6_32x16_1_4_ScanPanel.ino b/examples/P6_32x16_1_4_ScanPanel/P6_32x16_1_4_ScanPanel.ino
new file mode 100644
index 0000000..8efd79f
--- /dev/null
+++ b/examples/P6_32x16_1_4_ScanPanel/P6_32x16_1_4_ScanPanel.ino
@@ -0,0 +1,223 @@
+/*************************************************************************
+ * 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'
+ *
+ **************************************************************************/
+
+// 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 "QuarterScanMatrixPanel.h" // Virtual Display to re-map co-ordinates such that they draw correctly on a32x16 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 \ No newline at end of file
diff --git a/examples/P6_32x16_1_4_ScanPanel/QuarterScanMatrixPanel.h b/examples/P6_32x16_1_4_ScanPanel/QuarterScanMatrixPanel.h
new file mode 100644
index 0000000..b7955f5
--- /dev/null
+++ b/examples/P6_32x16_1_4_ScanPanel/QuarterScanMatrixPanel.h
@@ -0,0 +1,449 @@
+
+/*
+ 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;}
+ /** extende 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 postion
+ virtual size_t write(const char *str); // write a character array (string) on curreont cursor postion
+
+ 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 Multiplikator default = 1 => 5x7 Font (5widht,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 arry 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 firste 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 colunm of currenc 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 coordinats 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 orgininal 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 orgininal 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 wouldnt 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 \ No newline at end of file
diff --git a/examples/P6_32x16_1_4_ScanPanel/README.md b/examples/P6_32x16_1_4_ScanPanel/README.md
new file mode 100644
index 0000000..6af1fa6
--- /dev/null
+++ b/examples/P6_32x16_1_4_ScanPanel/README.md
@@ -0,0 +1,78 @@
+# 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 postion 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
+
diff --git a/examples/PIO_TestPatterns/README.md b/examples/PIO_TestPatterns/README.md
new file mode 100644
index 0000000..291bee2
--- /dev/null
+++ b/examples/PIO_TestPatterns/README.md
@@ -0,0 +1,16 @@
+# Test Patterns
+
+Simple solid colors, gradients and test line patterns, could be used to test matrixes for proper operation, flickering and estimate fillrate timings.
+
+Should be build and uploaded as a [platformio](https://platformio.org/) project
+
+
+To build with Arduino's framework use
+```
+pio run -t upload
+```
+
+To build using ESP32 IDF with arduino's component use
+```
+pio run -t upload -e idfarduino
+```
diff --git a/examples/PIO_TestPatterns/platformio.ini b/examples/PIO_TestPatterns/platformio.ini
new file mode 100644
index 0000000..0edd28a
--- /dev/null
+++ b/examples/PIO_TestPatterns/platformio.ini
@@ -0,0 +1,42 @@
+[platformio]
+default_envs = esp32
+
+[env]
+framework = arduino
+platform = espressif32
+board_build.filesystem = littlefs
+board = wemos_d1_mini32
+lib_deps =
+ FastLED
+build_flags =
+; -DSERIAL_DEBUG=1
+upload_speed = 921600
+monitor_speed = 115200
+monitor_filters = esp32_exception_decoder
+
+[env:esp32]
+build_flags =
+ ${env.build_flags}
+ -DUSE_FASTLINES
+ -DNO_GFX
+lib_deps =
+ ${env.lib_deps}
+; use dev version of the lib
+ https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA.git#dev
+
+
+[env:idfarduino]
+platform = espressif32
+platform_packages =
+ ; use a special branch
+ framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#idf-release/v4.0
+framework = arduino, espidf
+build_flags =
+ ${env.build_flags}
+ -DARDUINO=200
+ -DESP32
+ -DUSE_FASTLINES
+ -DNO_GFX
+lib_deps =
+ ${env.lib_deps}
+ https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA.git#dev
diff --git a/examples/PIO_TestPatterns/src/CMakeLists.txt b/examples/PIO_TestPatterns/src/CMakeLists.txt
new file mode 100644
index 0000000..483bc0c
--- /dev/null
+++ b/examples/PIO_TestPatterns/src/CMakeLists.txt
@@ -0,0 +1,6 @@
+# This file was automatically generated for projects
+# without default 'CMakeLists.txt' file.
+
+FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
+
+idf_component_register(SRCS ${app_sources})
diff --git a/examples/PIO_TestPatterns/src/main.cpp b/examples/PIO_TestPatterns/src/main.cpp
new file mode 100644
index 0000000..7ba159c
--- /dev/null
+++ b/examples/PIO_TestPatterns/src/main.cpp
@@ -0,0 +1,382 @@
+// How to use this library with a FM6126 panel, thanks goes to:
+// https://github.com/hzeller/rpi-rgb-led-matrix/issues/746
+
+// IDF
+#if defined(IDF_VER)
+ #include <stdio.h>
+ #include <freertos/FreeRTOS.h>
+ #include <freertos/task.h>
+ #include <driver/gpio.h>
+ #include "sdkconfig.h"
+#endif
+
+#include <Arduino.h>
+#include "xtensa/core-macros.h"
+#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
+
+#include "main.h"
+
+// HUB75E pinout
+// R1 | G1
+// B1 | GND
+// R2 | G2
+// B2 | E
+// A | B
+// C | D
+// CLK| LAT
+// OE | GND
+
+#define R1 25
+#define G1 26
+#define BL1 27
+#define R2 14 // 21 SDA
+#define G2 12 // 22 SDL
+#define BL2 13
+#define CH_A 23
+#define CH_B 19
+#define CH_C 5
+#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 CLK 16
+#define LAT 4
+#define OE 15
+
+
+#define M_WIDTH 256
+#define M_HEIGHT 64
+#define PATTERN_DELAY 2000
+
+#define NUM_LEDS M_WIDTH*M_HEIGHT
+
+//#define USE_FASTLINES
+
+MatrixPanel_I2S_DMA *matrix = nullptr;
+
+uint16_t time_counter = 0, cycles = 0, fps = 0;
+unsigned long fps_timer;
+
+//
+CRGB *ledbuff;
+//
+
+unsigned long t1, t2, s1=0, s2=0, s3=0;
+uint32_t ccount1, ccount2;
+
+uint8_t color1 = 0, color2 = 0, color3 = 0;
+uint16_t x,y;
+
+void setup(){
+
+ Serial.begin(BAUD_RATE);
+ 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};
+ HUB75_I2S_CFG mxconfig(64, 64, 4, _pins, HUB75_I2S_CFG::FM6126A);
+ mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;
+
+ matrix = new MatrixPanel_I2S_DMA(mxconfig);
+
+ matrix->begin();
+ matrix->setBrightness8(255);
+ //matrix->setLatBlanking(2);
+
+ ledbuff = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB)); // allocate buffer for some tests
+ buffclear(ledbuff);
+
+}
+
+
+void loop(){
+
+ Serial.printf("Cycle: %d\n", ++cycles);
+
+ Serial.print("Estimating clearScreen() - ");
+ ccount1 = XTHAL_GET_CCOUNT();
+ matrix->clearScreen();
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ Serial.printf("%d ticks\n", ccount1);
+ delay(PATTERN_DELAY);
+
+/*
+// Power supply tester
+// slowly fills matrix with white, stressing PSU
+ for (int y=0; y!=M_HEIGHT; ++y){
+ for (int x=0; x!=M_WIDTH; ++x){
+ matrix->drawPixelRGB888(x, y, 255,255,255);
+ //matrix->drawPixelRGB888(x, y-1, 255,0,0); // pls, be gentle :)
+ delay(10);
+ }
+ }
+ delay(5000);
+*/
+
+
+ // simple solid colors
+ Serial.println("Fill screen: RED");
+ matrix->fillScreenRGB888(255, 0, 0);
+ delay(PATTERN_DELAY);
+ Serial.println("Fill screen: GREEN");
+ matrix->fillScreenRGB888(0, 255, 0);
+ delay(PATTERN_DELAY);
+ Serial.println("Fill screen: BLUE");
+ matrix->fillScreenRGB888(0, 0, 255);
+ delay(PATTERN_DELAY);
+
+
+ for (uint8_t i=5; i; --i){
+ Serial.print("Estimating single drawPixelRGB888(r, g, b) ticks: ");
+ color1 = random8();
+ ccount1 = XTHAL_GET_CCOUNT();
+ matrix->drawPixelRGB888(i,i, color1, color1, color1);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ Serial.printf("%d ticks\n", ccount1);
+ }
+
+// Clearing CRGB ledbuff
+ Serial.print("Estimating ledbuff clear time: ");
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ buffclear(ledbuff);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ Serial.printf("%lu us, %u ticks\n\n", t2, ccount1);
+
+ // Bare fillscreen(r, g, b)
+ Serial.print("Estimating fillscreenRGB888(r, g, b) time: ");
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ matrix->fillScreenRGB888(64, 64, 64); // white
+ ccount2 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ s1+=t2;
+ Serial.printf("%lu us, avg: %lu, ccnt: %d\n", t2, s1/cycles, ccount2);
+ delay(PATTERN_DELAY);
+
+
+ Serial.print("Estimating full-screen fillrate with looped drawPixelRGB888(): ");
+ y = M_HEIGHT;
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ do {
+ --y;
+ uint16_t x = M_WIDTH;
+ do {
+ --x;
+ matrix->drawPixelRGB888( x, y, 0, 0, 0);
+ } while(x);
+ } while(y);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ Serial.printf("%lu us, %u ticks\n", t2, ccount1);
+
+
+
+// created random color gradient in ledbuff
+ uint8_t color1 = 0;
+ uint8_t color2 = random8();
+ uint8_t color3 = 0;
+
+ for (uint16_t i = 0; i<NUM_LEDS; ++i){
+ ledbuff[i].r=color1++;
+ ledbuff[i].g=color2;
+ if (i%M_WIDTH==0)
+ color3+=255/M_HEIGHT;
+
+ ledbuff[i].b=color3;
+ }
+//
+
+//
+ Serial.print("Estimating ledbuff-to-matrix fillrate with drawPixelRGB888(), time: ");
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ mxfill(ledbuff);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ s2+=t2;
+ Serial.printf("%lu us, avg: %lu, %d ticks:\n", t2, s2/cycles, ccount1);
+ delay(PATTERN_DELAY);
+//
+
+#ifdef USE_FASTLINES
+ // Fillrate for fillRect() function
+ Serial.print("Estimating fullscreen fillrate with fillRect() time: ");
+ t1 = micros();
+ matrix->fillRect(0, 0, M_WIDTH, M_HEIGHT, 0, 224, 0);
+ t2 = micros()-t1;
+ Serial.printf("%lu us\n", t2);
+ delay(PATTERN_DELAY);
+
+
+ Serial.print("Chessboard with fillRect(): "); // шахматка
+ matrix->fillScreen(0);
+ x =0, y = 0;
+ color1 = random8();
+ color2 = random8();
+ color3 = random8();
+ bool toggle=0;
+ t1 = micros();
+ do {
+ do{
+ matrix->fillRect(x, y, 8, 8, color1, color2, color3);
+ x+=16;
+ }while(x < M_WIDTH);
+ y+=8;
+ toggle = !toggle;
+ x = toggle ? 8 : 0;
+ }while(y < M_HEIGHT);
+ t2 = micros()-t1;
+ Serial.printf("%lu us\n", t2);
+ delay(PATTERN_DELAY);
+#endif
+
+// ======== V-Lines ==========
+ Serial.println("Estimating V-lines with drawPixelRGB888(): "); //
+ matrix->fillScreen(0);
+ color1 = random8();
+ color2 = random8();
+ x = y = 0;
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ do {
+ y=0;
+ do{
+ matrix->drawPixelRGB888(x, y, color1, color2, color3);
+ } while(++y != M_HEIGHT);
+ x+=2;
+ } while(x != M_WIDTH);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ Serial.printf("%lu us, %u ticks\n", t2, ccount1);
+ delay(PATTERN_DELAY);
+
+#ifdef USE_FASTLINES
+ Serial.println("Estimating V-lines with vlineDMA(): "); //
+ matrix->fillScreen(0);
+ color2 = random8();
+ x = y = 0;
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ do {
+ matrix->drawFastVLine(x, y, M_HEIGHT, color1, color2, color3);
+ x+=2;
+ } while(x != M_WIDTH);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ Serial.printf("%lu us, %u ticks\n", t2, ccount1);
+ delay(PATTERN_DELAY);
+
+ Serial.println("Estimating V-lines with fillRect(): "); //
+ matrix->fillScreen(0);
+ color1 = random8();
+ color2 = random8();
+ x = y = 0;
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ do {
+ matrix->fillRect(x, y, 1, M_HEIGHT, color1, color2, color3);
+ x+=2;
+ } while(x != M_WIDTH);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ Serial.printf("%lu us, %u ticks\n", t2, ccount1);
+ delay(PATTERN_DELAY);
+#endif
+
+
+
+// ======== H-Lines ==========
+ Serial.println("Estimating H-lines with drawPixelRGB888(): "); //
+ matrix->fillScreen(0);
+ color2 = random8();
+ x = y = 0;
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ do {
+ x=0;
+ do{
+ matrix->drawPixelRGB888(x, y, color1, color2, color3);
+ } while(++x != M_WIDTH);
+ y+=2;
+ } while(y != M_HEIGHT);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ Serial.printf("%lu us, %u ticks\n", t2, ccount1);
+ delay(PATTERN_DELAY);
+
+#ifdef USE_FASTLINES
+ Serial.println("Estimating H-lines with hlineDMA(): ");
+ matrix->fillScreen(0);
+ color2 = random8();
+ color3 = random8();
+ x = y = 0;
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ do {
+ matrix->drawFastHLine(x, y, M_WIDTH, color1, color2, color3);
+ y+=2;
+ } while(y != M_HEIGHT);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ Serial.printf("%lu us, %u ticks\n", t2, ccount1);
+ delay(PATTERN_DELAY);
+
+ Serial.println("Estimating H-lines with fillRect(): "); //
+ matrix->fillScreen(0);
+ color2 = random8();
+ color3 = random8();
+ x = y = 0;
+ t1 = micros();
+ ccount1 = XTHAL_GET_CCOUNT();
+ do {
+ matrix->fillRect(x, y, M_WIDTH, 1, color1, color2, color3);
+ y+=2;
+ } while(y != M_HEIGHT);
+ ccount1 = XTHAL_GET_CCOUNT() - ccount1;
+ t2 = micros()-t1;
+ Serial.printf("%lu us, %u ticks\n", t2, ccount1);
+ delay(PATTERN_DELAY);
+#endif
+
+
+
+
+ Serial.println("\n====\n");
+
+ // take a rest for a while
+ delay(10000);
+}
+
+
+void buffclear(CRGB *buf){
+ memset(buf, 0x00, NUM_LEDS * sizeof(CRGB)); // flush buffer to black
+}
+
+void IRAM_ATTR mxfill(CRGB *leds){
+ uint16_t y = M_HEIGHT;
+ do {
+ --y;
+ uint16_t x = M_WIDTH;
+ do {
+ --x;
+ uint16_t _pixel = y * M_WIDTH + x;
+ matrix->drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b);
+ } while(x);
+ } while(y);
+}
+//
+
+/**
+ * The one for 256+ matrixes
+ * otherwise this:
+ * for (uint8_t i = 0; i < MATRIX_WIDTH; i++) {}
+ * turns into an infinite loop
+ */
+uint16_t XY16( uint16_t x, uint16_t y)
+{
+ if (x<M_WIDTH && y < M_HEIGHT){
+ return (y * M_WIDTH) + x; // everything offset by one to capute out of bounds stuff - never displayed by ShowFrame()
+ } else {
+ return 0;
+ }
+}
diff --git a/examples/PIO_TestPatterns/src/main.h b/examples/PIO_TestPatterns/src/main.h
new file mode 100644
index 0000000..d947d8e
--- /dev/null
+++ b/examples/PIO_TestPatterns/src/main.h
@@ -0,0 +1,8 @@
+
+#include <FastLED.h>
+
+#define BAUD_RATE 115200 // serial debug port baud rate
+
+void buffclear(CRGB *buf);
+uint16_t XY16( uint16_t x, uint16_t y);
+void mxfill(CRGB *leds); \ No newline at end of file
diff --git a/examples/PatternPlasma/PatternPlasma.ino b/examples/PatternPlasma/PatternPlasma.ino
deleted file mode 100644
index e8a16d9..0000000
--- a/examples/PatternPlasma/PatternPlasma.ino
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Portions of this code are adapted from Aurora: https://github.com/pixelmatix/aurora
- * Copyright (c) 2014 Jason Coon
- *
- * Portions of this code are adapted from LedEffects Plasma by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Plasma.cpp?at=default
- * Copyright (c) 2013 Robert Atkins
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-//#define USE_CUSTOM_PINS // uncomment to use custom pins, then provide below
-
-#define A_PIN 26
-#define B_PIN 4
-#define C_PIN 27
-#define D_PIN 2
-#define E_PIN 21
-
-#define R1_PIN 5
-#define R2_PIN 19
-#define G1_PIN 17
-#define G2_PIN 16
-#define B1_PIN 18
-#define B2_PIN 25
-
-#define CLK_PIN 14
-#define LAT_PIN 15
-#define OE_PIN 13
-
-
-#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
-MatrixPanel_I2S_DMA dma_display;
-
-#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);
-}
-
-void setup() {
-
- Serial.begin(115200);
-
- Serial.println("*****************************************************");
- Serial.println(" HELLO !");
- Serial.println("*****************************************************");
-
-#ifdef USE_CUSTOM_PINS
- dma_display.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
- dma_display.begin();
-#endif
-
- // fill the screen with 'black'
- dma_display.fillScreen(dma_display.color444(0, 0, 0));
-
- // Set current FastLED palette
- currentPalette = RainbowColors_p;
-
-}
-
-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 += 1;
- cycles++;
-
- if (cycles >= 2048) {
- time_counter = 0;
- cycles = 0;
- }
-
-} // end loop \ No newline at end of file
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..6b55f37
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,14 @@
+| Example Name |Description |
+|--|--|
+|1_SimpleTestShapes |Example for new starters - how to display basic shapes. |
+|2_PatternPlasma |Example for new starters - how to display a cool plasma pattern. |
+|3_FM6126Panel |Example for new starters - how to initialise FM6126/FM6126A panels with this library.
+|AnimatedGIFPanel |Using Larry Bank's GIF Decoder to display animated GIFs. |
+|AuroraDemo |Simple example demonstrating various animated effects. |
+|BitmapIcons |Simple example of how to display a bitmap image to the display. |
+|ChainedPanels |Popular example on how to use the 'VirtualDisplay' class to chain multiple LED Matrix Panels to form a much bigger display! Refer to the README within this example's folder! |
+|ChainedPanelsAuroraDemo |As above, but showing a large trippy plasma animation. |
+|DoubleBufferSwap |Advanced example of using a back-buffer (double buffering). Not useful for 99% of use cases. |
+|GraphicsLayer |Advanced example of using an off-screen 'layer' library before writing to the LED Matrix Panels. |
+|P6_32x16_1_4_ScanPanel |An advanced example ('hack') on how to use this library on 32w x 16h 1/4 Scan LED Matrix Panel. |
+|PIO_TestPatterns |Non-Arduino example of how to display basic shapes. |