diff --git a/src/WSLed.cpp b/src/WSLed.cpp index 7ca0fba..c386bcf 100644 --- a/src/WSLed.cpp +++ b/src/WSLed.cpp @@ -1,6 +1,7 @@ // Ovladani signalizacni chytre LED diody #include "WSLed.hpp" #include +#include #if defined(ARDUINO_ARCH_ESP32) // # include "esp_task.h" // https://github.com/JSchaenzle/ESP32-NeoPixel-WS2812-RMT/blob/master/ws2812_control.c @@ -31,20 +32,12 @@ static const uint16_t LB[] ACPU_PROGMEM = { 0x1c4, 0x1bd, 0x1b6, 0x1af, 0x1a7, 0x1a0, 0x198, 0x191, 0x18a, 0x182, 0x17b, 0x174, 0x16d, 0x167, 0x161, 0x15a, 0x154, 0x14f, 0x149, 0x144, 0x13f, 0x13a, 0x136, 0x131, 0x12d, 0x12a, 0x126, 0x123, 0x11f, 0x11c, 0x11a, 0x117, 0x115, 0x112, 0x110, 0x10e, 0x10c, 0x10b, 0x109, 0x108, 0x107, 0x105, 0x104, 0x203, 0x102, 0x201, 0x2900}; -static void ledTrampoline(wsLED * ptr) -{ - - ptr->rtLed(); -} - -inline bool wsLED::canShow() const -{ +inline bool wsLED::canShow() const { return (micros() - mEndTime) >= 70L; } -void wsLED::show() -{ +void wsLED::show() { uint8_t color[3]; for (uint8_t i = 0; i < 3; i++) { @@ -52,8 +45,13 @@ void wsLED::show() uint16_t c = (uint16_t) mColor[i] * (1 + (uint16_t) mScale); color[i] = (uint8_t) (c >> 8); } - while (!canShow()) + if (memcmp(color, mPrevColor, 3) == 0) { + return; // no change + } + memcpy(mPrevColor, color, 3); + while (!canShow()) { __asm__ volatile("nop"); + } #if defined(ARDUINO_ARCH_ESP32) uint32_t bits_to_send = ((uint32_t) color[0] << 16) | ((uint32_t) color[1] << 8) | (uint32_t) color[2]; uint32_t mask = 1 << (BITS_PER_LED_CMD - 1); @@ -78,13 +76,11 @@ void wsLED::show() } wsLED::wsLED(int pin, int order) - : mPin(pin), mOrder(order) -{ + : mPin(pin), mOrder(order) { } wsLED::wsLED() - : mPin(NOT_A_PIN), mOrder(RGB) -{ + : mPin(NOT_A_PIN), mOrder(RGB) { } void wsLED::begin(int pin) @@ -94,8 +90,7 @@ void wsLED::begin(int pin) begin(); } -void wsLED::begin() -{ +void wsLED::begin() { if (NOT_A_PIN != mPin) { #if defined(ARDUINO_ARCH_ESP8266) @@ -122,16 +117,14 @@ void wsLED::begin() } } -void wsLED::setColor(const LEDRGB & color) -{ +void wsLED::setColor(const LEDRGB & color) { mColor[(mOrder >> 6) & 7] = color.r; mColor[(mOrder >> 3) & 7] = color.g; mColor[mOrder & 7] = color.b; } -void wsLED::rtLed() -{ +void wsLED::rtLed() { uint32_t timing; mTimer.detach(); @@ -178,11 +171,10 @@ void wsLED::rtLed() break; } show(); - mTimer.attach_ms(timing, ledTrampoline, this); + mTimer.attach_ms(timing, wsLED::ledTrampoline, this); } -void wsLED::setColors(const LEDRGB & color1, const LEDRGB & color2) -{ +void wsLED::setColors(const LEDRGB & color1, const LEDRGB & color2) { mColor1 = color1; mColor2 = color2; @@ -191,8 +183,7 @@ void wsLED::setColors(const LEDRGB & color1, const LEDRGB & color2) } } -void wsLED::blink(uint32_t speed) -{ +void wsLED::blink(uint32_t speed) { if (NOT_A_PIN != mPin) { if (LED_BLINK != mLedState) { @@ -201,13 +192,12 @@ void wsLED::blink(uint32_t speed) mScale = 0xff; mSubState = 1; mBlinkSpeed = speed; - mTimer.attach_ms(5, ledTrampoline, this); + mTimer.attach_ms(5, wsLED::ledTrampoline, this); } } } -void wsLED::breath() -{ +void wsLED::breath() { if (NOT_A_PIN != mPin) { if (LED_BREATH != mLedState) { @@ -215,19 +205,17 @@ void wsLED::breath() mLedState = LED_BREATH; mSubState = 0; setColor(mColor1); - mTimer.attach_ms(5, ledTrampoline, this); + mTimer.attach_ms(5, wsLED::ledTrampoline, this); } } } -void wsLED::setOrder(int neworder) -{ +void wsLED::setOrder(int neworder) { mOrder = neworder; } -void wsLED::pulse(const LEDRGB & color, uint32_t duration) -{ +void wsLED::pulse(const LEDRGB & color, uint32_t duration) { if (NOT_A_PIN != mPin) { mTimer.detach(); @@ -240,18 +228,16 @@ void wsLED::pulse(const LEDRGB & color, uint32_t duration) } mPulseDuration = duration; mLedState = LED_PULSE_START; - mTimer.attach_ms(5, ledTrampoline, this); + mTimer.attach_ms(5, wsLED::ledTrampoline, this); } } -ledstate_t wsLED::getState() -{ +ledstate_t wsLED::getState() { return mLedState; } -void wsLED::stop(const LEDRGB & color) -{ +void wsLED::stop(const LEDRGB & color) { if (NOT_A_PIN != mPin) { mTimer.detach(); diff --git a/src/WSLed.hpp b/src/WSLed.hpp index b4f7dfb..4d6abb8 100644 --- a/src/WSLed.hpp +++ b/src/WSLed.hpp @@ -136,7 +136,7 @@ class wsLED { Ticker mTimer; volatile ledstate_t mLedState = LED_STOP; // stav LEDky (blika, dycha, ...) volatile ledstate_t mSavedState = LED_STOP; // stav pro navrat - volatile int mSubState = 0; // pomocny stav/index v poli dychani + volatile unsigned mSubState = 0; // pomocny stav/index v poli dychani uint32_t mPulseDuration = 0; uint32_t mBlinkSpeed = 0; LEDRGB mPulseColor; @@ -145,17 +145,24 @@ class wsLED { rmt_item32_t led_data_buffer[LED_BUFFER_ITEMS] = {0}; #endif uint32_t mEndTime = 0; + uint8_t mPrevColor[3] = {1, 2, 3}; // some not used colors void show(); void setColor(const LEDRGB & color); [[nodiscard]] bool canShow() const; + void rtLed(); // vykonna metoda + + static void ledTrampoline(wsLED * ptr) { + + ptr->rtLed(); + } + public: - wsLED(int pin, int order = RGB); + explicit wsLED(int pin, int order = RGB); wsLED(); void begin(); void begin(int pin); - void rtLed(); // vykonna metoda void setColors(const LEDRGB & color1, const LEDRGB & color2 = LEDRGB(0, 0, 0)); void blink(uint32_t speed = 300); void breath();