1+ import time
2+
3+ MIN_VOLTAGE = 3.15
4+ MAX_VOLTAGE = 4.15
5+
16adc = None
2- have_adc = True
7+ scale_factor = 0
38
49# This gets called by (the device-specific) boot*.py
5- def init_adc (pinnr ):
10+ def init_adc (pinnr , scale_factor ):
611global adc
712try :
813from machine import ADC ,Pin
9- print ("setting adc " )
14+ print ("Initializing ADC pin {pinnr} with scale_factor {scale_factor} " )
1015adc = ADC (Pin (pinnr ))
11- print ("adc set" )
1216# Set ADC to 11dB attenuation for 0–3.3V range (common for ESP32)
1317adc .atten (ADC .ATTN_11DB )
1418except Exception as e :
1519print ("Info: this platform has no ADC for measuring battery voltage" )
16- have_adc = False
17-
18- import time
1920
20- # ADC parameters
21- VREF = 3.3 # Reference voltage (3.3V for most boards, adjust if different)
22- ADC_MAX = 4095 # 12-bit ADC resolution
23- VOLTAGE_DIVIDER = 3 # (R1 + R2) / R2 = (200k + 100k) / 100k = 3
24-
25- MIN_VOLTAGE = 3.7
26- MAX_VOLTAGE = 4.2
27-
28- # On fri3d-2024, it's 2367 for full
29- # Battery voltage ranges from 3.15V (0%) to 4.15 (100%) as datasheet specifies
30- # 3.0 +/- 0.1V (discharge cut-off) to 4.2V (no margin of error provided, assuming 0.05V)
31- # Charger stops charging at 4.07V (92%) to reduce battery wear.
32- #define RG_BATTERY_CALC_PERCENT(raw) (((raw) * 2.f - 3150.f) / (4150.f - 3150.f) * 100.f)
33- #define RG_BATTERY_CALC_VOLTAGE(raw) ((raw) * 2.f * 0.001f)
34-
35-
36- # USB connected, full battery: VBAT 4.179 5V: 5.1
37- # read_battery_voltage raw_value: 1598.4
38- # read_battery_voltage raw_value: 1598.1
39- # read_battery_voltage raw_value: 1596.5
40- # on display: 1596.8
41- # => FULL is 1597 at 4.193V so * 2.6255 / 1000
42- #
43- # unplugged: VBAT: 4.157 5V: 0
44- # 1591.3: 4.1572.6123
45- # 1588.5: 4.156
46- # 1580.4: 4.142.619
47- # 1577.8: 4.12
48- # 1561.2: 4.082.61
49- # 1555: 4.06
50- # 1505: 3.952.624
51- # 1489: 3.90
52- # 1470: 3.852.61
53- # 1454: 3.8
54- # 1445: 3.81
55- # 1412 should be empty 3.7
56- #
57- # USB connected, no battery:
58- # 1566 * 0.00261 = 4.08V = 75%
59- # 1566 * 0.00241 = 3.77V = 14%
60- # 1564-1567
61- #
62- # quite empty and charging:
63- # 1594: 4.18V
64- # 16..
65- #
66- # logically, it should be * 0.00241758241758 but emperically, it seems to be * 0.00261 which is 8% higher
67- # => Let's go with 0.00262
6821def read_battery_voltage ():
69- if not have_adc :
22+ if not adc :
7023import random
7124random_voltage = random .randint (round (MIN_VOLTAGE * 100 ),round (MAX_VOLTAGE * 100 ))/ 100
7225#print(f"returning random voltage: {random_voltage}")
@@ -79,23 +32,12 @@ def read_battery_voltage():
7932total = total + adc .read ()
8033raw_value = total / 10
8134#print(f"read_battery_voltage raw_value: {raw_value}")
82- # Convert to voltage, accounting for divider and reference
83- #voltage = (raw_value / ADC_MAX) * VREF * VOLTAGE_DIVIDER
84- #voltage = raw_value * 262 / 100000 # 2inch
85- voltage = raw_value * 2 / 1000 # fri3d-2024
35+ voltage = raw_value * scale_factor
8636# Clamp to 0–4.2V range for LiPo battery
8737voltage = max (0 ,min (voltage ,MAX_VOLTAGE ))
88- #return raw_value
8938return voltage
9039
9140# Could be interesting to keep a "rolling average" of the percentage so that it doesn't fluctuate too quickly
9241def get_battery_percentage ():
9342return (read_battery_voltage ()- MIN_VOLTAGE )* 100 / (MAX_VOLTAGE - MIN_VOLTAGE )
9443
95-
96- # Main loop to read and print battery voltage
97- if False :
98- #for _ in range(10):
99- battery_voltage = read_battery_voltage ()
100- print ("Battery Voltage: {:.2f} V" .format (battery_voltage ))
101- time .sleep (1 )# Wait 1 second