Battery Gauge missing Badger2040(W) & some noob questsions

Thats what I’m thinking? Might be time to
Contact Us for Raspberry Pi Technical Support - Pimoroni

1 Like

Oh snap!
There is a „real support“ and not only the community pulling requests on GitHub?
Great! Will do tomorrow! Just finished work and I’m „shot“…

I listened to your advice not to use CR2032 Lithium batteries in series. Modified new battery cases for parallel and found some LIR2032, rechargeable Li-Ion button cells with 3.6V. They run in parallel now with a capacity of about 80mAh and this is great for this pico with e-ink display.

Edit: Actually it’s not a good idea to connect Li-Ion batteries in parallel without BMS.
The explanation you read here: Multi-battery Packs | Li-Ion & LiPoly Batteries | Adafruit Learning System

Slatfatf!

The Hitchhiker

The Forum is the first point of contact for Tech support.
Contacting Tech Support directly is another option.
Especially for suspected issues with uf2 files etc.

There is also Github.
Phil hangs out there a lot more than he does here on the forum.
Issues · pimoroni/badger2040 (github.com)

1 Like

Github issues is probably the best place to post if something isn’t working with a specific uf2. If you could include a succinct piece of test code that can be run to demonstrate the problem (and the error that you’re getting) that would be handy :)

1 Like

Thanks for the details!
Will do!

This is dangerous. You should read this guide here: Overview | Li-Ion & LiPoly Batteries | Adafruit Learning System

It explicitly states: “Not only should you not do this with alkaline batteries, but its especially dangerous with lithium batteries. One battery can discharge into another, damaging it or causing a fire!”

Another thing to be aware off: rechargeable coin-cells usually need trickle-charging, i.e. a special circuitry. The Badger has no battery charging at all, so you will have to take out the coin-cells and put them in a specal charger. Trickle-charging is usually implemented in devices with a backup-battery, so you might have a hard time finding a correct charger. Best thing is to check the datasheet of the batteries.

I don’t think running with two CR2032 in series is a problem. New batteries without load will provide 6V (too much for the Badger), but as soon as you have any kind of load, the voltage drops to a reasonable value (you have seen this effect already according to your post above). This is the reason why there are special battery-testers for coin-cells: they don’t just measure the voltage, but apply a load for a very short time as well.

1 Like

Hey @bablokb!
Good point with the „discharging into each other“.
This is a real safety issue.

The charger for the LIR2032 is external and (trickle charges) them individually and also measures the cells. So both go into the Badger or into the charger. But good you emphasize the risk, not that some kids just copy it and some bad things happen.
Thanks for that!

The Badger2040W already has its own LiPo battery (Pimoroni Galleon) and it’s dedicated “inline” LiPo charger, so I even don’t have to unplug it for charging.

And don’t forget to bring your own towel!

The Hitchhiker

Oh and I had the CR2032 in series, that’s how it started to measure the battery level. And yes, I can confirm, the voltage drops from 6V to 4.8V on a new pair of cells, since there is a draw of ~20mA even on a 2040-non-W Badger, when waking up. This, and the limited “shortcut-current“ of a button cell battery (vs. a rechargeable 3.6V Li-Ion-button cell) makes the „normal“ batteries much more safer.

Just for environmental aspects. I was replacing almost all button cells with rechargeable ones step by step.

The Hitchhiker .

1 Like

So, after trying this and trying that I switched finally to “THE GALLEON”, the LiPo battery PIMORONI recommends for the badger 2040/2040W. And with a LiPo charger like the lipo amigo pro driving on 200mA this is a perfect match, I have to say! I measured the current being drawn by the Pico and its around 35mA when active, thats a bit too much for button cells / rechargeable button cells, so the vsys “caves in” too much.

I tried out 2 differend LiPo battteries and charger combo on the badger2040 / 2040 W. Unfortunately the behaviour of both are different when measuring the vsys against a vref (different pins required). By adding time.sleep(0.5) for the badger204 (non-w) before reading the vsys and probing 5 times to calculate an average value, the battery voltage is quite that what I measuered with a voltmeter.

Can’t recommend to use the version V0.0.4 from Micropython BadgerOS, since the Badger2040W can’t see WL_GPIO2/VBUS Sense in this version (already filed a bug on Github).

I added a function for a battery bar in the launcher.py
def draw_battery_usage(x):

    # Pico W voltage read function by darconeous on reddit with a little help of Kerry Waterfield aka alphanumeric: 
    # https://www.reddit.com/r/raspberrypipico/comments/xalach/comment/ipigfzu/
    # in reference of https://pico.pinout.xyz/ and https://picow.pinout.xyz/
    # the pins and ports are transfered, to make it work on a badger2040 non-W
         
    # these are our reference voltages for a full/empty battery, in volts 
    # the values could vary by battery size/manufacturer so you might need to adjust them
    # full/empty-pairs for some batteries:
    # lipo: 4.2 / 2.8
    # 2xAA/2xAAA alkaline: 3.2 / 2.4
    full_battery = 4.2 
    empty_battery = 2.8 
    vsys = 0

    conversion_factor = 3 * 3.3 / 2**16  # for Badger 2040W internal 3.3V as referece
    little_wait = 0.01  # time slice to wait for vref to stabilize

    if badger2040.is_wireless() == True:
        
        wlan = network.WLAN(network.STA_IF)
        wlan_active = wlan.active()
    
        try:
            # Don't use the WLAN chip for a moment.
            wlan.active(False)
            
        
            # Make sure pin 25 is high.
            Pin(25, mode=Pin.OUT, pull=Pin.PULL_DOWN).high()
  
            # Reconfigure pin 29 as an input.
            Pin(29, Pin.IN, pull=None)

            # reading 'WL_GPIO2' on a picoW tells us whether or not USB power is connected (VBUS Sense)
            # be aware, that on MicroPython v0.0.4 there is a bug and it doesnt work! Stay on v0.0.3!
            vbus = Pin('WL_GPIO2', Pin.IN).value()

            # doing one shot for free
            vsys_sample = ADC(29).read_u16() * conversion_factor
            time.sleep(10 * little_wait)
            
            # we will read 5 times 
            for i in range(5):
                # reading vsys aka battery-level
                vsys_sample = ADC(29).read_u16() * conversion_factor
                vsys = vsys + vsys_sample
                time.sleep(5 * little_wait)

            # arithmetic average over the 5 samples
            vsys = ( vsys / 5 )
                    
        finally:

            # Restore the pin state and possibly reactivate WLAN
            Pin(25, Pin.OUT, value=0, pull=Pin.PULL_DOWN)
            Pin(29, Pin.ALT, pull=Pin.PULL_DOWN, alt=7)
            wlan.active(wlan_active)


    else:
        # Configure pin 29 as an input. (Read VSYS/3 through resistor divider and FET Q1)
        Pin(25, mode=Pin.OUT, pull=Pin.PULL_DOWN).high()
        Pin(29, Pin.IN, pull=None)
        
        # reading pin24 on a pico-non-w tells us whether or not USB power is connected (VBUS Sense)
        vbus = Pin(24, Pin.IN).value()  
        
        # give vref a little time to stabilize
        vsys_sample = ADC(29).read_u16() * conversion_factor
        time.sleep(50 * little_wait) 

        # we well read 5 times 
        for i in range(5):
            # reading vsys aka battery-level
            vsys_sample = ADC(29).read_u16() * conversion_factor
            vsys = vsys + vsys_sample
            time.sleep(5 * little_wait) 
        
        # arithmetic average over the 5 samples
        vsys = ( vsys / 5 )

        
    # convert the val_sys (raw ADC read) into a voltage, and then a percentage
    b_level = 100 * ( ( vsys - empty_battery) / (full_battery - empty_battery) )
    if b_level > 100:
        b_level = 100.00

    display.set_pen(15)
    display.image(
        bytearray(
            (
                0b110011,
                0b001100,
                0b011110,
                0b011110,
                0b010010,
                0b010010,
                0b010010,
                0b011110,
                0b000001,
            )
        ),
        6,
        9,
        x,
        3,
    )
    # assemble horizontal bar-graph beginning at position x+8 (bc. width of 6px the battery symbol)
    # outer white box
    display.rectangle(x + 8, 3, 80, 10)
    display.set_pen(0)
    # inner black box
    display.rectangle(x + 9, 4, 78, 8)
    # white bar according to percentage
    display.set_pen(15)
    #print(f"b_level: {b_level}")

    # reading 'WL_GPIO2' on a picoW or pin 24 on pico tells us whether or not USB power is connected (VBUS Sense)

    # if it's not plugged into USB power...
    if vbus == False:
        # if vbus is false, display the battery status:
        # bar starts at coordinates x+10,5 and 6px high max length 76px (accordingly to percentage)
        display.rectangle(x + 10, 5, int(76 / 100.0 * b_level), 6) 
        display.text("{:.2f}%".format(b_level), x + 91, 4, WIDTH, 1.0)
    else:
        # fake full power on USB when "vbus" is true
        display.rectangle(x + 10, 5, int(76 / 100.0 * 100 ), 6) 
        display.text("USB", x + 91, 4, WIDTH, 1.0)


def render():
    display.set_pen(15)
    display.clear()
    display.set_pen(0)

    max_icons = min(3, len(examples[(state["page"] * 3):]))

    for i in range(max_icons):
        x = centers[i]
        label = examples[i + (state["page"] * 3)]
        #icon_label = label.replace("_", "-")
        icon_label = label.replace("code_", "icon_")
        icon = f"{APP_DIR}/{icon_label}.jpg"
        label = re.sub(r'^code_\d+_', '', label)
        label = label.replace("_", " ")
        jpeg.open_file(icon)
        jpeg.decode(x - 26, 30)
        display.set_pen(0)
        w = display.measure_text(label, FONT_SIZE)
        display.text(label, int(x - (w / 2)), 16 + 80, WIDTH, FONT_SIZE)

    for i in range(MAX_PAGE):
        x = 286
        y = int((128 / 2) - (MAX_PAGE * 10 / 2) + (i * 10))
        display.set_pen(0)
        display.rectangle(x, y, 8, 8)
        if state["page"] != i:
            display.set_pen(15)
            display.rectangle(x + 1, y + 1, 6, 6)

    display.set_pen(0)
    display.rectangle(0, 0, WIDTH, 16)
    draw_disk_usage(50)  # moved a bit more left to give room for battery bar
    draw_battery_usage(175) # call the battery bar
    display.set_pen(15)
    display.text("bitsOS", 4, 4, WIDTH, 1.0)

    display.update()

Some better solution for the battery (under the tape wrap is a charger).
Just one sentence about the “pico lipo” is there a pico W LiPo in the make?
Maybe a also a Badger2040WL?

@hel:
Saw your “heads up” call for Gadgetoid in the issue #60.
Thanks!

1 Like