Skip to content

Reinstatement of voltage monitor Β #145

@Julia7676

Description

@Julia7676

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.

  1. 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).

  2. The digital drivers connected to GPIO29 need to be completely disabled. (see dection 2.19.4. Pads of the RP2040 datasheet).

  3. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions