Ulozeni kodu
This commit is contained in:
parent
fbc32db3fd
commit
69a5b37616
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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user