DOPLED 1.1.1
ESP32 Library for driving 24-29V low speed Data Over Power LED Sets
 
Loading...
Searching...
No Matches
DOPLED.h
1
14#ifndef DOPLED_H
15#define DOPLED_H
16
17#include "Arduino.h"
18#include "driver/rmt_tx.h"
19
26class DOPLED
27{
28public:
39 DOPLED(uint8_t pin, uint8_t timeBase_us);
48 DOPLED(uint8_t pin);
55 void begin();
62 void end();
73 void sendRaw(uint8_t *data, size_t size);
96 void fillMatchingAddresses(uint8_t mask, uint8_t address, uint8_t r, uint8_t g, uint8_t b);
108 void writePixel(uint8_t address, uint8_t r, uint8_t g, uint8_t b);
119 void fillAll(uint8_t r, uint8_t g, uint8_t b);
149 void fillRandomGroups(uint8_t mask, uint8_t address, uint8_t r, uint8_t g, uint8_t b);
159 void setFlags(uint8_t flagByte);
168 bool transmitDone();
173 ~DOPLED();
174
175private:
176 static const unsigned long RMT_RESOLUTION_HZ = 1000000;
177 static const unsigned int RMT_TICK_US = (RMT_RESOLUTION_HZ / 1000000);
178
179 static const unsigned int DEFAULT_TIMING_BASE_US = 70;
180
181 static const unsigned int T0L = 1 * RMT_TICK_US;
182 static const unsigned int T0H = 1 * RMT_TICK_US;
183 static const unsigned int T1L = 1 * RMT_TICK_US;
184 static const unsigned int T1H = 3 * RMT_TICK_US;
185 static const unsigned int PRE_PKT_L = 1 * RMT_TICK_US;
186 static const unsigned int INTER_PKT_H = 7 * RMT_TICK_US;
187
188 unsigned int timebase;
189
190 uint8_t _setCommand = 0b00110000;
191 uint8_t _fillCommand = 0b00011000;
192 uint8_t _randFillCommand = 0b01001000;
193
194 struct dopled_encoder_t
195 {
196 rmt_encoder_t base;
197 rmt_encoder_t *bytes_encoder;
198 rmt_encoder_t *copy_encoder;
199 int state;
200
201 rmt_symbol_word_t leading_symbol;
202 rmt_symbol_word_t ending_symbol;
203 };
204
205 uint8_t _pin;
206 bool _initialized = false;
207 bool _txDone = true;
208 rmt_channel_handle_t led_chan = NULL;
209 rmt_encoder_handle_t dopled_encoder = NULL;
210 rmt_transmit_config_t tx_config;
211
212 static size_t rmt_encode_dopled(
213 rmt_encoder_t *encoder,
214 rmt_channel_handle_t channel,
215 const void *primary_data,
216 size_t data_size,
217 rmt_encode_state_t *ret_state)
218 {
219 dopled_encoder_t *led_encoder = __containerof(encoder, dopled_encoder_t, base);
220 rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder;
221 rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder;
222 rmt_encode_state_t session_state = RMT_ENCODING_RESET;
223 rmt_encode_state_t state = RMT_ENCODING_RESET;
224 size_t encoded_symbols = 0;
225 switch (led_encoder->state)
226 {
227 case 0: // leading symbol
228 encoded_symbols += copy_encoder->encode(
229 copy_encoder,
230 channel,
231 &led_encoder->leading_symbol,
232 sizeof(rmt_symbol_word_t),
233 &session_state);
234 if (session_state & RMT_ENCODING_COMPLETE)
235 {
236 led_encoder->state = 1; // we can only switch to the next state when the current encoder finished
237 }
238 if (session_state & RMT_ENCODING_MEM_FULL)
239 {
240 state = RMT_ENCODING_MEM_FULL;
241 goto out; // yield if there is no free space to put other encoding artifacts
242 }
243 // fall-through
244 case 1: // send data
245 encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state);
246 if (session_state & RMT_ENCODING_COMPLETE)
247 {
248 led_encoder->state = 2; // switch to next state when current encoding session finished
249 }
250 if (session_state & RMT_ENCODING_MEM_FULL)
251 {
252 state = RMT_ENCODING_MEM_FULL;
253 goto out; // yield if there is no free space to put other encoding artifacts
254 }
255 // fall-through
256 case 2: // send reset code
257 encoded_symbols += copy_encoder->encode(
258 copy_encoder,
259 channel,
260 &led_encoder->ending_symbol,
261 sizeof(rmt_symbol_word_t),
262 &session_state);
263 if (session_state & RMT_ENCODING_COMPLETE)
264 {
265 led_encoder->state = RMT_ENCODING_RESET; // back to the initial encoding session
266 state = RMT_ENCODING_COMPLETE; // telling the caller the encoding has finished
267 }
268 if (session_state & RMT_ENCODING_MEM_FULL)
269 {
270 state = RMT_ENCODING_MEM_FULL;
271 goto out; // yield if there is no free space to put other encoding artifacts
272 }
273 }
274 out:
275 *ret_state = state;
276 return encoded_symbols;
277 }
278
279 static esp_err_t rmt_del_dopled_encoder(rmt_encoder_t *encoder)
280 {
281 dopled_encoder_t *led_encoder = __containerof(encoder, dopled_encoder_t, base);
282 rmt_del_encoder(led_encoder->bytes_encoder);
283 rmt_del_encoder(led_encoder->copy_encoder);
284 free(led_encoder);
285 return ESP_OK;
286 }
287
288 static esp_err_t rmt_dopled_encoder_reset(rmt_encoder_t *encoder)
289 {
290 dopled_encoder_t *led_encoder = __containerof(encoder, dopled_encoder_t, base);
291 rmt_encoder_reset(led_encoder->bytes_encoder);
292 rmt_encoder_reset(led_encoder->copy_encoder);
293 led_encoder->state = RMT_ENCODING_RESET;
294 return ESP_OK;
295 }
296
297 esp_err_t rmt_new_dopled_encoder(rmt_encoder_handle_t *ret_encoder);
298
299 friend bool dopled_tx_done_callback(
300 rmt_channel_handle_t,
301 const rmt_tx_done_event_data_t *,
302 void *);
303};
304
305#endif
Driver for Data Over Power addressable LEDs.
Definition DOPLED.h:27
void fillRandomGroups(uint8_t mask, uint8_t address, uint8_t r, uint8_t g, uint8_t b)
Creates random groups and sets them to a specific color.
Definition DOPLED.cpp:197
DOPLED(uint8_t pin, uint8_t timeBase_us)
Creates a DOPLED Object with a specific timebase.
Definition DOPLED.cpp:27
void writePixel(uint8_t address, uint8_t r, uint8_t g, uint8_t b)
Sets a specific pixel to a specific color.
Definition DOPLED.cpp:181
~DOPLED()
Definition DOPLED.cpp:221
bool transmitDone()
Checks if the previous transmission has completed.
Definition DOPLED.cpp:216
void end()
Disables the ESP32's RMT output and set the pin LOW.
Definition DOPLED.cpp:127
void sendRaw(uint8_t *data, size_t size)
Definition DOPLED.cpp:148
void setFlags(uint8_t flagByte)
Definition DOPLED.cpp:209
void fillMatchingAddresses(uint8_t mask, uint8_t address, uint8_t r, uint8_t g, uint8_t b)
Definition DOPLED.cpp:168
void fillAll(uint8_t r, uint8_t g, uint8_t b)
Fills all pixels with a specific color.
Definition DOPLED.cpp:186
void begin()
Enables the ESP32's RMT output.
Definition DOPLED.cpp:115