From 7e308b3f07a49e4c2eef5281c055d9711d0adab7 Mon Sep 17 00:00:00 2001 From: Juergen Jung Date: Fri, 17 Feb 2017 00:40:42 +0100 Subject: [PATCH 1/6] New way of effect handling --- .gitignore | 1 + esp-wemos-schild/NeoPatterns.cpp | 260 +++++++++++++++++++++++ esp-wemos-schild/NeoPatterns.h | 51 +++++ esp-wemos-schild/data/homie/config.json | 6 +- esp-wemos-schild/esp-wemos-schild.ino | 269 +++++++----------------- platformio.ini | 7 +- 6 files changed, 398 insertions(+), 196 deletions(-) create mode 100644 esp-wemos-schild/NeoPatterns.cpp create mode 100644 esp-wemos-schild/NeoPatterns.h diff --git a/.gitignore b/.gitignore index 5bcdef9..b4de7ac 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .clang_complete .gcc-flags.json .DS_Store +esp-wemos-schild/data/homie/config.json diff --git a/esp-wemos-schild/NeoPatterns.cpp b/esp-wemos-schild/NeoPatterns.cpp new file mode 100644 index 0000000..ba04826 --- /dev/null +++ b/esp-wemos-schild/NeoPatterns.cpp @@ -0,0 +1,260 @@ +#include "NeoPatterns.h" + +NeoPatterns::NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)()) : + Adafruit_NeoPixel(pixels, pin, type) +{ + OnComplete = callback; +} + +void NeoPatterns::Update(){ + if((millis() - lastUpdate) > Interval) // time to update + { + lastUpdate = millis(); + switch(ActivePattern) + { + case RAINBOW_CYCLE: + RainbowCycleUpdate(); + break; + case THEATER_CHASE: + TheaterChaseUpdate(); + break; + case COLOR_WIPE: + ColorWipeUpdate(); + break; + case SCANNER: + ScannerUpdate(); + break; + case FADE: + FadeUpdate(); + break; + case NONE: + break; + default: + break; + } + } +} + +void NeoPatterns::Increment() +{ + if (Direction == FORWARD) + { + Index++; + if (Index >= TotalSteps) + { + Index = 0; + if (OnComplete != NULL) + { + OnComplete(); // call the comlpetion callback + } + } + } + else // Direction == REVERSE + { + --Index; + if (Index <= 0) + { + Index = TotalSteps-1; + if (OnComplete != NULL) + { + OnComplete(); // call the comlpetion callback + } + } + } +} + +void NeoPatterns::Reverse(){ + if (Direction == FORWARD) + { + Direction = REVERSE; + Index = TotalSteps-1; + } + else + { + Direction = FORWARD; + Index = 0; + } +} + +void NeoPatterns::None(){ + if(ActivePattern != NONE) { + clear(); + show(); + } + ActivePattern = NONE; +} + +void NeoPatterns::RainbowCycle(uint8_t interval, direction dir){ + ActivePattern = RAINBOW_CYCLE; + Interval = interval; + TotalSteps = 255; + Index = 0; + Direction = dir; +} + +void NeoPatterns::RainbowCycleUpdate() +{ + for(int i=0; i< numPixels(); i++) + { + setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255)); + } + show(); + Increment(); +} + +void NeoPatterns::TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir){ + ActivePattern = THEATER_CHASE; + Interval = interval; + TotalSteps = numPixels(); + Color1 = color1; + Color2 = color2; + Index = 0; + Direction = dir; +} +void NeoPatterns::TheaterChaseUpdate(){ + for(int i=0; i< numPixels(); i++) + { + if ((i + Index) % 3 == 0) + { + setPixelColor(i, Color1); + } + else + { + setPixelColor(i, Color2); + } + } + show(); + Increment(); +} + +void NeoPatterns::ColorWipe(uint32_t color, uint8_t interval, direction dir) +{ + ActivePattern = COLOR_WIPE; + Interval = interval; + TotalSteps = numPixels(); + Color1 = color; + Index = 0; + Direction = dir; +} + +// Update the Color Wipe Pattern +void NeoPatterns::ColorWipeUpdate() +{ + setPixelColor(Index, Color1); + show(); + Increment(); +} + +// Initialize for a SCANNNER +void NeoPatterns::Scanner(uint32_t color1, uint8_t interval) +{ + ActivePattern = SCANNER; + Interval = interval; + TotalSteps = (numPixels() - 1) * 2; + Color1 = color1; + Index = 0; +} + +// Update the Scanner Pattern +void NeoPatterns::ScannerUpdate() +{ + for (int i = 0; i < numPixels(); i++) + { + if (i == Index) // Scan Pixel to the right + { + setPixelColor(i, Color1); + } + else if (i == TotalSteps - Index) // Scan Pixel to the left + { + setPixelColor(i, Color1); + } + else // Fading tail + { + setPixelColor(i, DimColor(getPixelColor(i))); + } + } + show(); + Increment(); +} + +void NeoPatterns::Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir) +{ + ActivePattern = FADE; + Interval = interval; + TotalSteps = steps; + Color1 = color1; + Color2 = color2; + Index = 0; + Direction = dir; +} + +// Update the Fade Pattern +void NeoPatterns::FadeUpdate() +{ + // Calculate linear interpolation between Color1 and Color2 + // Optimise order of operations to minimize truncation error + uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps; + uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps; + uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps; + + ColorSet(Color(red, green, blue)); + show(); + Increment(); +} + +// Calculate 50% dimmed version of a color (used by ScannerUpdate) +uint32_t NeoPatterns::DimColor(uint32_t color) +{ + // Shift R, G and B components one bit to the right + uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1); + return dimColor; +} + +// Set all pixels to a color (synchronously) +void NeoPatterns::ColorSet(uint32_t color) +{ + for (int i = 0; i < numPixels(); i++) + { + setPixelColor(i, color); + } + show(); +} + +// Returns the Red component of a 32-bit color +uint8_t NeoPatterns::Red(uint32_t color) +{ + return (color >> 16) & 0xFF; +} + +// Returns the Green component of a 32-bit color +uint8_t NeoPatterns::Green(uint32_t color) +{ + return (color >> 8) & 0xFF; +} + +// Returns the Blue component of a 32-bit color +uint8_t NeoPatterns::Blue(uint32_t color) +{ + return color & 0xFF; +} + +// Input a value 0 to 255 to get a color value. +// The colours are a transition r - g - b - back to r. +uint32_t NeoPatterns::Wheel(byte WheelPos) +{ + WheelPos = 255 - WheelPos; + if(WheelPos < 85) + { + return Color(255 - WheelPos * 3, 0, WheelPos * 3); + } + else if(WheelPos < 170) + { + WheelPos -= 85; + return Color(0, WheelPos * 3, 255 - WheelPos * 3); + } + else + { + WheelPos -= 170; + return Color(WheelPos * 3, 255 - WheelPos * 3, 0); + } +} diff --git a/esp-wemos-schild/NeoPatterns.h b/esp-wemos-schild/NeoPatterns.h new file mode 100644 index 0000000..17f07e9 --- /dev/null +++ b/esp-wemos-schild/NeoPatterns.h @@ -0,0 +1,51 @@ +#include + +// Pattern types supported: +enum pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE }; +// Patern directions supported: +enum direction { FORWARD, REVERSE }; + +class NeoPatterns : public Adafruit_NeoPixel +{ +public: +NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)()); + +void Update(); + +void Reverse(); +void None(); +void RainbowCycle(uint8_t interval, direction dir = FORWARD); +void RainbowCycleUpdate(); +void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD); +void TheaterChaseUpdate(); +void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD); +void ColorWipeUpdate(); +void Scanner(uint32_t color1, uint8_t interval); +void ScannerUpdate(); +void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD); +void FadeUpdate(); +//Utilities +void ColorSet(uint32_t color); +uint8_t Red(uint32_t color); +uint8_t Green(uint32_t color); +uint8_t Blue(uint32_t color); +uint32_t Wheel(byte WheelPos); + +private: + +// Member Variables: +pattern ActivePattern; // which pattern is running +direction Direction; // direction to run the pattern + +unsigned long Interval; // milliseconds between updates +unsigned long lastUpdate; // last update of position + +uint32_t Color1, Color2; // What colors are in use +uint16_t TotalSteps; // total number of steps in the pattern +uint16_t Index; // current step within the pattern + +uint32_t DimColor(uint32_t color); +void Increment(); +void (*OnComplete)(); // Callback on completion of pattern + +}; diff --git a/esp-wemos-schild/data/homie/config.json b/esp-wemos-schild/data/homie/config.json index 9de67c9..8063e3f 100644 --- a/esp-wemos-schild/data/homie/config.json +++ b/esp-wemos-schild/data/homie/config.json @@ -2,11 +2,11 @@ "name": "Homie CTDO Schild", "device_id": "schild", "wifi": { - "ssid": "ctdo", - "password": "ctdo2342" + "ssid": "Nudel", + "password": "Unser WLAN ist sicher!" }, "mqtt": { - "host": "raum.ctdo.de", + "host": "prometheus.local", "port": 1883, "auth": false }, diff --git a/esp-wemos-schild/esp-wemos-schild.ino b/esp-wemos-schild/esp-wemos-schild.ino index 91e20fa..e1ba9e7 100644 --- a/esp-wemos-schild/esp-wemos-schild.ino +++ b/esp-wemos-schild/esp-wemos-schild.ino @@ -3,229 +3,118 @@ #include #include #include +#include "NeoPatterns.h" #define PIN D1 -#define NUMPIXELS 30 +#define NUMPIXELS 144 + + -uint16_t effectI=0,effectJ=0,wait = 50; -unsigned long lastCall = 0; byte wPos = 0; uint8_t state = 0; -Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); +void StripComplete(){ + return; +} + +NeoPatterns pixels = NeoPatterns(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800,&StripComplete); HomieNode stripNode("strip", "strip"); -String effect = "none"; - -// Input a value 0 to 255 to get a color value. -// The colours are a transition r - g - b - back to r. -uint32_t wheel(byte wheelPos) { - wheelPos = 255 - wheelPos; - if(wheelPos < 85) { - return pixels.Color(255 - wheelPos * 3, 0, wheelPos * 3); - } - if(wheelPos < 170) { - wheelPos -= 85; - return pixels.Color(0, wheelPos * 3, 255 - wheelPos * 3); - } - wheelPos -= 170; - return pixels.Color(wheelPos * 3, 255 - wheelPos * 3, 0); -} - -void getRGBValues(uint32_t *rgbBuffer,uint32_t const color){ - rgbBuffer[0] = color >> 16 & 255; - rgbBuffer[1] = color >> 8 & 255; - rgbBuffer[2] = color & 255; - return ; -} - bool onSetPixel(const HomieRange& range, const String& value){ - if(!range.isRange){ - effect = "none"; - pixels.clear(); - for(int i=0;i pixels.numPixels()-1) { - return false; - } - effect = "none"; - pixels.setPixelColor(range.index, value.toInt()); - pixels.show(); - stripNode.setProperty("pixel_" + String(range.index)).send(value); + if(!range.isRange) { + pixels.None(); + pixels.ColorSet(value.toInt()); + stripNode.setProperty("pixel").send(value); + return true; + } + if (range.index < 0 || range.index > pixels.numPixels()-1) { + return false; + } + pixels.None(); + pixels.setPixelColor(range.index, value.toInt()); + pixels.show(); + stripNode.setProperty("pixel_" + String(range.index)).send(value); } bool onSetBrightness(const HomieRange& range, const String& value){ - long brightness= value.toInt(); - if (brightness < 0 || brightness > 255) { - return false; - } - pixels.setBrightness(brightness); - pixels.show(); - stripNode.setProperty("brightness").send(value); + long brightness= value.toInt(); + if (brightness < 0 || brightness > 255) { + return false; + } + pixels.setBrightness(brightness); + pixels.show(); + stripNode.setProperty("brightness").send(value); } bool onSetEffect(const HomieRange& range, const String& value){ - effect = value; - effect.toLowerCase(); - effectI=0,effectJ=0,wait=50; - stripNode.setProperty("effect").send(value); + String effect = value; + effect.toLowerCase(); + if(effect == "scanner") { + pixels.Scanner(pixels.Color(255,0,0), 55); + } + else if(effect == "rainbowcycle") { + pixels.RainbowCycle(50); + } + else if(effect == "theaterchase") { + pixels.TheaterChase(pixels.Color(0,0,255), pixels.Color(255,0,00), 100); + } + else if(effect == "fade") { + pixels.Fade(pixels.Wheel(255),pixels.Wheel(0),255,25); + } + else { + pixels.None(); + } + + stripNode.setProperty("effect").send(value); } bool onSetClear(const HomieRange& range, const String& value){ - effect = "none"; - pixels.clear(); - pixels.show(); - stripNode.setProperty("clear").send(value); + pixels.None(); + pixels.clear(); + pixels.show(); + stripNode.setProperty("clear").send(value); } bool onSetLength(const HomieRange& range, const String& value){ - effect = "none"; - pixels.clear(); - pixels.show(); - int newLength = value.toInt(); - if(newLength > 0){ - pixels.updateLength(newLength); - } - stripNode.setProperty("length").send(value); + pixels.None(); + pixels.clear(); + pixels.show(); + int newLength = value.toInt(); + if(newLength > 0) { + pixels.updateLength(newLength); + } + stripNode.setProperty("length").send(value); } void loopHandler() { - if (effect == "none"){ - return; - } - else if (effect == "larson") { - int SpeedDelay = 20; - int EyeSize = 5; - uint32_t rgb[3] = {0}; - - switch(state){ - case 0: - if(lastCall + wait < millis()){ - state++; - } - break; - case 1: - for(int i = 0; i < pixels.numPixels()-EyeSize-2; i++) { - pixels.clear(); - getRGBValues(rgb,wheel(wPos)); - pixels.setPixelColor(i, rgb[0]/10, rgb[1]/10, rgb[2]/10); - for(int j = 1; j <= EyeSize; j++) { - pixels.setPixelColor(i+j, wheel(wPos++)); - } - getRGBValues(rgb,wheel(wPos)); - pixels.setPixelColor(i+EyeSize+1, rgb[0]/10, rgb[1]/10, rgb[2]/10); - pixels.show(); - - delay(SpeedDelay); - } - lastCall = millis(); - state++; - break; - case 2: - if(lastCall + wait < millis()){ - state++; - } - break; - case 3: - for(int i = pixels.numPixels()-EyeSize-2; i > 0; i--) { - pixels.clear(); - getRGBValues(rgb,wheel(wPos)); - pixels.setPixelColor(i, rgb[0]/10, rgb[1]/10, rgb[2]/10); - for(int j = 1; j <= EyeSize; j++) { - pixels.setPixelColor(i+j, wheel(wPos++)); - } - pixels.setPixelColor(i+EyeSize+1, rgb[0]/10, rgb[1]/10, rgb[2]/10); - pixels.show(); - - delay(SpeedDelay); - } - lastCall = millis(); - state++; - break; - default: - state = 0; - } - } - else if (effect == "randomfade") { - if(lastCall + wait > millis()){ - return; - } - lastCall = millis(); - for(int i=0;i= millis()){ - return; - } - if(effectJ<256) { - if(effectI Date: Fri, 17 Feb 2017 03:01:52 +0100 Subject: [PATCH 2/6] Input Sensor for motion --- esp-wemos-schild/esp-wemos-schild.ino | 24 ++++++++++++++++++++---- platformio.ini | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/esp-wemos-schild/esp-wemos-schild.ino b/esp-wemos-schild/esp-wemos-schild.ino index e1ba9e7..598af35 100644 --- a/esp-wemos-schild/esp-wemos-schild.ino +++ b/esp-wemos-schild/esp-wemos-schild.ino @@ -6,12 +6,12 @@ #include "NeoPatterns.h" #define PIN D1 +#define SENSOR D3 #define NUMPIXELS 144 -byte wPos = 0; -uint8_t state = 0; +bool lastSensorValue = false; void StripComplete(){ return; @@ -20,6 +20,8 @@ void StripComplete(){ NeoPatterns pixels = NeoPatterns(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800,&StripComplete); HomieNode stripNode("strip", "strip"); +HomieNode sensorNode("sensor", "sensor"); +Bounce debouncer = Bounce(); bool onSetPixel(const HomieRange& range, const String& value){ if(!range.isRange) { @@ -60,12 +62,11 @@ bool onSetEffect(const HomieRange& range, const String& value){ pixels.TheaterChase(pixels.Color(0,0,255), pixels.Color(255,0,00), 100); } else if(effect == "fade") { - pixels.Fade(pixels.Wheel(255),pixels.Wheel(0),255,25); + pixels.Fade(pixels.Wheel(0),pixels.Wheel(255),pixels.Color(255,255,255),25); } else { pixels.None(); } - stripNode.setProperty("effect").send(value); } @@ -89,19 +90,33 @@ bool onSetLength(const HomieRange& range, const String& value){ void loopHandler() { pixels.Update(); + + int sensorValue = debouncer.read(); + if (Homie.isConfigured() && Homie.isConnected() && sensorValue != lastSensorValue) { + sensorNode.setProperty("motion").send(sensorValue ? "true" : "false"); + lastSensorValue = sensorValue; + } + } void setup() { Serial.begin(115200); + + debouncer.attach(SENSOR,INPUT); + debouncer.interval(50); + Homie_setFirmware("schild", "1.0.0"); Homie.setLoopFunction(loopHandler); + stripNode.advertiseRange("pixel", 0, NUMPIXELS-1).settable(onSetPixel); stripNode.advertise("brightness").settable(onSetBrightness); stripNode.advertise("effect").settable(onSetEffect); stripNode.advertise("clear").settable(onSetClear); stripNode.advertise("length").settable(onSetLength); + sensorNode.advertise("motion"); + pixels.begin(); pixels.clear(); pixels.setBrightness(64); @@ -116,5 +131,6 @@ void setup() { void loop() { Homie.loop(); + debouncer.update(); ArduinoOTA.handle(); } diff --git a/platformio.ini b/platformio.ini index 2a6fa9b..77d00ab 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ platform=espressif8266 board=d1_mini framework=arduino -;upload_port = /dev/tty.wchusbserial640 +;upload_port = /dev/tty.wchusbserial410 ;upload_speed = 921600 ;upload_port = 5ccf7f1db369.local From 7673b4e19c5d0bf971c5f95dd220181e585f40ba Mon Sep 17 00:00:00 2001 From: Juergen Jung Date: Fri, 17 Feb 2017 03:49:22 +0100 Subject: [PATCH 3/6] New randomscanner and randomfade effect --- esp-wemos-schild/NeoPatterns.cpp | 28 ++++++++++++++++++++++++++- esp-wemos-schild/NeoPatterns.h | 9 +++++++-- esp-wemos-schild/esp-wemos-schild.ino | 10 ++++++++-- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/esp-wemos-schild/NeoPatterns.cpp b/esp-wemos-schild/NeoPatterns.cpp index ba04826..e51e81a 100644 --- a/esp-wemos-schild/NeoPatterns.cpp +++ b/esp-wemos-schild/NeoPatterns.cpp @@ -27,6 +27,9 @@ void NeoPatterns::Update(){ case FADE: FadeUpdate(); break; + case RANDOM_FADE: + RandomFadeUpdate(); + break; case NONE: break; default: @@ -146,18 +149,29 @@ void NeoPatterns::ColorWipeUpdate() } // Initialize for a SCANNNER -void NeoPatterns::Scanner(uint32_t color1, uint8_t interval) +void NeoPatterns::Scanner(uint32_t color1, uint8_t interval, bool colorful) { ActivePattern = SCANNER; Interval = interval; TotalSteps = (numPixels() - 1) * 2; Color1 = color1; Index = 0; + wPos = 0; + this->colorful = colorful; } // Update the Scanner Pattern void NeoPatterns::ScannerUpdate() { + if(colorful) { + Color1 = Wheel(wPos); + if(wPos >= 255) { + wPos =0; + } + else { + wPos++; + } + } for (int i = 0; i < numPixels(); i++) { if (i == Index) // Scan Pixel to the right @@ -175,6 +189,7 @@ void NeoPatterns::ScannerUpdate() } show(); Increment(); + } void NeoPatterns::Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir) @@ -202,6 +217,17 @@ void NeoPatterns::FadeUpdate() Increment(); } +void NeoPatterns::RandomFade(uint8_t interval ){ + ActivePattern = RANDOM_FADE; + Interval = interval; + TotalSteps = 255; + Index = 0; +} +void NeoPatterns::RandomFadeUpdate(){ + ColorSet(Wheel(Index)); + Increment(); +} + // Calculate 50% dimmed version of a color (used by ScannerUpdate) uint32_t NeoPatterns::DimColor(uint32_t color) { diff --git a/esp-wemos-schild/NeoPatterns.h b/esp-wemos-schild/NeoPatterns.h index 17f07e9..7168fed 100644 --- a/esp-wemos-schild/NeoPatterns.h +++ b/esp-wemos-schild/NeoPatterns.h @@ -1,7 +1,7 @@ #include // Pattern types supported: -enum pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE }; +enum pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE, RANDOM_FADE }; // Patern directions supported: enum direction { FORWARD, REVERSE }; @@ -20,10 +20,12 @@ void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction void TheaterChaseUpdate(); void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD); void ColorWipeUpdate(); -void Scanner(uint32_t color1, uint8_t interval); +void Scanner(uint32_t color1, uint8_t interval = 40,bool colorful = false); void ScannerUpdate(); void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD); void FadeUpdate(); +void RandomFade(uint8_t interval = 100); +void RandomFadeUpdate(); //Utilities void ColorSet(uint32_t color); uint8_t Red(uint32_t color); @@ -44,6 +46,9 @@ uint32_t Color1, Color2; // What colors are in use uint16_t TotalSteps; // total number of steps in the pattern uint16_t Index; // current step within the pattern +byte wPos; +bool colorful; + uint32_t DimColor(uint32_t color); void Increment(); void (*OnComplete)(); // Callback on completion of pattern diff --git a/esp-wemos-schild/esp-wemos-schild.ino b/esp-wemos-schild/esp-wemos-schild.ino index 598af35..a9f416c 100644 --- a/esp-wemos-schild/esp-wemos-schild.ino +++ b/esp-wemos-schild/esp-wemos-schild.ino @@ -53,7 +53,10 @@ bool onSetEffect(const HomieRange& range, const String& value){ String effect = value; effect.toLowerCase(); if(effect == "scanner") { - pixels.Scanner(pixels.Color(255,0,0), 55); + pixels.Scanner(pixels.Color(255,0,0), 40); + } + else if(effect == "randomscanner") { + pixels.Scanner(pixels.Color(255,0,0), 40,true); } else if(effect == "rainbowcycle") { pixels.RainbowCycle(50); @@ -62,7 +65,10 @@ bool onSetEffect(const HomieRange& range, const String& value){ pixels.TheaterChase(pixels.Color(0,0,255), pixels.Color(255,0,00), 100); } else if(effect == "fade") { - pixels.Fade(pixels.Wheel(0),pixels.Wheel(255),pixels.Color(255,255,255),25); + pixels.Fade(pixels.Color(100,0,0),pixels.Color(0,0,100),200,100); + } + else if(effect == "randomfade") { + pixels.RandomFade(); } else { pixels.None(); From 7a954bea55f04dfb8df150c24774723e102675f9 Mon Sep 17 00:00:00 2001 From: Juergen Jung Date: Sun, 19 Feb 2017 14:49:00 +0100 Subject: [PATCH 4/6] Add possibility to set color1 and color2 --- esp-wemos-schild/esp-wemos-schild.ino | 33 ++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/esp-wemos-schild/esp-wemos-schild.ino b/esp-wemos-schild/esp-wemos-schild.ino index a9f416c..5790312 100644 --- a/esp-wemos-schild/esp-wemos-schild.ino +++ b/esp-wemos-schild/esp-wemos-schild.ino @@ -23,6 +23,27 @@ HomieNode stripNode("strip", "strip"); HomieNode sensorNode("sensor", "sensor"); Bounce debouncer = Bounce(); +uint32_t color1 = pixels.Color(255, 0, 0); +uint32_t color2 = pixels.Color(0, 0, 255); + +bool onSetColor(const HomieRange& range, const String& value){ + if (!range.isRange || range.index < 0 || range.index > 1) { + return false; + } + switch(range.index) { + case 0: + color1 = value.toInt(); + break; + case 1: + color2 = value.toInt(); + break; + } + stripNode.setProperty("color_" + String(range.index)).send(value); +} + + + + bool onSetPixel(const HomieRange& range, const String& value){ if(!range.isRange) { pixels.None(); @@ -53,19 +74,19 @@ bool onSetEffect(const HomieRange& range, const String& value){ String effect = value; effect.toLowerCase(); if(effect == "scanner") { - pixels.Scanner(pixels.Color(255,0,0), 40); + pixels.Scanner(color1); } else if(effect == "randomscanner") { - pixels.Scanner(pixels.Color(255,0,0), 40,true); + pixels.Scanner(color1, 40, true); } else if(effect == "rainbowcycle") { pixels.RainbowCycle(50); } else if(effect == "theaterchase") { - pixels.TheaterChase(pixels.Color(0,0,255), pixels.Color(255,0,00), 100); + pixels.TheaterChase(color1, color2, 100); } else if(effect == "fade") { - pixels.Fade(pixels.Color(100,0,0),pixels.Color(0,0,100),200,100); + pixels.Fade(color1, color2, 200, 100); } else if(effect == "randomfade") { pixels.RandomFade(); @@ -97,7 +118,7 @@ bool onSetLength(const HomieRange& range, const String& value){ void loopHandler() { pixels.Update(); - int sensorValue = debouncer.read(); + bool sensorValue = debouncer.read(); if (Homie.isConfigured() && Homie.isConnected() && sensorValue != lastSensorValue) { sensorNode.setProperty("motion").send(sensorValue ? "true" : "false"); lastSensorValue = sensorValue; @@ -114,8 +135,8 @@ void setup() { Homie_setFirmware("schild", "1.0.0"); Homie.setLoopFunction(loopHandler); - stripNode.advertiseRange("pixel", 0, NUMPIXELS-1).settable(onSetPixel); + stripNode.advertiseRange("color", 0, 1).settable(onSetColor); stripNode.advertise("brightness").settable(onSetBrightness); stripNode.advertise("effect").settable(onSetEffect); stripNode.advertise("clear").settable(onSetClear); From 5d07dbb73d5b0a34a0b54bcc2d25c5cc704bce76 Mon Sep 17 00:00:00 2001 From: Juergen Jung Date: Sun, 19 Feb 2017 21:43:23 +0100 Subject: [PATCH 5/6] Add documentation --- Readme.md | 80 +++++++++++++++++++++++++++ esp-wemos-schild/NeoPatterns.cpp | 7 +++ esp-wemos-schild/NeoPatterns.h | 3 + esp-wemos-schild/esp-wemos-schild.ino | 14 ++--- 4 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 Readme.md diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..4e5823d --- /dev/null +++ b/Readme.md @@ -0,0 +1,80 @@ +Homie Schild Firmware +===================== +## About +## Features +|Topic |Descriptions |settable |Values | +|---------|--------------|:---------:|---------| +|`device_id`/strip/pixel/|Range property from 0 - (number of pixels - 1)|ja|Color as uint32_t see [Color](#color)| +|`device_id`/strip/color|Range property to set the effects colors 1 & 2 see: [effect colors](#effect-colors)|ja|Color as uint32_t see [Color](#color)| +|`device_id`/strip/brightness|Sets the brightness of the pixel strip|ja|possible values: 0 - 255| +|`device_id`/strip/effect|Set effect|ja|see: [effects](#effects)| +|`device_id`/strip/clear|Clears the pixels strip|ja|any value is possible| +|`device_id`/strip/length|Set the strip length|ja|Possible values: 0 - length| + +## Color +To convert RGB value use the following bash code: +```bash +function rgbToColor { + echo $(( $(($1<<16)) + $(($2<<8)) + $(($3)) )); +} + +function colorToRGB { + echo "Red: $(($1>>16&0xff))" + echo "Green: $(($1>>8&0xff))" + echo "Blue: $(($1&0xff))" +} +``` +#### Example +RGB Value to color uint32_t +```bash + bash$ rgbToColor 155 230 32 + 10216992 + bash$ +``` +uint32_t to RGB values +```bash + bash$ colorToRGB 10216992 + Red: 155 + Green: 230 + Blue: 32 + bash$ +``` + +## Effects +* scanner +Shows the moving larson scanner eye known form *Battlestar Galactica* and *Knight Rider*. The used effect color can be specified by *color_0* +* randomscanner +This is the same scanner then the scanner above but uses an alternating color pattern +* rainbowcycle +Shows a cycling rainbown on the LED strip +* theaterchase +Shows an color chasing LED strip. +You can specify the color by set *color_0* and *color_1* +* fade +Fades from effect color_0 to effect_color_1 +* randomfade +Fades thru an alternating color pattern +* none +Stop all effects + +## Effect colors +You can set to different effect colors +* *color_0* (default R: 255, G: 0 B: 0) +* *color_1* (default R: 0, G: 0 B: 255) + +The effect color has to be set after the effect. +###### Example: +1. `homie/device_id/strip/effect/set -m "fade"` +2. `homie/device_id/strip/color_0/set -m "255"` +3. `homie/device_id/strip/color_1/set -m "10216992"` + +##### color_0 +This color will be used for the following effects: +* scanner +* theaterchase +* fade + +##### color_1 +This color will be used for the following effects: +* theaterchase +* fade diff --git a/esp-wemos-schild/NeoPatterns.cpp b/esp-wemos-schild/NeoPatterns.cpp index e51e81a..91cea44 100644 --- a/esp-wemos-schild/NeoPatterns.cpp +++ b/esp-wemos-schild/NeoPatterns.cpp @@ -228,6 +228,13 @@ void NeoPatterns::RandomFadeUpdate(){ Increment(); } +void NeoPatterns::SetColor1(uint32_t color){ + Color1 = color; +} +void NeoPatterns::SetColor2(uint32_t color){ + Color2 = color; +} + // Calculate 50% dimmed version of a color (used by ScannerUpdate) uint32_t NeoPatterns::DimColor(uint32_t color) { diff --git a/esp-wemos-schild/NeoPatterns.h b/esp-wemos-schild/NeoPatterns.h index 7168fed..68e470b 100644 --- a/esp-wemos-schild/NeoPatterns.h +++ b/esp-wemos-schild/NeoPatterns.h @@ -26,6 +26,9 @@ void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, di void FadeUpdate(); void RandomFade(uint8_t interval = 100); void RandomFadeUpdate(); + +void SetColor1(uint32_t color); +void SetColor2(uint32_t color); //Utilities void ColorSet(uint32_t color); uint8_t Red(uint32_t color); diff --git a/esp-wemos-schild/esp-wemos-schild.ino b/esp-wemos-schild/esp-wemos-schild.ino index 5790312..3d8ff89 100644 --- a/esp-wemos-schild/esp-wemos-schild.ino +++ b/esp-wemos-schild/esp-wemos-schild.ino @@ -23,8 +23,6 @@ HomieNode stripNode("strip", "strip"); HomieNode sensorNode("sensor", "sensor"); Bounce debouncer = Bounce(); -uint32_t color1 = pixels.Color(255, 0, 0); -uint32_t color2 = pixels.Color(0, 0, 255); bool onSetColor(const HomieRange& range, const String& value){ if (!range.isRange || range.index < 0 || range.index > 1) { @@ -32,10 +30,10 @@ bool onSetColor(const HomieRange& range, const String& value){ } switch(range.index) { case 0: - color1 = value.toInt(); + pixels.SetColor1(value.toInt()); break; case 1: - color2 = value.toInt(); + pixels.SetColor2(value.toInt()); break; } stripNode.setProperty("color_" + String(range.index)).send(value); @@ -74,19 +72,19 @@ bool onSetEffect(const HomieRange& range, const String& value){ String effect = value; effect.toLowerCase(); if(effect == "scanner") { - pixels.Scanner(color1); + pixels.Scanner(pixels.Color(255, 0, 0)); } else if(effect == "randomscanner") { - pixels.Scanner(color1, 40, true); + pixels.Scanner(pixels.Color(255, 0, 0), 40, true); } else if(effect == "rainbowcycle") { pixels.RainbowCycle(50); } else if(effect == "theaterchase") { - pixels.TheaterChase(color1, color2, 100); + pixels.TheaterChase(pixels.Color(255, 0, 0), pixels.Color(0,0,255), 100); } else if(effect == "fade") { - pixels.Fade(color1, color2, 200, 100); + pixels.Fade(pixels.Color(255, 0, 0), pixels.Color(0,0,255), 200, 100); } else if(effect == "randomfade") { pixels.RandomFade(); From 1477caeb83967e88b585da615ac320ac4ba34607 Mon Sep 17 00:00:00 2001 From: Juergen Jung Date: Sun, 19 Feb 2017 21:50:24 +0100 Subject: [PATCH 6/6] Add motion sensor documentation --- Readme.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index 4e5823d..8ce4bb5 100644 --- a/Readme.md +++ b/Readme.md @@ -2,14 +2,21 @@ Homie Schild Firmware ===================== ## About ## Features +### LED Strip |Topic |Descriptions |settable |Values | |---------|--------------|:---------:|---------| -|`device_id`/strip/pixel/|Range property from 0 - (number of pixels - 1)|ja|Color as uint32_t see [Color](#color)| -|`device_id`/strip/color|Range property to set the effects colors 1 & 2 see: [effect colors](#effect-colors)|ja|Color as uint32_t see [Color](#color)| -|`device_id`/strip/brightness|Sets the brightness of the pixel strip|ja|possible values: 0 - 255| -|`device_id`/strip/effect|Set effect|ja|see: [effects](#effects)| -|`device_id`/strip/clear|Clears the pixels strip|ja|any value is possible| -|`device_id`/strip/length|Set the strip length|ja|Possible values: 0 - length| +|`device_id`/strip/pixel/|Range property from 0 - (number of pixels - 1)|yes|Color as uint32_t see [Color](#color)| +|`device_id`/strip/color|Range property to set the effects colors 1 & 2 see: [effect colors](#effect-colors)|yes|Color as uint32_t see [Color](#color)| +|`device_id`/strip/brightness|Sets the brightness of the pixel strip|yes|possible values: 0 - 255| +|`device_id`/strip/effect|Set effect|yes|see: [effects](#effects)| +|`device_id`/strip/clear|Clears the pixels strip|yes|any value is possible| +|`device_id`/strip/length|Set the strip length|yes|Possible values: 0 - length| + +### Motion sensor +|Topic |Descriptions |settable |Values | +|---------|--------------|:---------:|---------| +|`device_id`/sensor/motion|Activated on motion|no|true or false| + ## Color To convert RGB value use the following bash code: