Getting battery consumption from ADC



  • Re: Always reading same battery voltage

    Hi,
    I'm also trying to get this to work.
    For the moment I've got a LoPy connected to an expansion board v3.1. I created the function as stated in another example:

    def ADCloopMeanStdDev():
        numADCreadings = const(100)
        adc = machine.ADC(0)
        adcread = adc.channel(attn=3, pin='P16')
        samplesADC = [0.0]*numADCreadings; meanADC = 0.0
        i = 0
        while (i < numADCreadings):
            adcint = adcread()
            samplesADC[i] = adcint
            meanADC += adcint
            i += 1
        meanADC /= numADCreadings
        varianceADC = 0.0
        for adcint in samplesADC:
            varianceADC += (adcint - meanADC)**2
        varianceADC /= (numADCreadings - 1)
        print("%u ADC readings :\n%s" %(numADCreadings, str(samplesADC)))
        print("Mean of ADC readings (0-1023) = %15.13f" % meanADC)
        print("Mean of ADC readings (0-1400 mV) = %15.13f" % (meanADC*1400/1024))
        print("Variance of ADC readings = %15.13f" % varianceADC)
        print("10**6*Variance/(Mean**2) of ADC readings = %15.13f" % ((varianceADC*10**6)//(meanADC**2)))
    

    I call this function at the time wanted...

    As stated in some posts that the expansionboard had a builtin voltage divider and that the attenuation should be set to 3 I get this as output:

    100 ADC readings :
    [2832, 2823, 2825, 2825, 2829, 2826, 2823, 2826, 2826, 2831, 2823, 2827, 2827, 2853, 2825, 2826, 2823, 2830, 2830, 2829, 2823, 2822, 2831, 2831, 2827, 2829, 2824, 2823, 2827, 2832, 2822, 2821, 2826, 2827, 2829, 2827, 2827, 2828, 2822, 2825, 2829, 2823, 2827, 2823, 2817, 2826, 2831, 2823, 2828, 2827, 2822, 2831, 2826, 2828, 2831, 2821, 2828, 2827, 2825, 2821, 2827, 2829, 2826, 2823, 2828, 2829, 2819, 2826, 2823, 2823, 2829, 2832, 2822, 2824, 2833, 2831, 2830, 2827, 2830, 2827, 2821, 2823, 2832, 2830, 2831, 2831, 2826, 2829, 2832, 2823, 2823, 2823, 2826, 2826, 2819, 2819, 2827, 2831, 2832, 2827]
    Mean of ADC readings (0-1023) = 2826.6498565673828
    Mean of ADC readings (0-1400 mV) = 3864.5603179931641
    Variance of ADC readings = 19.8257484436035
    10**6*Variance/(Mean**2) of ADC readings = 2.0000000000000
    range: mm  718.55
    

    The range is another sensor that is connected.
    This is the reading I'm getting when the LoPy is connected trough USB with no battery...

    When connecting a battery (3,7V, 1200mAh) as well:

    100 ADC readings :
    [2752, 2756, 2753, 2754, 2756, 2765, 2759, 2766, 2754, 2765, 2759, 2754, 2758, 2752, 2756, 2764, 2748, 2763, 2754, 2759, 2754, 2765, 2754, 2757, 2753, 2754, 2757, 2759, 2756, 2763, 2754, 2764, 2763, 2757, 2757, 2756, 2753, 2753, 2755, 2759, 2757, 2759, 2746, 2761, 2753, 2752, 2752, 2763, 2753, 2765, 2762, 2758, 2759, 2755, 2767, 2754, 2763, 2751, 2763, 2766, 2766, 2757, 2754, 2757, 2763, 2758, 2759, 2756, 2751, 2755, 2750, 2759, 2763, 2754, 2762, 2757, 2752, 2765, 2753, 2755, 2759, 2749, 2763, 2778, 2763, 2762, 2726, 2767, 2767, 2754, 2764, 2759, 2758, 2762, 2757, 2775, 2755, 2754, 2762, 2755]
    Mean of ADC readings (0-1023) = 2757.8399181365967
    Mean of ADC readings (0-1400 mV) = 3770.4842090606689
    Variance of ADC readings = 40.2569675445557
    10**6*Variance/(Mean**2) of ADC readings = 5.0000000000000
    range: mm  1172.5
    

    I get the above...

    My questions:

    • what am I reading here? What is the difference between those 2 lines (0-1023 and 0-1400 mV)?
    • is the 3770 (in line 2, 0 - 1400mV) my battery and thus saying how much voltage it is providing?
    • how do i know what the overall consumption is and how to measure it with a multimeter? (what contacts, when LoPy is connected to Expansion board)

    Sorry for the N00bness, just trying to figure this out.
    Kindest regards and thank you for the help.



  • @robert-hh Thanks for clearing that up. I was confused with the dB scale for power.



  • I recommend :

    Code I've been using :

        import machine
        import statistics
        
        NUM_ADC_READINGS = const(50)
    
        adc = machine.ADC()
        adc.vref(1126)  # put here ESP32 VRef measured in mV with a voltmeter
        # adcP16 = adc.channel(pin='P16', attn=machine.ADC.ATTN_6DB) # For Expansion Board v2.x
        adcP16 = adc.channel(pin='P16', attn=machine.ADC.ATTN_11DB) # For Expansion Board v3.x
        samples_voltage = [0]*NUM_ADC_READINGS
        for i in range(NUM_ADC_READINGS):
        #    samples_voltage[i] = (171*adcP16.voltage())//56     # Expansion Board v2.x has voltage divider (115K + 56K) converting to integer voltage, [0, 6702] mV
            samples_voltage[i] = (2*adcP16.voltage())//1   # Expansion Board v3.x has voltage divider (1M + 1M) converting to integer voltage, [0, 6600] mV
        batt_mV = round(statistics.mean(samples_voltage))
        batt_mV_error = round(statistics.stdev(samples_voltage))
    


  • @Gijs There was some confusion about the voltage divider on the Expansion board 3.1. But I think the latest result was, that it consists of two 1 MOhm resistors, whatever the documentation tells, giving a division factor of 2.
    About the attenuation levels of the ADC, taken from the ESP32 specs:

    0db for a full-scale voltage of 1.1V (default)
    2.5db for a full-scale voltage of 1.5V
    6db for a full-scale voltage of 2.2V
    11db for a full-scale voltage of 3.9V
    

    That again divided (or better multiplied) by the hardware attenuation factor.



  • Based on the voltage you can know how much is left in the Lipo battery, but it's an indication more like 10%, 20% etc. not very accurate 3.54V is like 20% , 4.12V is like 100%

    import machine
    adc = machine.ADC()             # create an ADC object
    apin = adc.channel(pin='P16', attn=adc.ATTN_11DB)   # create an analog pin on P16, only with expansion board
    
    def getVoltage(): # Voltage on the Battery
        voltage = (apin.voltage() + apin.voltage() + apin.voltage() + apin.voltage()) / 4 # average 4
        return round(2*voltage/1000,2)
    


  • Hey,

    No worries, everybody was a beginner once ;)
    I tried to recreate your sample, but I do not have a battery so it just read the supply voltage.
    The maximum input voltage on the ADC is 1.1V. For a 12 bit resolution, this would give 4095 as a result (I think your example is for a 10 bit ADC with max value of 1023)
    Attenuation of 3dB would half the power, so we can read up to 2.2V.
    However there is already a voltage divider present on the board, already allowing us to read values up to 3.3V without attenuation (the resistor divide the voltage by 3.
    Of course, battery voltages are generally higher, up to 4.2V, which is why you would need the attenuation.
    In this case, the input voltage can be up to 6.6V with 3dB attenuation, that would return 4095. Your samples give around 2755, and doing the calculation, give 4.4V.

    You could check your reading against a multimeter reading to verify the result. I believe the built in charging circuit is supplying voltage to the rail when the battery is not connected?

    Let me know if it works for you

    Gijs


Log in to reply
 

Pycom on Twitter