From 4b3f8b79d571ad1b4f356f5be8817fb7d45a2300 Mon Sep 17 00:00:00 2001
From: user2684 <you@example.com>
Date: Tue, 4 Apr 2017 23:37:01 +0200
Subject: [PATCH] Waking up from an interrupt should not count as a sleeping
 cycle for battery level report #40

---
 NodeManager.cpp | 20 +++++++++++++-------
 NodeManager.h   |  3 +++
 README.md       |  2 ++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/NodeManager.cpp b/NodeManager.cpp
index bca2614..7ca319a 100644
--- a/NodeManager.cpp
+++ b/NodeManager.cpp
@@ -1277,6 +1277,9 @@ void NodeManager::setRetries(int value) {
   void NodeManager::setBatteryVoltsPerBit(float value) {
     _battery_volts_per_bit = value;
   }
+  void NodeManager::setBatteryReportWithInterrupt(bool value) {
+    _battery_report_with_interrupt = value;
+  }
 #endif
 #if SLEEP_MANAGER == 1
   void NodeManager::setSleepMode(int value) {
@@ -1850,6 +1853,7 @@ void NodeManager::_sleep() {
     Serial.println("");
   #endif
   // go to sleep
+  int interrupt = -1;
   if (_sleep_mode == WAIT) {
     // wait for the given interval
     wait(sleep_ms);
@@ -1859,15 +1863,17 @@ void NodeManager::_sleep() {
     int interrupt_1_pin = _interrupt_1_mode == MODE_NOT_DEFINED ? INTERRUPT_NOT_DEFINED  : digitalPinToInterrupt(INTERRUPT_PIN_1);
     int interrupt_2_pin = _interrupt_2_mode == MODE_NOT_DEFINED ? INTERRUPT_NOT_DEFINED  : digitalPinToInterrupt(INTERRUPT_PIN_2);
     // enter smart sleep for the requested sleep interval and with the configured interrupts
-    int ret = sleep(interrupt_1_pin,_interrupt_1_mode,interrupt_2_pin,_interrupt_2_mode,sleep_ms, true);
-    if (ret > -1) {
+    interrupt = sleep(interrupt_1_pin,_interrupt_1_mode,interrupt_2_pin,_interrupt_2_mode,sleep_ms, true);
+    if (interrupt > -1) {
+      // woke up by an interrupt
       int pin_number = -1;
-      int interrupt_mode = -1;      
-      if (digitalPinToInterrupt(INTERRUPT_PIN_1) == ret) {
+      int interrupt_mode = -1;
+      // map the interrupt to the pin
+      if (digitalPinToInterrupt(INTERRUPT_PIN_1) == interrupt) {
         pin_number = INTERRUPT_PIN_1;
         interrupt_mode = _interrupt_1_mode;
       }
-      if (digitalPinToInterrupt(INTERRUPT_PIN_2) == ret) {
+      if (digitalPinToInterrupt(INTERRUPT_PIN_2) == interrupt) {
         pin_number = INTERRUPT_PIN_2;
         interrupt_mode = _interrupt_2_mode;
       }
@@ -1892,8 +1898,8 @@ void NodeManager::_sleep() {
     _send(_msg.set("AWAKE"));
   #endif
   #if BATTERY_MANAGER == 1
-    // keep track of the number of sleeping cycles
-    _cycles++;
+    // keep track of the number of sleeping cycles (ignoring if woke up by an interrupt)
+    if (interrupt == -1 || _battery_report_with_interrupt) _cycles++;
     // battery has to be reported after the configured number of sleep cycles
     if (_battery_report_cycles == _cycles) {
       // time to report the battery level again
diff --git a/NodeManager.h b/NodeManager.h
index 299fd8f..917fb42 100644
--- a/NodeManager.h
+++ b/NodeManager.h
@@ -722,6 +722,8 @@ class NodeManager {
       void setBatteryPin(int value);
       // if setBatteryInternalVcc() is set to false, the volts per bit ratio used to calculate the battery voltage (default: 0.003363075)
       void setBatteryVoltsPerBit(float value);
+      // If true, wake up by an interrupt counts as a valid cycle for battery reports otherwise only uninterrupted sleep cycles would contribute (default: false)
+      void setBatteryReportWithInterrupt(bool value);
     #endif
     #if SLEEP_MANAGER == 1
       // define if the board has to sleep every time entering loop (default: IDLE). It can be IDLE (no sleep), SLEEP (sleep at every cycle), WAIT (wait at every cycle)
@@ -771,6 +773,7 @@ class NodeManager {
       float _battery_min = 2.6;
       float _battery_max = 3.3;
       int _battery_report_cycles = 10;
+      bool _battery_report_with_interrupt = false;
       bool _battery_internal_vcc = true;
       int _battery_pin = -1;
       float _battery_volts_per_bit = 0.003363075;
diff --git a/README.md b/README.md
index 0d952b0..da1f0fc 100644
--- a/README.md
+++ b/README.md
@@ -134,6 +134,8 @@ Node Manager comes with a reasonable default configuration. If you want/need to
       void setBatteryPin(int value);
       // if setBatteryInternalVcc() is set to false, the volts per bit ratio used to calculate the battery voltage (default: 0.003363075)
       void setBatteryVoltsPerBit(float value);
+      // If true, wake up by an interrupt counts as a valid cycle for battery reports otherwise only uninterrupted sleep cycles would contribute (default: false)
+      void setBatteryReportWithInterrupt(bool value);
     #endif
     #if SLEEP_MANAGER == 1
       // define if the board has to sleep every time entering loop (default: IDLE). It can be IDLE (no sleep), SLEEP (sleep at every cycle), WAIT (wait at every cycle
-- 
GitLab