Last active
October 7, 2020 16:34
-
-
Save clclon/8c1ffa2b7d0566055a5b69b6fd9534a5 to your computer and use it in GitHub Desktop.
MySensors Advanced features I2C patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define MY_DEFAULT_LED_EXT 1 | |
#define MY_INCLUSION_MODE_FEATURE | |
#define MY_INCLUSION_BUTTON_FEATURE | |
#define MY_INCLUSION_MODE_DURATION 10 | |
#include <MySensors.h> | |
#include <core/MyInclusionMode.h> | |
#include <PCF8574.h> | |
const uint8_t scl_PIN = D1; | |
const uint8_t sda_PIN = D2; | |
const uint8_t led_device[4] { 2U, 3U, 6U, 4U }; | |
const uint8_t btn_device[4] { 0U, 1U, 5U, 7U }; | |
PCF8574 expander(0x22, sda_PIN, scl_PIN); | |
void setup() { | |
Wire.begin(sda_PIN, scl_PIN); | |
Serial.begin(115200); | |
while (!Serial) delay(50); | |
for (uint8_t i = 0; i < 4U; i++) { | |
expander.pinMode(led_device[i], OUTPUT); | |
expander.digitalWrite(led_device[i], HIGH); | |
Serial.printf("Init LED expander: %u/%u\n", (uint16_t)i, (uint16_t)led_device[i]); | |
} | |
for (uint8_t i = 0; i < 4U; i++) { | |
expander.pinMode(btn_device[i], INPUT); | |
expander.digitalWrite(btn_device[i], HIGH); | |
Serial.printf("Init BTN expander: %u/%u\n", (uint16_t)i, (uint16_t)btn_device[i]); | |
} | |
expander.begin(); | |
ledsSetCb( | |
[=](uint8_t & state) { expander.digitalWrite(led_device[1], state); }, | |
[=](uint8_t & state) { expander.digitalWrite(led_device[2], state); }, | |
[=](uint8_t & state) { expander.digitalWrite(led_device[3], state); } | |
); | |
inclusionSetCb( | |
[=]() { return (expander.digitalRead(btn_device[0], true) == LOW); }, | |
[=](uint8_t & state) { expander.digitalWrite(led_device[0], state); } | |
); | |
} | |
void loop() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- E:/__BuildSource/__LIB__/Arduino/Sketch/MySensors-development/MySensors.h Sat Aug 22 11:07:35 2020 | |
+++ E:/__BuildSource/__LIB__/Arduino/Sketch/libraries/MySensors/MySensors.h Tue Oct 6 11:28:48 2020 | |
@@ -119,6 +119,8 @@ | |
#if defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) | |
#include "core/MyLeds.cpp" | |
+#elif defined(MY_DEFAULT_LED_EXT) | |
+#include "core/MyLedsExt.cpp" | |
#else | |
#include "core/MyLeds.h" | |
#endif | |
--- MyInclusionMode.cpp Sat Aug 22 11:07:35 2020 | |
+++ MyInclusionMode.cpp Tue Oct 6 13:44:58 2020 | |
@@ -18,25 +18,44 @@ | |
*/ | |
#include "MyInclusionMode.h" | |
+#if defined(ARDUINO_ARCH_ESP8266) | |
+# include <Esp.h> | |
+#endif | |
// global variables | |
extern MyMessage _msgTmp; | |
-unsigned long _inclusionStartTime; | |
-bool _inclusionMode; | |
+unsigned long _inclusionStartTime = 0U, _rebootStartTime = 0U; | |
+bool _inclusionMode, _rebootMode; | |
+ | |
+#if (defined(MY_INCLUSION_BUTTON_FEATURE) && defined(MY_DEFAULT_LED_EXT)) | |
+static btn_cb btnInclusionFunc = [](){ return false; }; | |
+static led_cb ledInclusionFunc = [](uint8_t&){}; | |
+ | |
+void inclusionSetCb(btn_cb btn, led_cb led) { | |
+ btnInclusionFunc = btn; | |
+ ledInclusionFunc = led; | |
+} | |
+#endif | |
inline void inclusionInit() | |
{ | |
+ _rebootMode = false; | |
_inclusionMode = false; | |
#if defined(MY_INCLUSION_BUTTON_FEATURE) | |
+# if defined(MY_DEFAULT_LED_EXT) | |
+ uint8_t state = static_cast<uint8_t>(LED_OFF); | |
+ ledInclusionFunc(state); | |
+# else | |
// Setup digital in that triggers inclusion mode | |
hwPinMode(MY_INCLUSION_MODE_BUTTON_PIN, INPUT_PULLUP); | |
-#endif | |
#if defined (MY_INCLUSION_LED_PIN) | |
// Setup LED pin that indicates inclusion mode | |
hwPinMode(MY_INCLUSION_LED_PIN, OUTPUT); | |
hwDigitalWrite(MY_INCLUSION_LED_PIN, LED_OFF); | |
#endif | |
+# endif | |
+#endif | |
} | |
@@ -51,21 +70,44 @@ | |
_inclusionStartTime = hwMillis(); | |
} | |
} | |
-#if defined (MY_INCLUSION_LED_PIN) | |
+#if defined(MY_INCLUSION_BUTTON_FEATURE) | |
+# if defined(MY_DEFAULT_LED_EXT) | |
+ uint8_t state = static_cast<uint8_t>(_inclusionMode); | |
+ ledInclusionFunc(state); | |
+# elif defined (MY_INCLUSION_LED_PIN) | |
hwDigitalWrite(MY_INCLUSION_LED_PIN, _inclusionMode ? LED_ON : LED_OFF); | |
#endif | |
+#endif | |
} | |
inline void inclusionProcess() | |
{ | |
-#ifdef MY_INCLUSION_BUTTON_FEATURE | |
- if (!_inclusionMode && hwDigitalRead(MY_INCLUSION_MODE_BUTTON_PIN) == MY_INCLUSION_BUTTON_PRESSED) { | |
+#if defined(MY_INCLUSION_BUTTON_FEATURE) | |
+# if defined(MY_DEFAULT_LED_EXT) | |
+ bool b = btnInclusionFunc(); | |
+# else | |
+ bool b = (hwDigitalRead(MY_INCLUSION_MODE_BUTTON_PIN) == MY_INCLUSION_BUTTON_PRESSED); | |
+# endif | |
+ | |
+ if (!_inclusionMode && b) { | |
// Start inclusion mode | |
inclusionModeSet(true); | |
} | |
-#endif | |
+# if defined(ARDUINO_ARCH_ESP8266) | |
+ if (!_rebootMode && b) { | |
+ _rebootStartTime = hwMillis() + 10000U; | |
+ _rebootMode = true; | |
+ | |
+ } else if (_rebootMode && b) { | |
+ if (_rebootStartTime < hwMillis()) | |
+ ESP.restart(); | |
- if (_inclusionMode && hwMillis()-_inclusionStartTime>MY_INCLUSION_MODE_DURATION*1000L) { | |
+ } else if (_rebootMode) { | |
+ _rebootMode = false; | |
+ } | |
+# endif | |
+#endif | |
+ if (_inclusionMode && (hwMillis() - _inclusionStartTime > MY_INCLUSION_MODE_DURATION * 1000L)) { | |
// inclusionTimeInMinutes minute(s) has passed.. stop inclusion mode | |
inclusionModeSet(false); | |
} | |
--- MyInclusionMode.h Sat Aug 22 11:07:35 2020 | |
+++ MyInclusionMode.h Tue Oct 6 13:46:53 2020 | |
@@ -22,6 +22,11 @@ | |
#include "MySensorsCore.h" | |
+#if (defined(MY_INCLUSION_BUTTON_FEATURE) && defined(MY_DEFAULT_LED_EXT)) | |
+typedef bool (*btn_cb)(); | |
+typedef void (*led_cb)(uint8_t&); | |
+void inclusionSetCb(btn_cb, led_cb); | |
+#endif | |
extern bool gatewayTransportSend(MyMessage &message); | |
--- MyIndication.cpp Sat Aug 22 11:07:35 2020 | |
+++ MyIndication.cpp Tue Oct 6 11:54:37 2020 | |
@@ -18,23 +18,23 @@ | |
*/ | |
#include "MyIndication.h" | |
-#if defined(MY_DEFAULT_TX_LED_PIN)|| defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) | |
+#if defined(MY_DEFAULT_TX_LED_PIN)|| defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) || defined(MY_DEFAULT_LED_EXT) | |
#include "MyLeds.h" | |
#endif | |
void setIndication( const indication_t ind ) | |
{ | |
-#if defined(MY_DEFAULT_TX_LED_PIN) | |
+#if (defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_LED_EXT)) | |
if ((INDICATION_TX == ind) || (INDICATION_GW_TX == ind)) { | |
ledsBlinkTx(1); | |
} else | |
#endif | |
-#if defined(MY_DEFAULT_RX_LED_PIN) | |
+#if (defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_LED_EXT)) | |
if ((INDICATION_RX == ind) || (INDICATION_GW_RX == ind)) { | |
ledsBlinkRx(1); | |
} else | |
#endif | |
-#if defined(MY_DEFAULT_ERR_LED_PIN) | |
+#if (defined(MY_DEFAULT_ERR_LED_PIN) || defined(MY_DEFAULT_LED_EXT)) | |
if (ind > INDICATION_ERR_START) { | |
// Number of blinks indicates which error occurred. | |
ledsBlinkErr(ind-INDICATION_ERR_START); | |
--- MyLeds.h Sat Aug 22 11:07:35 2020 | |
+++ MyLeds.h Tue Oct 6 11:45:46 2020 | |
@@ -29,7 +29,12 @@ | |
#define LED_OFF 0x1 | |
#endif | |
-#if defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) | |
+#if defined(MY_DEFAULT_LED_EXT) | |
+typedef void (*led_cb)(uint8_t&); | |
+void ledsSetCb(led_cb, led_cb, led_cb); | |
+#endif | |
+ | |
+#if defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) || defined(MY_DEFAULT_LED_EXT) | |
#define ledBlinkTx(x,...) ledsBlinkTx(x) | |
#define ledBlinkRx(x,...) ledsBlinkRx(x) | |
#define ledBlinkErr(x,...) ledsBlinkErr(x) | |
--- /dev/null Thu Jan 1 03:00:00 1970 | |
+++ MyLedsExt.cpp Tue Oct 6 13:46:02 2020 | |
@@ -0,0 +1,111 @@ | |
+/* | |
+ * The MySensors Arduino library handles the wireless radio link and protocol | |
+ * between your home built sensors/actuators and HA controller of choice. | |
+ * The sensors forms a self healing radio network with optional repeaters. Each | |
+ * repeater and gateway builds a routing tables in EEPROM which keeps track of the | |
+ * network topology allowing messages to be routed to nodes. | |
+ * | |
+ * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> | |
+ * Copyright (C) 2013-2019 Sensnology AB | |
+ * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors | |
+ * | |
+ * Documentation: http://www.mysensors.org | |
+ * Support Forum: http://forum.mysensors.org | |
+ * | |
+ * This program is free software; you can redistribute it and/or | |
+ * modify it under the terms of the GNU General Public License | |
+ * version 2 as published by the Free Software Foundation. | |
+ */ | |
+ | |
+#include "MyLeds.h" | |
+ | |
+#define LED_ON_OFF_RATIO (4) // Power of 2 please | |
+#define LED_PROCESS_INTERVAL_MS (MY_DEFAULT_LED_BLINK_PERIOD/LED_ON_OFF_RATIO) | |
+ | |
+// these variables don't need to be volatile, since we are not using interrupts | |
+static uint8_t countRx; | |
+static uint8_t countTx; | |
+static uint8_t countErr; | |
+static unsigned long prevTime; | |
+ | |
+static led_cb ledsInfoFunc[3]{ | |
+ [](uint8_t&){}, | |
+ [](uint8_t&){}, | |
+ [](uint8_t&){} | |
+}; | |
+ | |
+void ledsSetCb(led_cb rxLed, led_cb txLed, led_cb errLed) { | |
+ ledsInfoFunc[0] = rxLed; | |
+ ledsInfoFunc[1] = txLed; | |
+ ledsInfoFunc[2] = errLed; | |
+} | |
+ | |
+inline void ledsInit() | |
+{ | |
+ // initialize counters | |
+ countRx = 0; | |
+ countTx = 0; | |
+ countErr = 0; | |
+ | |
+ // Setup led pins | |
+ prevTime = hwMillis() - | |
+ LED_PROCESS_INTERVAL_MS; // Subtract some, to make sure leds gets updated on first run. | |
+ ledsProcess(); | |
+} | |
+ | |
+void ledsProcess() | |
+{ | |
+ // Just return if it is not the time... | |
+ if ((hwMillis() - prevTime) < LED_PROCESS_INTERVAL_MS) { | |
+ return; | |
+ } | |
+ prevTime = hwMillis(); | |
+ uint8_t state; | |
+ | |
+ // For an On/Off ratio of 4, the pattern repeated will be [on, on, on, off] | |
+ // until the counter becomes 0. | |
+ if (countRx) { | |
+ --countRx; | |
+ } | |
+ state = (countRx & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF; | |
+ ledsInfoFunc[0](state); // MY_DEFAULT_RX_LED_PIN | |
+ if (countTx) { | |
+ --countTx; | |
+ } | |
+ state = (countTx & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF; | |
+ ledsInfoFunc[1](state); // MY_DEFAULT_TX_LED_PIN | |
+ if (countErr) { | |
+ --countErr; | |
+ } | |
+ state = (countErr & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF; | |
+ ledsInfoFunc[2](state); // MY_DEFAULT_ERR_LED_PIN | |
+} | |
+ | |
+void ledsBlinkRx(uint8_t cnt) | |
+{ | |
+ if (!countRx) { | |
+ countRx = cnt*LED_ON_OFF_RATIO; | |
+ } | |
+ ledsProcess(); | |
+} | |
+ | |
+void ledsBlinkTx(uint8_t cnt) | |
+{ | |
+ if(!countTx) { | |
+ countTx = cnt*LED_ON_OFF_RATIO; | |
+ } | |
+ ledsProcess(); | |
+} | |
+ | |
+void ledsBlinkErr(uint8_t cnt) | |
+{ | |
+ if(!countErr) { | |
+ countErr = cnt*LED_ON_OFF_RATIO; | |
+ } | |
+ ledsProcess(); | |
+} | |
+ | |
+bool ledsBlinking() | |
+{ | |
+ return countRx || countTx || countErr; | |
+} | |
--- MySensorsCore.cpp Sat Aug 22 11:07:35 2020 | |
+++ MySensorsCore.cpp Tue Oct 6 11:56:07 2020 | |
@@ -144,7 +144,7 @@ | |
before(); | |
} | |
-#if defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) | |
+#if defined(MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) || defined(MY_DEFAULT_LED_EXT) | |
ledsInit(); | |
#endif | |
@@ -310,7 +310,7 @@ | |
return _coreConfig.controllerConfig; | |
} | |
-// cppcheck-suppress constParameter | |
+ | |
bool _sendRoute(MyMessage &message) | |
{ | |
#if defined(MY_CORE_ONLY) | |
@@ -620,20 +620,11 @@ | |
{ | |
hwWatchdogReset(); | |
yield(); | |
-#if defined (MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) | |
+#if defined (MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) || defined(MY_DEFAULT_LED_EXT) | |
ledsProcess(); | |
#endif | |
} | |
-#if !defined(MY_SLEEP_HANDLER) | |
-void sleepHandler(bool sleep) | |
-{ | |
- (void)sleep; | |
- // empty function, resolves AVR-specific GCC optimization bug (<5.5) if handler not used | |
- // see here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77326 | |
-} | |
-#endif | |
- | |
int8_t _sleep(const uint32_t sleepingMS, const bool smartSleep, const uint8_t interrupt1, | |
const uint8_t mode1, const uint8_t interrupt2, const uint8_t mode2) | |
{ | |
@@ -709,16 +700,13 @@ | |
#endif | |
setIndication(INDICATION_SLEEP); | |
-#if defined (MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) | |
+#if defined (MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN) || defined(MY_DEFAULT_LED_EXT) | |
// Wait until leds finish their blinking pattern | |
while (ledsBlinking()) { | |
doYield(); | |
} | |
#endif | |
- // Call the sleep handler to turn off peripherals optimally | |
- sleepHandler(true); | |
- | |
int8_t result = MY_SLEEP_NOT_POSSIBLE; // default | |
if (interrupt1 != INTERRUPT_NOT_DEFINED && interrupt2 != INTERRUPT_NOT_DEFINED) { | |
// both IRQs | |
@@ -730,10 +718,6 @@ | |
// no IRQ | |
result = hwSleep(sleepingTimeMS); | |
} | |
- | |
- // Call the sleep handler to turn on peripherals optimally | |
- sleepHandler(false); | |
- | |
setIndication(INDICATION_WAKEUP); | |
CORE_DEBUG(PSTR("MCO:SLP:WUP=%" PRIi8 "\n"), result); // sleep wake-up | |
#if defined(MY_SENSOR_NETWORK) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment