-
Notifications
You must be signed in to change notification settings - Fork 95
Description
I am attracted to the range of Enviro boards by there ability to operate for months unattended using AA cells. in addition to reliability (see issue #119) battery monitoring is essential for my application. I have been considering a HW workaround consisting of a pair of external resistor feeding VSYS /3 to ADC(2). A far better solution would be to get the PICO W voltage monitor working on ADC(3) as intended.
This is notoriously difficult and may require changes to the micropython firmware outside of the scope of the enviro software. The difficulties arise because the RP2040 pin used for the voltage monitor is shared with the WiFi chip.
The following code from 0.0.8 show the code that needed to be removed to improve stability.
# all the other imports, so many shiny modules
import machine, sys, os, json
from machine import RTC, ADC
import phew
from pcf85063a import PCF85063A
import enviro.helpers as helpers
# all the other imports, so many shiny modules
import machine, sys, os, json
from machine import RTC, ADC
import phew
from pcf85063a import PCF85063A
import enviro.helpers as helpers
# read battery voltage - we have to toggle the wifi chip select
# pin to take the reading - this is probably not ideal but doesn't
# seem to cause issues. there is no obvious way to shut down the
# wifi for a while properly to do this (wlan.disonnect() and
# wlan.active(False) both seem to mess things up big style..)
old_state = Pin(WIFI_CS_PIN).value()
Pin(WIFI_CS_PIN, Pin.OUT, value=True)
sample_count = 50
battery_voltage = 0
for i in range(0, sample_count):
battery_voltage += (ADC(29).read_u16() * 3.3 / 65535) * 3
battery_voltage /= sample_count
battery_voltage = round(battery_voltage, 3)
Pin(WIFI_CS_PIN).value(old_state)
# set up the button, external trigger, and rtc alarm pins
rtc_alarm_pin = Pin(RTC_ALARM_PIN, Pin.IN, Pin.PULL_DOWN)
external_trigger_pin = Pin(EXTERNAL_INTERRUPT_PIN, Pin.IN, Pin.PULL_DOWN)
There is nothing wrong with the code that reads the voltage except that 50 reads is a bit excessive. The problem is how it interacts with WiFi.
-
The code should not touch the WIFI_CS_PIN. If WIFI_CS_PIN is ever False during a ADC read it is a indication that WiFi is active. We must ensure that WiFI is inactive (easier said than done).
-
The digital drivers connected to GPIO29 need to be completely disabled. (see dection 2.19.4. Pads of the RP2040 datasheet).
-
Extreme measures needed to be implement to endure that WiFi is off. It appears to be active whilst using Thonny even before import network.
The following code is showing promise but given the nature of past issues needs further testing.
WIFI_CLK_ADC_PIN = 29 # add to constants
import network
wlan=network.WLAN()
wlan.disconnect()
wlan.active(False)
wlan.deinit()
def setPadCtr(gpio, value):
mem32[0x4001c000 | (4 + (4 * gpio))] = value
def getPadCtr(gpio):
return mem32[0x4001c000 | (4 + (4 * gpio))]
padCtrSave = getPadCtr(WIFI_CLK_ADC_PIN)
setPadCtr(WIFI_CLK_ADC_PIN, 0x80)
sample_count = 4
battery_voltage = 0
for i in range(0, sample_count):
battery_voltage += (ADC(WIFI_CLK_ADC_PIN).read_u16() * 3.3 / 65535) * 3
battery_voltage /= sample_count
battery_voltage = round(battery_voltage, 3)
setPadCtr(WIFI_CLK_ADC_PIN,padCtrSave)