Compare commits

..

No commits in common. "master" and "fsm" have entirely different histories.
master ... fsm

15 changed files with 392 additions and 1747 deletions

BIN
.vscode/browse.vc.db vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,163 +0,0 @@
{
"WARNING": "This file was generated by the PlatformIO extension. Changes to this file will be lost when it is regenerated.",
"configurations": [
{
"name": "Mac",
"includePath": [
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/tools/sdk/include",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip/include",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/cores/esp8266",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/variants/d1_mini",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ArduinoJson_ID64",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Bounce2_ID1106",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/AsyncMqttClient_ID346/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Adafruit NeoPixel_ID28",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/homie-esp8266/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/esp-wemos-schild",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Adafruit NeoPixel_ID28",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ArduinoJson_ID64",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ArduinoJson_ID64",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/AsyncMqttClient_ID346/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/AsyncMqttClient_ID346/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Bounce2_ID1106",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Bounce2_ID1106",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/homie-esp8266/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ArduinoJson_ID64",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/AsyncMqttClient_ID346/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Bounce2_ID1106",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/homie-esp8266/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/EEPROM",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266AVRISP/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPUpdateServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SSDP",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFiMesh/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266httpUpdate/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Ethernet/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/GDBStub/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Hash/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/SD/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/SPI",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Servo/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/SoftwareSerial",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/TFT_Touch_Shield_V2",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Wire",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/esp8266/src",
"/Users/dukat/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include",
"/Users/dukat/.platformio/packages/toolchain-xtensa/lib/gcc/xtensa-lx106-elf/4.8.2/include",
"/Users/dukat/.platformio/packages/toolchain-xtensa/lib/gcc/xtensa-lx106-elf/4.8.2/include-fixed"
],
"defines": [
"ARDUINO=20300",
"LWIP_OPEN_SRC",
"F_CPU=80000000L",
"__ets__",
"ICACHE_FLASH",
"PLATFORMIO=30300",
"ESP8266",
"ARDUINO_ARCH_ESP8266",
"ESP8266_WEMOS_D1MINI"
],
"browse": {
"path": [
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/tools/sdk/include",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip/include",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/cores/esp8266",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/variants/d1_mini",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ArduinoJson_ID64",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Bounce2_ID1106",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/AsyncMqttClient_ID346/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Adafruit NeoPixel_ID28",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/homie-esp8266/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/esp-wemos-schild",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Adafruit NeoPixel_ID28",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ArduinoJson_ID64",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ArduinoJson_ID64",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/AsyncMqttClient_ID346/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/AsyncMqttClient_ID346/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Bounce2_ID1106",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Bounce2_ID1106",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/homie-esp8266/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ArduinoJson_ID64",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/ESPAsyncTCP_ID305/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/AsyncMqttClient_ID346/src",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/Bounce2_ID1106",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS",
"/Users/dukat/Documents/Arduino/Homie/esp-wemos-schild/.piolibdeps/homie-esp8266/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/EEPROM",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266AVRISP/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPUpdateServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SSDP",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFiMesh/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266httpUpdate/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Ethernet/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/GDBStub/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Hash/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/SD/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/SPI",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Servo/src",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/SoftwareSerial",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/TFT_Touch_Shield_V2",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/Wire",
"/Users/dukat/.platformio/packages/framework-arduinoespressif8266/libraries/esp8266/src",
"/Users/dukat/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include",
"/Users/dukat/.platformio/packages/toolchain-xtensa/lib/gcc/xtensa-lx106-elf/4.8.2/include",
"/Users/dukat/.platformio/packages/toolchain-xtensa/lib/gcc/xtensa-lx106-elf/4.8.2/include-fixed"
],
"limitSymbolsToIncludedHeaders": false,
"databaseFilename": "${workspaceRoot}/.vscode/browse.vc.db"
}
}
]
}

View File

@ -12,9 +12,15 @@ Homie Schild Firmware
|`device_id`/strip/clear|Clears the pixels strip|yes|any value is possible| |`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| |`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 ## Color
To convert RGB value use the following bash code: To convert RGB value use the following bash code:
```shell ```bash
function rgbToColor { function rgbToColor {
echo $(( $(($1<<16)) + $(($2<<8)) + $(($3)) )); echo $(( $(($1<<16)) + $(($2<<8)) + $(($3)) ));
} }
@ -24,17 +30,16 @@ function colorToRGB {
echo "Green: $(($1>>8&0xff))" echo "Green: $(($1>>8&0xff))"
echo "Blue: $(($1&0xff))" echo "Blue: $(($1&0xff))"
} }
``` ```
#### Example #### Example
RGB Value to color uint32_t RGB Value to color uint32_t
```shell ```bash
bash$ rgbToColor 155 230 32 bash$ rgbToColor 155 230 32
10216992 10216992
bash$ bash$
``` ```
uint32_t to RGB values uint32_t to RGB values
```shell ```bash
bash$ colorToRGB 10216992 bash$ colorToRGB 10216992
Red: 155 Red: 155
Green: 230 Green: 230
@ -43,39 +48,20 @@ uint32_t to RGB values
``` ```
## Effects ## Effects
* **scanner** * scanner
Shows the moving larson scanner eye known form *Battlestar Galactica* and *Knight Rider*. The used effect color can be specified by *color_0* Shows the moving larson scanner eye known form *Battlestar Galactica* and *Knight Rider*. The used effect color can be specified by *color_0*
* **randomscanner** * randomscanner
This is the same scanner then the scanner above but uses an alternating color pattern This is the same scanner then the scanner above but uses an alternating color pattern
* **rainbowcycle** * rainbowcycle
Shows a cycling rainbown on the LED strip Shows a cycling rainbown on the LED strip
* **theaterchase** * theaterchase
Shows an color chasing LED strip. Shows an color chasing LED strip.
You can specify the color by set *color_0* and *color_1* You can specify the color by set *color_0* and *color_1*
* **bvb** * fade
Shows an color chasing LED strip.
It is predefined with yellow and black (off)
* **fade**
Fades from effect color_0 to effect_color_1 Fades from effect color_0 to effect_color_1
* **randomfade** * randomfade
Fades thru an alternating color pattern Fades thru an alternating color pattern
* **random** * none
Set the color of each pixel randomly, once
* **smooth**
Smooth transitions, created for pixelprojektor
* **plasma**
Plasma animation, created for pixelprojektor
* **fire**
Yellow-Orange-red flicker fire effect
* **fireworks**
(Beta) Works best on very long stripes, this one is a bit short (30 LEDs)
* **drop**
Water drop effect
* **scannerrandom**
Like randomscanner, but randomly changes directions
* **ring**
Water drop effect with expanding "ring"
* **none**
Stop all effects Stop all effects
## Effect colors ## Effect colors
@ -91,11 +77,11 @@ The effect color has to be set after the effect.
##### color_0 ##### color_0
This color will be used for the following effects: This color will be used for the following effects:
* *scanner* * scanner
* *theaterchase* * theaterchase
* *fade* * fade
##### color_1 ##### color_1
This color will be used for the following effects: This color will be used for the following effects:
* *theaterchase* * theaterchase
* *fade* * fade

View File

