Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Micropython Helper Libraries - get_battery_voltage() results not usable #12

Open
Hamsanger opened this issue Feb 16, 2023 · 2 comments
Open

Comments

@Hamsanger
Copy link

Hamsanger commented Feb 16, 2023

Using Micropython V1.19.1+, the implementation of the battery monitor on GPIO2 and get_battery_voltage() produces invalid results. The default range of the ADC with attenuation of 0dB is only 850mV (refer to the ADC Characteristics in the ESP32-S3 datasheet), so the voltage presented to the ADC from the voltage divider on GPIO2 saturates the count for any usable LiPo voltages unless some input attenuation is used.

I have obtained good results using ATTN_2_5DB and the newer ADC.read_uv() function while scaling the voltage reading using the voltage divider resistor values. For a FeatherS3 board, the code looks similar to:

# Battery voltage divider.  Voltage seen by the ADC is VBAT * R1 / (R1 + R2)
R1 = 160 # voltage divider R1 in kOhms
R2 = 442 # voltage divider R2 in kOhms

vbat_scale_factor = (R1 + R2) / R1 / 1_000_000 # to convert the microvolt reading to volts

def get_battery_voltage():
    """
    Returns the current battery voltage. If no battery is connected, returns around 4.2V which is the charge voltage
    This is an approximation only, but useful to detect if the charge state of the battery is getting low.
    """
    adc = ADC(Pin(VBAT_SENSE), atten=ADC.ATTN_2_5DB) # Assign the ADC pin to read with nominal 0..1.1V range
    # We are going to read the ADC 10 times and discard the results as we can't guarantee the ADC is calibrated or stable yet after boot. Not sure why we have to do this :(
    for _ in range(10):
        adc.read()
    measuredvbat = adc.read_uv() * vbat_scale_factor
    return round(measuredvbat, 2)

As the voltage scaling factor is derived from first principles, the values of R1 and R2 shown can be adjusted to suit other designs.

@ShayBox
Copy link

ShayBox commented Jul 4, 2023

How does this compare to the current version, it seems to have changed to not use ADC()

@anglerfish27
Copy link

anglerfish27 commented Sep 28, 2023

FYI. I've used the built in examples with firmware 1.20 (current supported release not the nightly build). It works fine for me. The voltage of the battery when polled is exactly the voltage reading I get from a benchtop multi meter. So if the board says my Lipo battery is at 3.1V I disconnect and check it indeed its right on at 3.1xxxxxx Volts. I'm not doing anything special except running 1.20 official release of MP from their website. Good luck.

I found this to be a very handy feature so I can shutdown the MCU workload when the battery reaches what I decide is too low for that particular set of Lipo 18650's based on manufacturer specs. Best of luck. Seems to work fine for me. ::shrug::

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants