Initial commit: ESP32-S3-RLCD-4.2 hardware utility classes and demo
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
from machine import ADC, Pin
|
||||
|
||||
class BatteryMonitor:
|
||||
"""Utility class for monitoring battery voltage and capacity on ESP32-S3-RLCD-4.2."""
|
||||
|
||||
def __init__(self, pin_num=4):
|
||||
# Initialize ADC on GPIO 4 with 11dB attenuation
|
||||
self.adc = ADC(Pin(pin_num))
|
||||
self.adc.atten(ADC.ATTN_11DB)
|
||||
|
||||
def read_voltage(self):
|
||||
"""Reads the battery voltage in Volts using internal calibration.
|
||||
|
||||
Returns:
|
||||
float: Battery voltage in Volts (e.g. 4.15) or None on error.
|
||||
"""
|
||||
try:
|
||||
# Try calibrated reading in microvolts first
|
||||
uv = self.adc.read_uv()
|
||||
# 3x voltage divider onboard scales 3.0V-4.2V battery to 1.0V-1.4V
|
||||
voltage = (uv / 1_000_000.0) * 3.0
|
||||
return round(voltage, 3)
|
||||
except AttributeError:
|
||||
# Fallback if read_uv() is not supported on older MicroPython builds
|
||||
try:
|
||||
# Read 12-bit value (0-4095)
|
||||
raw = self.adc.read()
|
||||
# 3.3V reference at 11dB attenuation, 3x divider
|
||||
voltage = (raw / 4095.0) * 3.3 * 3.0
|
||||
return round(voltage, 3)
|
||||
except Exception as e:
|
||||
print(f"Error reading battery raw ADC: {e}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Error reading battery calibrated ADC: {e}")
|
||||
return None
|
||||
|
||||
def read_percentage(self):
|
||||
"""Computes approximate battery percentage based on discharge curve.
|
||||
|
||||
Assumes linear approximation between 3.0V (0%) and 4.2V (100%).
|
||||
|
||||
Returns:
|
||||
int: Percentage between 0 and 100.
|
||||
"""
|
||||
voltage = self.read_voltage()
|
||||
if voltage is None:
|
||||
return 0
|
||||
|
||||
# Bound typical lithium-ion limits
|
||||
# 3.0V is typically empty for ESP32 systems where the LDO drops out around 3.3V
|
||||
v_min = 3.0
|
||||
v_max = 4.2
|
||||
|
||||
if voltage <= v_min:
|
||||
return 0
|
||||
if voltage >= v_max:
|
||||
return 100
|
||||
|
||||
# Linear scaling
|
||||
pct = (voltage - v_min) / (v_max - v_min) * 100.0
|
||||
return int(pct)
|
||||
|
||||
def get_status_summary(self):
|
||||
"""Returns a string description of battery status."""
|
||||
v = self.read_voltage()
|
||||
p = self.read_percentage()
|
||||
if v is None:
|
||||
return "Battery: Error"
|
||||
return f"Battery: {v:.2f}V ({p}%)"
|
||||
Reference in New Issue
Block a user