diff --git a/examples/HueValueSpectrumTestDemo/HueValueSpectrumTestDemo.ino b/examples/HueValueSpectrumTestDemo/HueValueSpectrumTestDemo.ino new file mode 100644 index 0000000..3fcbb31 --- /dev/null +++ b/examples/HueValueSpectrumTestDemo/HueValueSpectrumTestDemo.ino @@ -0,0 +1,71 @@ +#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 NO_CIE1931 +#define PIXEL_COLOUR_DEPTH_BITS 8 +#include + +MatrixPanel_I2S_DMA *dma_display = nullptr; + +#define R1_PIN 25 +#define G1_PIN 26 +#define B1_PIN 27 +#define R2_PIN 14 +#define G2_PIN 12 +#define B2_PIN 13 +#define A_PIN 23 +#define B_PIN 19 +#define C_PIN 5 +#define D_PIN 17 +#define E_PIN -1 // required for 1/32 scan panels, esp for 64x64 or 128x64 displays +#define LAT_PIN 4 +#define OE_PIN 15 +#define CLK_PIN 16 + +uint32_t lastMillis; + +void setup() { + HUB75_I2S_CFG::i2s_pins _pins={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}; + HUB75_I2S_CFG mxconfig( + PANEL_RES_X, // Module width + PANEL_RES_Y, // Module height + 1, // chain length + _pins // pin mapping + ); + //mxconfig.gpio.e = 18; + //mxconfig.clkphase = false; + //mxconfig.driver = HUB75_I2S_CFG::FM6126A; + + // Display Setup + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); + dma_display->clearScreen(); +} + +void loop() { + // Canvas loop + float t = (float)(millis()%4000)/4000.f; + for(int x = 0; x < PANEL_RES_X; x++){ + float r =max(min(cosf(2.f*PI*(t+(float)x/PANEL_RES_X+0.f/3.f))+0.5f,1.f),0.f); + float g =max(min(cosf(2.f*PI*(t+(float)x/PANEL_RES_X+1.f/3.f))+0.5f,1.f),0.f); + float b =max(min(cosf(2.f*PI*(t+(float)x/PANEL_RES_X+2.f/3.f))+0.5f,1.f),0.f); + for(int y = 0; y < PANEL_RES_Y; y++) + if(y*2 < PANEL_RES_Y){ + float t = (2.f*y)/PANEL_RES_Y; + dma_display->drawPixelRGB888(x,y, + (r*t)*255, + (g*t)*255, + (b*t)*255 + ); + }else{ + float t = (2.f*(PANEL_RES_Y-y))/PANEL_RES_Y; + dma_display->drawPixelRGB888(x,y, + (r*t+1-t)*255, + (g*t+1-t)*255, + (b*t+1-t)*255 + ); + } + + } +} diff --git a/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp b/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp index 383643e..2bb4da0 100644 --- a/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp +++ b/src/ESP32-HUB75-MatrixPanel-I2S-DMA.cpp @@ -705,7 +705,20 @@ void MatrixPanel_I2S_DMA::brtCtrlOEv2(uint8_t brt, const int _buff_id) { // let's set OE control bits for specific pixels in each color_index subrows uint8_t colouridx = dma_buff.rowBits[row_idx]->colour_depth; do { - int brightness_in_x_pixels = PIXELS_PER_ROW * brt >> 8 + max( ( dma_buff.rowBits[row_idx]->colour_depth - colouridx - 2 ), 0); + // Multiply brightness according to index of bitplane (color index subrow) + // in respect of accumulating LED intensities with Binary-Coded Modulation: + // bitplane 0 is 1/1 of total brightness; bitplane 1 is 1/2; bitplane 2 is 1/4, etc + // accumulating all of them together means we will get only ~1/4 of the total brightness. + + // During the DMA, assume bitplane 0 shown for 4 subrows; bitplane 1 shown for 2 subrows; + // bitplane 2 and the rest shown for one subrow, would give us ~2/3 of the total brightness, + // which is good balance for the depth, brightness, while the flickers still less noticeable: + // row 0 (blanking)\ row 1 (blanking)\ row 2 (blanking)\ .. + // bitplane : ... 0 0 0 0 1 1 2 3 4 5 6 7 \- 0 0 0 0 1 1 2 3 4 5 6 7 \- 0 0 0 0 1 1 2 3 4 5 6 7 \- .. + // rightshift: ... 0 0 0 0 0 0 0 1 2 3 4 5 -\ 0 0 0 0 0 0 0 1 2 3 4 5 -\ 0 0 0 0 0 0 0 1 2 3 4 5 -\ .. + char bitplane = dma_buff.rowBits[row_idx]->colour_depth-colouridx; + char rightshift = std::max(bitplane-2,0); + int brightness_in_x_pixels = PIXELS_PER_ROW * brt >> 8 + rightshift; --colouridx; // switch pointer to a row for a specific color index