222 lines
7.3 KiB
C++
222 lines
7.3 KiB
C++
#ifdef ENABLE_MOON
|
|
|
|
// Needs refactoring
|
|
// Use https://adrianotiger.github.io/Neopixel-Effect-Generator/ for inspiration
|
|
// Read up on final comment at https://forum.arduino.cc/index.php?topic=534060.0
|
|
|
|
#include <Adafruit_NeoPixel.h>
|
|
|
|
/*
|
|
* Based on https://adrianotiger.github.io/Neopixel-Effect-Generator/
|
|
* TODO: Refactor for just a single string effect, less frills
|
|
* Rainbow pattern
|
|
*/
|
|
class Strip
|
|
{
|
|
public:
|
|
uint8_t effect;
|
|
uint8_t effects;
|
|
uint16_t effStep;
|
|
unsigned long effStart;
|
|
Adafruit_NeoPixel strip;
|
|
Strip(uint16_t leds, uint8_t pin, uint8_t toteffects) : strip(leds, pin, NEO_GRB + NEO_KHZ800) {
|
|
effect = -1;
|
|
effects = toteffects;
|
|
Reset();
|
|
}
|
|
void Reset(){
|
|
effStep = 0;
|
|
effect = (effect + 1) % effects;
|
|
effStart = millis();
|
|
}
|
|
};
|
|
|
|
struct Loop
|
|
{
|
|
uint8_t currentChild;
|
|
uint8_t childs;
|
|
bool timeBased;
|
|
uint16_t cycles;
|
|
uint16_t currentTime;
|
|
Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
|
|
};
|
|
|
|
Strip strip_0(7, MOON_PIXEL, 7 );
|
|
struct Loop strip0loop0(1, false, 1);
|
|
|
|
//[GLOBAL_VARIABLES]
|
|
int speed = 200; // started at 101
|
|
|
|
uint8_t strip0_loop0_eff0() {
|
|
// Strip ID: 0 - Effect: Rainbow - LEDS: 7
|
|
// Steps: 35 - Delay: 100
|
|
// Colors: 6 (255.255.0, 0.255.0, 0.0.255, 255.0.255, 255.0.0, 255.255.255, )
|
|
// Options: toLeft=true,
|
|
if(millis() - strip_0.effStart < 100 * (strip_0.effStep)) return 0x00;
|
|
float factor1, factor2;
|
|
uint16_t ind;
|
|
for(uint16_t j=0;j<7;j++) {
|
|
ind = strip_0.effStep + j * 1;
|
|
switch((int)((ind % 35) / 5.833333333333333)) {
|
|
case 0: factor1 = 1.0 - ((float)(ind % 35 - 0 * 5.833333333333333) / 5.833333333333333);
|
|
factor2 = (float)((int)(ind - 0) % 35) / 5.833333333333333;
|
|
strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 255 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2);
|
|
break;
|
|
case 1: factor1 = 1.0 - ((float)(ind % 35 - 1 * 5.833333333333333) / 5.833333333333333);
|
|
factor2 = (float)((int)(ind - 5.833333333333333) % 35) / 5.833333333333333;
|
|
strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2);
|
|
break;
|
|
case 2: factor1 = 1.0 - ((float)(ind % 35 - 2 * 5.833333333333333) / 5.833333333333333);
|
|
factor2 = (float)((int)(ind - 11.666666666666666) % 35) / 5.833333333333333;
|
|
strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 255 * factor2);
|
|
break;
|
|
case 3: factor1 = 1.0 - ((float)(ind % 35 - 3 * 5.833333333333333) / 5.833333333333333);
|
|
factor2 = (float)((int)(ind - 17.5) % 35) / 5.833333333333333;
|
|
strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2);
|
|
break;
|
|
case 4: factor1 = 1.0 - ((float)(ind % 35 - 4 * 5.833333333333333) / 5.833333333333333);
|
|
factor2 = (float)((int)(ind - 23.333333333333332) % 35) / 5.833333333333333;
|
|
strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 255 * factor2);
|
|
break;
|
|
case 5: factor1 = 1.0 - ((float)(ind % 35 - 5 * 5.833333333333333) / 5.833333333333333);
|
|
factor2 = (float)((int)(ind - 29.166666666666664) % 35) / 5.833333333333333;
|
|
strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 255 * factor1 + 255 * factor2, 255 * factor1 + 0 * factor2);
|
|
break;
|
|
}
|
|
}
|
|
if(strip_0.effStep >= 35) {strip_0.Reset(); return 0x03; }
|
|
else strip_0.effStep++;
|
|
return 0x01;
|
|
}
|
|
|
|
uint8_t strip0_loop0() {
|
|
uint8_t ret = 0x00;
|
|
switch(strip0loop0.currentChild) {
|
|
case 0:
|
|
ret = strip0_loop0_eff0();break;
|
|
}
|
|
if(ret & 0x02) {
|
|
ret &= 0xfd;
|
|
if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
|
|
strip0loop0.currentChild = 0;
|
|
if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
|
|
}
|
|
else {
|
|
strip0loop0.currentChild++;
|
|
}
|
|
};
|
|
return ret;
|
|
}
|
|
|
|
void strips_loop() {
|
|
if(strip0_loop0() & 0x01)
|
|
strip_0.strip.show();
|
|
}
|
|
|
|
/*
|
|
* Interface with other modules
|
|
*/
|
|
|
|
void newcmd(String cmd) {
|
|
cmd.toLowerCase();
|
|
if(cmd.equals("off")) {
|
|
settings.mode = 0;
|
|
PRINTLN_SERIAL("Moon off");
|
|
strip_0.strip.setBrightness(0); // 0-255
|
|
state.text = "Moon switched off";
|
|
}
|
|
if(cmd.equals("on")) {
|
|
settings.mode = 1;
|
|
PRINTLN_SERIAL("Moon switched on");
|
|
strip_0.strip.setBrightness(10); // 0-255
|
|
state.text = "Moon switched off";
|
|
}
|
|
}
|
|
|
|
void module_message(const String& shorttopic, const String& message) {
|
|
char msgptr[10];
|
|
String buffer;
|
|
|
|
if(shorttopic.equalsIgnoreCase("cmd")) {
|
|
if(message.equalsIgnoreCase("off")) {
|
|
state.mode = 0;
|
|
PRINTLN_SERIAL("Moon off");
|
|
strip_0.strip.setBrightness(0); // 0-255
|
|
state.text = "Moon switched off";
|
|
} else if(message.equalsIgnoreCase("on")) {
|
|
state.mode = 1;
|
|
PRINTLN_SERIAL("Moon switched on");
|
|
strip_0.strip.setBrightness(10); // 0-255
|
|
state.text = "Moon switched off";
|
|
}
|
|
|
|
} else if(shorttopic.equalsIgnoreCase("mode")) {
|
|
if(message.equals("off")) {
|
|
state.mode = 0;
|
|
PRINTLN_SERIAL("Shutting off");
|
|
} else if(message.startsWith("0x")) {
|
|
state.mode = 1;
|
|
message.toCharArray(msgptr, 9);
|
|
state.color = strtoll( &msgptr[2], NULL, 16);
|
|
sprintf(printbuffer, "Switching to static color 0x%x", state.color);
|
|
PRINTLN_SERIAL(printbuffer);
|
|
} else if(message.startsWith("#")) {
|
|
state.mode = 1;
|
|
message.toCharArray(msgptr, 8);
|
|
state.color = strtoll( &msgptr[1], NULL, 16);
|
|
sprintf(printbuffer, "Switching to static color 0x%x", state.color);
|
|
PRINTLN_SERIAL(printbuffer);
|
|
} else if(message.equals("rainbow")) {
|
|
state.mode = 2;
|
|
PRINTLN_SERIAL("Switching to rainbow mode");
|
|
}
|
|
mqtt_publish((deviceprefix + "log"), ("mode=" + String(state.mode))); // @@@FIXME@@@ this needs to go elsewhere
|
|
|
|
} else if(shorttopic.equalsIgnoreCase("brightness")) {
|
|
PRINTLN_SERIAL("Setting brightness to " + message);
|
|
settings.brightness = message.toInt();
|
|
strip_0.strip.setBrightness(settings.brightness);
|
|
buffer = "brightness=";
|
|
buffer.concat(settings.brightness);
|
|
mqtt_publish((deviceprefix + "log"), buffer.c_str()); // @@@FIXME@@@ this needs to go elsewhere
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Setup and loop code. Be cooperative! No delays, timers.
|
|
*/
|
|
|
|
void moon_setup() {
|
|
PRINTLN_SERIAL("initialising module Moon");
|
|
strip_0.strip.setBrightness(2); // 0-255
|
|
strip_0.strip.begin();
|
|
}
|
|
|
|
void moon_loop() {
|
|
uint16_t r;
|
|
|
|
switch(state.mode) {
|
|
case 0: // Off
|
|
for(r=0; r< strip_0.strip.numPixels(); r++) {
|
|
strip_0.strip.setPixelColor(r, 0,0,0);
|
|
}
|
|
strip_0.strip.show();
|
|
break;
|
|
case 1: // Static color
|
|
for(r=0; r< strip_0.strip.numPixels(); r++) {
|
|
// Split the set color code up into r, g, b values
|
|
int rval = state.color >> 16;
|
|
int gval = state.color >> 8 & 0xFF;
|
|
int bval = state.color & 0xFF;
|
|
strip_0.strip.setPixelColor(r, rval, gval, bval);
|
|
}
|
|
strip_0.strip.show();
|
|
break;
|
|
case 2: // Rainbow
|
|
strips_loop();
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endif
|