diff --git a/README.md b/README.md index e200baa..3b0ab68 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,36 @@ **Table of Content** -[TOC] +- [Introduction](#introduction) + * [Features](#features) + * [Panels Supported](#panels-supported) + * [Panel driver chips known to be working well](#panel-driver-chips-known-to-be-working-well) + * [Panels Not Supported](#panels-not-supported) + * [Update for 16x32 Panels](#update-for-16x32-panels) +- [Getting Started](#getting-started) + * [1. Library Installation](#1-library-installation) + * [2. Wiring ESP32 with the LED Matrix Panel](#2-wiring-esp32-with-the-led-matrix-panel) + * [3. Run a Test Sketch](#3-run-a-test-sketch) +- [More Information](#more-information) + * [Build-time options](#build-time-options) + * [Memory constraints](#memory-constraints) + * [Can I use with a larger panel (i.e. 64x64px square panel)?](#can-i-use-with-a-larger-panel--ie-64x64px-square-panel--) + * [Can I chain panels?](#can-i-chain-panels-) + * [Panel Brightness](#panel-brightness) + * [Latch blanking](#latch-blanking) + * [Power, Power and Power!](#power--power-and-power-) + * [Inspiration](#inspiration) ## Introduction This ESP32 Arduino/IDF library for HUB75 / HUB75E connector type 64x32 RGB LED 1/16 Scan OR 64x64 RGB LED 1/32 Scan LED Matrix Panel, utilities the DMA functionality provided by the ESP32's I2S 'LCD Mode'. -**Features** -- **Low CPU overhead**, once initialized pixel data is pumped to the matrix inputs via DMA engine directly from memory -- **Fast**, updating pixel data involves only bit-wise logic over DMA buffer memory, no pins manipulation or blocking IO -- **Full screen BCM**, library utilizes [binary-code modulation](http://www.batsocks.co.uk/readme/art_bcm_5.htm) to render pixel color depth / brightness over the entire matrix -- **Variable color depth**, up to TrueColor 24 bits output is possible depending on matrix size/refresh rate required -- **CIE 1931** luminance correction (aka natural LED dimming) -- **Adafruit GFX API**, library could be build with AdafruitGFX, simplified GFX or without GFX API at all +### Features +- **Low CPU overhead** - once initialized pixel data is pumped to the matrix inputs via DMA engine directly from memory +- **Fast** - updating pixel data involves only bit-wise logic over DMA buffer memory, no pins manipulation or blocking IO +- **Full screen BCM** - library utilizes [binary-code modulation](http://www.batsocks.co.uk/readme/art_bcm_5.htm) to render pixel color depth / brightness over the entire matrix +- **Variable color depth** - up to TrueColor 24 bits output is possible depending on matrix size/refresh rate required +- **CIE 1931** luminance [correction](https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/) (aka natural LED dimming) +- **Adafruit GFX API** - library could be build with AdafruitGFX, simplified GFX or without GFX API at all If you wanna ask "*...OK, OK, than whats the price for those features?*" I'll tell you - "[memory](/doc/i2s_memcalc.md), you pay it all by precious MCU's memory for DMA buffer". @@ -24,7 +42,7 @@ If you wanna ask "*...OK, OK, than whats the price for those features?*" I'll te Ones interested in internals of such matrixes could find [this article](https://www.sparkfun.com/news/2650) useful. -Due to the high-speed optimized nature of this library, only specific panels are supported. Please do not raised issues with respect to panels not supported on the list below. +Due to the high-speed optimized nature of this library, only specific panels are supported. Please do not raise issues with respect to panels not supported on the list below. ## Panel driver chips known to be working well @@ -53,17 +71,17 @@ Please use an [alternative library](https://github.com/2dom/PxMatrix) if you bou By default the pin mapping is as follows (defaults defined in ESP32-HUB75-MatrixPanel-I2S-DMA.h). ``` -HUB 75 PANEL ESP 32 PIN -+-----------+ -| R1 G1 | R1 -> IO25 G1 -> IO26 -| B1 GND | B1 -> IO27 -| R2 G2 | R2 -> IO14 G2 -> IO12 -| B2 E | B2 -> IO13 E -> N/A (required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32 ) -| A B | A -> IO23 B -> IO19 -| C D | C -> IO 5 D -> IO17 -| CLK LAT | CLK -> IO16 LAT -> IO 4 -| OE GND | OE -> IO15 GND -> ESP32 GND -+-----------+ +HUB 75 PANEL ESP 32 PIN ++----------+ +| R1 G1 | R1 -> IO25 G1 -> IO26 +| B1 GND | B1 -> IO27 +| R2 G2 | R2 -> IO14 G2 -> IO12 +| B2 E | B2 -> IO13 E -> N/A (required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32 ) +| A B | A -> IO23 B -> IO19 +| C D | C -> IO05 D -> IO17 +| CLK LAT | CLK -> IO16 LAT -> IO 4 +| OE GND | OE -> IO15 GND -> ESP32 GND ++----------+ ``` However, if you want to change this, simply provide the wanted pin mapping as part of the class initialization structure. For example, in your sketch have something like the following: @@ -110,12 +128,14 @@ void setup(){ void loop(){ } ``` -Once this is working, refer to the [PIO Test Patterns](/examples/PIO_TestPatterns) example. ->Note: Requires the use of [PlatformIO](https://platformio.org/), which you should probably use if you aren't already. - +Once this is working, refer to the [PIO Test Patterns](/examples/PIO_TestPatterns) example. This sketch draws simple colors/lines/gradients over the entire matrix and it could help to troubleshoot various issues with ghosting, flickering, etc... +>Note: Requires the use of [PlatformIO](https://platformio.org/), which you should probably use if you aren't already. # More Information ## Build-time options -Although Arduino IDE does not seem to offer any way of specifying compile-time options for external libs there are other IDE's (like [PlatformIO](https://platformio.org/)/[Eclipse](https://www.eclipse.org/ide/)) that could use that. Check [BuldOptions](doc/BuildOptions.md) document for reference. +Although Arduino IDE does not [seem](https://github.com/arduino/Arduino/issues/421) to offer any way of specifying compile-time options for external libs there are other IDE's (like [PlatformIO](https://platformio.org/)/[Eclipse](https://www.eclipse.org/ide/)) that could use that. Check [Buld Options](doc/BuildOptions.md) document for reference. + +## Memory constraints +If you are going to use large/combined panels make sure to check for [memory constraints](/doc/i2s_memcalc.md). ## 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' diff --git a/doc/BuildOptions.md b/doc/BuildOptions.md index 4207a58..bf6f5ad 100644 --- a/doc/BuildOptions.md +++ b/doc/BuildOptions.md @@ -11,23 +11,21 @@ lib_deps = ESP32 HUB75 LED MATRIX PANEL DMA Display build_flags = -DSERIAL_DEBUG - -DNO_GFX + -DNO_GFX ``` -##Build flags +## Build flags | Flag | Description | Note | | :------------ |---------------|-----| -| **SERIAL_DEBUG** |Print out detailed information about memory allocations, DMA descriptors setup and color depth BCM | +| **SERIAL_DEBUG** |Print out detailed information about memory allocations, DMA descriptors setup and color depth [BCM](http://www.batsocks.co.uk/readme/art_bcm_5.htm) | | **USE_GFX_ROOT** | Use [lightweight](https://github.com/mrfaptastic/Adafruit_GFX_Lite) version of AdafuitGFX, without Adafruit BusIO extensions | You **must** install [Adafruit_GFX_Lite](https://github.com/mrfaptastic/Adafruit_GFX_Lite) library instead of original AdafruitGFX| -| **NO_GFX** | Build without AdafuitGFX API, only native methods supported based on manipulating DMA buffer. I.e. no methods of drawing circles/shapes, typing text or using fonts!!! This might save some resources for applications using it's own internal graphics buffer or works solely with per-pixel manipulation. For example Aurora effects can work fine w/o AdafruitGFX. | Use this if you rely on FastLED, Neomatrix or any other API. For example Aurora effects can work fine w/o AdafruitGFX. | +| **NO_GFX** | Build without AdafuitGFX API, only native methods supported based on manipulating DMA buffer. I.e. no methods of drawing circles/shapes, typing text or using fonts!!! This might save some resources for applications using it's own internal graphics buffer or working solely with per-pixel manipulation. | Use this if you rely on FastLED, Neomatrix or any other API. For example [Aurora](/examples/AuroraDemo/) effects can work fine w/o AdafruitGFX. | | **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 ;) | If you are not using AdafruitGFX than you probably do not need this eather| |**NO_CIE1931**|Do not use LED brightness [compensation](https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/) described in [CIE 1931](https://en.wikipedia.org/wiki/CIE_1931_color_space). Normaly library would adjust every pixel's RGB888 so that liminance (or brighness control) for the corresponding LED's would apper 'linear' to the human's eye. I.e. a white dot with rgb(128,128,128) would seem to be at 50% brightness between rgb(0,0,0) and rgb(255,255,255). Normaly you would like to keep this enabled by default. Not only it makes brightness control "linear", it also makes colors more vivid, otherwise it looks brighter but 'bleached'.|You might want to turn it off in some special cases like: | - - -##Build-time variables +## Build-time variables | Flag | Description | Note | | :------------ |---------------|-----| -| **PIXEL_COLOR_DEPTH_BITS=8** | Color depth per color per pixel in range 2-8. More bit's - more natural color. But on the other hand every additional bit: | Default is 8 bits per color per pixel, i.e. TrueColor 24 bit RGB. For higher resolutions, from 64x64 and above it is not possible to provide full 24 bits color without significant flickering OR reducing dynamic range in shadows. In that case using 5-6 bits at high res make very small difference to the humans eye actually. Refer to the [I2S memcalc](i2s_memcalc.md) for more details| \ No newline at end of file +| **PIXEL_COLOR_DEPTH_BITS=8** | Color depth per color per pixel in range 2-8. More bit's - more natural color. But on the other hand every additional bit: | Default is 8 bits per color per pixel, i.e. TrueColor 24 bit RGB. For higher resolutions, from 64x64 and above it is not possible to provide full 24 bits color without significant flickering OR reducing dynamic range in shadows. In that case using 5-6 bits at high res make very small difference to the humans eye actually. Refer to the [I2S memcalc](i2s_memcalc.md) for more details| \ No newline at end of file diff --git a/doc/i2s_memcalc.md b/doc/i2s_memcalc.md index 2997376..47806af 100644 --- a/doc/i2s_memcalc.md +++ b/doc/i2s_memcalc.md @@ -1,7 +1,7 @@ ### I2S HUB75 Calculator I've made this [spreadsheet](i2s_memcalc.xlsm) to estimate all of the main parameters for ESP32-HUB75-MatrixPanel-I2S-DMA lib driving any combination of matrixes/chains so that I do not need to reflash it hundreds of times just to check for the debug info about memory. -Be sure to enable embede macro's to allow refresh rate calculations. +Be sure to enable embeded macro's to allow refresh rate calculations. ![](i2scalc.png) Just fill-in all of the INPUT fields and get the OUTPUTs. @@ -19,16 +19,20 @@ And there are lot's of hogs for those: Equalising ones with the others results in **Refresh rate**, -or (rough approximation) $$RefreshRate=\frac{resolution \times chain \times (ColorDepth-LSB2MSB)}{ I ^2S _ {clock} }$$ +or (rough approximation) + -So, how to find otimum balance for all of these? Obviously you can't change *resolution* and *chain length* it's a physical characteristics and the is not much you can do about it except cutting of your chain or pushing it to the memory limits. +[//]: # (github markdown does not like LaTex formulas) +[//]: # ($$RefreshRate=\frac{resolution \times chain \times (ColorDepth-LSB2MSB)}{ I ^2S _ {clock} }$$) + +So, how to find optimum balance for all of these? Obviously you can't change *resolution* and *chain length*, it is physical characteristics and there is not much you can do about it except cutting of your chain or pushing it to the memory limits. There are 3 parameters you can choose from (actually two:) - - Color Depth - predefined at build-time option + - **Color Depth** - predefined at [build-time]((/doc/BuildOptions.md)) option - - $$I^2S$$ clock speed - run-time tunable with a very limited options + - I2S clock speed - run-time tunable with a very limited options -- LSB to MSB transition - it can't be controlled in any way, library uses it internaly trying to balance all of the above +- **LSB-to-MSB** transition - it can't be controlled in any way, library uses it internaly trying to balance all of the above Using provided table it is possible to estimate all of the parameters before running the library. Besides calculating memory requirements it could help to find **optimum color depth** for your matrix configuration. For higher resolutions default 8 bits could be too much to sustain minimal refresh rate and avoid annoying flickering. So the library would increase MSB transition to keep the balance, thus reducing dynamic range in shadows and dark colors. As a result it is nearly almost the same as just reducing overal color depth. **But** reducing global color depth would also saves lot's of precious RAM! Now it's all up to you to decide :)