esp8266-ws2801d/src/fader.cpp

116 lines
2.9 KiB
C++

#include "ws2801.h"
#include "fader.h"
int16_t fadestep = 1;
int somethingChanged = 0; // indicates when a ws2801 update is required
struct Colour {
int16_t red, green, blue; // value range is 0 to 255
};
struct Colour curColour[MAX_NUM_MODULES];
struct Colour targetColour[MAX_NUM_MODULES];
void fader_init(void)
{
for(uint32_t i = 0; i < ws2801_num_modules; i++) {
curColour[i].red = targetColour[i].red = 0;
curColour[i].green = targetColour[i].green = 0;
curColour[i].blue = targetColour[i].blue = 0;
}
}
void fader_set_colour(uint32_t module, uint8_t r, uint8_t g, uint8_t b)
{
curColour[module].red = targetColour[module].red = r;
curColour[module].green = targetColour[module].green = g;
curColour[module].blue = targetColour[module].blue = b;
somethingChanged = 1;
}
void fader_fade_colour(uint32_t module, uint8_t r, uint8_t g, uint8_t b)
{
targetColour[module].red = r;
targetColour[module].green = g;
targetColour[module].blue = b;
}
void fader_add_colour(uint32_t module, uint8_t r, uint8_t g, uint8_t b)
{
curColour[module].red += r;
curColour[module].green += g;
curColour[module].blue += b;
if(curColour[module].red > 255) { curColour[module].red = 255; }
if(curColour[module].green > 255) { curColour[module].green = 255; }
if(curColour[module].blue > 255) { curColour[module].blue = 255; }
targetColour[module].red += r;
targetColour[module].green += g;
targetColour[module].blue += b;
if(targetColour[module].red > 255) { targetColour[module].red = 255; }
if(targetColour[module].green > 255) { targetColour[module].green = 255; }
if(targetColour[module].blue > 255) { targetColour[module].blue = 255; }
somethingChanged = 1;
}
void fader_set_fadestep(uint8_t newFadestep)
{
fadestep = newFadestep;
}
/*!
* Fade the colour value in cur towards target.
*
* \param cur The colour value to update.
* \param target The target value that should be reached.
* \param changed Output value which is set to 1 if cur was changed.
*/
static void fade_colour(int16_t *cur, const int16_t *target, int *changed)
{
int16_t diff;
if(*cur > *target) {
diff = *cur - *target;
if(diff < fadestep) {
*cur = *target;
} else {
*cur -= fadestep;
}
*changed = 1;
} else if(*cur < *target) {
diff = *target - *cur;
if(diff < fadestep) {
*cur = *target;
} else {
*cur += fadestep;
}
*changed = 1;
}
}
void fader_update(void)
{
for(uint32_t i = 0; i < ws2801_num_modules; i++) {
fade_colour(&(curColour[i].red), &(targetColour[i].red), &somethingChanged);
fade_colour(&(curColour[i].green), &(targetColour[i].green), &somethingChanged);
fade_colour(&(curColour[i].blue), &(targetColour[i].blue), &somethingChanged);
ws2801_set_colour(i,
(uint8_t)curColour[i].red,
(uint8_t)curColour[i].green,
(uint8_t)curColour[i].blue);
}
if(somethingChanged) {
ws2801_send_update();
somethingChanged = 0;
}
}