Skip to content

Commit 499032e

Browse files
authored
Add I2S prefill & multisegment parallel output (#17)
* Add parallel output mode for segments * Use snprintf * Better statistics update * Critical fixes. Add a semaphore. (WIP) * Update benchmark results * Increase buffer * Update README.md * Switch ESP32-S2 single segment to I2S * Improved statistics formatting * Minor changes * Increase priority * Final changes * Version * Upgrade to v9 protocol
1 parent e7b43cf commit 499032e

File tree

9 files changed

+214
-279
lines changed

9 files changed

+214
-279
lines changed

MakunaNeoPixelBusLicence.txt

Lines changed: 0 additions & 165 deletions
This file was deleted.

README.md

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ RGB to RGBW conversion is calibrated for the neutral white channel BTF SK6812 bu
1818

1919
# Example of supported boards
2020

21-
**ESP32 MH-ET Live (CH9102x/CP2104) and ESP32-S2 Lolin mini (CDC)**
21+
**ESP32 MH-ET Live (CP2104 or CH9102x: for Windows you may need CH343CDC driver from *wch* website) and ESP32-S2 Lolin mini (CDC)**
2222
<p align="center">
2323
<img src="https://user-images.githubusercontent.com/69086569/207587620-1c4c53c8-426c-486e-a6d9-d429fd1b050d.png" /><img src="https://user-images.githubusercontent.com/69086569/207587635-b7816329-0e29-47ee-a75a-bc6c41cdc51f.png" />
2424
</p>
@@ -60,7 +60,7 @@ Enabling `White channel calibration` is optional, if you want to fine tune the w
6060
# Compiling
6161

6262
Currently we use PlatformIO to compile the project. Install [Visual Studio Code](https://code.visualstudio.com/) and add [PlatformIO plugin](https://platformio.org/).
63-
This environment will take care of everything and compile the firmware for you. Low-level LED strip support is provided by the https://github.com/Makuna/NeoPixelBus library.
63+
This environment will take care of everything and compile the firmware for you. Low-level LED strip support is provided by my highly optimizated (pre-fill I2S DMA modes, turbo I2S parallel mode for up to 2 segments etc) version of Neopixelbus library: [link](https://github.com/awawa-dev/NeoPixelBus).
6464

6565
But there is also an alternative and an easier way. Just fork the project and enable its Github Action. Use the online editor to make changes to the ```platformio.ini``` file, for example change default pin-outs/speed or enable multi-segments support, and save it. Github Action will compile new firmware automatically in the Artifacts archive. It has never been so easy!
6666

@@ -100,23 +100,23 @@ build_flags = -DNEOPIXEL_RGB -DDATA_PIN=2 ${env.build_flags} -DSECOND_SEGMENT_ST
100100

101101
# Some benchmark results
102102

103-
ESP32 MH-ET LIVE mini is capable of 4Mb serial port speed and ESP32-S2 lolin mini is capable of 5Mb. But to give equal chances all models were tested using the default speed of 2Mb.
103+
ESP32 MH-ET LIVE mini is capable of 4Mb serial port speed and ESP32-S2 lolin mini is capable of 5Mb. But to give equal chances for a single-segment mode all models were tested using the default speed of 2Mb which should saturate Neopixel data line. Parallel multi-segment mode uses the highest option available because communication performance is critical here.
104104

105-
## Multi-segments can double your large sk6812/ws2812b setup refresh rate for free. All you need is to properly project & construct the LED strip and use HyperSerialESP32 v8.
105+
## Parallel multi-segments can double your large sk6812/ws2812b setup refresh rate for free. All you need is to properly project & construct the LED strip and use HyperSerialESP32 v9. Parallel communication provides perfect synchronization between Neopixel segments.
106106

107-
| LED strip / Device | ESP32<br>MH-ET LIVE mini |
108-
|----------------------------------------------------------------------------------|--------------------------|
109-
| 300LEDs<br>Refresh rate/continues output=100Hz<br>SECOND_SEGMENT_START_INDEX=150 | 93-97 |
110-
| 600LEDs<br>Refresh rate/continues output=100Hz<br>SECOND_SEGMENT_START_INDEX=300 | 78-79 |
111-
| 900LEDs<br>Refresh rate/continues output=100Hz<br>SECOND_SEGMENT_START_INDEX=450 | 55-56 |
107+
| LED strip / Device | ESP32<br>MH-ET LIVE mini @ 4Mb speed | ESP32-S2<br> Lolin mini @ 5Mb speed |
108+
|-----------------------------------------------------------------------------------------|--------------------------|------------------------------|
109+
| 300LEDs sk6812<br>Refresh rate/continues output=100Hz<br>SECOND_SEGMENT_START_INDEX=150 | 100 | 100 |
110+
| 600LEDs sk6812<br>Refresh rate/continues output=100Hz<br>SECOND_SEGMENT_START_INDEX=300 | 83 | 82 |
111+
| 900LEDs sk6812<br>Refresh rate/continues output=**60Hz** <br>SECOND_SEGMENT_START_INDEX=450 | 54-56 | 55-56 |
112112

113-
## Comparing v6.1 and v8 version (single segment) refresh rate using MH-ET LIVE mini
113+
## Comparing v6.1 and v9 version (single segment) refresh rate using MH-ET LIVE mini
114114

115-
| LED strip / Device | ESP32<br>MH-ET LIVE mini<br>HyperSerialESP32 v6.1 | ESP32<br>MH-ET LIVE mini<br>HyperSerialESP32 v8 |
115+
| LED strip / Device | ESP32<br>MH-ET LIVE mini<br>HyperSerialESP32 v6.1 | ESP32<br>MH-ET LIVE mini<br>HyperSerialESP32 v9 |
116116
|------------------------------------------------|---------------------------------------------------|-------------------------------------------------|
117-
| 300LEDs<br>Refresh rate/continues output=100Hz | 81-83 | 80-83 |
117+
| 300LEDs<br>Refresh rate/continues output=100Hz | 81-83 | 83 |
118118
| 600LEDs<br>Refresh rate/continues output=60Hz | 39-40 | 41-42 |
119-
| 900LEDs<br>Refresh rate/continues output=40Hz | 21-26 | 26-28 |
119+
| 900LEDs<br>Refresh rate/continues output=40Hz | 21-26 | 28 |
120120

121121
## Comparing v6.1 and v8 version (single segment) refresh rate using generic ESP32 with CH340C
122122

@@ -134,8 +134,3 @@ ESP32 MH-ET LIVE mini is capable of 4Mb serial port speed and ESP32-S2 lolin min
134134
| 600LEDs<br>Refresh rate/continues output=60Hz | 42 |
135135
| 900LEDs<br>Refresh rate/continues output=40Hz | 27-28 |
136136

137-
# Disclaimer
138-
139-
You use it on your own risk.
140-
Don't touch these firmwares if you don't know how to put the device in the programming mode if something goes wrong.
141-
As per the MIT license, I assume no liability for any damage to you or any other person or equipment.

include/base.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#ifndef BASE_H
2929
#define BASE_H
3030

31+
#include "freertos/semphr.h"
32+
3133
#if defined(SECOND_SEGMENT_START_INDEX)
3234
#if !defined(SECOND_SEGMENT_DATA_PIN)
3335
#error "Please define SECOND_SEGMENT_DATA_PIN for second segment"
@@ -49,13 +51,16 @@ class Base
4951

5052
public:
5153
// static data buffer for the loop
52-
uint8_t buffer[MAX_BUFFER];
54+
uint8_t buffer[MAX_BUFFER + 1] = {0};
5355
// handle to tasks
54-
TaskHandle_t processTaskHandle;
56+
TaskHandle_t processDataHandle = nullptr;
57+
TaskHandle_t processSerialHandle = nullptr;
58+
// semaphore to synchronize them
59+
xSemaphoreHandle i2sXSemaphore;
5560
// current queue position
56-
uint16_t queueCurrent = 0;
61+
volatile int queueCurrent = 0;
5762
// queue end position
58-
volatile uint16_t queueEnd = 0;
63+
volatile int queueEnd = 0;
5964

6065
inline int getLedsNumber()
6166
{
@@ -128,6 +133,11 @@ class Base
128133
return readyToRender;
129134
}
130135

136+
inline void dropLateFrame()
137+
{
138+
readyToRender = false;
139+
}
140+
131141
inline void renderLeds(bool newFrame)
132142
{
133143
if (newFrame)

include/calibration.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,10 @@ class CalibrationConfig
119119
*/
120120
void printCalibration()
121121
{
122-
#ifdef SerialPort
123-
SerialPort.write("\r\nRGBW => Gain: ");
124-
SerialPort.print(gain);
125-
SerialPort.write("/255, red: ");
126-
SerialPort.print(red);
127-
SerialPort.write(" , green: ");
128-
SerialPort.print(green);
129-
SerialPort.write(" , blue: ");
130-
SerialPort.print(blue);
122+
#ifdef SerialPort
123+
char output[128];
124+
snprintf(output, sizeof(output),"RGBW => Gain: %i/255, red: %i, green: %i, blue: %i\r\n", gain, red, green, blue);
125+
SerialPort.print(output);
131126
#endif
132127
}
133128
} calibrationConfig;

include/framestate.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ enum class AwaProtocol
5858
*/
5959
class
6060
{
61-
AwaProtocol state = AwaProtocol::HEADER_A;
61+
volatile AwaProtocol state = AwaProtocol::HEADER_A;
6262
bool protocolVersion2 = false;
6363
uint8_t CRC = 0;
6464
uint16_t count = 0;
@@ -85,6 +85,7 @@ class
8585
fletcher2 = 0;
8686
fletcherExt = 0;
8787
position = 0;
88+
base.dropLateFrame();
8889
}
8990

9091
/**

0 commit comments

Comments
 (0)