Ulozeni kodu
This commit is contained in:
		
							
								
								
									
										104
									
								
								src/NeoPixelesp8266.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/NeoPixelesp8266.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| <http://www.gnu.org/licenses/>. | ||||
| -------------------------------------------------------------------------*/ | ||||
|  | ||||
| #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) | ||||
|  | ||||
| #include <Arduino.h> | ||||
| #if defined(ARDUINO_ARCH_ESP8266) | ||||
| #include <eagle_soc.h> | ||||
| #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 | ||||
							
								
								
									
										145
									
								
								src/wsLED.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/wsLED.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
| } | ||||
							
								
								
									
										151
									
								
								src/wsLED.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								src/wsLED.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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 <Arduino.h> | ||||
| #include <Ticker.h> | ||||
|  | ||||
| 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 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user