2021-11-03 17:55:42 +01:00
|
|
|
#ifndef __leds_H__
|
|
|
|
#define __leds_H__
|
|
|
|
|
|
|
|
#include "Arduino.h"
|
|
|
|
#include <Adafruit_NeoPixel.h>
|
|
|
|
|
|
|
|
class leds
|
|
|
|
{
|
|
|
|
const uint8_t FADESTEPS = 40;
|
|
|
|
const unsigned long FADE_WAIT_MS = 10;
|
|
|
|
const uint8_t MAX_BRIGHTNESS = 255;
|
|
|
|
const uint8_t MIN_BRIGHTNESS = 10;
|
|
|
|
const unsigned long WAIT_RAINBOWCYCLE_MS = 50;
|
|
|
|
|
|
|
|
uint8_t _local_brightness = 255;
|
|
|
|
float _R = 0;
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint16_t lednr;
|
|
|
|
uint32_t color;
|
|
|
|
} _pixel;
|
|
|
|
unsigned int _pixel_nr = 0;
|
|
|
|
unsigned int _pixel_last, _pixel_first;
|
|
|
|
_pixel *_pixels;
|
2021-12-08 18:25:51 +01:00
|
|
|
uint32_t * _state_flag;
|
|
|
|
uint32_t _state_mask;
|
2021-11-03 17:55:42 +01:00
|
|
|
int _fadestep = 0;
|
|
|
|
unsigned long _last_faded_ms = 0;
|
|
|
|
bool _fading_done = false;
|
|
|
|
uint16_t _prev_state = 0;
|
|
|
|
Adafruit_NeoPixel * _stripe;
|
|
|
|
|
2021-12-08 22:58:58 +01:00
|
|
|
int _tcr_firstPixelHue;
|
|
|
|
int _tcr_b ;
|
|
|
|
|
|
|
|
|
2021-11-03 17:55:42 +01:00
|
|
|
uint8_t _s = 0;
|
|
|
|
uint16_t _h = 0;
|
|
|
|
|
|
|
|
float _calc_R();
|
|
|
|
void _setLeds();
|
|
|
|
void _setLeds(uint32_t color);
|
|
|
|
void _resetLeds(uint32_t color);
|
|
|
|
bool _fade(bool fade_in);
|
|
|
|
bool _fade_off();
|
|
|
|
bool _fade_on();
|
|
|
|
|
|
|
|
uint16_t _rainbow_pixel, _rainbow_color;
|
|
|
|
unsigned long _last_rainbowcycle = 0;
|
|
|
|
uint32_t _wheel(byte pos);
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2021-12-08 18:25:51 +01:00
|
|
|
enum led_update {UP_RAINBOW = 1, UP_FADE = 2};
|
|
|
|
|
|
|
|
leds(Adafruit_NeoPixel * stripe, uint32_t * state_flag, uint16_t state_mask, uint16_t H, uint8_t S, unsigned int pixel_first, unsigned int pixel_last );
|
2021-11-03 17:55:42 +01:00
|
|
|
~leds();
|
2021-12-08 18:25:51 +01:00
|
|
|
bool update();
|
|
|
|
bool update(led_update type);
|
2021-11-03 17:55:42 +01:00
|
|
|
void clear();
|
|
|
|
bool colorWipe( uint32_t color );
|
|
|
|
void add_button_id(uint16_t mask);
|
|
|
|
bool do_fade();
|
2021-11-15 08:25:19 +01:00
|
|
|
bool fade_off();
|
|
|
|
bool fade_on();
|
2021-11-03 17:55:42 +01:00
|
|
|
void setBrigthness(uint8_t brigthness);
|
|
|
|
void setHS(uint16_t H, uint8_t S);
|
|
|
|
void setColor(uint32_t color);
|
|
|
|
void rainbowCycle();
|
2021-12-08 18:25:51 +01:00
|
|
|
bool do_rainbowCycle();
|
2021-12-08 22:58:58 +01:00
|
|
|
void theaterChaseRainbow();
|
2021-11-03 17:55:42 +01:00
|
|
|
};
|
|
|
|
|
2021-12-08 18:25:51 +01:00
|
|
|
leds::leds(Adafruit_NeoPixel * stripe, uint32_t * state_flag, uint16_t state_mask, uint16_t H, uint8_t S, unsigned int pixel_first, unsigned int pixel_last )
|
2021-11-03 17:55:42 +01:00
|
|
|
{
|
2021-12-08 22:58:58 +01:00
|
|
|
_tcr_firstPixelHue = 0;
|
|
|
|
_tcr_b = 0;
|
2021-11-03 17:55:42 +01:00
|
|
|
_state_flag = state_flag;
|
|
|
|
_state_mask = state_mask;
|
|
|
|
_h = H;
|
|
|
|
_s = S;
|
|
|
|
_pixel_last = pixel_last;
|
|
|
|
_pixel_first = pixel_first;
|
|
|
|
_pixel_nr = 1 + abs(pixel_last - pixel_first);
|
|
|
|
_pixels = (_pixel *) malloc(sizeof(_pixel) * _pixel_nr);
|
2021-11-15 08:25:19 +01:00
|
|
|
size_t index = 0;
|
|
|
|
for(size_t nr=pixel_first; nr<=pixel_last;nr++)
|
|
|
|
{
|
|
|
|
_pixels[index].lednr = nr;
|
|
|
|
index++;
|
|
|
|
}
|
2021-11-03 17:55:42 +01:00
|
|
|
_stripe = stripe;
|
|
|
|
_R = _calc_R();
|
|
|
|
_setLeds(0);
|
|
|
|
_rainbow_pixel = 0;
|
|
|
|
_rainbow_color = 0;
|
2021-11-15 08:25:19 +01:00
|
|
|
_prev_state = *_state_flag;
|
|
|
|
_fading_done = true;
|
2021-11-03 17:55:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
leds::~leds()
|
|
|
|
{
|
|
|
|
if(NULL != _pixels)
|
|
|
|
free(_pixels);
|
|
|
|
}
|
|
|
|
|
|
|
|
void leds::_setLeds()
|
|
|
|
{
|
2021-11-15 08:25:19 +01:00
|
|
|
for(unsigned int nr = 0; nr < _pixel_nr; nr++)
|
2021-11-03 17:55:42 +01:00
|
|
|
{
|
|
|
|
_stripe->setPixelColor(_pixels[nr].lednr, _pixels[nr].color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void leds::_setLeds(uint32_t color)
|
|
|
|
{
|
2021-11-15 08:25:19 +01:00
|
|
|
for(unsigned int nr = 0; nr < _pixel_nr; nr++)
|
2021-11-03 17:55:42 +01:00
|
|
|
{
|
2021-11-15 08:25:19 +01:00
|
|
|
//Serial.printf("setting led %d with nr %d in stripe to color %d\n", nr, _pixels[nr].lednr, color);
|
2021-11-03 17:55:42 +01:00
|
|
|
_stripe->setPixelColor(_pixels[nr].lednr, color);
|
|
|
|
_pixels[nr].color = color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void leds::clear()
|
|
|
|
{
|
|
|
|
_setLeds(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void leds::add_button_id(uint16_t id)
|
|
|
|
{
|
|
|
|
_state_mask = _state_mask | id;
|
|
|
|
}
|
|
|
|
|
2021-12-08 18:25:51 +01:00
|
|
|
|
|
|
|
bool leds::update()
|
|
|
|
{
|
|
|
|
return(update(UP_FADE));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool leds::update(led_update type)
|
|
|
|
{
|
|
|
|
if(type == UP_RAINBOW )
|
|
|
|
{
|
|
|
|
return(do_rainbowCycle());
|
|
|
|
}
|
|
|
|
|
|
|
|
if(type == UP_FADE)
|
|
|
|
{
|
|
|
|
return(do_fade());
|
|
|
|
}
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool leds::do_rainbowCycle()
|
|
|
|
{
|
|
|
|
bool updated = false;
|
|
|
|
uint16_t curr_state = _state_mask & *_state_flag;
|
|
|
|
if(curr_state == 0)
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rainbowCycle();
|
|
|
|
updated = true;
|
|
|
|
}
|
|
|
|
return(updated);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-03 17:55:42 +01:00
|
|
|
bool leds::do_fade()
|
|
|
|
{
|
|
|
|
bool updated = false;
|
|
|
|
uint16_t curr_state = _state_mask & *_state_flag;
|
|
|
|
|
|
|
|
if(_prev_state != curr_state)
|
|
|
|
{
|
2021-11-15 08:25:19 +01:00
|
|
|
//Serial.printf("Current state is 0x%08x\n", curr_state);
|
2021-11-03 17:55:42 +01:00
|
|
|
_prev_state = curr_state;
|
|
|
|
_fading_done = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(_fading_done == false)
|
|
|
|
{
|
|
|
|
updated = true;
|
|
|
|
if(0 == curr_state)
|
|
|
|
{
|
|
|
|
_fade_off();
|
2021-11-15 08:25:19 +01:00
|
|
|
//Serial.printf("Fading off.\n");
|
2021-11-03 17:55:42 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_fade_on();
|
2021-11-15 08:25:19 +01:00
|
|
|
//Serial.printf("Fading ON\n");
|
2021-11-03 17:55:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return updated;
|
|
|
|
}
|
|
|
|
|
2021-11-15 08:25:19 +01:00
|
|
|
bool leds::fade_on()
|
|
|
|
{
|
|
|
|
return _fade_on();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool leds::fade_off()
|
|
|
|
{
|
|
|
|
return _fade_off();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-03 17:55:42 +01:00
|
|
|
float leds::_calc_R(void)
|
|
|
|
{
|
|
|
|
return (FADESTEPS * log10(2))/(log10(_local_brightness));
|
|
|
|
}
|
|
|
|
|
|
|
|
void leds::setBrigthness(uint8_t brigthness)
|
|
|
|
{
|
|
|
|
if(brigthness > MAX_BRIGHTNESS)
|
|
|
|
_local_brightness = MAX_BRIGHTNESS;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(brigthness < MIN_BRIGHTNESS)
|
|
|
|
_local_brightness = MIN_BRIGHTNESS;
|
|
|
|
else
|
|
|
|
_local_brightness = brigthness;
|
|
|
|
}
|
|
|
|
_R = _calc_R();
|
|
|
|
uint8_t fade = pow (2, (_fadestep / _R)) - 1;
|
|
|
|
_setLeds(_stripe->ColorHSV(_h, _s, fade));
|
|
|
|
}
|
|
|
|
|
|
|
|
void leds::setHS(uint16_t H, uint8_t S)
|
|
|
|
{
|
|
|
|
_h = H;
|
|
|
|
_s = S;
|
|
|
|
uint8_t fade = pow (2, (_fadestep / _R)) - 1;
|
|
|
|
_setLeds(_stripe->ColorHSV(_h, _s, fade));
|
|
|
|
}
|
|
|
|
|
|
|
|
void leds::setColor(uint32_t color)
|
|
|
|
{
|
|
|
|
_setLeds(color);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool leds::_fade(bool fade_in)
|
|
|
|
{
|
|
|
|
unsigned long curr_millis = millis();
|
|
|
|
|
|
|
|
if( _last_faded_ms > (curr_millis - FADE_WAIT_MS))
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
_last_faded_ms = curr_millis;
|
|
|
|
if(_fadestep != -1)
|
|
|
|
{
|
|
|
|
uint8_t fade = pow (2, (_fadestep / _R)) - 1;
|
|
|
|
_setLeds(_stripe->ColorHSV(_h, _s, fade));
|
|
|
|
}
|
|
|
|
|
|
|
|
if(true == fade_in)
|
|
|
|
{
|
|
|
|
if(_fadestep == -1)
|
|
|
|
_fadestep = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(_fadestep<FADESTEPS)
|
|
|
|
_fadestep++ ;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_fadestep = -1;
|
|
|
|
_fading_done = true;
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(_fadestep == -1)
|
|
|
|
_fadestep = FADESTEPS;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(_fadestep>0)
|
|
|
|
_fadestep--;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_fadestep = -1;
|
|
|
|
_fading_done = true;
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool leds::_fade_on()
|
|
|
|
{
|
|
|
|
return _fade(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool leds::_fade_off()
|
|
|
|
{
|
|
|
|
return _fade(false);
|
|
|
|
}
|
|
|
|
|
2021-12-08 22:58:58 +01:00
|
|
|
void leds::theaterChaseRainbow()
|
|
|
|
{
|
|
|
|
if((millis() - _last_rainbowcycle) > WAIT_RAINBOWCYCLE_MS)
|
|
|
|
{
|
|
|
|
_last_rainbowcycle = millis();
|
|
|
|
_tcr_b++;
|
|
|
|
if(_tcr_b >= 3)
|
|
|
|
_tcr_b = 0;
|
|
|
|
clear(); // Set all pixels in RAM to 0 (off)
|
|
|
|
for(int c=_tcr_b; c<_pixel_nr; c += 3)
|
|
|
|
{
|
|
|
|
int hue = _tcr_firstPixelHue + c * 65536L / _pixel_nr;
|
|
|
|
uint32_t color = _stripe->gamma32(_stripe->ColorHSV(hue)); // hue -> RGB
|
|
|
|
_pixels[c].color = color;
|
|
|
|
}
|
|
|
|
_setLeds();
|
|
|
|
_tcr_firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-03 17:55:42 +01:00
|
|
|
|
|
|
|
void leds::rainbowCycle()
|
|
|
|
{
|
|
|
|
if((millis() - _last_rainbowcycle) > WAIT_RAINBOWCYCLE_MS)
|
|
|
|
{
|
2021-11-15 08:25:19 +01:00
|
|
|
//Serial.printf("Rainbow! Next color\n");
|
2021-11-03 17:55:42 +01:00
|
|
|
_last_rainbowcycle = millis();
|
|
|
|
_rainbow_color++;
|
|
|
|
if(_rainbow_color >= 256*1)
|
|
|
|
_rainbow_color = 0;
|
|
|
|
for(size_t nr = 0; nr< _pixel_nr; ++nr) {
|
|
|
|
_pixels[nr].color = _wheel(((_rainbow_pixel * 256 / _pixel_nr) + _rainbow_color) & 255);
|
|
|
|
}
|
|
|
|
_setLeds();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Input a value 0 to 255 to get a color value.
|
|
|
|
// The colours are a transition r - g - b - back to r.
|
|
|
|
uint32_t leds::_wheel(byte pos) {
|
|
|
|
pos = 255 - pos;
|
|
|
|
if(pos < 85) {
|
|
|
|
return _stripe->Color(255 - pos * 3, 0, pos * 3);
|
|
|
|
}
|
|
|
|
if(pos < 170) {
|
|
|
|
pos -= 85;
|
|
|
|
return _stripe->Color(0, pos * 3, 255 - pos * 3);
|
|
|
|
}
|
|
|
|
pos -= 170;
|
|
|
|
return _stripe->Color(pos * 3, 255 - pos * 3, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|