Measure battery state, Plus 2W + Amigo Pro

Strange, this is standard MicroPython. I will check the Pimoroni-flavor on what is going on here.

Ok, this makes sense, but remove the pullup you set in software, you only need this for floating pins.

Just to reiterate, my original code (from the other thread) worked just fine with a Pico W and Pico 2W. The problem(s) started when I swapped in the Pico Plus 2W.

Yes, this is because the Plus2W uses GPIO43. Have you tried removing the Pin(43,Pin.IN) line?

Pin.ANALOG is only in the documentation :-( Nothing Pimoroni-specific, seems to be a problem of upstream MicroPython.

If vsys = ADC(3) does not work, then some MP expert has to have a look - maybe channel 3 is not correctly tied to GPIO43 for the RP2350B.

If I do that I get.

MPY: soft reboot
1.31V
-106%
1.30V
-107%
1.30V
-106%

Thats with no power supply plugged in. If i plug it in the voltage goes up a little and then back down when i unplug it again. No charging indication either.

1.30V
-106%
1.56V
-88%
1.56V
-88%
1.55V
-88%
1.30V
-106%
1.31V
-106%

calling @gadgetoid for help: is the RP2350B configured correctly to link ADC channel 3 to GPIO43?

I have cleaned up my code as best I can. Here is the current irritation.

import time

from pimoroni import Analog
from machine import ADC, Pin

Pin(43, Pin.IN)
vsys = ADC(3)
power = Pin('WL_GPIO2', Pin.IN)
charging = Pin(22, Pin.IN)
conversion_factor = 3 * 3.3 / 65535
full_battery = 4.2                  
empty_battery = 2.8  

while True:
    voltage = vsys.read_u16() * conversion_factor
    percentage = 100 * ((voltage - empty_battery) / (full_battery - empty_battery))
    
    if percentage > 100:
        percentage = 100.00
        
    print('{:.2f}V'.format(voltage))
    print('{:.0f}%'.format(percentage))
    
    if power.value() == True:
        
        if charging.value() == 0:
            print ("Charging!")
 
        else:
            print ("USB Powered")
                        
    else:# if not, display the battery stats
        print ("Battery Powered")
               
    time.sleep(5.0)

You should remove this line, since it configures the GPIO43 as a digital input. You want to use it as an analog input. vsys = ADC(3) should take care of this. Note that you should power-cycle after fixing this code.

Ok, did that, and it gets rid of the high voltage issue. It also messes up the conversion factor and percent left? I think we may be getting closer to a fix though?

MPY: soft reboot
1.56V
-88%
Charging!
1.56V
-88%
Charging!
1.30V
-107%
Battery Powered
1.56V
-88%
Charging!

Fixed it :) class ADC – analog to digital conversion — MicroPython latest documentation

import time

from pimoroni import Analog
from machine import ADC, Pin

adc = ADC(43)

power = Pin('WL_GPIO2', Pin.IN)
charging = Pin(22, Pin.IN)
conversion_factor = 3 * 3.3 / 65535
full_battery = 4.2                  
empty_battery = 2.8  

while True:
    voltage = adc.read_u16() * conversion_factor
    percentage = 100 * ((voltage - empty_battery) / (full_battery - empty_battery))
    
    if percentage > 100:
        percentage = 100.00
        
    print('{:.2f}V'.format(voltage))
    print('{:.0f}%'.format(percentage))
    
    if power.value() == True:
        
        if charging.value() == 0:
            print ("Charging!")
 
        else:
            print ("USB Powered")
                        
    else:
        print ("Battery Powered")
               
    time.sleep(5.0)
>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
4.12V
94%
Battery Powered
4.90V
100%
Charging!
4.91V
100%
Charging!
4.13V
95%
Battery Powered

2 Likes

Glad to hear that you got it working :) Squirrelling this information away for future use!

1 Like

Nevertheless, something is not working as it should: ADC(3) and ADC(43) should return the same adc-object - the first passing the channel number, the second passing the GPIO-number. It seems that for the Pico Plus 2W the mapping from channel to gpio does not work.

Internally, the SDK defines an ADC_BASE_PIN, which is 26 for the RP2040 and RP2350A, and 40 for the RP2350B and calculates the pin-number of the channel by simple math. It might be that the MicroPython build process does not provide the correct chip-variant (B) for the Pico Plus 2W. At least the board-header for the Pico Plus 2W in the Pico SDK is missing the definition (#define PICO_RP2350B 1).

@hel: Maybe this is something that @gadgetoid should look into. I am not an expert on this and might be wrong and the channel-to-gpio mapping has some other root cause.

1 Like

Here is a picture of the wiring on my isolated test setup.

And here is a picture of the overall test setup.

The lower support board in your second image seems to be useful … what is it called?

It’s an Adafruit Swirly. Can confirm, very helpful, I bought a box of standoff screws with mine and use it to keep a bunch of breakouts organised together. I’m not sure why Pimoroni don’t sell them.

1 Like

Thanks! It is also not available here in Germany. But I found this: https://www.printables.com/model/513648-swirly-mounting-grid-for-01-pcbs. Not aluminium, but might be an alternative for something in between breadboarding and permanent setup.

Yeah, it’s an Adafruit Swirly.
Adafruit Swirly Aluminum Mounting Grid for 0.1 Spaced PCBs [10x10] : ID 5781 : Adafruit Industries, Unique & fun DIY electronics and kits
I also bought these to make things even easier.
Black Nylon Machine Screw and Stand-off Set – M2.5 Thread : ID 3299 : Adafruit Industries, Unique & fun DIY electronics and kits