update battery voltage icon

This commit is contained in:
Thomas Farstrike
2025-06-20 00:26:13 +02:00
parent 6b1709acf6
commit 51716d31a8
3 changed files with 68 additions and 11 deletions
@@ -34,7 +34,6 @@ def on_long_press(t): # Callback for when long press duration is reached.
else:
is_pressed = False
def button_handler(pin):
"""Interrupt handler for button press and release."""
global press_start_time, is_pressed, timer
@@ -49,7 +48,6 @@ def button_handler(pin):
timer.deinit() # Cancel timer if button is released early
is_pressed = False
# Set up interrupt for both falling (press) and rising (release) edges
button.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=button_handler)
@@ -0,0 +1,35 @@
have_adc=True
try:
from machine import ADC, Pin
# Configure ADC on pin 5 (IO5 / BAT_ADC)
adc = ADC(Pin(5))
# Set ADC to 11dB attenuation for 03.3V range (common for ESP32)
adc.atten(ADC.ATTN_11DB)
except Exception as e:
print("Info: this platform has no ADC for measuring battery voltage")
have_adc=False
import time
# ADC parameters
VREF = 3.3 # Reference voltage (3.3V for most boards, adjust if different)
ADC_MAX = 4095 # 12-bit ADC resolution
VOLTAGE_DIVIDER = 3 # (R1 + R2) / R2 = (200k + 100k) / 100k = 3
def read_battery_voltage():
if not have_adc:
import random
return random.randint(370,420) / 100
# Read raw ADC value
raw_value = adc.read()
# Convert to voltage, accounting for divider and reference
voltage = (raw_value / ADC_MAX) * VREF * VOLTAGE_DIVIDER
# Clamp to 04.2V range for LiPo battery
voltage = max(0, min(voltage, 4.2))
return voltage
# Main loop to read and print battery voltage
while False: # for testing
battery_voltage = read_battery_voltage()
print("Battery Voltage: {:.2f} V".format(battery_voltage))
time.sleep(1) # Wait 1 second
+33 -9
View File
@@ -2,6 +2,7 @@ import utime # for timing calls
import lvgl as lv
import mpos.apps
import mpos.battery_voltage
import mpos.wifi
from mpos.ui.anim import WidgetAnimator
@@ -15,6 +16,7 @@ NOTIFICATION_BAR_HEIGHT=24
CLOCK_UPDATE_INTERVAL = 1000 # 10 or even 1 ms doesn't seem to change the framerate but 100ms is enough
WIFI_ICON_UPDATE_INTERVAL = 1500
BATTERY_ICON_UPDATE_INTERVAL = 30000
TEMPERATURE_UPDATE_INTERVAL = 2000
MEMFREE_UPDATE_INTERVAL = 5000 # not too frequent because there's a forced gc.collect() to give it a reliable value
@@ -157,10 +159,10 @@ def create_notification_bar():
time_label.align(lv.ALIGN.LEFT_MID, 0, 0)
temp_label = lv.label(notification_bar)
temp_label.set_text("00°C")
temp_label.align_to(time_label, lv.ALIGN.OUT_RIGHT_MID, NOTIFICATION_BAR_HEIGHT , 0)
temp_label.align_to(time_label, lv.ALIGN.OUT_RIGHT_MID, mpos.ui.pct_of_display_width(7) , 0)
memfree_label = lv.label(notification_bar)
memfree_label.set_text("")
memfree_label.align_to(temp_label, lv.ALIGN.OUT_RIGHT_MID, NOTIFICATION_BAR_HEIGHT, 0)
memfree_label.align_to(temp_label, lv.ALIGN.OUT_RIGHT_MID, mpos.ui.pct_of_display_width(7), 0)
#style = lv.style_t()
#style.init()
#style.set_text_font(lv.font_montserrat_8) # tiny font
@@ -169,19 +171,21 @@ def create_notification_bar():
#notif_icon = lv.label(notification_bar)
#notif_icon.set_text(lv.SYMBOL.BELL)
#notif_icon.align_to(time_label, lv.ALIGN.OUT_RIGHT_MID, PADDING_TINY, 0)
# Battery percentage
battery_label = lv.label(notification_bar)
battery_label.set_text("100%")
battery_label.align(lv.ALIGN.RIGHT_MID, 0, 0)
battery_label.add_flag(lv.obj.FLAG.HIDDEN)
# Battery icon
battery_icon = lv.label(notification_bar)
battery_icon.set_text(lv.SYMBOL.BATTERY_FULL)
battery_icon.align(lv.ALIGN.RIGHT_MID, 0, 0)
battery_icon.align_to(battery_label, lv.ALIGN.OUT_LEFT_MID, 0, 0)
battery_icon.add_flag(lv.obj.FLAG.HIDDEN)
# WiFi icon
wifi_icon = lv.label(notification_bar)
wifi_icon.set_text(lv.SYMBOL.WIFI)
wifi_icon.align_to(battery_icon, lv.ALIGN.OUT_LEFT_MID, -NOTIFICATION_BAR_HEIGHT, 0)
wifi_icon.align_to(battery_icon, lv.ALIGN.OUT_LEFT_MID, -mpos.ui.pct_of_display_width(7), 0)
wifi_icon.add_flag(lv.obj.FLAG.HIDDEN)
# Battery percentage - not shown to conserve space
#battery_label = lv.label(notification_bar)
#battery_label.set_text("100%")
#battery_label.align(lv.ALIGN.RIGHT_MID, 0, 0)
# Update time
import time
def update_time(timer):
@@ -197,6 +201,25 @@ def create_notification_bar():
except Exception as e:
print("Warning: could not check WLAN status:", str(e))
def update_battery_icon(timer=None):
volt = mpos.battery_voltage.read_battery_voltage()
percent = (volt - 3.7) * 100 / (4.2 - 3.7)
battery_label.set_text(f"{round(percent)}%")
battery_label.remove_flag(lv.obj.FLAG.HIDDEN)
# 3.7 - 4.15 => 0.5V diff / 3 = 0.015
if volt > 4.15:
battery_icon.set_text(lv.SYMBOL.BATTERY_FULL)
elif volt > 4:
battery_icon.set_text(lv.SYMBOL.BATTERY_3)
elif volt > 3.85:
battery_icon.set_text(lv.SYMBOL.BATTERY_2)
elif volt > 3.75:
battery_icon.set_text(lv.SYMBOL.BATTERY_1)
else:
battery_icon.set_text(lv.SYMBOL.BATTERY_EMPTY)
battery_icon.remove_flag(lv.obj.FLAG.HIDDEN)
update_battery_icon() # run it immediately instead of waiting for the timer
def update_wifi_icon(timer):
if mpos.wifi.WifiService.is_connected():
wifi_icon.remove_flag(lv.obj.FLAG.HIDDEN)
@@ -229,6 +252,7 @@ def create_notification_bar():
timer2 = lv.timer_create(update_temperature, TEMPERATURE_UPDATE_INTERVAL, None)
timer3 = lv.timer_create(update_memfree, MEMFREE_UPDATE_INTERVAL, None)
timer4 = lv.timer_create(update_wifi_icon, WIFI_ICON_UPDATE_INTERVAL, None)
timer5 = lv.timer_create(update_battery_icon, BATTERY_ICON_UPDATE_INTERVAL, None)
# hide bar animation
global hide_bar_animation
@@ -371,7 +395,7 @@ def create_drawer(display=None):
import machine
# DON'T configure BOOT button (Pin 0) as wake-up source because it wakes up immediately.
# Luckily, the RESET button can be used to wake it up.
#wake_pin = Pin(0, machine.Pin.IN, machine.Pin.PULL_UP) # Pull-up enabled, active low
#wake_pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP) # Pull-up enabled, active low
#import esp32
#esp32.wake_on_ext0(pin=wake_pin, level=esp32.WAKEUP_ALL_LOW)
print("Entering deep sleep. Press BOOT button to wake up.")