You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
Finialize battery icon
This commit is contained in:
@@ -16,10 +16,47 @@ 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
|
||||
|
||||
MIN_VOLTAGE = 3.7
|
||||
MAX_VOLTAGE = 4.2
|
||||
|
||||
# USB connected, full battery: VBAT 4.179 5V: 5.1
|
||||
# read_battery_voltage raw_value: 1598.4
|
||||
# read_battery_voltage raw_value: 1598.1
|
||||
# read_battery_voltage raw_value: 1596.5
|
||||
# on display: 1596.8
|
||||
# => FULL is 1597 at 4.193V so * 2.6255 / 1000
|
||||
#
|
||||
# unplugged: VBAT: 4.157 5V: 0
|
||||
# 1591.3: 4.157 2.6123
|
||||
# 1588.5: 4.156
|
||||
# 1580.4: 4.14 2.619
|
||||
# 1577.8: 4.12
|
||||
# 1561.2: 4.08 2.61
|
||||
# 1555: 4.06
|
||||
# 1505: 3.95 2.624
|
||||
# 1489: 3.90
|
||||
# 1470: 3.85 2.61
|
||||
# 1454: 3.8
|
||||
# 1445: 3.81
|
||||
# 1412 should be empty 3.7
|
||||
#
|
||||
# USB connected, no battery:
|
||||
# 1566 * 0.00261 = 4.08V = 75%
|
||||
# 1566 * 0.00241 = 3.77V = 14%
|
||||
# 1564-1567
|
||||
#
|
||||
# quite empty and charging:
|
||||
# 1594: 4.18V
|
||||
# 16..
|
||||
#
|
||||
# logically, it should be * 0.00241758241758 but emperically, it seems to be * 0.00261 which is 8% higher
|
||||
# => Let's go with 0.00262
|
||||
def read_battery_voltage():
|
||||
if not have_adc:
|
||||
import random
|
||||
return random.randint(370,420) / 100
|
||||
random_voltage = random.randint(round(MIN_VOLTAGE*100),round(MAX_VOLTAGE*100)) / 100
|
||||
#print(f"returning random voltage: {random_voltage}")
|
||||
return random_voltage
|
||||
# Read raw ADC value
|
||||
total = 0
|
||||
# Read multiple times to try to reduce variability.
|
||||
@@ -27,12 +64,20 @@ def read_battery_voltage():
|
||||
for _ in range(10):
|
||||
total = total + adc.read()
|
||||
raw_value = total / 10
|
||||
#print(f"read_battery_voltage raw_value: {raw_value}")
|
||||
# Convert to voltage, accounting for divider and reference
|
||||
voltage = (raw_value / ADC_MAX) * VREF * VOLTAGE_DIVIDER
|
||||
#voltage = (raw_value / ADC_MAX) * VREF * VOLTAGE_DIVIDER
|
||||
voltage = raw_value * 262 / 100000
|
||||
# Clamp to 0–4.2V range for LiPo battery
|
||||
voltage = max(0, min(voltage, 4.2))
|
||||
voltage = max(0, min(voltage, MAX_VOLTAGE))
|
||||
#return raw_value
|
||||
return voltage
|
||||
|
||||
# Could be interesting to keep a "rolling average" of the percentage so that it doesn't fluctuate too quickly
|
||||
def get_battery_percentage():
|
||||
return (read_battery_voltage() - MIN_VOLTAGE) * 100 / (MAX_VOLTAGE - MIN_VOLTAGE)
|
||||
|
||||
|
||||
# Main loop to read and print battery voltage
|
||||
if False:
|
||||
#for _ in range(10):
|
||||
|
||||
@@ -16,7 +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
|
||||
BATTERY_ICON_UPDATE_INTERVAL = 5000
|
||||
TEMPERATURE_UPDATE_INTERVAL = 2000
|
||||
MEMFREE_UPDATE_INTERVAL = 5000 # not too frequent because there's a forced gc.collect() to give it a reliable value
|
||||
|
||||
@@ -136,15 +136,8 @@ def init_rootscreen():
|
||||
rootlabel.set_text("Welcome to MicroPythonOS")
|
||||
rootlabel.center()
|
||||
|
||||
|
||||
timer1 = None
|
||||
timer2 = None
|
||||
timer3 = None
|
||||
timer4 = None
|
||||
|
||||
def create_notification_bar():
|
||||
global notification_bar
|
||||
global timer1, timer2, timer3, timer4
|
||||
# Create notification bar
|
||||
notification_bar = lv.obj(lv.layer_top())
|
||||
notification_bar.set_size(lv.pct(100), NOTIFICATION_BAR_HEIGHT)
|
||||
@@ -172,15 +165,16 @@ def create_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_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_to(battery_label, lv.ALIGN.OUT_LEFT_MID, 0, 0)
|
||||
battery_icon.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
#battery_icon.align_to(battery_label, lv.ALIGN.OUT_LEFT_MID, 0, 0)
|
||||
battery_icon.align(lv.ALIGN.RIGHT_MID, 0, 0)
|
||||
battery_icon.add_flag(lv.obj.FLAG.HIDDEN) # keep it hidden until it has a correct value
|
||||
# WiFi icon
|
||||
wifi_icon = lv.label(notification_bar)
|
||||
wifi_icon.set_text(lv.SYMBOL.WIFI)
|
||||
@@ -202,22 +196,21 @@ def create_notification_bar():
|
||||
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:
|
||||
percent = mpos.battery_voltage.get_battery_percentage()
|
||||
if percent > 80: # 4.1V
|
||||
battery_icon.set_text(lv.SYMBOL.BATTERY_FULL)
|
||||
elif volt > 4:
|
||||
elif percent > 60: # 4.0V
|
||||
battery_icon.set_text(lv.SYMBOL.BATTERY_3)
|
||||
elif volt > 3.85:
|
||||
elif percent > 40: # 3.9V
|
||||
battery_icon.set_text(lv.SYMBOL.BATTERY_2)
|
||||
elif volt > 3.75:
|
||||
elif percent > 20: # 3.8V
|
||||
battery_icon.set_text(lv.SYMBOL.BATTERY_1)
|
||||
else:
|
||||
else: # > 3.7V
|
||||
battery_icon.set_text(lv.SYMBOL.BATTERY_EMPTY)
|
||||
battery_icon.remove_flag(lv.obj.FLAG.HIDDEN)
|
||||
# Percentage is not shown for now:
|
||||
#battery_label.set_text(f"{round(percent)}%")
|
||||
#battery_label.remove_flag(lv.obj.FLAG.HIDDEN)
|
||||
update_battery_icon() # run it immediately instead of waiting for the timer
|
||||
|
||||
def update_wifi_icon(timer):
|
||||
@@ -248,11 +241,11 @@ def create_notification_bar():
|
||||
percentage = round(free * 100 / (free + used))
|
||||
memfree_label.set_text(f"{percentage}%")
|
||||
|
||||
timer1 = lv.timer_create(update_time, CLOCK_UPDATE_INTERVAL, None)
|
||||
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)
|
||||
lv.timer_create(update_time, CLOCK_UPDATE_INTERVAL, None)
|
||||
lv.timer_create(update_temperature, TEMPERATURE_UPDATE_INTERVAL, None)
|
||||
lv.timer_create(update_memfree, MEMFREE_UPDATE_INTERVAL, None)
|
||||
lv.timer_create(update_wifi_icon, WIFI_ICON_UPDATE_INTERVAL, None)
|
||||
lv.timer_create(update_battery_icon, BATTERY_ICON_UPDATE_INTERVAL, None)
|
||||
|
||||
# hide bar animation
|
||||
global hide_bar_animation
|
||||
|
||||
Reference in New Issue
Block a user