From d2a785b1b5b62aef3522d1b1116001fd2b08aaba Mon Sep 17 00:00:00 2001
From: user2684 <you@example.com>
Date: Fri, 31 Mar 2017 12:58:19 +0200
Subject: [PATCH] Add option to measure battery level via a pin #23

---
 NodeManagerTemplate/NodeManager.cpp | 19 +++++++++++++++++--
 NodeManagerTemplate/NodeManager.h   |  9 +++++++++
 README.md                           |  6 ++++++
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/NodeManagerTemplate/NodeManager.cpp b/NodeManagerTemplate/NodeManager.cpp
index bc1765b..2c8e2f0 100644
--- a/NodeManagerTemplate/NodeManager.cpp
+++ b/NodeManagerTemplate/NodeManager.cpp
@@ -915,6 +915,15 @@ void NodeManager::setRetries(int value) {
   void NodeManager::setBatteryReportCycles(int value) {
     _battery_report_cycles = value;
   }
+  void NodeManager::setBatteryInternalVcc(bool value) {
+    _battery_internal_vcc = value;
+  }
+  void NodeManager::setBatteryPin(int value) {
+    _battery_pin = value;
+  }
+  void NodeManager::setBatteryVoltsPerBit(float value) {
+    _battery_volts_per_bit = value;
+  }
 #endif
 #if SLEEP_MANAGER == 1
   void NodeManager::setSleepMode(int value) {
@@ -1145,6 +1154,10 @@ void NodeManager::before() {
       #endif
     }
   #endif
+  #if POWER_MANAGER == 1
+    // set analogReference to internal if measuring the battery through a pin
+    if (! _battery_internal_vcc && _battery_pin > -1) analogReference(INTERNAL);
+  #endif
   // setup individual sensors
   for (int i = 0; i < 255; i++) {
     if (_sensors[i] == 0) continue;
@@ -1300,7 +1313,9 @@ void NodeManager::_process(const char * message) {
     // BATTERY: return the battery level
     else if (strcmp(message, BATTERY) == 0) {
       // measure the board vcc
-      float volt = _getVcc();
+      float volt = 0;
+      if (_battery_internal_vcc || _battery_pin == -1) volt = _getVcc();
+      else volt = analogRead(_battery_pin) * _battery_volts_per_bit;
       // calculate the percentage
       int percentage = ((volt - _battery_min) / (_battery_max - _battery_min)) * 100;
       if (percentage > 100) percentage = 100;
@@ -1311,7 +1326,7 @@ void NodeManager::_process(const char * message) {
         Serial.print(" P=");
         Serial.println(percentage);
       #endif
-      #if BATTERY_MANAGER == 1 && BATTERY_SENSOR == 1
+      #if BATTERY_SENSOR == 1
         // report battery voltage
         MyMessage battery_msg(BATTERY_CHILD_ID, V_VOLTAGE);
         _send(battery_msg.set(volt, 2));
diff --git a/NodeManagerTemplate/NodeManager.h b/NodeManagerTemplate/NodeManager.h
index 86871b2..b3dcb60 100644
--- a/NodeManagerTemplate/NodeManager.h
+++ b/NodeManagerTemplate/NodeManager.h
@@ -595,6 +595,12 @@ class NodeManager {
       void setBatteryMax(float value);
       // after how many sleeping cycles report the battery level to the controller. When reset the battery is always reported (default: 10)
       void setBatteryReportCycles(int value);
+      // if true, the battery level will be evaluated by measuring the internal vcc without the need to connect any pin, if false the voltage divider methon will be used (default: true)
+      void setBatteryInternalVcc(bool value);
+      // if setBatteryInternalVcc() is set to false, the analog pin to which the battery's vcc is attached (https://www.mysensors.org/build/battery) (default: -1)
+      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);
     #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
@@ -644,6 +650,9 @@ class NodeManager {
       float _battery_min = 2.6;
       float _battery_max = 3.3;
       int _battery_report_cycles = 10;
+      bool _battery_internal_vcc = true;
+      int _battery_pin = -1;
+      float _battery_volts_per_bit = 0.003363075;
       int _cycles = 0;
       float _getVcc();
     #endif
diff --git a/README.md b/README.md
index ca30163..143ceac 100644
--- a/README.md
+++ b/README.md
@@ -126,6 +126,12 @@ Node Manager comes with a reasonable default configuration. If you want/need to
       void setBatteryMax(float value);
       // after how many sleeping cycles report the battery level to the controller. When reset the battery is always reported (default: 10)
       void setBatteryReportCycles(int value);
+      // if true, the battery level will be evaluated by measuring the internal vcc without the need to connect any pin, if false the voltage divider methon will be used (default: true)
+      void setBatteryInternalVcc(bool value);
+      // if setBatteryInternalVcc() is set to false, the analog pin to which the battery's vcc is attached (https://www.mysensors.org/build/battery) (default: -1)
+      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);
     #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