diff --git a/src/NeoPixelesp8266.c b/src/NeoPixelesp8266.c
new file mode 100644
index 0000000..6ecff6e
--- /dev/null
+++ b/src/NeoPixelesp8266.c
@@ -0,0 +1,104 @@
+/*-------------------------------------------------------------------------
+NeoPixel library helper functions for Esp8266 and Esp32.
+
+Written by Michael C. Miller.
+
+I invest time and resources providing this open source code,
+please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
+
+-------------------------------------------------------------------------
+This file is part of the Makuna/NeoPixelBus library.
+
+NeoPixelBus is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation, either version 3 of
+the License, or (at your option) any later version.
+
+NeoPixelBus is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with NeoPixel. If not, see
+.
+-------------------------------------------------------------------------*/
+
+#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
+
+#include
+#if defined(ARDUINO_ARCH_ESP8266)
+#include
+#endif
+
+// ESP32 doesn't define ICACHE_RAM_ATTR
+#ifndef ICACHE_RAM_ATTR
+#define ICACHE_RAM_ATTR IRAM_ATTR
+#endif
+
+inline uint32_t _getCycleCount()
+{
+ uint32_t ccount;
+ __asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
+ return ccount;
+}
+
+//#define CYCLES_800_T0H (F_CPU / 2500000) // 0.4us
+//#define CYCLES_800_T1H (F_CPU / 1250000) // 0.8us
+//#define CYCLES_800 (F_CPU / 800000) // 1.25us per bit
+#define CYCLES_800_T0H (F_CPU / 2600000) // 0.4us
+#define CYCLES_800_T1H (F_CPU / 1350000) // 0.8us
+#define CYCLES_800 (F_CPU / 900000) // 1.25us per bit
+
+void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixels, size_t count, uint8_t pin)
+{
+ const uint32_t pinRegister = _BV(pin);
+ uint8_t mask;
+ uint8_t subpix;
+ uint32_t cyclesStart;
+ uint8_t *end = pixels + (3 * count);
+
+ // trigger emediately
+ cyclesStart = _getCycleCount() - CYCLES_800;
+ do
+ {
+ subpix = *pixels++;
+ for (mask = 0x80; mask != 0; mask >>= 1)
+ {
+ // do the checks here while we are waiting on time to pass
+ uint32_t cyclesBit = ((subpix & mask)) ? CYCLES_800_T1H : CYCLES_800_T0H;
+ uint32_t cyclesNext = cyclesStart;
+
+ // after we have done as much work as needed for this next bit
+ // now wait for the HIGH
+ do
+ {
+ // cache and use this count so we don't incur another
+ // instruction before we turn the bit high
+ cyclesStart = _getCycleCount();
+ } while ((cyclesStart - cyclesNext) < CYCLES_800);
+
+ // set high
+#if defined(ARDUINO_ARCH_ESP32)
+ GPIO.out_w1ts = pinRegister;
+#else
+ GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinRegister);
+#endif
+
+ // wait for the LOW
+ do
+ {
+ cyclesNext = _getCycleCount();
+ } while ((cyclesNext - cyclesStart) < cyclesBit);
+
+ // set low
+#if defined(ARDUINO_ARCH_ESP32)
+ GPIO.out_w1tc = pinRegister;
+#else
+ GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
+#endif
+ }
+ } while (pixels < end);
+}
+
+#endif
diff --git a/src/wsLED.cpp b/src/wsLED.cpp
new file mode 100644
index 0000000..a824f75
--- /dev/null
+++ b/src/wsLED.cpp
@@ -0,0 +1,145 @@
+// Ovladani signalizacni chytre LED diody
+#include "wsLED.h"
+// due to linker overriding the ICACHE_RAM_ATTR for cpp files, these methods are
+// moved into a C file so the attribute will be applied correctly
+extern "C" void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixel, size_t count, uint8_t pin);
+
+#define countof(a) (sizeof(a) / sizeof(a[0]))
+
+static const uint16_t LB[] PROGMEM = {
+ 0x201 , 0x202 , 0x103 , 0x104 , 0x105 , 0x106 , 0x107 , 0x109 , 0x10a , 0x10c , 0x10e , 0x110 , 0x112 , 0x114 , 0x116 , 0x119 , 0x11c , 0x11e , 0x122 , 0x125 , 0x128 , 0x12c , 0x130 , 0x134,
+ 0x139 , 0x13d , 0x142 , 0x147 , 0x14d , 0x152 , 0x158 , 0x15e , 0x165 , 0x16b , 0x172 , 0x179 , 0x180 , 0x187 , 0x18e , 0x196 , 0x19d , 0x1a5 , 0x1ac , 0x1b3 , 0x1bb , 0x1c2 , 0x1c9 , 0x1cf,
+ 0x1d6 , 0x1dc , 0x1e2 , 0x1e7 , 0x1ec , 0x1f0 , 0x1f4 , 0x1f7 , 0x1fa , 0x1fc , 0x1fd , 0x3fe , 0x1fd , 0x1fb , 0x1f8 , 0x1f5 , 0x1f2 , 0x1ed , 0x1e9 , 0x1e4 , 0x1de , 0x1d8 , 0x1d2 , 0x1cb,
+ 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 , 0x2a00
+};
+
+inline bool wsLED::canShow(void)
+{
+
+ return (micros() - _endtime) >= 50L;
+}
+
+void wsLED::show(void)
+{
+ uint8_t color[3];
+
+ for (uint8_t i = 0; i < 3; i++) {
+// https://github.com/FastLED/FastLED/wiki/FastLED-Color-Correction
+ uint16_t c = (uint16_t)_color[i] * (1 + (uint16_t)_scale);
+ color[i] = (uint8_t)(c >> 8);
+ }
+ while (!canShow())
+ __asm__ volatile ("nop");
+#if defined(ARDUINO_ARCH_ESP32)
+ uint32_t volatile register ilevel = XTOS_DISABLE_ALL_INTERRUPTS;
+#else
+ noInterrupts();
+ //cli();
+#endif
+ send_pixels_800(color, 1, _pin);
+#if defined(ARDUINO_ARCH_ESP32)
+ XTOS_RESTORE_INTLEVEL(ilevel);
+#else
+ interrupts();
+ //sei();
+#endif
+ _endtime = micros();
+}
+
+
+wsLED::wsLED(int pin, int order)
+{
+
+ _pin = pin;
+ _order = order;
+}
+
+void wsLED::begin(void)
+{
+
+ pinMode(_pin, OUTPUT);
+ _color[0] = _color[1] = _color[2] = 0;
+ show();
+}
+
+void wsLED::setColor(LEDRGB &color)
+{
+
+ _color[(_order >> 6) & 7] = color.r;
+ _color[(_order >> 3) & 7] = color.g;
+ _color[_order & 7] = color.b;
+}
+
+void ICACHE_RAM_ATTR wsLED::rtLed(void)
+{
+
+ switch (_ledState) {
+ case LED_BLINK:
+ _scale = 0xff;
+ if (_subState) {
+ _subState = 0;
+ setColor(_color2);
+ } else {
+ _subState = 1;
+ setColor(_color1);
+ }
+ show();
+ break;
+
+
+ case LED_BREATH: {
+ ++_subState;
+ _subState %= countof(LB);
+ uint16_t val = pgm_read_word(&LB[_subState]);
+ _scale = (uint8_t)val;
+ show();
+ val >>= 8;
+ _handler.attach_ms(30ul * val, lh, this);
+ break;
+ }
+
+ default:
+ _handler.attach_ms(300, lh, this); // jen pomale casovani
+ break;
+ }
+}
+
+void ICACHE_RAM_ATTR wsLED::lh(wsLED *ptr)
+{
+
+ wsLED *pled = ptr;
+ pled->rtLed();
+}
+
+void wsLED::setColors(LEDRGB color1, LEDRGB color2)
+{
+
+ _color1 = color1;
+ _color2 = color2;
+}
+
+void wsLED::blink(int speed)
+{
+
+ _handler.detach();
+ _ledState = LED_BLINK;
+ _subState = 1;
+ _handler.attach_ms(300, lh, this);
+}
+
+void wsLED::breath(void)
+{
+
+ _handler.detach();
+ _ledState = LED_BREATH;
+ _subState = 0;
+ setColor(_color1);
+ _handler.attach_ms(1, lh, this);
+}
+
+void wsLED::setOrder(int neworder)
+{
+
+ _order = neworder;
+}
diff --git a/src/wsLED.h b/src/wsLED.h
new file mode 100644
index 0000000..aec7773
--- /dev/null
+++ b/src/wsLED.h
@@ -0,0 +1,151 @@
+// Ovladani RGB WS2812 LED diody pro signalizacni ucely
+/**The MIT License (MIT)
+Copyright (c) 2017,2020 by Pavel Brychta
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+See more at http://www.xpablo.cz
+*/
+
+#ifndef __WSLED_H__
+#define __WSLED_H__
+#include
+#include
+
+struct LEDRGB {
+ union {
+ struct {
+ union {
+ uint8_t r;
+ uint8_t red;
+ };
+ union {
+ uint8_t g;
+ uint8_t green;
+ };
+ union {
+ uint8_t b;
+ uint8_t blue;
+ };
+ };
+ uint8_t raw[3];
+ };
+
+ // Array access operator to index into the crgb object
+ inline uint8_t& operator[] (uint8_t x) __attribute__((always_inline))
+ {
+ return raw[x];
+ }
+
+ // Array access operator to index into the crgb object
+ inline const uint8_t& operator[] (uint8_t x) const __attribute__((always_inline))
+ {
+ return raw[x];
+ }
+
+ // default values are UNINITIALIZED
+ inline LEDRGB() __attribute__((always_inline))
+ {
+ }
+
+ // allow construction from R, G, B
+ inline LEDRGB( uint8_t ir, uint8_t ig, uint8_t ib) __attribute__((always_inline))
+ : r(ir), g(ig), b(ib)
+ {
+ }
+
+ // allow construction from 32-bit (really 24-bit) bit 0xRRGGBB color code
+ inline LEDRGB( uint32_t colorcode) __attribute__((always_inline))
+ : r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF)
+ {
+ }
+
+ // allow copy construction
+ inline LEDRGB(const LEDRGB& rhs) __attribute__((always_inline))
+ {
+ r = rhs.r;
+ g = rhs.g;
+ b = rhs.b;
+ }
+
+ // allow assignment from one RGB struct to another
+ inline LEDRGB& operator= (const LEDRGB& rhs) __attribute__((always_inline))
+ {
+ r = rhs.r;
+ g = rhs.g;
+ b = rhs.b;
+ return *this;
+ }
+
+ // allow assignment from 32-bit (really 24-bit) 0xRRGGBB color code
+ inline LEDRGB& operator= (const uint32_t colorcode) __attribute__((always_inline))
+ {
+ r = (colorcode >> 16) & 0xFF;
+ g = (colorcode >> 8) & 0xFF;
+ b = (colorcode >> 0) & 0xFF;
+ return *this;
+ }
+
+ // allow assignment from R, G, and B
+ inline LEDRGB& setRGB (uint8_t nr, uint8_t ng, uint8_t nb) __attribute__((always_inline))
+ {
+ r = nr;
+ g = ng;
+ b = nb;
+ return *this;
+ }
+};
+
+enum ColorOrder {
+ RGB = 0012,
+ GRB = 0102
+};
+
+class wsLED
+{
+protected:
+ int _pin; // pin, na kterem je LED pripojena
+ LEDRGB _color1;
+ LEDRGB _color2;
+ int _order; // ColorOrder
+ uint32_t _endtime;
+ uint8_t _scale;
+ uint8_t _color[3];
+ Ticker _handler;
+ enum {
+ LED_STOP = 0,
+ LED_BLINK,
+ LED_BREATH,
+ LED_PATTERN,
+ } _ledState; // stav LEDky (blika, dycha, ...)
+ int _subState; // pomocny stav/index v poli dychani
+
+ bool canShow(void);
+ void show(void);
+ void setColor(LEDRGB &color);
+
+public:
+ wsLED(int pin, int order = RGB);
+ void begin(void);
+ static void lh(wsLED *ptr);
+ void rtLed(void); // vykonna metoda
+ void setColors(LEDRGB color1, LEDRGB color2 = LEDRGB(0, 0, 0));
+ void blink(int speed = 300);
+ void breath(void);
+ void setOrder(int neworder);
+};
+
+#endif
+