Skip to content

Commit b750f82

Browse files
authored
Merge pull request wled#2168 from itCarl/usermod_battery_status
Updated Usermod Battery Status Basic
2 parents 5d14716 + f368bbe commit b750f82

File tree

5 files changed

+86
-20
lines changed

5 files changed

+86
-20
lines changed
48 KB
Loading
45.6 KB
Loading
67.6 KB
Loading

usermods/battery_status_basic/readme.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,25 @@
22

33
This Usermod allows you to monitor the battery level of your battery powered project.
44

5-
You can see the battery level in the `info modal` right under the `estimated current`.
5+
You can see the battery level and voltage in the `info modal`.
66

77
For this to work the positive side of the (18650) battery must be connected to pin `A0` of the d1mini/esp8266 with a 100k ohm resistor (see [Useful Links](#useful-links)).
88

99
If you have a esp32 board it is best to connect the positive side of the battery to ADC1 (GPIO32 - GPIO39)
1010

11+
<p align="center">
12+
<img width="300" src="assets/battery_info_screen.png">
13+
</p>
14+
1115
## Installation
1216

1317
define `USERMOD_BATTERY_STATUS_BASIC` in `my_config.h`
1418

19+
### Basic wiring diagram
20+
<p align="center">
21+
<img width="300" src="assets/battery_connection_schematic_01.png">
22+
</p>
23+
1524
### Define Your Options
1625

1726
* `USERMOD_BATTERY_STATUS_BASIC` - define this (in `my_config.h`) to have this user mod included wled00\usermods_list.cpp
@@ -45,6 +54,11 @@ Specification from: [Molicel INR18650-M35A, 3500mAh 10A Lithium-ion battery, 3.
4554
* https://arduinodiy.wordpress.com/2016/12/25/monitoring-lipo-battery-voltage-with-wemos-d1-minibattery-shield-and-thingspeak/
4655

4756
## Change Log
57+
2021-09-02
58+
* added "Battery voltage" to info
59+
* added circuit diagram to readme
60+
* added MQTT support, sending battery voltage
61+
* minor fixes
4862

4963
2021-08-15
5064
* changed `USERMOD_BATTERY_MIN_VOLTAGE` to 2.6 volt as default for 18650 batteries

usermods/battery_status_basic/usermod_v2_battery_status_basic.h

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#endif
3030

3131

32-
// the frequency to check the battery, 1 minute
32+
// the frequency to check the battery, 30 sec
3333
#ifndef USERMOD_BATTERY_MEASUREMENT_INTERVAL
3434
#define USERMOD_BATTERY_MEASUREMENT_INTERVAL 30000
3535
#endif
@@ -53,7 +53,8 @@ class UsermodBatteryBasic : public Usermod
5353
int8_t batteryPin = USERMOD_BATTERY_MEASUREMENT_PIN;
5454
// how often to read the battery voltage
5555
unsigned long readingInterval = USERMOD_BATTERY_MEASUREMENT_INTERVAL;
56-
unsigned long lastTime = 0;
56+
unsigned long nextReadTime = 0;
57+
unsigned long lastReadTime = 0;
5758
// battery min. voltage
5859
float minBatteryVoltage = USERMOD_BATTERY_MIN_VOLTAGE;
5960
// battery max. voltage
@@ -68,6 +69,7 @@ class UsermodBatteryBasic : public Usermod
6869
// mapped battery level based on voltage
6970
long batteryLevel = 0;
7071
bool initDone = false;
72+
bool initializing = true;
7173

7274

7375
// strings to reduce flash memory usage (used more than twice)
@@ -82,6 +84,19 @@ class UsermodBatteryBasic : public Usermod
8284
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
8385
}
8486

87+
float truncate(float val, byte dec)
88+
{
89+
float x = val * pow(10, dec);
90+
float y = round(x);
91+
float z = x - y;
92+
if ((int)z == 5)
93+
{
94+
y++;
95+
}
96+
x = y / pow(10, dec);
97+
return x;
98+
}
99+
85100

86101

87102
public:
@@ -107,6 +122,9 @@ class UsermodBatteryBasic : public Usermod
107122
pinMode(batteryPin, INPUT);
108123
#endif
109124

125+
nextReadTime = millis() + readingInterval;
126+
lastReadTime = millis();
127+
110128
initDone = true;
111129
}
112130

@@ -129,26 +147,38 @@ class UsermodBatteryBasic : public Usermod
129147
{
130148
if(strip.isUpdating()) return;
131149

132-
unsigned long now = millis();
133-
134150
// check the battery level every USERMOD_BATTERY_MEASUREMENT_INTERVAL (ms)
135-
if (now - lastTime >= readingInterval) {
151+
if (millis() < nextReadTime) return;
152+
136153

137-
// read battery raw input
138-
rawValue = analogRead(batteryPin);
154+
nextReadTime = millis() + readingInterval;
155+
lastReadTime = millis();
156+
initializing = false;
139157

140-
// calculate the voltage
141-
voltage = (rawValue / adcPrecision) * maxBatteryVoltage ;
158+
// read battery raw input
159+
rawValue = analogRead(batteryPin);
142160

143-
// translate battery voltage into percentage
144-
/*
145-
the standard "map" function doesn't work
146-
https://www.arduino.cc/reference/en/language/functions/math/map/ notes and warnings at the bottom
147-
*/
148-
batteryLevel = mapf(voltage, minBatteryVoltage, maxBatteryVoltage, 0, 100);
161+
// calculate the voltage
162+
voltage = (rawValue / adcPrecision) * maxBatteryVoltage ;
163+
// check if voltage is within specified voltage range
164+
voltage = voltage<minBatteryVoltage||voltage>maxBatteryVoltage?-1.0f:voltage;
149165

150-
lastTime = now;
166+
// translate battery voltage into percentage
167+
/*
168+
the standard "map" function doesn't work
169+
https://www.arduino.cc/reference/en/language/functions/math/map/ notes and warnings at the bottom
170+
*/
171+
batteryLevel = mapf(voltage, minBatteryVoltage, maxBatteryVoltage, 0, 100);
172+
173+
174+
// SmartHome stuff
175+
if (WLED_MQTT_CONNECTED) {
176+
char subuf[64];
177+
strcpy(subuf, mqttDeviceTopic);
178+
strcat_P(subuf, PSTR("/voltage"));
179+
mqtt->publish(subuf, 0, false, String(voltage).c_str());
151180
}
181+
152182
}
153183

154184

@@ -163,9 +193,31 @@ class UsermodBatteryBasic : public Usermod
163193
JsonObject user = root["u"];
164194
if (user.isNull()) user = root.createNestedObject("u");
165195

166-
JsonArray battery = user.createNestedArray("Battery level");
167-
battery.add(batteryLevel);
168-
battery.add(F(" %"));
196+
// info modal display names
197+
JsonArray batteryPercentage = user.createNestedArray("Battery level");
198+
JsonArray batteryVoltage = user.createNestedArray("Battery voltage");
199+
200+
if (initializing) {
201+
batteryPercentage.add((nextReadTime - millis()) / 1000);
202+
batteryPercentage.add(" sec");
203+
batteryVoltage.add((nextReadTime - millis()) / 1000);
204+
batteryVoltage.add(" sec");
205+
return;
206+
}
207+
208+
if(batteryLevel < 0) {
209+
batteryPercentage.add(F("invalid"));
210+
} else {
211+
batteryPercentage.add(batteryLevel);
212+
}
213+
batteryPercentage.add(F(" %"));
214+
215+
if(voltage < 0) {
216+
batteryVoltage.add(F("invalid"));
217+
} else {
218+
batteryVoltage.add(truncate(voltage, 2));
219+
}
220+
batteryVoltage.add(F(" V"));
169221
}
170222

171223

0 commit comments

Comments
 (0)