From 8c7417dc7ba67f22dfbaa21533f228bc5387cb66 Mon Sep 17 00:00:00 2001 From: matzman Date: Sat, 17 Mar 2018 21:53:38 +0100 Subject: [PATCH] Some improvements. --- .cproject | 65 +++++++++----------- .project | 28 +++------ NotificationLEDs.h | 147 ++++++++++++++++++++++++++++++++++++--------- SceneAnalogClock.h | 23 +++++++ SceneColorWheel.h | 3 - SceneFollow.h | 105 ++++++++++++++++++++++++++++++++ 6 files changed, 287 insertions(+), 84 deletions(-) create mode 100644 SceneFollow.h diff --git a/.cproject b/.cproject index 5ea270d..b1266e5 100644 --- a/.cproject +++ b/.cproject @@ -19,49 +19,40 @@ @@ -72,7 +63,7 @@ - + @@ -87,5 +78,9 @@ - + + + + + diff --git a/.project b/.project index 5c3c06b..97747a4 100644 --- a/.project +++ b/.project @@ -34,42 +34,32 @@ core/core 2 - ECLIPSE_HOME/arduinoPlugin/packages/arduino/hardware/avr/1.6.18/cores/arduino + ECLIPSE_HOME/arduinoPlugin/packages/arduino/hardware/avr/1.6.21/cores/arduino core/variant 2 - ECLIPSE_HOME/arduinoPlugin/packages/arduino/hardware/avr/1.6.18/variants/eightanaloginputs - - - libraries/Adafruit_GFX_Library - 2 - ECLIPSE_HOME/arduinoPlugin/libraries/Adafruit_GFX_Library/1.1.8 + ECLIPSE_HOME/arduinoPlugin/packages/arduino/hardware/avr/1.6.21/variants/eightanaloginputs libraries/Adafruit_NeoPixel 2 - ECLIPSE_HOME/arduinoPlugin/libraries/Adafruit_NeoPixel/1.0.6 - - - libraries/EEPROM - 2 - ECLIPSE_HOME/arduinoPlugin/packages/arduino/hardware/avr/1.6.18/libraries/EEPROM - - - libraries/MyNodeManager - 2 - ECLIPSE_HOME/arduinoPlugin/libraries/MyNodeManager/1.0.0 + ECLIPSE_HOME/arduinoPlugin/libraries/Adafruit_NeoPixel/1.1.6 libraries/MySensors 2 ECLIPSE_HOME/arduinoPlugin/libraries/MySensors/2.2.0 + + libraries/NodeManager + 2 + ECLIPSE_HOME/arduinoPlugin/libraries/NodeManager/1.0.0 + libraries/SPI 2 - ECLIPSE_HOME/arduinoPlugin/packages/arduino/hardware/avr/1.6.18/libraries/SPI + ECLIPSE_HOME/arduinoPlugin/packages/arduino/hardware/avr/1.6.21/libraries/SPI diff --git a/NotificationLEDs.h b/NotificationLEDs.h index eb60dda..d64b5c8 100644 --- a/NotificationLEDs.h +++ b/NotificationLEDs.h @@ -8,6 +8,23 @@ #include + +#define EEPROM_POS_STATUSTABLE 1 +#define EEPROM_POS_HOUROFFSET 2 + +union _eeprom_NotificationLEDs_StatusTable { + struct { + int hourOffset : 1; + } status; + uint8_t data; +}; + + +// mathematically correct modulo +#define MOD(a,b) ((((a)%(b))+(b))%(b)) + + + template< uint8_t _tpin, uint8_t _trgbwId, @@ -33,6 +50,10 @@ public: void powerOn() noexcept; void returnToLastMode() noexcept; + void sendRGBWStatus() noexcept; + void sendDimmerStatus() noexcept; + void sendPowerSwitchStatus() noexcept; + void defaultScene_config(uint8_t id) noexcept; void defaultScene_init() noexcept; void defaultScene_loop(unsigned long currentUnixTime, unsigned long currentMillis) noexcept; @@ -41,6 +62,7 @@ public: void overrideScene_init() noexcept; void overrideScene_loop(unsigned long currentUnixTime, unsigned long currentMillis) noexcept; + void analogClock_setup() noexcept; void analogClock_config() noexcept; void analogClock_init() noexcept; void analogClock_loop(unsigned long currentUnixTime, unsigned long currentMillis) noexcept; @@ -57,6 +79,10 @@ public: void pulse1_init() noexcept; void pulse1_loop(unsigned long currentUnixTime, unsigned long currentMillis) noexcept; + void follow1_config() noexcept; + void follow1_init() noexcept; + void follow1_loop(unsigned long currentUnixTime, unsigned long currentMillis) noexcept; + protected: unsigned long lastSendTime = 0; Adafruit_NeoPixel pixels = Adafruit_NeoPixel(_tpixelCount, _tpin, NEO_GRBW + NEO_KHZ800); @@ -110,6 +136,19 @@ protected: uint8_t pulseValue = 0; unsigned long lastMillis = 0; } pulse1; + struct { + union { + uint8_t wrgb[4]; + uint32_t color = 0x00FF0000; + } color; + uint8_t maxCycles = 5; + int8_t followDir = 1; + int8_t followPos = 0; + uint8_t waitTime = 50; + uint8_t currentCycles = 0; + bool finishing = false; + unsigned long lastMillis = 0; + } follow1; } sceneData; }; @@ -138,6 +177,7 @@ template< > void NotificationLEDs<_tpin, _trgbwId, _tdimmerId, _tpowerSwitchId, _tcommandId, _tpixelCount, _msgSendInterval> ::setup() noexcept { pixels.begin(); + analogClock_setup(); defaultScene_init(); } @@ -163,6 +203,62 @@ template< } +template< + uint8_t _tpin, + uint8_t _trgbwId, + uint8_t _tdimmerId, + uint8_t _tpowerSwitchId, + uint8_t _tcommandId, + uint16_t _tpixelCount, + unsigned long _msgSendInterval +> void NotificationLEDs<_tpin, _trgbwId, _tdimmerId, _tpowerSwitchId, _tcommandId, _tpixelCount, _msgSendInterval> +::sendRGBWStatus() noexcept { + if (mode > 0 && sceneMode == 1) { + _sendValue(true, _trgbwId, V_STATUS); + char rgbw[9] = "00000000"; + // WRGB => RGBW + String tmp((staticColor.color & 0xFF000000) >> 24 | ((staticColor.color & 0x00FFFFFF) << 8)); + memcpy(rgbw+(8-tmp.length()), tmp.c_str(), tmp.length()); + _sendValue(rgbw, _trgbwId, V_RGBW); + } else { + _sendValue(false, _trgbwId, V_STATUS); + } +} + + +template< + uint8_t _tpin, + uint8_t _trgbwId, + uint8_t _tdimmerId, + uint8_t _tpowerSwitchId, + uint8_t _tcommandId, + uint16_t _tpixelCount, + unsigned long _msgSendInterval +> void NotificationLEDs<_tpin, _trgbwId, _tdimmerId, _tpowerSwitchId, _tcommandId, _tpixelCount, _msgSendInterval> +::sendDimmerStatus() noexcept { + if (sceneMode == 0) { + _sendValue(brightness, _tdimmerId, V_PERCENTAGE); + } else { + uint16_t cb = max(staticColor.wrgb[0], max(staticColor.wrgb[1], max(staticColor.wrgb[2], staticColor.wrgb[3]))) * 100 / 255; + _sendValue(cb, _tdimmerId, V_PERCENTAGE); + } +} + + +template< + uint8_t _tpin, + uint8_t _trgbwId, + uint8_t _tdimmerId, + uint8_t _tpowerSwitchId, + uint8_t _tcommandId, + uint16_t _tpixelCount, + unsigned long _msgSendInterval +> void NotificationLEDs<_tpin, _trgbwId, _tdimmerId, _tpowerSwitchId, _tcommandId, _tpixelCount, _msgSendInterval> +::sendPowerSwitchStatus() noexcept { + _sendValue(mode == 0 ? 0 : 1, _tpowerSwitchId, V_STATUS); +} + + template< uint8_t _tpin, uint8_t _trgbwId, @@ -184,22 +280,11 @@ template< if (lastSendTime == 0 || currentMillis - lastSendTime >= _msgSendInterval) { // RGBW Sensor - char rgbw[9] = "00000000"; - // WRGB => RGBW - String tmp((staticColor.color & 0xFF000000) >> 24 | ((staticColor.color & 0x00FFFFFF) << 8)); - memcpy(rgbw+(8-tmp.length()), tmp.c_str(), tmp.length()); - _sendValue(rgbw, _trgbwId, V_RGBW); - + sendRGBWStatus(); //Dimmer - if (sceneMode == 0) { - _sendValue(brightness, _tdimmerId, V_STATUS); - } else { - uint16_t cb = max(staticColor.wrgb[0], max(staticColor.wrgb[1], max(staticColor.wrgb[2], staticColor.wrgb[3]))) * 100 / 255; - _sendValue(cb, _tdimmerId, V_STATUS); - } - + sendDimmerStatus(); //Power Switch - _sendValue(mode == 0 ? 0 : 1, _tpowerSwitchId, V_STATUS); + sendPowerSwitchStatus(); lastSendTime = currentMillis; } @@ -223,7 +308,7 @@ template< // Set Message if (msg.getCommand() == C_SET) { if (msg.type == V_STATUS) { - auto onOff = msg.getByte(); + auto onOff = msg.getBool(); if (onOff) { enableStaticColor(); } else { @@ -248,13 +333,14 @@ template< setStaticColor((color & 0xFFFFFF00) >> 8 | ((color & 0xFF) << 24)); retval = true; } + if (retval) { + sendPowerSwitchStatus(); + sendRGBWStatus(); + sendDimmerStatus(); + } // Request Message } else if (msg.getCommand() == C_REQ) { - char rgbw[9] = "00000000"; - // WRGB => RGBW - String tmp((staticColor.color & 0xFF000000) >> 24 | ((staticColor.color & 0x00FFFFFF) << 8)); - memcpy(rgbw+(8-tmp.length()), tmp.c_str(), tmp.length()); - _sendValue(rgbw, _trgbwId, V_RGBW); + sendRGBWStatus(); retval = true; } } @@ -281,15 +367,11 @@ template< setStaticColor(staticColor.color); } retval = true; + sendDimmerStatus(); } // Request Message } else if (msg.getCommand() == C_REQ) { - if (sceneMode == 0) { - _sendValue(brightness, _tdimmerId, V_STATUS); - } else { - uint16_t cb = max(staticColor.wrgb[0], max(staticColor.wrgb[1], max(staticColor.wrgb[2], staticColor.wrgb[3]))) * 100 / 255; - _sendValue(cb, _tdimmerId, V_STATUS); - } + sendDimmerStatus(); retval = true; } } @@ -306,10 +388,13 @@ template< powerOn(); } retval = true; + sendPowerSwitchStatus(); + sendRGBWStatus(); + sendDimmerStatus(); } // Request Message } else if (msg.getCommand() == C_REQ) { - _sendValue(mode == 0 ? 0 : 1, _tpowerSwitchId, V_STATUS); + sendPowerSwitchStatus(); retval = true; } } @@ -578,6 +663,9 @@ template< if (id == 0) { overrideScene = id; pulse1_config(); + } else if (id == 1) { + overrideScene = id; + follow1_config(); } } @@ -594,6 +682,8 @@ template< ::overrideScene_init() noexcept { if (overrideScene == 0) { pulse1_init(); + } else if (overrideScene == 1) { + follow1_init(); } } @@ -610,12 +700,15 @@ template< ::overrideScene_loop(unsigned long currentUnixTime, unsigned long currentMillis) noexcept { if (overrideScene == 0) { pulse1_loop(currentUnixTime, currentMillis); + } else if (overrideScene == 1) { + follow1_loop(currentUnixTime, currentMillis); } } #include "SceneAnalogClock.h" #include "SceneColorWheel.h" #include "ScenePulse.h" +#include "SceneFollow.h" diff --git a/SceneAnalogClock.h b/SceneAnalogClock.h index 4bb601a..ccc7f84 100644 --- a/SceneAnalogClock.h +++ b/SceneAnalogClock.h @@ -8,6 +8,24 @@ #include "NotificationLEDs.h" +template< + uint8_t _tpin, + uint8_t _trgbwId, + uint8_t _tdimmerId, + uint8_t _tpowerSwitchId, + uint8_t _tcommandId, + uint16_t _tpixelCount, + unsigned long _msgSendInterval +> void NotificationLEDs<_tpin, _trgbwId, _tdimmerId, _tpowerSwitchId, _tcommandId, _tpixelCount, _msgSendInterval> +::analogClock_setup() noexcept { + _eeprom_NotificationLEDs_StatusTable statusTable; + statusTable.data = loadState(EEPROM_POS_STATUSTABLE); + if (statusTable.status.hourOffset == 1) { + sceneData.analogClock.hourOffset = (int8_t)loadState(EEPROM_POS_HOUROFFSET); + } +} + + template< uint8_t _tpin, uint8_t _trgbwId, @@ -22,6 +40,11 @@ template< if (token && token[0] != ' ') { auto offset = atoi(token); sceneData.analogClock.hourOffset = offset; + _eeprom_NotificationLEDs_StatusTable statusTable; + statusTable.data = loadState(EEPROM_POS_STATUSTABLE); + statusTable.status.hourOffset = 1; + saveState(EEPROM_POS_HOUROFFSET, offset); + saveState(EEPROM_POS_STATUSTABLE, statusTable.data); } token = strtok(NULL, _configDelims); if (token && token[0] != ' ') { diff --git a/SceneColorWheel.h b/SceneColorWheel.h index f7af58c..56ae151 100644 --- a/SceneColorWheel.h +++ b/SceneColorWheel.h @@ -26,9 +26,6 @@ void _colorWheel_mapIndex(uint16_t c, uint16_t& r, uint16_t& g, uint16_t& b) { } } -// mathematically correct modulo -#define MOD(a,b) ((((a)%(b))+(b))%(b)) - template< uint8_t _tpin, uint8_t _trgbwId, diff --git a/SceneFollow.h b/SceneFollow.h new file mode 100644 index 0000000..e38dd00 --- /dev/null +++ b/SceneFollow.h @@ -0,0 +1,105 @@ +#ifndef SCENEFOLLOW_H_ +#define SCENEFOLLOW_H_ + +#include +#include +#include +#include +#include "NotificationLEDs.h" + + +template< + uint8_t _tpin, + uint8_t _trgbwId, + uint8_t _tdimmerId, + uint8_t _tpowerSwitchId, + uint8_t _tcommandId, + uint16_t _tpixelCount, + unsigned long _msgSendInterval +> void NotificationLEDs<_tpin, _trgbwId, _tdimmerId, _tpowerSwitchId, _tcommandId, _tpixelCount, _msgSendInterval> +::follow1_config() noexcept { + auto token = strtok(NULL, _configDelims); + if (token && token[0] != ' ') { + auto color = strtoul(token, NULL, 16); + sceneData.follow1.color.color = color; + } + token = strtok(NULL, _configDelims); + if (token && token[0] != ' ') { + auto maxCycles = atoi(token); + sceneData.follow1.maxCycles = maxCycles; + } + token = strtok(NULL, _configDelims); + if (token && token[0] != ' ') { + auto followDir = atoi(token); + sceneData.follow1.followDir = followDir; + } + token = strtok(NULL, _configDelims); + if (token && token[0] != ' ') { + auto waitTime = atoi(token); + sceneData.follow1.waitTime = waitTime; + } +} + + +template< + uint8_t _tpin, + uint8_t _trgbwId, + uint8_t _tdimmerId, + uint8_t _tpowerSwitchId, + uint8_t _tcommandId, + uint16_t _tpixelCount, + unsigned long _msgSendInterval +> void NotificationLEDs<_tpin, _trgbwId, _tdimmerId, _tpowerSwitchId, _tcommandId, _tpixelCount, _msgSendInterval> +::follow1_init() noexcept { + for (uint8_t i = 0; i < _tpixelCount; i++) { + pixels.setPixelColor(i, 0); + } + pixels.show(); + if (sceneData.follow1.followDir > 0) { + sceneData.follow1.followPos = 0; + } else { + sceneData.follow1.followPos = 11; + } + sceneData.follow1.finishing = false; + sceneData.follow1.currentCycles = 0; + sceneData.follow1.lastMillis = 0; +} + + +template< + uint8_t _tpin, + uint8_t _trgbwId, + uint8_t _tdimmerId, + uint8_t _tpowerSwitchId, + uint8_t _tcommandId, + uint16_t _tpixelCount, + unsigned long _msgSendInterval +> void NotificationLEDs<_tpin, _trgbwId, _tdimmerId, _tpowerSwitchId, _tcommandId, _tpixelCount, _msgSendInterval> +::follow1_loop(unsigned long currentUnixTime, unsigned long currentMillis) noexcept { + if (currentMillis - sceneData.follow1.lastMillis >= sceneData.follow1.waitTime) { + if (sceneData.follow1.finishing) { + auto delPos = MOD(sceneData.follow1.followPos-sceneData.follow1.followDir*4, 12); + pixels.setPixelColor(delPos, 0); + pixels.show(); + sceneData.follow1.followPos += sceneData.follow1.followDir; + if (sceneData.follow1.followPos > 4 && sceneData.follow1.followPos < 7) { + returnToLastMode(); + } + } else { + pixels.setPixelColor(sceneData.follow1.followPos, sceneData.follow1.color.color); + auto delPos = MOD(sceneData.follow1.followPos-sceneData.follow1.followDir*4, 12); + pixels.setPixelColor(delPos, 0); + pixels.show(); + sceneData.follow1.followPos += sceneData.follow1.followDir; + if (sceneData.follow1.followPos < 0 || sceneData.follow1.followPos > 11) { + sceneData.follow1.followPos = MOD(sceneData.follow1.followPos, 12); + if (sceneData.follow1.maxCycles > 0 && sceneData.follow1.currentCycles > sceneData.follow1.maxCycles) { + sceneData.follow1.finishing = true; + } + } + } + sceneData.follow1.lastMillis = currentMillis; + } +} + +#endif /* SCENEFOLLOW_H_ */