@ -1,35 +1,14 @@
#include "NeoPatterns.h" #include "NeoPatterns.h"
NeoPatterns::NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)(), void (*callbackDebug)(String)) : NeoPatterns::NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)()) :
Adafruit_NeoPixel(pixels, pin, type) Adafruit_NeoPixel(pixels, pin, type)
{ {
OnComplete = callback; OnComplete = callback;
OnDebugOutput = callbackDebug;
//Allocate a zero initialized block of memory big enough to hold "pixels" uint8_t.
pixelR = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) );
pixelG = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) );
pixelB = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) );
pixelR_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) );
pixelG_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) );
pixelB_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) );
// Max. MAX_DROPS Drops: Location
drop = ( uint8_t* ) calloc (MAX_DROPS, sizeof( uint8_t ) );
// Max. MAX_DROPS Drops: Brightness (Default to 0)
dropBrightness = ( uint8_t* ) calloc (MAX_DROPS, sizeof( uint8_t ) );
// Max. MAX_RINGS Rings: Location
ring = ( uint8_t* ) calloc (MAX_RINGS, sizeof( uint8_t ) );
// Max. MAX_RINGS Rings: Brightness (Default to 0)
ringBrightness = ( uint8_t* ) calloc (MAX_RINGS, sizeof( uint8_t ) );
ringDistance = ( uint8_t* ) calloc (MAX_RINGS, sizeof( uint8_t ) );
} }
void NeoPatterns::Update(){ void NeoPatterns::Update(){
if((millis() - lastUpdate) > Interval) // time to update if((millis() - lastUpdate) > Interval) // time to update
{ {
// OnDebugOutput(String("Updating at " ) + String(millis()));
lastUpdate = millis(); lastUpdate = millis();
switch(ActivePattern) switch(ActivePattern)
{ {
@ -39,9 +18,6 @@ void NeoPatterns::Update() {
case THEATER_CHASE: case THEATER_CHASE:
TheaterChaseUpdate(); TheaterChaseUpdate();
break; break;
case BVB:
BVBChaseUpdate();
break;
case COLOR_WIPE: case COLOR_WIPE:
ColorWipeUpdate(); ColorWipeUpdate();
break; break;
@ -54,53 +30,16 @@ void NeoPatterns::Update() {
case RANDOM_FADE: case RANDOM_FADE:
RandomFadeUpdate(); RandomFadeUpdate();
break; break;
case RANDOM_FADE_SINGLE:
RandomFadeSingleUpdate();
break;
case SMOOTH:
SmoothUpdate();
break;
case PLASMA:
PlasmaUpdate();
break;
case FILL:
break;
case RANDOM:
break;
case FIRE:
FireUpdate();
break;
case FIREWORKS:
FireworksUpdate();
break;
case DROP:
DropUpdate();
break;
case RINGS:
RingsUpdate();
break;
case SCANNER_RANDOM:
ScannerRandomUpdate();
break;
case NONE: case NONE:
break; break;
default: default:
break; break;
} }
} else {
delay(1);
// Serial.print(".");
} }
} }
void NeoPatterns::setInterval(uint8_t interval)
{
Interval = interval;
}
void NeoPatterns::Increment() void NeoPatterns::Increment()
{ {
// OnDebugOutput(String(Index) + " / " + String(TotalSteps));
if (Direction == FORWARD) if (Direction == FORWARD)
{ {
Index++; Index++;
@ -109,7 +48,7 @@ void NeoPatterns::Increment()
Index = 0; Index = 0;
if (OnComplete != NULL) if (OnComplete != NULL)
{ {
OnComplete(); // call the completion callback OnComplete(); // call the comlpetion callback
} }
} }
} }
@ -121,7 +60,7 @@ void NeoPatterns::Increment()
Index = TotalSteps-1; Index = TotalSteps-1;
if (OnComplete != NULL) if (OnComplete != NULL)
{ {
OnComplete(); // call the completion callback OnComplete(); // call the comlpetion callback
} }
} }
} }
@ -131,17 +70,16 @@ void NeoPatterns::Reverse() {
if (Direction == FORWARD) if (Direction == FORWARD)
{ {
Direction = REVERSE; Direction = REVERSE;
// Index = TotalSteps - 1; Index = TotalSteps-1;
} }
else else
{ {
Direction = FORWARD; Direction = FORWARD;
// Index = numPixels()-TotalSteps; Index = 0;
} }
} }
void NeoPatterns::None(uint8_t interval) { void NeoPatterns::None(){
Interval = interval;
if(ActivePattern != NONE) { if(ActivePattern != NONE) {
clear(); clear();
show(); show();
@ -149,8 +87,6 @@ void NeoPatterns::None(uint8_t interval) {
ActivePattern = NONE; ActivePattern = NONE;
} }
/****************** Effects ******************/
void NeoPatterns::RainbowCycle(uint8_t interval, direction dir){ void NeoPatterns::RainbowCycle(uint8_t interval, direction dir){
ActivePattern = RAINBOW_CYCLE; ActivePattern = RAINBOW_CYCLE;
Interval = interval; Interval = interval;
@ -181,55 +117,19 @@ void NeoPatterns::TheaterChase(uint32_t color1, uint32_t color2, uint8_t interva
void NeoPatterns::TheaterChaseUpdate(){ void NeoPatterns::TheaterChaseUpdate(){
for(int i=0; i< numPixels(); i++) for(int i=0; i< numPixels(); i++)
{ {
if ((i + Index) % 8 == 0) if ((i + Index) % 3 == 0)
{ {
setPixelColor(i, Color1); setPixelColor(i, Color1);
} }
else else
{ {
// Reduce brightness for the base pixels setPixelColor(i, Color2);
float _brightness = 0.2;
uint8_t _r = (uint8_t)(Color2 >> 16);
uint8_t _g = (uint8_t)(Color2 >> 8);
uint8_t _b = (uint8_t)Color2;
setPixelColor(i, Color(_r * _brightness, _g * _brightness, _b * _brightness));
} }
} }
show(); show();
Increment(); Increment();
} }
void NeoPatterns::BVBChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir) {
ActivePattern = BVB;
Interval = interval;
TotalSteps = numPixels();
Color1 = color1;
Color2 = color2;
Index = 0;
Direction = dir;
}
void NeoPatterns::BVBChaseUpdate() {
for (int i = 0; i < numPixels(); i++)
{
if ((i + Index) % 8 == 0)
{
setPixelColor(i, Color1);
}
else
{
// Reduce brightness for the base pixels
float _brightness = 0.2;
uint8_t _r = (uint8_t)(Color2 >> 16);
uint8_t _g = (uint8_t)(Color2 >> 8);
uint8_t _b = (uint8_t)Color2;
setPixelColor(i, Color(_r * _brightness, _g * _brightness, _b * _brightness));
}
}
show();
Increment();
}
void NeoPatterns::ColorWipe(uint32_t color, uint8_t interval, direction dir) void NeoPatterns::ColorWipe(uint32_t color, uint8_t interval, direction dir)
{ {
ActivePattern = COLOR_WIPE; ActivePattern = COLOR_WIPE;
@ -249,7 +149,7 @@ void NeoPatterns::ColorWipeUpdate()
} }
// Initialize for a SCANNNER // Initialize for a SCANNNER
void NeoPatterns::Scanner(uint32_t color1, uint8_t interval, bool colorful, bool spiral) void NeoPatterns::Scanner(uint32_t color1, uint8_t interval, bool colorful)
{ {
ActivePattern = SCANNER; ActivePattern = SCANNER;
Interval = interval; Interval = interval;
@ -258,7 +158,6 @@ void NeoPatterns::Scanner(uint32_t color1, uint8_t interval, bool colorful, bool
Index = 0; Index = 0;
wPos = 0; wPos = 0;
this->colorful = colorful; this->colorful = colorful;
this->spiral = spiral;
} }
// Update the Scanner Pattern // Update the Scanner Pattern
@ -275,25 +174,17 @@ void NeoPatterns::ScannerUpdate()
} }
for (int i = 0; i < numPixels(); i++) for (int i = 0; i < numPixels(); i++)
{ {
int finalpos;
if (spiral) {
finalpos = numToSpiralPos(i);
}
else
{
finalpos = i;
}
if (i == Index) // Scan Pixel to the right if (i == Index) // Scan Pixel to the right
{ {
setPixelColor(finalpos, Color1); setPixelColor(i, Color1);
} }
else if (i == TotalSteps - Index) // Scan Pixel to the left else if (i == TotalSteps - Index) // Scan Pixel to the left
{ {
setPixelColor(finalpos, Color1); setPixelColor(i, Color1);
} }
else // Fading tail else // Fading tail
{ {
setPixelColor(finalpos, DimColor(getPixelColor(finalpos))); setPixelColor(i, DimColor(getPixelColor(i)));
} }
} }
show(); show();
@ -301,67 +192,6 @@ void NeoPatterns::ScannerUpdate()
} }
// Initialize for a SCANNNER_RANDOM
void NeoPatterns::ScannerRandom(uint32_t color1, uint8_t interval, bool colorful, bool spiral)
{
ActivePattern = SCANNER_RANDOM;
Interval = interval;
TotalSteps = (numPixels() - 1) * 2;
Color1 = color1;
Index = numPixels() / 2;
wPos = 0;
this->colorful = colorful;
this->spiral = spiral;
}
// Update the Scanner Pattern
void NeoPatterns::ScannerRandomUpdate()
{
if (colorful) {
Color1 = Wheel(wPos);
if (wPos >= 255) {
wPos = 0;
}
else {
wPos++;
}
}
if (random(0, 1000) < 5)
{
Reverse();
}
for (int i = 0; i < numPixels(); i++)
{
int finalpos;
if (spiral) {
finalpos = numToSpiralPos(i);
}
else
{
finalpos = i;
}
if (i == Index) // Scan Pixel to the right
{
setPixelColor(finalpos, Color1);
}
else if (i == TotalSteps - Index) // Scan Pixel to the left
{
setPixelColor(finalpos, Color1);
}
else // Fading tail
{
setPixelColor(finalpos, DimColor(getPixelColor(finalpos)));
}
}
show();
Increment();
}
void NeoPatterns::Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir) void NeoPatterns::Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir)
{ {
ActivePattern = FADE; ActivePattern = FADE;
@ -393,548 +223,11 @@ void NeoPatterns::RandomFade(uint8_t interval ) {
TotalSteps = 255; TotalSteps = 255;
Index = 0; Index = 0;
} }
void NeoPatterns::RandomFadeUpdate(){ void NeoPatterns::RandomFadeUpdate(){
ColorSet(Wheel(Index)); ColorSet(Wheel(Index));
Increment(); Increment();
} }
void NeoPatterns::RandomFadeSingle(uint8_t interval, uint8_t speed) {
ActivePattern = RANDOM_FADE_SINGLE;
Interval = interval;
TotalSteps = 255;
Index = 0;
WheelSpeed = speed;
RandomBuffer();
}
void NeoPatterns::RandomFadeSingleUpdate() {
for (int i = 0; i < numPixels(); i++) {
pixelR_buffer[i] += random(0, random(0, WheelSpeed + 1) + 1); //use buffer red channel for color wheel
setPixelColor(i, Wheel(pixelR_buffer[i]));
}
show();
Increment();
}
void NeoPatterns::RandomBuffer()
{
for (int i = 0; i < numPixels(); i++) {
uint32_t c = Wheel(random(0, 256));
pixelR_buffer[i] = (uint8_t)(c >> 16);
pixelG_buffer[i] = (uint8_t)(c >> 8);
pixelB_buffer[i] = (uint8_t)c;
}
}
void NeoPatterns::Random()
{
None(); // Stop all other effects
ActivePattern = RANDOM;
for (int i = 0; i < numPixels(); i++) {
setPixelColor(i, Wheel(random(0, 256)));
}
show();
}
/********** FIRE ********/
void NeoPatterns::Fire(uint8_t interval)
{
ActivePattern = FIRE;
Interval = interval;
TotalSteps = 255;
Index = 0;
}
void NeoPatterns::FireUpdate()
{
int r = 255;
int g = r - 140;
int b = 0;
for (int i = 0; i < numPixels(); i++) {
int flicker = random(0, 70);
int r1 = r - flicker;
int g1 = g - flicker;
int b1 = b - flicker;
if (g1 < 0) g1 = 0;
if (r1 < 0) r1 = 0;
if (b1 < 0) b1 = 0;
setPixelColor(i, r1, g1, b1);
}
show();
Interval = random(50, 150);
}
/********** FIRE END ****/
/********** FIREWORKS ********/
// Manchmal noch instabil und lässt den ESP abstürzen. Müsste mal mit Serial mal gedebuggt werden...
void NeoPatterns::Fireworks()
{
ActivePattern = FIREWORKS;
Interval = 20; // 12ms ist so ziemlich die untere Grenze, durch die Berechnugen und Speicherzugriffe.
// Calculate "good" explosion speed
// 60 LED Strip: 50, 100, 0.985 is a good choice (with Interval = 25)
// Start 0, with maximum speed (100), the rocket should explode at the LATEST at position 50 (of 60). (Which is 10 pixels before maximum)
// rocket_speed_max should not be >100, as this would skip LEDs.
explosion_speed = 0.25f;
rocket_speed_max = 100;
rocket_slowdown = pow(explosion_speed, (float)((float)1/(float)(2*numPixels()-10))); // 0.985f;
rocket_speed_min = int(log(explosion_speed)/((numPixels()/4) * log(rocket_slowdown)))+1;
if (rocket_speed_min/100 < explosion_speed)
{
rocket_speed_min += explosion_speed*100;
}
// OnDebugOutput(String(rocket_slowdown, 6));
// OnDebugOutput(String(rocket_speed_min));
}
/** Debug Output
haus/RGB5m/strip/DEBUG Start: 0: Speed: 0.960 Pos: 0
haus/RGB5m/strip/DEBUG Explode 0: Speed 0.249 Pos: 149 Iterations: 282 // Die Anzahl der Iterationen ist gut berechnet (0.96 -- 282 von 290 max). Nur wurde der Slowdown nicht mit einberechnet
*/
void NeoPatterns::explosion(int pos, float rocketspeed)
{
uint8_t hue = random(0, 256);
uint8_t explosionsize = random(EXPLOSION_SIZE_MIN, EXPLOSION_SIZE_MAX + 1);
for (int i = 0; i < explosionsize; i++)
{
particle_arr.push_back(Particle(this, pos + i - 3, (float)(((float)random(-50, 50)) / 100) + rocketspeed / 2, hue, 1, 0.99f));
}
}
void NeoPatterns::FireworksUpdate()
{
if (millis() > currentRocketMillis + rocketTimeout)
{
// Start a new rocket
if (random(0, 2) == 0)
{
Rocket tmpr = Rocket(this, 0, (float)(((float)random(rocket_speed_min, rocket_speed_max)) / 100), rocket_slowdown);
// OnDebugOutput(String("Start: ") + String(tmpr.id()) + String(": Speed: ") + String(tmpr.rocketspeed(), 3) + String(" Pos: 0"));
rocket_arr.push_back(tmpr);
}
else
{
Rocket tmpr = Rocket(this, numPixels(), -(float)(((float)random(rocket_speed_min, rocket_speed_max)) / 100), rocket_slowdown);
// OnDebugOutput(String("Start: ") + String(tmpr.id()) + String(": Speed: ") + String(tmpr.rocketspeed(), 3) + String(" Pos: ") + String(numPixels()));
rocket_arr.push_back(tmpr);
}
rocketTimeout = random(ROCKET_LAUNCH_TIMEOUT_MIN, ROCKET_LAUNCH_TIMEOUT_MAX+1);
currentRocketMillis = millis();
}
clear();
// Iterate through all particles
for (std::vector<Particle>::iterator it = particle_arr.begin(); it != particle_arr.end(); ++it)
{
Particle & p = *it;
p.update();
// Erase Particles which are too dark
if (p.brightness() < 0.1)
{
it = particle_arr.erase(it); // After erasing, it is now pointing the next element.
--it;
}
}
// Iterate through all rockets
for (std::vector<Rocket>::iterator it = rocket_arr.begin(); it != rocket_arr.end(); ++it)
{
Rocket & r = *it;
// Create Trail on old position
particle_arr.push_back(Particle(this, r.pos(), 0, 20, 0.3));
r.update();
if ((r.rocketspeed() <= explosion_speed) && (r.rocketspeed() >= -explosion_speed))
{
// OnDebugOutput(String("Explode ") + String(r.id()) + String(": Speed ") + String(r.rocketspeed(), 3) + String(" Pos: ") + String(r.pos()) + String(" Iterations: ") + String(r.iteration()));
explosion( r.pos(), r.rocketspeed());
it = rocket_arr.erase(it); // After erasing, it is now pointing the next element.
--it;
}
}
show();
}
/********** FIREWORKS END ****/
/********** DROP ********/
void NeoPatterns::Drop(uint8_t interval)
{
ActivePattern = DROP;
Interval = interval;
TotalSteps = 255;
Index = 0;
for (int i = 0; i < 10; i++) {
drop[i] = 0;
dropBrightness[i] = 0;
}
clear();
}
void NeoPatterns::DropUpdate()
{
// Generate new drop?
if (random(0, 100) > 50)
{
Serial.println("Will generate a new drop");
// New drop
// Find first free drop and discard, if no free place
for (int i = 0; i < MAX_DROPS; i++) {
if (drop[i] == 0)
{
Serial.print("Found a free position for a drop: ");
// Random position
drop[i] = random(0, numPixels());
dropBrightness[i] = 255; // Initial brightness
Serial.print(i);
Serial.print(" pos ");
Serial.println(drop[i]);
break;
}
}
}
// Work for all other drops
for (int i = 0; i < MAX_DROPS; i++) {
if (drop[i] > 0)
{
Serial.print("Updating drop on ");
Serial.println(i);
// Current drop
// dropBrightness[i] = dropBrightness[i]>>1;
dropBrightness[i] *= 0.9;
if (dropBrightness[i] <= 8)
{
// Brightness to zero for all neighbours
dropBrightness[i] = 0;
}
setPixelColor(drop[i], 0, 0, dropBrightness[i]); // TODO: Other colors?
// Set neighbouring drops
int nBright;
for (int neighbour = 1; neighbour < 5; neighbour++) {
//nBright = dropBrightness[i] >> neighbour;
nBright = dropBrightness[i];
for (int j = 1; j < neighbour; j++)
{
nBright *= 0.6;
}
Serial.print(neighbour);
Serial.print(": ");
Serial.println(nBright);
if ((drop[i] - neighbour) >= 0)
{
setPixelColor(drop[i] - neighbour, 0, 0, nBright);
}
if ((drop[i] + neighbour) <= numPixels())
{
setPixelColor(drop[i] + neighbour, 0, 0, nBright);
}
}
if (dropBrightness[i] <= 8)
{
// Disable this drop
drop[i] = 0;
}
}
}
show();
}
/********** DROP END ****/
/********** RINGS ********/
void NeoPatterns::Rings(uint8_t interval)
{
ActivePattern = RINGS;
Interval = interval;
TotalSteps = 255;
Index = 0;
for (int i = 0; i < 10; i++) {
ring[i] = 0;
ringBrightness[i] = 0;
ringDistance[i] = 0;
}
clear();
}
void NeoPatterns::RingsUpdate()
{
// Generate new ring?
if (random(0, 100) > 50)
{
Serial.println("Will generate a new ring");
// New ring
// Find first free ring and discard, if no free place
for (int i = 0; i < MAX_RINGS; i++) {
if (ring[i] == 0)
{
Serial.print("Found a free position for a ring: ");
// Random position
ring[i] = random(0, numPixels());
ringBrightness[i] = 255 << 1; // Initial brightness
ringDistance[i] = 0;
Serial.print(i);
Serial.print(" pos ");
Serial.println(ring[i]);
break;
}
}
}
// Work for all other rings
for (int i = 0; i < MAX_RINGS; i++) {
if (ring[i] > 0)
{
Serial.print("Updating ring on ");
Serial.println(i);
// Center of the ring
ringBrightness[i] *= 0.9;
if (ringBrightness[i] <= 8)
{
// Brightness to zero for the middle
ringBrightness[i] = 0;
}
setPixelColor(ring[i], 0, 0, ringBrightness[i]); // TODO: Other colors?
// Set neighbouring rings
int nBright;
// Maximum distance for rings is 10
// General idea: Start with the middle (max brightness), continue left and right with brightness * 0.9
// For each step, dim current brightness for ALL pixels simply by 0.7, below thershold -> off
ringDistance[i]++;
// Neighbours: Color of middle, dimmed by 0.9 to max distance
for (int neighbour = 1; neighbour < ringDistance[i]; neighbour++)
{
Serial.print("Neighbour ");
Serial.print(neighbour);
nBright = 255;
if (ringBrightness[i] == 0)
{
nBright = 0;
}
else
{
for (int j = 0; j < ringDistance[i] - neighbour; j++)
{
nBright *= 0.8;
}
nBright *= (1 - 0.1 * ringDistance[i]);
}
if (nBright < 10) {
nBright = 0;
}
Serial.print(" brightness: ");
Serial.println(nBright);
if ((ring[i] - neighbour) >= 0)
{
setPixelColor(ring[i] - neighbour, 0, 0, nBright);
}
if ((ring[i] + neighbour) <= numPixels())
{
setPixelColor(ring[i] + neighbour, 0, 0, nBright);
}
}
if (ringBrightness[i] <= 8)
{
// Disable this ring
ring[i] = 0;
}
}
}
show();
}
/********** RINGS END ****/
void NeoPatterns::Smooth(uint8_t wheelSpeed, uint8_t smoothing, uint8_t strength, uint8_t interval) {
ActivePattern = SMOOTH;
Interval = interval;
Index = 0;
WheelSpeed = wheelSpeed;
Smoothing = smoothing;
Strength = strength;
movingPoint_x = 3;
movingPoint_y = 3;
// Clear buffer (from previous or different effects)
for (int i = 0; i < numPixels(); i++) {
pixelR_buffer[i] = 0;
pixelG_buffer[i] = 0;
pixelB_buffer[i] = 0;
}
}
void NeoPatterns::SmoothUpdate() {
uint32_t c = Wheel(wPos);
wPosSlow += WheelSpeed;
wPos = (wPos + (wPosSlow / 10) ) % 255;
wPosSlow = wPosSlow % 16;
uint8_t r = (uint8_t)(c >> 16);
uint8_t g = (uint8_t)(c >> 8);
uint8_t b = (uint8_t)c;
movingPoint_x = movingPoint_x + 8 + random(-random(0, 1 + 1), random(0, 1 + 1) + 1);
movingPoint_y = movingPoint_y + 8 + random(-random(0, 1 + 1), random(0, 1 + 1) + 1);
if (movingPoint_x < 8) {
movingPoint_x = 8 - movingPoint_x;
} else if (movingPoint_x >= 16) {
movingPoint_x = 22 - movingPoint_x;
} else {
movingPoint_x -= 8;
}
if (movingPoint_y < 8) {
movingPoint_y = 8 - movingPoint_y;
} else if (movingPoint_y >= 16) {
movingPoint_y = 22 - movingPoint_y;
} else {
movingPoint_y -= 8;
}
uint8_t startx = movingPoint_x;
uint8_t starty = movingPoint_y;
for (int i = 0; i < Strength; i++) {
movingPoint_x = startx + 8 + random(-random(0, 2 + 1), random(0, 2 + 1) + 1);
movingPoint_y = starty + 8 + random(-random(0, 2 + 1), random(0, 2 + 1) + 1);
if (movingPoint_x < 8) {
movingPoint_x = 8 - movingPoint_x;
} else if (movingPoint_x >= 16) {
movingPoint_x = 22 - movingPoint_x;
} else {
movingPoint_x -= 8;
}
if (movingPoint_y < 8) {
movingPoint_y = 8 - movingPoint_y;
} else if (movingPoint_y >= 16) {
movingPoint_y = 22 - movingPoint_y;
} else {
movingPoint_y -= 8;
}
if (pixelR[xyToPos(movingPoint_x, movingPoint_y)] < r) {
pixelR[xyToPos(movingPoint_x, movingPoint_y)]++;
} else if (pixelR[xyToPos(movingPoint_x, movingPoint_y)] > r) {
pixelR[xyToPos(movingPoint_x, movingPoint_y)]--;
}
if (pixelG[xyToPos(movingPoint_x, movingPoint_y)] < g) {
pixelG[xyToPos(movingPoint_x, movingPoint_y)]++;
} else if (pixelG[xyToPos(movingPoint_x, movingPoint_y)] > g) {
pixelG[xyToPos(movingPoint_x, movingPoint_y)]--;
}
if (pixelB[xyToPos(movingPoint_x, movingPoint_y)] < b) {
pixelB[xyToPos(movingPoint_x, movingPoint_y)]++;
} else if (pixelB[xyToPos(movingPoint_x, movingPoint_y)] > b) {
pixelB[xyToPos(movingPoint_x, movingPoint_y)]--;
}
}
movingPoint_x = startx;
movingPoint_y = starty;
for (int i = 0; i < numPixels(); i++) {
pixelR_buffer[i] = (Smoothing / 100.0) * pixelR[i] + (1.0 - (Smoothing / 100.0)) * getAverage(pixelR, i, 0, 0);
pixelG_buffer[i] = (Smoothing / 100.0) * pixelG[i] + (1.0 - (Smoothing / 100.0)) * getAverage(pixelG, i, 0, 0);
pixelB_buffer[i] = (Smoothing / 100.0) * pixelB[i] + (1.0 - (Smoothing / 100.0)) * getAverage(pixelB, i, 0, 0);
}
for (int i = 0; i < numPixels(); i++) {
pixelR[i] = pixelR_buffer[i];
pixelG[i] = pixelG_buffer[i];
pixelB[i] = pixelB_buffer[i];
setPixelColor(i, pixelR[i], pixelG[i], pixelB[i]);
}
show();
}
// Based upon https://github.com/johncarl81/neopixelplasma
void NeoPatterns::Plasma(float phase, float phaseIncrement, float colorStretch, uint8_t interval)
{
ActivePattern = PLASMA;
Interval = interval;
PlasmaPhase = phase;
PlasmaPhaseIncrement = phaseIncrement;
PlasmaColorStretch = colorStretch;
}
void NeoPatterns::PlasmaUpdate()
{
PlasmaPhase += PlasmaPhaseIncrement;
int edge = (int)sqrt(numPixels());
// The two points move along Lissajious curves, see: http://en.wikipedia.org/wiki/Lissajous_curve
// The sin() function returns values in the range of -1.0..1.0, so scale these to our desired ranges.
// The phase value is multiplied by various constants; I chose these semi-randomly, to produce a nice motion.
Point p1 = { (sin(PlasmaPhase * 1.000) + 1.0) * (edge / 2), (sin(PlasmaPhase * 1.310) + 1.0) * (edge / 2) };
Point p2 = { (sin(PlasmaPhase * 1.770) + 1.0) * (edge / 2), (sin(PlasmaPhase * 2.865) + 1.0) * (edge / 2) };
Point p3 = { (sin(PlasmaPhase * 0.250) + 1.0) * (edge / 2), (sin(PlasmaPhase * 0.750) + 1.0) * (edge / 2)};
byte row, col;
// For each row...
for ( row = 0; row < edge; row++ ) {
float row_f = float(row); // Optimization: Keep a floating point value of the row number, instead of recasting it repeatedly.
// For each column...
for ( col = 0; col < edge; col++ ) {
float col_f = float(col); // Optimization.
// Calculate the distance between this LED, and p1.
Point dist1 = { col_f - p1.x, row_f - p1.y }; // The vector from p1 to this LED.
float distance1 = sqrt( dist1.x * dist1.x + dist1.y * dist1.y );
// Calculate the distance between this LED, and p2.
Point dist2 = { col_f - p2.x, row_f - p2.y }; // The vector from p2 to this LED.
float distance2 = sqrt( dist2.x * dist2.x + dist2.y * dist2.y );
// Calculate the distance between this LED, and p3.
Point dist3 = { col_f - p3.x, row_f - p3.y }; // The vector from p3 to this LED.
float distance3 = sqrt( dist3.x * dist3.x + dist3.y * dist3.y );
// Warp the distance with a sin() function. As the distance value increases, the LEDs will get light,dark,light,dark,etc...
// You can use a cos() for slightly different shading, or experiment with other functions. Go crazy!
float color_1 = distance1; // range: 0.0...1.0
float color_2 = distance2;
float color_3 = distance3;
float color_4 = (sin( distance1 * distance2 * PlasmaColorStretch )) + 2.0 * 0.5;
// Square the color_f value to weight it towards 0. The image will be darker and have higher contrast.
color_1 *= color_1 * color_4;
color_2 *= color_2 * color_4;
color_3 *= color_3 * color_4;
color_4 *= color_4;
// Scale the color up to 0..7 . Max brightness is 7.
//strip.setPixelColor(col + (edge * row), strip.Color(color_4, 0, 0) );
setPixelColor(col + (edge * row), Color(color_1, color_2, color_3));
}
}
show();
}
/****************** Helper functions ******************/
void NeoPatterns::SetColor1(uint32_t color){ void NeoPatterns::SetColor1(uint32_t color){
Color1 = color; Color1 = color;
} }
@ -960,13 +253,6 @@ void NeoPatterns::ColorSet(uint32_t color)
show(); show();
} }
void NeoPatterns::ColorSetParameters(String parameters)
{
None();
ActivePattern = FILL;
ColorSet(parseColor(parameters));
}
// Returns the Red component of a 32-bit color // Returns the Red component of a 32-bit color
uint8_t NeoPatterns::Red(uint32_t color) uint8_t NeoPatterns::Red(uint32_t color)
{ {
@ -986,7 +272,7 @@ uint8_t NeoPatterns::Blue(uint32_t color)
} }
// Input a value 0 to 255 to get a color value. // Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r. // The colours are a transition r - g - b - back to r.
uint32_t NeoPatterns::Wheel(byte WheelPos) uint32_t NeoPatterns::Wheel(byte WheelPos)
{ {
WheelPos = 255 - WheelPos; WheelPos = 255 - WheelPos;
@ -1005,116 +291,3 @@ uint32_t NeoPatterns::Wheel(byte WheelPos)
return Color(WheelPos * 3, 255 - WheelPos * 3, 0); return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} }
} }
uint32_t NeoPatterns::Wheel(byte WheelPos, float brightness) {
WheelPos = 255 - WheelPos;
// OnDebugOutput(String("Value ") + String (WheelPos * 3) + String(" converted by brightness ") + String(brightness, 6) + String(" to ") + String(int((float)(WheelPos * 3) * brightness)));
if (WheelPos < 85) {
return Color(int((float)(255 - WheelPos * 3) * brightness), 0, int((float)(WheelPos * 3) * brightness));
}
if (WheelPos < 170) {
WheelPos -= 85;
return Color(0, int((float)(WheelPos * 3) * brightness), int((float)(255 - WheelPos * 3) * brightness));
}
WheelPos -= 170;
return Color(int((float)(WheelPos * 3) * brightness), int((float)(255 - WheelPos * 3) * brightness), 0);
}
// Convert x y pixel position to matrix position
uint8_t NeoPatterns::xyToPos(int x, int y) {
if (y % 2 == 0) {
return (y * 8 + x);
} else {
return (y * 8 + (7 - x));
}
}
//convert pixel number to actual 8x8 matrix position
uint8_t NeoPatterns::numToPos(int num) {
int x = num % 8;
int y = num / 8;
return xyToPos(x, y);
}
// Convert pixel number to actual 8x8 matrix position in a spiral
uint8_t NeoPatterns::numToSpiralPos(int num) {
int edge = (int)sqrt(numPixels());
int findx = edge - 1; // 7
int findy = 0;
int stepsize = edge - 1; // initial value (0..7)
int stepnumber = 0; // each "step" should be used twice
int count = -1;
int dir = 1; // direction: 0 = incX, 1=incY, 2=decX, 3=decY
if (num < edge) {
return num; // trivial
}
for (int i = edge; i <= num; i++)
{
count++;
if (count == stepsize) {
count = 0;
// Change direction
dir++;
stepnumber++;
if (stepnumber == 2) {
stepsize -= 1;
stepnumber = 0;
}
if (dir == 4) {
dir = 0;
}
}
switch (dir) {
case 0:
findx++;
break;
case 1:
findy++;
break;
case 2:
findx--;
break;
case 3:
findy--;
break;
}
}
return xyToPos(findx, findy);
}
uint8_t NeoPatterns::getAverage(uint8_t array[], uint8_t i, int x, int y)
{
// TODO: This currently works only with 8x8 (64 pixel)!
uint16_t sum = 0;
uint8_t count = 0;
if (i >= 8) { //up
sum += array[i - 8];
count++;
}
if (i < (64 - 8)) { //down
sum += array[i + 8];
count++;
}
if (i >= 1) { //left
sum += array[i - 1];
count++;
}
if (i < (64 - 1)) { //right
sum += array[i + 1];
count++;
}
return sum / count;
}
uint32_t NeoPatterns::parseColor(String value) {
if (value.charAt(0) == '#') { //solid fill
String color = value.substring(1);
int number = (int) strtol( &color[0], NULL, 16);
// Split them up into r, g, b values
int r = number >> 16;
int g = number >> 8 & 0xFF;
int b = number & 0xFF;
return Color(r, g, b);
}
return 0;
}

