From cec50cca6bc78fcfdeb2bd6fe1f632521a19d4d5 Mon Sep 17 00:00:00 2001 From: user2684 <you@example.com> Date: Tue, 23 May 2017 18:10:37 +0200 Subject: [PATCH] Use software reboot instead of reboot pin #101 --- NodeManager.cpp | 65 ++++++++++++++++++++++++------------------------- NodeManager.h | 12 ++++----- README.md | 18 ++++++-------- config.h | 5 ++-- 4 files changed, 46 insertions(+), 54 deletions(-) diff --git a/NodeManager.cpp b/NodeManager.cpp index ada6e32..333fe5b 100644 --- a/NodeManager.cpp +++ b/NodeManager.cpp @@ -616,27 +616,29 @@ void SensorRainGauge::onSetup() { // what to do when when receiving an interrupt void SensorRainGauge::_onTipped() { + long now = millis(); // on tipping, two consecutive interrupts are received, ignore the second one - if (millis() - _last_tip > 100){ + if ( (now - _last_tip > 100) || (now < _last_tip) ){ // increase the counter _count++; #if DEBUG == 1 Serial.println(F("RAIN+")); #endif } - _last_tip = millis(); + _last_tip = now; } // what to do during loop void SensorRainGauge::onLoop() { // avoid reporting the same value multiple times _value_float = -1; + long now = millis(); // time elapsed since the last report - long elapsed = millis() - _last_report; + long elapsed = now - _last_report; // minimum time interval between reports long min_interval = ((long)_report_interval*1000)*60; - // time to report - if (elapsed > min_interval) { + // time to report or millis() reset + if ( (elapsed > min_interval) || (now < _last_report)) { // report the total amount of rain for the last period _value_float = _count*_single_tip; #if DEBUG == 1 @@ -647,7 +649,7 @@ void SensorRainGauge::onLoop() { #endif // reset the counters _count = 0; - _last_report = millis(); + _last_report = now; } } @@ -876,6 +878,9 @@ void SensorDigitalOutput::setPulseWidth(int value) { void SensorDigitalOutput::setOnValue(int value) { _on_value = value; } +void SensorDigitalOutput::setLegacyMode(bool value) { + _legacy_mode = value; +} // main task void SensorDigitalOutput::onLoop() { @@ -884,7 +889,8 @@ void SensorDigitalOutput::onLoop() { // what to do as the main task when receiving a message void SensorDigitalOutput::onReceive(const MyMessage & message) { - if (message.getCommand() == C_SET) { + // by default handle a SET message but when legacy mode is set when a REQ message is expected instead + if ( (message.getCommand() == C_SET && ! _legacy_mode) || (message.getCommand() == C_REQ && _legacy_mode)) { // retrieve from the message the value to set int value = message.getInt(); if (value != 0 && value != 1) return; @@ -915,7 +921,7 @@ void SensorDigitalOutput::onReceive(const MyMessage & message) { _state = value; _value_int = value; } - if (message.getCommand() == C_REQ) { + if (message.getCommand() == C_REQ && ! _legacy_mode) { // return the current status _value_int = _state; } @@ -1826,9 +1832,6 @@ NodeManager::NodeManager() { } // setter/getter -void NodeManager::setRebootPin(int value) { - _reboot_pin = value; -} void NodeManager::setRetries(int value) { _retries = value; } @@ -2132,15 +2135,6 @@ void NodeManager::before() { Serial.print(F("NodeManager v")); Serial.println(VERSION); #endif - if (_reboot_pin > -1) { - #if DEBUG == 1 - Serial.print(F("REB P=")); - Serial.println(_reboot_pin); - #endif - // setup the reboot pin - pinMode(_reboot_pin, OUTPUT); - digitalWrite(_reboot_pin, HIGH); - } // setup the sleep interrupt pin if (_sleep_interrupt_pin > -1) { // set the interrupt when the pin is connected to ground @@ -2388,15 +2382,22 @@ void NodeManager::_process(const char * message) { sendBatteryLevel(percentage,_ack); } #endif - // REBOOT: reboot the board - else if (strcmp(message, "REBOOT") == 0 && _reboot_pin > -1) { - #if DEBUG == 1 - Serial.println(F("REBOOT")); - #endif - // set the reboot pin connected to RST to low so to reboot the board - _send(_msg.set(message)); - digitalWrite(_reboot_pin, LOW); - } + #ifndef MY_GATEWAY_ESP8266 + // REBOOT: reboot the board + else if (strcmp(message, "REBOOT") == 0) { + #if DEBUG == 1 + Serial.println(F("REBOOT")); + #endif + // set the reboot pin connected to RST to low so to reboot the board + _send(_msg.set(message)); + // Software reboot with watchdog timer. Enter Watchdog Configuration mode: + WDTCSR |= (1<<WDCE) | (1<<WDE); + // Reset enable + WDTCSR= (1<<WDE); + // Infinite loop until watchdog reset after 16 ms + while(true){} + } + #endif // CLEAR: clear the user's eeprom else if (strcmp(message, "CLEAR") == 0) { #if DEBUG == 1 @@ -2425,12 +2426,10 @@ void NodeManager::_process(const char * message) { #endif #ifndef MY_GATEWAY_ESP8266 // Save static ID to eeprom - hwWriteConfig(EEPROM_NODE_ID_ADDRESS, (uint8_t)node_id); + //hwWriteConfig(EEPROM_NODE_ID_ADDRESS, (uint8_t)node_id); #endif // reboot the board - #if REBOOT_PIN == 1 - _process(REBOOT); - #endif + _process("REBOOT"); } // MODEx: change the way the node behaves. 0: stay awake withtout executing each sensors' loop(), 1: go to sleep for the configured interval, 2: wait for the configured interval, 3: stay awake and execute each sensors' loop() (e.g. MODE1) else if (strlen(message) == 5 && strncmp("MODE", message, strlen("MODE")) == 0) { diff --git a/NodeManager.h b/NodeManager.h index e0bab90..e5170ed 100644 --- a/NodeManager.h +++ b/NodeManager.h @@ -7,7 +7,7 @@ #include <Arduino.h> // define NodeManager version -#define VERSION "1.5-dev5" +#define VERSION "1.5" /*********************************** Constants @@ -245,10 +245,6 @@ // include MySensors libraries #include <core/MySensorsCore.h> -#ifndef MY_GATEWAY_ESP8266 - #include <core/MyHwAVR.h> - //#include <core/MyHwATMega328.h> -#endif // include third party libraries #if MODULE_DHT == 1 @@ -589,7 +585,7 @@ class SensorRainGauge: public Sensor { static long _last_tip; static long _count; protected: - int _report_interval = 4; + int _report_interval = 60; float _single_tip = 0.11; long _last_report = 0; }; @@ -619,6 +615,8 @@ class SensorDigitalOutput: public Sensor { void setPulseWidth(int value); // define which value to set to the output when set to on (default: HIGH) void setOnValue(int value); + // when legacy mode is enabled expect a REQ message to trigger, otherwise the default SET (default: false) + void setLegacyMode(bool value); // define what to do at each stage of the sketch void onBefore(); void onSetup(); @@ -629,6 +627,7 @@ class SensorDigitalOutput: public Sensor { int _on_value = HIGH; int _state = 0; int _pulse_width = 0; + bool _legacy_mode = false; }; @@ -1058,7 +1057,6 @@ class NodeManager { int _interrupt_1_pull = -1; int _interrupt_2_pull = -1; int _last_interrupt_pin = -1; - int _reboot_pin = -1; long _timestamp = -1; Sensor* _sensors[255] = {0}; bool _ack = false; diff --git a/README.md b/README.md index d7c15d9..846f7e3 100644 --- a/README.md +++ b/README.md @@ -197,8 +197,6 @@ MODULE_MCP9808 | https://github.com/adafruit/Adafruit_MCP9808_Library Node Manager comes with a reasonable default configuration. If you want/need to change its settings, this can be done in your sketch, inside the `before()` function and just before registering your sensors. The following methods are exposed for your convenience: ~~~c - // the pin to connect to the RST pin to reboot the board (default: 4) - void setRebootPin(int value); // send the same service message multiple times (default: 1) void setRetries(int value); #if BATTERY_MANAGER == 1 @@ -449,6 +447,8 @@ Each sensor class can expose additional methods. void setPulseWidth(int value); // define which value to set to the output when set to on (default: HIGH) void setOnValue(int value); + // when legacy mode is enabled expect a REQ message to trigger, otherwise the default SET (default: false) + void setLegacyMode(bool value); ~~~ #### SensorSwitch / SensorDoor / SensorMotion @@ -587,7 +587,6 @@ If `PERSIST` is enabled, the settings provided with `INTVLnnnX` and `MODEx` are A NodeManager object must be created and called from within your sketch during `before()`, `presentation()`, `loop()` and `receive()` to work properly. NodeManager will do the following during each phase: ## NodeManager::before() -* Configure the reboot pin so to allow rebooting the board * Setup the interrupt pins to wake up the board based on the configured interrupts (e.g. stop sleeping when the pin is connected to ground or wake up and notify when a motion sensor has trigger) * If persistance is enabled, restore from the EEPROM the latest sleeping settings * Call `before()` of each registered sensor @@ -624,12 +623,6 @@ A NodeManager object must be created and called from within your sketch during ` # Examples All the examples below takes place within the before() function in the main sketch, just below the "Register below your sensors" comment. -Enable reboot pin, connect pin 4 to RST to enable rebooting the board with the REBOOT message: - -~~~c - nodeManager.setRebootPin(4); -~~~ - Set battery minimum and maxium voltage. This will be used to calculate the level percentage: ~~~c @@ -1076,11 +1069,14 @@ v1.5: * Added support for HC-SR04 distance sensor * Added support for BMP085/BMP180 temperature and pressure sensor * Added support for Sonoff smart switch -* Added forecast output to BME280 sensor -* Added capability to retrieve the time from the controller +* Added support for Rain Gauge sensor +* Added support for MCP9808 temperature sensor +* Added forecast output to all Bosch sensors +* Added I2C address auto-discovery for all Bosch sensors * Added support for running as a gateway * A heartbeat is sent when waking up from a wait cycle * Allowed combining sensors waking up from an interrupt and sensors reporting periodically +* Added capability to retrieve the time from the controller * Optimized battery life for DS18B20 sensors * SLEEP_MANAGER has been deprecated and setMode() replaces setSleepMode() * New mode ALWAYS_ON to let the node staying awake and executing each sensors' loop diff --git a/config.h b/config.h index 48e6aae..eded817 100644 --- a/config.h +++ b/config.h @@ -97,11 +97,10 @@ #define REMOTE_CONFIGURATION 1 // if enabled, persist the remote configuration settings on EEPROM #define PERSIST 0 - -// if enabled, send a SLEEPING and AWAKE service messages just before entering and just after leaving a sleep cycle and STARTED when starting/rebooting -#define SERVICE_MESSAGES 0 // if enabled, a battery sensor will be created at BATTERY_CHILD_ID and will report vcc voltage together with the battery level percentage #define BATTERY_SENSOR 1 +// if enabled, send a SLEEPING and AWAKE service messages just before entering and just after leaving a sleep cycle and STARTED when starting/rebooting +#define SERVICE_MESSAGES 0 // Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR, SENSOR_MQ, SENSOR_ML8511, SENSOR_ACS712, SENSOR_RAIN_GAUGE #define MODULE_ANALOG_INPUT 1 -- GitLab