diff --git a/internal_filesystem/lib/mpos/battery_voltage.py b/internal_filesystem/lib/mpos/battery_voltage.py index f6bc3571..9b943f63 100644 --- a/internal_filesystem/lib/mpos/battery_voltage.py +++ b/internal_filesystem/lib/mpos/battery_voltage.py @@ -87,16 +87,11 @@ def read_raw_adc(force_refresh=False): except ImportError: pass - # Check if WiFi operations are in progress - if WifiService and WifiService.wifi_busy: - raise RuntimeError("Cannot read battery voltage: WifiService is busy") - - # Disable WiFi for ADC2 reading - wifi_was_connected = False + # Temporarily disable WiFi for ADC2 reading + was_connected = False if needs_wifi_disable and WifiService: - wifi_was_connected = WifiService.is_connected() - WifiService.wifi_busy = True - WifiService.disconnect() + # This will raise RuntimeError if WiFi is already busy + was_connected = WifiService.temporarily_disable() time.sleep(0.05) # Brief delay for WiFi to fully disable try: @@ -113,14 +108,7 @@ def read_raw_adc(force_refresh=False): finally: # Re-enable WiFi (only if we disabled it) if needs_wifi_disable and WifiService: - WifiService.wifi_busy = False - if wifi_was_connected: - # Trigger reconnection in background thread - try: - import _thread - _thread.start_new_thread(WifiService.auto_connect, ()) - except Exception as e: - print(f"battery_voltage: Failed to start reconnect thread: {e}") + WifiService.temporarily_enable(was_connected) def read_battery_voltage(force_refresh=False): diff --git a/internal_filesystem/lib/mpos/board/fri3d_2024.py b/internal_filesystem/lib/mpos/board/fri3d_2024.py index db3c4ebf..c79c6522 100644 --- a/internal_filesystem/lib/mpos/board/fri3d_2024.py +++ b/internal_filesystem/lib/mpos/board/fri3d_2024.py @@ -260,9 +260,24 @@ indev.enable(True) # NOQA # Battery voltage ADC measuring # NOTE: GPIO13 is on ADC2, which requires WiFi to be disabled during reading on ESP32-S3. # battery_voltage.py handles this automatically: disables WiFi, reads ADC, reconnects WiFi. -# Readings are cached for 30 seconds to minimize WiFi interruptions. import mpos.battery_voltage -mpos.battery_voltage.init_adc(13, 3.3 * 2 / 4095) +""" +best fit on battery power: +2482 is 4.180 +2470 is 4.170 +2457 is 4.147 +2433 is 4.109 +2429 is 4.102 +2393 is 4.044 +2369 is 4.000 +2343 is 3.957 +2319 is 3.916 +2269 is 3.831 +""" +def adc_to_voltage(adc_value): + return (-0.0016237 * adc_value + 8.2035) +#mpos.battery_voltage.init_adc(13, adc_to_voltage) +mpos.battery_voltage.init_adc(13, 1/616) # simple scaling has an error of ~0.01V vs the adc_to_voltage() method import mpos.sdcard mpos.sdcard.init(spi_bus, cs_pin=14) diff --git a/internal_filesystem/lib/mpos/net/wifi_service.py b/internal_filesystem/lib/mpos/net/wifi_service.py index 927760e7..25d777a7 100644 --- a/internal_filesystem/lib/mpos/net/wifi_service.py +++ b/internal_filesystem/lib/mpos/net/wifi_service.py @@ -197,6 +197,63 @@ class WifiService: WifiService.wifi_busy = False print("WifiService: Auto-connect thread finished") + @staticmethod + def temporarily_disable(network_module=None): + """ + Temporarily disable WiFi for operations that require it (e.g., ESP32-S3 ADC2). + + This method sets wifi_busy flag and disconnects WiFi if connected. + Caller must call temporarily_enable() in a finally block. + + Args: + network_module: Network module for dependency injection (testing) + + Returns: + bool: True if WiFi was connected before disabling, False otherwise + + Raises: + RuntimeError: If WiFi operations are already in progress + """ + if WifiService.wifi_busy: + raise RuntimeError("Cannot disable WiFi: WifiService is already busy") + + # Check actual connection status BEFORE setting wifi_busy + was_connected = False + if HAS_NETWORK_MODULE or network_module: + try: + net = network_module if network_module else network + wlan = net.WLAN(net.STA_IF) + was_connected = wlan.isconnected() + except Exception as e: + print(f"WifiService: Error checking connection: {e}") + + # Now set busy flag and disconnect + WifiService.wifi_busy = True + WifiService.disconnect(network_module=network_module) + + return was_connected + + @staticmethod + def temporarily_enable(was_connected, network_module=None): + """ + Re-enable WiFi after temporary disable operation. + + Must be called in a finally block after temporarily_disable(). + + Args: + was_connected: Return value from temporarily_disable() + network_module: Network module for dependency injection (testing) + """ + WifiService.wifi_busy = False + + # Only reconnect if WiFi was connected before we disabled it + if was_connected: + try: + import _thread + _thread.start_new_thread(WifiService.auto_connect, ()) + except Exception as e: + print(f"WifiService: Failed to start reconnect thread: {e}") + @staticmethod def is_connected(network_module=None): """