Added Node-RED integration

Added Alexa integration
Added support for custom patterns
This commit is contained in:
Lorenz Nimmervoll 2019-02-24 21:48:14 +01:00
parent b83e48016c
commit 539804fbc8
26 changed files with 5471 additions and 25 deletions

View File

@ -4,6 +4,6 @@
"\\data", "\\data",
"\\data\\images" "\\data\\images"
], ],
"SelectedNode": "\\data\\index.htm", "SelectedNode": "\\esp8266-fastled-webserver.ino",
"PreviewInSolutionExplorer": false "PreviewInSolutionExplorer": false
} }

Binary file not shown.

5319
NodeRED_Flow.txt Normal file

File diff suppressed because one or more lines are too long

5
Secrets.h Normal file
View File

@ -0,0 +1,5 @@
const char WiFiAPPSK[] = "your-password";
// Wi-Fi network to connect to (if not in AP mode)
char* ssid = "WLAN23";
char* password = "57erChevy";

View File

@ -107,7 +107,7 @@ const uint8_t brightnessCount = 5;
uint8_t brightnessMap[brightnessCount] = { 16, 32, 64, 128, 255 }; uint8_t brightnessMap[brightnessCount] = { 16, 32, 64, 128, 255 };
uint8_t brightnessIndex = 0; uint8_t brightnessIndex = 0;
char vals[4 + LEAFCOUNT * 5][4] = {""};
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
@ -136,6 +136,10 @@ uint8_t currentPaletteIndex = 0;
uint8_t gHue = 0; // rotating "base color" used by many of the patterns uint8_t gHue = 0; // rotating "base color" used by many of the patterns
uint8_t breathe = 0; // value for starting custom pattern
uint8_t breathe_dir = 1; // 1== rising
char cpattern[500] = "";
CRGB solidColor = CRGB::Blue; CRGB solidColor = CRGB::Blue;
// scale the brightness of all pixels down // scale the brightness of all pixels down
@ -195,7 +199,9 @@ PatternAndNameList patterns = {
{ fire, "Fire" }, { fire, "Fire" },
{ water, "Water" }, { water, "Water" },
{ showSolidColor, "Solid Color" } { showSolidColor, "Solid Color" },
{ SetCustomPattern, "Custom Pattern"}
}; };
const uint8_t patternCount = ARRAY_SIZE(patterns); const uint8_t patternCount = ARRAY_SIZE(patterns);
@ -290,7 +296,7 @@ void setup() {
uint8_t mac[WL_MAC_ADDR_LENGTH]; uint8_t mac[WL_MAC_ADDR_LENGTH];
WiFi.softAPmacAddress(mac); WiFi.softAPmacAddress(mac);
String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) + String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
String(mac[WL_MAC_ADDR_LENGTH - 1], HEX); String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
macID.toUpperCase(); macID.toUpperCase();
String AP_NameString = "ESP8266 Thing " + macID; String AP_NameString = "ESP8266 Thing " + macID;
@ -385,12 +391,16 @@ void setup() {
String b = webServer.arg("b"); String b = webServer.arg("b");
setSolidColor(r.toInt(), g.toInt(), b.toInt()); setSolidColor(r.toInt(), g.toInt(), b.toInt());
sendString(String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b)); sendString(String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b));
Serial.println(String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b));
}); });
webServer.on("/pattern", HTTP_POST, []() { webServer.on("/pattern", HTTP_POST, []() {
String value = webServer.arg("value"); String value = webServer.arg("value");
setPattern(value.toInt()); if (value.toInt() <= 29)
sendInt(currentPatternIndex); {
setPattern(value.toInt());
sendInt(currentPatternIndex);
}
}); });
webServer.on("/patternName", HTTP_POST, []() { webServer.on("/patternName", HTTP_POST, []() {
@ -441,6 +451,17 @@ void setup() {
sendInt(selectedLeaf); sendInt(selectedLeaf);
}); });
webServer.on("/custom", HTTP_POST, []() {
String value = webServer.arg("value");
Serial.println(value);
value.toCharArray(cpattern, 500);
Serial.println(value);
sendString(value);
setPattern(30);
});
//list directory //list directory
webServer.on("/list", HTTP_GET, handleFileList); webServer.on("/list", HTTP_GET, handleFileList);
//load editor //load editor
@ -538,6 +559,14 @@ void loop() {
gHue++; // slowly cycle the "base color" through the rainbow gHue++; // slowly cycle the "base color" through the rainbow
} }
EVERY_N_MILLIS_I(thistimer, 128-(speed/2)) {
if (breathe_dir == 1)breathe++; else breathe--;
if (breathe >= 255)breathe_dir = 0;
else if (breathe <= 0) breathe_dir = 1;
//Serial.println(breathe);
}
thistimer.setPeriod(64-(speed/4));
if (autoplay && (millis() > autoPlayTimeout)) { if (autoplay && (millis() > autoPlayTimeout)) {
adjustPattern(true); adjustPattern(true);
autoPlayTimeout = millis() + (autoplayDuration * 1000); autoPlayTimeout = millis() + (autoplayDuration * 1000);
@ -691,9 +720,10 @@ void setSolidColor(uint8_t r, uint8_t g, uint8_t b)
EEPROM.write(4, b); EEPROM.write(4, b);
EEPROM.commit(); EEPROM.commit();
setPattern(patternCount - 1); setPattern(29);
broadcastString("color", String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b)); broadcastString("color", String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b));
FastLED.show();
} }
// increase or decrease the current pattern number, and wrap around at the ends // increase or decrease the current pattern number, and wrap around at the ends
@ -884,21 +914,21 @@ void bpm()
uint8_t beat = beatsin8(speed, 64, 255); uint8_t beat = beatsin8(speed, 64, 255);
CRGBPalette16 palette = palettes[currentPaletteIndex]; CRGBPalette16 palette = palettes[currentPaletteIndex];
for (int i = 0; i < LEAFCOUNT; i++) { for (int i = 0; i < LEAFCOUNT; i++) {
for (int i2 = 0; i2 < PIXELS_PER_LEAF; i2++)leds[i*PIXELS_PER_LEAF + i2] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10)); for (int i2 = 0; i2 < PIXELS_PER_LEAF; i2++)leds[i * PIXELS_PER_LEAF + i2] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10));
} }
} }
// BACKUP // BACKUP
/* /*
void bpm() void bpm()
{ {
// colored stripes pulsing at a defined Beats-Per-Minute (BPM) // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
uint8_t beat = beatsin8(speed, 64, 255); uint8_t beat = beatsin8(speed, 64, 255);
CRGBPalette16 palette = palettes[currentPaletteIndex]; CRGBPalette16 palette = palettes[currentPaletteIndex];
for (int i = 0; i < NUM_LEDS; i++) { for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10)); leds[i] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10));
} }
} }
*/ */
void juggle() void juggle()
@ -918,10 +948,10 @@ void juggle()
if (lastSecond != secondHand) { // Debounce to make sure we're not repeating an assignment. if (lastSecond != secondHand) { // Debounce to make sure we're not repeating an assignment.
lastSecond = secondHand; lastSecond = secondHand;
switch (secondHand) { switch (secondHand) {
case 0: numdots = 1; basebeat = 20; hueinc = 16; faderate = 2; thishue = 0; break; // You can change values here, one at a time , or altogether. case 0: numdots = 1; basebeat = 20; hueinc = 16; faderate = 2; thishue = 0; break; // You can change values here, one at a time , or altogether.
case 10: numdots = 4; basebeat = 10; hueinc = 16; faderate = 8; thishue = 128; break; case 10: numdots = 4; basebeat = 10; hueinc = 16; faderate = 8; thishue = 128; break;
case 20: numdots = 8; basebeat = 3; hueinc = 0; faderate = 8; thishue = random8(); break; // Only gets called once, and not continuously for the next several seconds. Therefore, no rainbows. case 20: numdots = 8; basebeat = 3; hueinc = 0; faderate = 8; thishue = random8(); break; // Only gets called once, and not continuously for the next several seconds. Therefore, no rainbows.
case 30: break; case 30: break;
} }
} }
@ -987,18 +1017,18 @@ void pride()
for (int i2 = 0; i2 < (PIXELS_PER_LEAF / 3); i2++) for (int i2 = 0; i2 < (PIXELS_PER_LEAF / 3); i2++)
{ {
nblend(leds[pixelnumber*(PIXELS_PER_LEAF / 3) + i2], newcolor, 64); nblend(leds[pixelnumber * (PIXELS_PER_LEAF / 3) + i2], newcolor, 64);
} }
} }
} }
//#############BACKUP######################## //#############BACKUP########################
/* /*
// Pride2015 by Mark Kriegsman: https://gist.github.com/kriegsman/964de772d64c502760e5 // Pride2015 by Mark Kriegsman: https://gist.github.com/kriegsman/964de772d64c502760e5
// This function draws rainbows with an ever-changing, // This function draws rainbows with an ever-changing,
// widely-varying set of parameters. // widely-varying set of parameters.
void pride() void pride()
{ {
static uint16_t sPseudotime = 0; static uint16_t sPseudotime = 0;
static uint16_t sLastMillis = 0; static uint16_t sLastMillis = 0;
static uint16_t sHue16 = 0; static uint16_t sHue16 = 0;
@ -1036,7 +1066,7 @@ void pride()
nblend( leds[pixelnumber], newcolor, 64); nblend( leds[pixelnumber], newcolor, 64);
} }
} }
*/ */
@ -1110,7 +1140,7 @@ extern const TProgmemRGBGradientPalettePtr gGradientPalettes[];
extern const uint8_t gGradientPaletteCount; extern const uint8_t gGradientPaletteCount;
uint8_t beatsaw8(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint8_t beatsaw8(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255,
uint32_t timebase = 0, uint8_t phase_offset = 0) uint32_t timebase = 0, uint8_t phase_offset = 0)
{ {
uint8_t beat = beat8(beats_per_minute, timebase); uint8_t beat = beat8(beats_per_minute, timebase);
uint8_t beatsaw = beat + phase_offset; uint8_t beatsaw = beat + phase_offset;
@ -1180,7 +1210,7 @@ void colorwaves(CRGB* ledarray, uint16_t numleds, CRGBPalette16& palette)
pixelnumber = ((LEAFCOUNT * 3) - 1) - pixelnumber; pixelnumber = ((LEAFCOUNT * 3) - 1) - pixelnumber;
for (int i2 = 0; i2 < (PIXELS_PER_LEAF / 3); i2++) for (int i2 = 0; i2 < (PIXELS_PER_LEAF / 3); i2++)
{ {
nblend(leds[pixelnumber*(PIXELS_PER_LEAF / 3) + i2], newcolor, 128); nblend(leds[pixelnumber * (PIXELS_PER_LEAF / 3) + i2], newcolor, 128);
} }
} }
} }
@ -1193,3 +1223,96 @@ void palettetest(CRGB* ledarray, uint16_t numleds, const CRGBPalette16& gCurrent
startindex--; startindex--;
fill_palette(ledarray, numleds, startindex, (256 / NUM_LEDS) + 1, gCurrentPalette, 255, LINEARBLEND); fill_palette(ledarray, numleds, startindex, (256 / NUM_LEDS) + 1, gCurrentPalette, 255, LINEARBLEND);
} }
/*
Function: ExtractValues
Used to extract a given amount of values from the message with a start index
Parameters:
- startindex: position in the string where to start
- valuecount: amount of values to capture
*/
void ExtractValues(char receivedChars[], int startindex, int valuecount)
{
int pos = startindex;
for (int c = 0; c < valuecount; c++)
{
int i = 0;
while (receivedChars[pos] != ';' && receivedChars[pos] != '\0') {
vals[c][i] = receivedChars[pos];
pos++;
i++;
}
vals[c][i] = '\0';
pos++;
}
#ifdef DEBUG_SERIAL
for (int p = 0; p < valuecount; p++)
{
Serial.print("Extracting: "); Serial.println(vals[p]);
}
#endif // DEBUG_SERIAL
}
void cycle(CRGB endclr, CRGB midclr, uint8_t start) {
fill_gradient_RGB(leds, start, endclr, PIXELS_PER_LEAF/ 2, midclr);
fill_gradient_RGB(leds, PIXELS_PER_LEAF/ 2 + 1, midclr, PIXELS_PER_LEAF, endclr);
}
// Set Custom Pattern for the node red part
void SetCustomPattern()
{
uint8_t cnt = 0;
uint8_t isflow = 0;
ExtractValues(cpattern, 0, 2);
cnt = atoi(vals[0]);
isflow = atoi(vals[1]);
ExtractValues(cpattern, 0, 2 + 5 * cnt);
if (isflow == 0)
{
for (uint8_t i = 0; i < cnt; i++)
{
int8_t cmode = atoi(vals[2 + i * 5]);
uint8_t phase = atoi(vals[2 + i * 5 + 1]);
int mul = breathe;
if (breathe_dir == 1)
{
if ((mul + phase) > 255)mul = 255 + (255 - mul - phase);
else mul += phase;
}
else
{
if ((mul - phase) < 0)mul = -mul + phase;
else mul -= phase;
}
if (cmode == 0)mul = 255;
double fac = (mul * 100) / 255.00;
//if(cmode==1)Serial.printf("%d ", mul);
for (uint8_t x = 0; x < PIXELS_PER_LEAF; x++)
{
//Serial.printf("Setting %d to %d, %d, %d\n", cnt*PIXELS_PER_LEAF+x,atoi(vals[2+i*5+2]), atoi(vals[2+i*5+3]), atoi(vals[2+i*5+4]));
leds[i * PIXELS_PER_LEAF + x] = CRGB((atoi(vals[2 + i * 5 + 2]) * fac) / 100.00, (atoi(vals[2 + i * 5 + 3]) * fac) / 100.00, (atoi(vals[2 + i * 5 + 4]) * fac) / 100.00);
}
}
}
else
{
for (int i = 0; i < cnt; i++)
{
if (i != (cnt - 1))
{
//uint8_t speed = beatsin8(6,0,255);
CRGB endclr = blend(CRGB(atoi(vals[2 + i * 5 + 2]), atoi(vals[2 + i * 5 + 3]), atoi(vals[2 + i * 5 + 4])), CRGB(atoi(vals[2 + (i + 1) * 5 + 2]), atoi(vals[2 + (i + 1) * 5 + 3]), atoi(vals[2 + (i + 1) * 5 + 4])), breathe);
CRGB midclr = blend(CRGB(atoi(vals[2 + (i + 1) * 5 + 2]), atoi(vals[2 + (i + 1) * 5 + 3]), atoi(vals[2 + (i + 1) * 5 + 4])), CRGB(atoi(vals[2 + i * 5 + 2]), atoi(vals[2 + i * 5 + 3]), atoi(vals[2 + i * 5 + 4])), breathe);
cycle(endclr, midclr, i*PIXELS_PER_LEAF);
}
else
{
//uint8_t speed = beatsin8(6,0,255);
CRGB endclr = blend(CRGB(atoi(vals[2 + 2]), atoi(vals[2 + 3]), atoi(vals[2 + 4])), CRGB(atoi(vals[2 + (i + 1) * 5 + 2]), atoi(vals[2 + (i + 1) * 5 + 3]), atoi(vals[2 + (i + 1) * 5 + 4])), breathe);
CRGB midclr = blend(CRGB(atoi(vals[2 + (i + 1) * 5 + 2]), atoi(vals[2 + (i + 1) * 5 + 3]), atoi(vals[2 + (i + 1) * 5 + 4])), CRGB(atoi(vals[2 + 2]), atoi(vals[2 + 3]), atoi(vals[2 + 4])), breathe);
cycle(endclr, midclr, i*PIXELS_PER_LEAF);
}
}
}
//Serial.println("");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
gallery/NodeRED_UI/full.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
gallery/NodeRED_UI/main.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1 +0,0 @@