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 :
- reading the Pycom MicroPython docs :
Firmware & API Reference > Pycom Modules > machine > ADC
Tutorials & Examples > All Pycom Device Examples > ADC - using the 'statistics' MicroPython module.
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))
- reading the Pycom MicroPython docs :
-
@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