#ifndef __leds_H__ #define __leds_H__ #include "Arduino.h" #include 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; uint16_t * _state_flag; uint16_t _state_mask; int _fadestep = 0; unsigned long _last_faded_ms = 0; bool _fading_done = false; uint16_t _prev_state = 0; Adafruit_NeoPixel * _stripe; 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: leds(Adafruit_NeoPixel * stripe, uint16_t * state_flag, uint16_t state_mask, uint16_t H, uint8_t S, unsigned int pixel_first, unsigned int pixel_last ); ~leds(); void clear(); bool colorWipe( uint32_t color ); void add_button_id(uint16_t mask); bool do_fade(); bool fade_off(); bool fade_on(); void setBrigthness(uint8_t brigthness); void setHS(uint16_t H, uint8_t S); void setColor(uint32_t color); void rainbowCycle(); }; leds::leds(Adafruit_NeoPixel * stripe, uint16_t * state_flag, uint16_t state_mask, uint16_t H, uint8_t S, unsigned int pixel_first, unsigned int pixel_last ) { _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); size_t index = 0; for(size_t nr=pixel_first; nr<=pixel_last;nr++) { _pixels[index].lednr = nr; index++; } _stripe = stripe; _R = _calc_R(); _setLeds(0); _rainbow_pixel = 0; _rainbow_color = 0; _prev_state = *_state_flag; _fading_done = true; } leds::~leds() { if(NULL != _pixels) free(_pixels); } void leds::_setLeds() { for(unsigned int nr = 0; nr < _pixel_nr; nr++) { _stripe->setPixelColor(_pixels[nr].lednr, _pixels[nr].color); } } void leds::_setLeds(uint32_t color) { for(unsigned int nr = 0; nr < _pixel_nr; nr++) { //Serial.printf("setting led %d with nr %d in stripe to color %d\n", nr, _pixels[nr].lednr, color); _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; } bool leds::do_fade() { bool updated = false; uint16_t curr_state = _state_mask & *_state_flag; if(_prev_state != curr_state) { //Serial.printf("Current state is 0x%08x\n", curr_state); _prev_state = curr_state; _fading_done = false; } if(_fading_done == false) { updated = true; if(0 == curr_state) { _fade_off(); //Serial.printf("Fading off.\n"); } else { _fade_on(); //Serial.printf("Fading ON\n"); } } return updated; } bool leds::fade_on() { return _fade_on(); } bool leds::fade_off() { return _fade_off(); } 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(_fadestep0) _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); } void leds::rainbowCycle() { if((millis() - _last_rainbowcycle) > WAIT_RAINBOWCYCLE_MS) { //Serial.printf("Rainbow! Next color\n"); _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