Correct formula for BATT monitoring on expansion board

  • Hi

    What's the correct formula for Battery monitoring with a LoPy on the pycom expanysion board.
    According to the datasheet it's a 1:2 voltage divider on the expansion board. And the ADC is 12bit (0-4095) and somewhere i was reading the the reference voltage is 1.4 volt

    so the formula i came up is:
    adcVoltage = adcReading * referenceVoltage / adcResolution
    battVoltage = adcVoltage * voltageDividerFactor

    my code is:

    from machine import ADC
    class LoPy(object):
        def __init__(self):
            self.adc = ADC()
            self.batt =, pin='P16')
        def get_batt(self):
            adcVoltage = self.batt.value()
            voltage = adcVoltage*3*1400/4095/1000
            # print("Battery V = %.3f" % voltage )
            return voltage

    but the result is too high, while i measure 3.31 Volt with a fluke, the reading is 3.91 from the formula above
    what could be wrong, my formula, the adc settings?

  • @roadfox The upper range value from dB is:


    so 6 dB results in 1.995, which is about 2

  • Ho do i calculate the range from dB attenuation?
    So far i have the following Table:
    attn = 0 = ADC.ATTN_0DB = 0 db gain = range 0-1V
    attn = 1 = ADC.ATTN_2_5DB = 2.5 dB = range 0-1.334V
    attn = 2 = ADC.ATTN_6DB = 6 dB = range 0-1.995V
    attn = 3 = ADC.ATTN_11DB = 11 dB = range 0 - 3.548V

    The Voltage divider consist of a 56k and 116k resistor witch gives a factor very close to 3

    so i changed my formula to: voltage = adcValue * 3 * 1.334 / 4095
    and it's pretty accurate now

    many thanks

  • @roadfox The basic ADC range is 1V. You can set an attenuation factor of 2.5 dB, 6 dB or 11 dB ( 11 dB results in a 3.548V range. The voltage divider on the expansion board consist of a 56k/100k resistor pair, resulting in an attenuation factor of the resistors of 2.79, resulting in a range of 0..2.79V. So you have to use an attenuation factor of the ADC.
    Update: I see that you use ATTN=1, which is 2.5 dB, resulting in a ADC range of 0..1.334 V. But the ADC on ESP32 is anyhow not very precise, and the impedances are not known. So you have to determine your own calibration factor.
    Update 2: Some discussion about that is here:
    A while ago I made similar measurements with a Lopy. The table below shows results for the 1 V range (attn=0).

    Input	ADC
    70	0
    100	127
    200	550
    300	974
    500	1820
    700	2650
    900	3510
    1000	3933
    1044	4095

    You see that it does not match the 0-1 rails. The same for attn=1. For attn=3 it is also non-linear above ADC readings of about 2500.

Looks like your connection to Pycom Forum was lost, please wait while we try to reconnect.