View File

@ -1,178 +1,59 @@
#ifndef NEOPATTERNS_H
#define NEOPATTERNS_H
#include <Adafruit_NeoPixel.h> #include <Adafruit_NeoPixel.h>
#include <math.h>
#include <vector>
#include <algorithm> // std::remove
#include "Rocket.h"
#include "Particle.h"
// class Rocket;
// class Particle;
// Ideas
// Drop (Middle high, than to both sides diming out)
#define MAX_DROPS 10
#define MAX_RINGS 1
// Two or more chasers
// Chaser changing direction randomly
// Pattern types supported: // Pattern types supported:
enum pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE, RANDOM_FADE, SMOOTH, RANDOM_FADE_SINGLE, PLASMA, FILL, RANDOM, FIRE, FIREWORKS, DROP, RINGS, SCANNER_RANDOM, BVB }; enum pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE, RANDOM_FADE };
// Patern directions supported: // Patern directions supported:
enum direction { FORWARD, REVERSE }; enum direction { FORWARD, REVERSE };
class NeoPatterns : public Adafruit_NeoPixel class NeoPatterns : public Adafruit_NeoPixel
{ {
public: public:
NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)(), void (*callbackDebug)(String)); NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)());
void Update(); void Update();
void Reverse(); void Reverse();
void None(uint8_t interval = 40); void None();
void RainbowCycle(uint8_t interval, direction dir = FORWARD); void RainbowCycle(uint8_t interval, direction dir = FORWARD);
void RainbowCycleUpdate(); void RainbowCycleUpdate();
void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD); void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD);
void TheaterChaseUpdate(); void TheaterChaseUpdate();
void BVBChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD);
void BVBChaseUpdate();
void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD); void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD);
void ColorWipeUpdate(); void ColorWipeUpdate();
void Scanner(uint32_t color1 = 16711680, uint8_t interval = 40, bool colorful = false, bool spiral = false); void Scanner(uint32_t color1, uint8_t interval = 40,bool colorful = false);
void ScannerUpdate(); void ScannerUpdate();
void ScannerRandom(uint32_t color1 = 16711680, uint8_t interval = 40, bool colorful = false, bool spiral = false);
void ScannerRandomUpdate();
void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD); void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD);
void FadeUpdate(); void FadeUpdate();
void RandomFade(uint8_t interval = 100); void RandomFade(uint8_t interval = 100);
void RandomFadeUpdate(); void RandomFadeUpdate();
void RandomFadeSingle(uint8_t interval = 100, uint8_t speed = 5);
void RandomFadeSingleUpdate();
void Fire(uint8_t interval = 100);
void FireUpdate();
void Fireworks();
void FireworksUpdate();
void explosion(int pos, float rocketspeed);
void Drop(uint8_t interval = 100);
void DropUpdate();
void Rings(uint8_t interval = 100);
void RingsUpdate();
void RandomBuffer();
void Random();
void Smooth(uint8_t wheelSpeed = 16, uint8_t smoothing = 80, uint8_t strength = 50, uint8_t interval = 40);
void SmoothUpdate();
void Plasma(float phase = 0, float phaseIncrement = 0.03, float colorStretch = 0.3, uint8_t interval = 60); // 0.08 and 0.11
void PlasmaUpdate();
void SetColor1(uint32_t color); void SetColor1(uint32_t color);
void SetColor2(uint32_t color); void SetColor2(uint32_t color);
//Utilities //Utilities
void ColorSet(uint32_t color); void ColorSet(uint32_t color);
void ColorSetParameters(String parameters);
uint8_t Red(uint32_t color); uint8_t Red(uint32_t color);
uint8_t Green(uint32_t color); uint8_t Green(uint32_t color);
uint8_t Blue(uint32_t color); uint8_t Blue(uint32_t color);
uint32_t Wheel(byte WheelPos); uint32_t Wheel(byte WheelPos);
uint32_t Wheel(byte WheelPos, float brightness);
uint8_t numToSpiralPos(int num);
uint8_t xyToPos(int x, int y);
uint8_t numToPos(int num);
uint8_t getAverage(uint8_t array[], uint8_t i, int x, int y);
uint32_t parseColor(String value);
void setInterval(uint8_t interval);
#define EXPLOSION_SIZE_MIN 5
#define EXPLOSION_SIZE_MAX 10
// 60 LED Strip: 50, 100, 0.985 is a good choice (with Interval = 25)
// Start 0, with maximum speed (100), the rocket should explode at the LATEST at position 50 (of 60). (Which is 10 pixels before maximum)
// #define EXPLOSION_SPEED 0.25f
// #define ROCKET_SPEED_MIN 50
// ROCKET_SPEED_MAX should not be >100, as this would skip LEDs.
// #define ROCKET_SPEED_MAX 100
// #define ROCKET_SLOWDOWN 0.985f
#define ROCKET_LAUNCH_TIMEOUT_MIN 1000
#define ROCKET_LAUNCH_TIMEOUT_MAX 3000
uint32_t maxRocketID = 0;
uint32_t maxParticleID = 0;
uint32_t currentRocketMillis = 0;
uint32_t rocketTimeout;
float explosion_speed = 0.25f;
uint8_t rocket_speed_min = 50;
uint8_t rocket_speed_max = 100;
double rocket_slowdown = 0.985f;
private: private:
std::vector <Rocket> rocket_arr;
std::vector <Particle> particle_arr;
// Member Variables: // Member Variables:
pattern ActivePattern; // which pattern is running pattern ActivePattern; // which pattern is running
pattern SavedPattern;
direction Direction; // direction to run the pattern direction Direction; // direction to run the pattern
direction SavedDirection;
unsigned long Interval; // milliseconds between updates unsigned long Interval; // milliseconds between updates
unsigned long SavedInterval;
unsigned long lastUpdate; // last update of position unsigned long lastUpdate; // last update of position
uint32_t Color1, Color2; // What colors are in use uint32_t Color1, Color2; // What colors are in use
uint32_t SavedColor1;
uint16_t TotalSteps; // total number of steps in the pattern uint16_t TotalSteps; // total number of steps in the pattern
uint16_t SavedTotalSteps;
uint16_t Index; // current step within the pattern uint16_t Index; // current step within the pattern
uint16_t SavedIndex;
uint8_t Every; // Turn every "Every" pixel in Color1/Color2
byte wPos; byte wPos;
bool colorful; bool colorful;
bool spiral;
uint8_t wPosSlow;
uint8_t WheelSpeed;
uint8_t Smoothing;
uint8_t Strength;
uint8_t movingPoint_x;
uint8_t movingPoint_y;
uint8_t *pixelR;
uint8_t *pixelG;
uint8_t *pixelB;
uint8_t *pixelR_buffer;
uint8_t *pixelG_buffer;
uint8_t *pixelB_buffer;
// Drops
uint8_t *drop;
uint8_t *dropBrightness;
// Rings
uint8_t *ring;
uint8_t *ringBrightness;
uint8_t *ringDistance;
uint8_t FontChar;
float PlasmaPhase;
float SavedPlasmaPhase;
float PlasmaPhaseIncrement;
float SavedPlasmaPhaseIncrement;
float PlasmaColorStretch;
float SavedPlasmaColorStretch;
uint32_t DimColor(uint32_t color); uint32_t DimColor(uint32_t color);
void Increment(); void Increment();
void (*OnComplete)(); // Callback on completion of pattern void (*OnComplete)(); // Callback on completion of pattern
void (*OnDebugOutput)(String); // Callback on completion of pattern
// Convenient 2D point structure
struct Point {
float x;
float y;
}; };
};
#endif

View File

@ -1,48 +0,0 @@
#include "Particle.h"
#include "NeoPatterns.h"
Particle::Particle() // Particle::Particle(NeoPatterns * parent)
{
_pos = 0;
// _id = parent->maxParticleID;
// parent->maxParticleID++;
} //Default constructor.
Particle::Particle(NeoPatterns * parent, float pos, float speed, uint8_t hue, float brightness, float decay )
{
_id = parent->maxParticleID;
parent->maxParticleID++;
_pos = pos;
_speed = speed;
_hue = hue;
_brightness = brightness;
_decay = decay;
_parent = parent;
}
bool Particle::operator==(const Particle &p) const {
return (p._id == _id);
}
void Particle::update()
{
_pos += _speed;
_speed *= 0.96;
_brightness *= _decay;
if (_pos > _parent->numPixels()) {
_pos = 0;
}
_parent->setPixelColor((int)_pos, _parent->Wheel(_hue, _brightness));
}
float Particle::brightness()
{
return _brightness;
}

View File

@ -1,25 +0,0 @@
#ifndef PARTICLE_H
#define PARTICLE_H
#include <Adafruit_NeoPixel.h>
class NeoPatterns; // Forward declaration
class Particle
{
public:
Particle(NeoPatterns * parent, float pos, float speed, uint8_t hue, float brightness, float decay = 0.95);
Particle();
bool operator==(const Particle &p) const;
void update();
int _id;
float brightness();
private:
float _pos;
float _speed;
float _brightness;
float _decay;
uint8_t _hue;
NeoPatterns * _parent;
};
#endif

View File

@ -1,62 +0,0 @@
#include "Rocket.h"
#include "NeoPatterns.h"
Rocket::Rocket()
{
// _id = maxRocketID;
// maxRocketID++;
_pos = 0;
_speed = 1;
_lastbright = 1;
}
Rocket::Rocket(NeoPatterns *parent, float pos, float rocketspeed, float rocket_slowdown)
{
_parent = parent;
_id = _parent->maxRocketID;
_parent->maxRocketID++;
_rocket_slowdown = rocket_slowdown;
_iteration = 0;
Serial.print("Rocket: ");
Serial.print(_id);
Serial.print(" ");
Serial.print(pos);
Serial.print(" ");
Serial.println(rocketspeed);
_pos = pos;
_speed = rocketspeed;
}
bool Rocket::operator==(const Rocket &r) const {
return (r._id == _id);
}
void Rocket::update()
{
_iteration++;
_pos += _speed;
_speed *= _rocket_slowdown; // 0.97
_parent->setPixelColor(_pos, _parent->Color(50, 32, 0));
}
// Schweif mit Sparkle
int Rocket::pos()
{
return _pos;
}
float Rocket::rocketspeed()
{
return _speed;
}
int Rocket::id()
{
return _id;
}
uint16_t Rocket::iteration()
{
return _iteration;
}

View File

@ -1,29 +0,0 @@
#ifndef ROCKET_H
#define ROCKET_H
#include <Adafruit_NeoPixel.h>
class NeoPatterns; // Forward declaration
class Rocket
{
public:
int _id;
Rocket(NeoPatterns *parent, float pos, float rocketspeed, float rocket_slowdown);
Rocket();
bool operator==(const Rocket &r) const;
void update();
int pos();
float rocketspeed();
int id();
uint16_t iteration();
private:
float _pos;
float _speed;
int _lastbright;
float _rocket_slowdown;
uint16_t _iteration;
NeoPatterns * _parent;
};
#endif

View File

@ -2,11 +2,11 @@
"name": "Homie CTDO Schild", "name": "Homie CTDO Schild",
"device_id": "schild", "device_id": "schild",
"wifi": { "wifi": {
"ssid": "CTDO-IoT", "ssid": "Nudel",
"password": "12345678" "password": "Unser WLAN ist sicher!"
}, },
"mqtt": { "mqtt": {
"host": "raum.ctdo.de", "host": "prometheus.local",
"port": 1883, "port": 1883,
"auth": false "auth": false
}, },

View File

@ -4,25 +4,25 @@
#include <ArduinoOTA.h> #include <ArduinoOTA.h>
#include <Adafruit_NeoPixel.h> #include <Adafruit_NeoPixel.h>
#include "NeoPatterns.h" #include "NeoPatterns.h"
#include <math.h>
#define PIN D1 #define PIN D1
#define NUMPIXELS 30 #define SENSOR D3
#define NUMPIXELS 144
#define FW_NAME "esp-schild"
#define FW_VERSION "1.0.4"
HomieNode homieNode("strip", "strip");
bool lastSensorValue = false;
void StripComplete(){ void StripComplete(){
return; return;
} }
void DebugOutput(String value) { NeoPatterns pixels = NeoPatterns(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800,&StripComplete);
homieNode.setProperty("DEBUG").send(value);
} HomieNode stripNode("strip", "strip");
HomieNode sensorNode("sensor", "sensor");
Bounce debouncer = Bounce();
NeoPatterns strip = NeoPatterns(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800, &StripComplete, &DebugOutput);
bool onSetColor(const HomieRange& range, const String& value){ bool onSetColor(const HomieRange& range, const String& value){
if (!range.isRange || range.index < 0 || range.index > 1) { if (!range.isRange || range.index < 0 || range.index > 1) {
@ -30,29 +30,32 @@ bool onSetColor(const HomieRange& range, const String& value) {
} }
switch(range.index) { switch(range.index) {
case 0: case 0:
strip.SetColor1(value.toInt()); pixels.SetColor1(value.toInt());
break; break;
case 1: case 1:
strip.SetColor2(value.toInt()); pixels.SetColor2(value.toInt());
break; break;
} }
homieNode.setProperty("color_" + String(range.index)).send(value); stripNode.setProperty("color_" + String(range.index)).send(value);
} }
bool onSetPixel(const HomieRange& range, const String& value){ bool onSetPixel(const HomieRange& range, const String& value){
if(!range.isRange) { if(!range.isRange) {
strip.None(); pixels.None();
strip.ColorSet(value.toInt()); pixels.ColorSet(value.toInt());
homieNode.setProperty("pixel").send(value); stripNode.setProperty("pixel").send(value);
return true; return true;
} }
if (range.index < 0 || range.index > strip.numPixels() - 1) { if (range.index < 0 || range.index > pixels.numPixels()-1) {
return false; return false;
} }
strip.None(); pixels.None();
strip.setPixelColor(range.index, value.toInt()); pixels.setPixelColor(range.index, value.toInt());
strip.show(); pixels.show();
homieNode.setProperty("pixel_" + String(range.index)).send(value); stripNode.setProperty("pixel_" + String(range.index)).send(value);
} }
bool onSetBrightness(const HomieRange& range, const String& value){ bool onSetBrightness(const HomieRange& range, const String& value){
@ -60,167 +63,99 @@ bool onSetBrightness(const HomieRange& range, const String& value) {
if (brightness < 0 || brightness > 255) { if (brightness < 0 || brightness > 255) {
return false; return false;
} }
strip.setBrightness(brightness); pixels.setBrightness(brightness);
strip.show(); pixels.show();
homieNode.setProperty("brightness").send(value); stripNode.setProperty("brightness").send(value);
}
bool onSetSpeed(const HomieRange& range, const String& value) {
long speed = value.toInt();
if (speed < 0 || speed > 255) {
return false;
}
strip.setInterval(speed);
strip.show();
homieNode.setProperty("speed").send(value);
} }
bool onSetEffect(const HomieRange& range, const String& value){ bool onSetEffect(const HomieRange& range, const String& value){
String effect = value; String effect = value;
effect.toLowerCase(); effect.toLowerCase();
if(effect == "scanner") { if(effect == "scanner") {
strip.Scanner(strip.Color(255, 0, 0)); pixels.Scanner(pixels.Color(255, 0, 0));
} }
else if(effect == "randomscanner") { else if(effect == "randomscanner") {
strip.Scanner(strip.Color(255, 0, 0), 4, true); pixels.Scanner(pixels.Color(255, 0, 0), 40, true);
}
else if (effect == "larsonspiral") {
strip.Scanner(strip.Color(255, 0, 0), 40, true, true);
} }
else if(effect == "rainbowcycle") { else if(effect == "rainbowcycle") {
strip.RainbowCycle(50); pixels.RainbowCycle(50);
} }
else if (effect == "theaterchase" || effect == "chase") { else if(effect == "theaterchase") {
strip.TheaterChase(strip.Color(255, 0, 0), strip.Color(0, 0, 255), 50); pixels.TheaterChase(pixels.Color(255, 0, 0), pixels.Color(0,0,255), 100);
}
else if (effect == "bvb") {
strip.BVBChase(strip.Color(255, 185, 0), strip.Color(0, 0, 0), 50);
} }
else if(effect == "fade") { else if(effect == "fade") {
strip.Fade(strip.Color(255, 0, 0), strip.Color(0, 0, 255), 200, 100); pixels.Fade(pixels.Color(255, 0, 0), pixels.Color(0,0,255), 200, 100);
} }
else if(effect == "randomfade") { else if(effect == "randomfade") {
strip.RandomFade(); pixels.RandomFade();
}
else if (effect == "random") {
strip.Random();
}
else if (effect == "smooth") { //example: smooth|[wheelspeed]|[smoothing]|[strength] wheelspeed=1-255, smoothing=0-100, strength=1-255
strip.Smooth(16, 80, 50, 40);
}
else if (effect == "plasma") {
strip.Plasma();
}
else if (effect == "fire") {
strip.Fire();
}
else if (effect == "fireworks") {
strip.Fireworks();
}
else if (effect == "drop") {
strip.Drop();
}
else if (effect == "scannerrandom") {
strip.ScannerRandom(strip.Color(255, 0, 0), 4, true);
}
else if (effect == "ring") {
strip.Rings();
} else {
// Test whether command with parameters was sent
int sep = value.indexOf("|");
String command = value.substring(0, sep);
String parameters = value.substring(sep + 1);
if (command.equals("fill")) {
strip.ColorSetParameters(parameters);
}
else if (command.equals("randomfade")) {
int sepparam = parameters.indexOf("|");
int p1 = parameters.substring(0, sepparam).toInt();
if (p1 <= 0) {
p1 = 5;
}
strip.RandomFadeSingle(p1);
}
else if (command.equals("randomscanner")) {
int sepparam = parameters.indexOf("|");
int p1 = parameters.substring(0, sepparam).toInt();
if (p1 <= 0) {
p1 = 5;
}
homieNode.setProperty("effect").send(String(p1));
strip.Scanner(strip.Color(255, 0, 0), p1, true);
} }
else { else {
strip.None(); pixels.None();
digitalWrite(PIN, LOW); // D4 ist auch gleichzeitig der LED-Pin, daher abschalten... (TODO: TEST: FIXME)
} }
stripNode.setProperty("effect").send(value);
} }
homieNode.setProperty("effect").send(value);
}
bool onSetClear(const HomieRange& range, const String& value){ bool onSetClear(const HomieRange& range, const String& value){
strip.None(); pixels.None();
strip.clear(); pixels.clear();
strip.show(); pixels.show();
homieNode.setProperty("clear").send(value); stripNode.setProperty("clear").send(value);
} }
bool onSetLength(const HomieRange& range, const String& value){ bool onSetLength(const HomieRange& range, const String& value){
strip.None(); pixels.None();
strip.clear(); pixels.clear();
strip.show(); pixels.show();
int newLength = value.toInt(); int newLength = value.toInt();
if(newLength > 0) { if(newLength > 0) {
strip.updateLength(newLength); pixels.updateLength(newLength);
} }
homieNode.setProperty("length").send(value); stripNode.setProperty("length").send(value);
} }
void loopHandler() { void loopHandler() {
strip.Update(); pixels.Update();
bool sensorValue = debouncer.read();
if (Homie.isConfigured() && Homie.isConnected() && sensorValue != lastSensorValue) {
sensorNode.setProperty("motion").send(sensorValue ? "true" : "false");
lastSensorValue = sensorValue;
}
} }
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
Homie_setFirmware(FW_NAME, FW_VERSION); debouncer.attach(SENSOR,INPUT);
Homie_setBrand(FW_NAME); debouncer.interval(50);
Homie_setFirmware("schild", "1.0.0");
Homie.setLoopFunction(loopHandler); Homie.setLoopFunction(loopHandler);
homieNode.advertiseRange("pixel", 0, NUMPIXELS - 1).settable(onSetPixel); stripNode.advertiseRange("pixel", 0, NUMPIXELS-1).settable(onSetPixel);
homieNode.advertiseRange("color", 0, 1).settable(onSetColor); stripNode.advertiseRange("color", 0, 1).settable(onSetColor);
homieNode.advertise("brightness").settable(onSetBrightness); stripNode.advertise("brightness").settable(onSetBrightness);
homieNode.advertise("speed").settable(onSetSpeed); stripNode.advertise("effect").settable(onSetEffect);
homieNode.advertise("effect").settable(onSetEffect); stripNode.advertise("clear").settable(onSetClear);
homieNode.advertise("clear").settable(onSetClear); stripNode.advertise("length").settable(onSetLength);
homieNode.advertise("length").settable(onSetLength);
strip.begin(); sensorNode.advertise("motion");
strip.clear();
strip.setBrightness(30); pixels.begin();
strip.show(); pixels.clear();
pixels.setBrightness(64);
pixels.show();
Homie.setup(); Homie.setup();
ArduinoOTA.setHostname(Homie.getConfiguration().deviceId); ArduinoOTA.setHostname(Homie.getConfiguration().deviceId);
ArduinoOTA.begin(); ArduinoOTA.setPassword((const char *)"ctdo2342");
ArduinoOTA.onStart([]() {
strip.clear();
});
ArduinoOTA.onEnd([]() {
strip.clear();
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
strip.setPixelColor(progress / (total / NUMPIXELS), strip.Color(100, 0, 0));
strip.show();
});
ArduinoOTA.begin(); ArduinoOTA.begin();
} }
void loop() { void loop() {
Homie.loop(); Homie.loop();
debouncer.update();
ArduinoOTA.handle(); ArduinoOTA.handle();
} }

View File

@ -1,3 +0,0 @@
#!/bin/bash
mosquitto_pub -h raum.ctdo.de -t 'homie/schild/strip/speed/set' -m '5'

View File

@ -16,8 +16,8 @@ framework=arduino
;upload_port = /dev/tty.wchusbserial410 ;upload_port = /dev/tty.wchusbserial410
;upload_speed = 921600 ;upload_speed = 921600
upload_port = 5ccf7f1db369.local ;upload_port = 5ccf7f1db369.local
#upload_port = schild.local upload_port = schild.local
upload_flags = --auth=ctdo2342 upload_flags = --auth=ctdo2342