RP2040-Zero battery connection

I have one of these and I’m wondering how to connect up a battery. With the pico you can connect to VSYS and ground and you’re good to go, but I’m not sure if/where this routes to on this.

3 Likes

I found the schematic here https://www.waveshare.com/w/upload/4/4c/RP2040_Zero.pdf

It looks like the 5V pin is VSYS, does that look right?

image

3 Likes

Hi Doug,

Just did a little test here in-house and checked the pinouts and it appears that you can power the RP2040 directly over the 3.3V line as it appears to be connected to the RP2040 IOVDD on the board. You’ll just want to make sure that your voltage doesn’t spike above 3.3V as typically the voltage range for RP2040’s is 2.5~3.3V although it can drop as low as 1.8V no problem (although I wouldn’t recommend this as other issues begin to occur at low voltage).

If you’re connecting it to a battery or batteries, I would suggest including a buck converter and a small decoupling capacitor to ensure that you’re getting relatively noise-free power supplied to your board at the appropriate voltage.

p.s. the RS2040 seems to draw only a few milliamps when idling on this board.

2 Likes

Thanks, that’s great. I’ll see how I go :slight_smile:

1 Like

The RPi Pico has :-
VBUS (USB 5V).
VSYS input to 3V3 regulator, (1.8V to 5.5V) this would be a LiPo battery connection.
3V3 output of regulator.
Diode separation of VBUS & VSYS on board.

The 5V on the Board linked above would be connected to the USB 5V.
This connects to the ME621 LDO regulator to produce 3V3.
From the datasheet the input range for the regulator is 4.3V to 6.5V.

Battery connection to this board is not straight forward as the RPi Pico.
Regards
Jim

2 Likes

Hi Doug,

Neat lil board, you could also get away with far less circuitry from a look at the schema (I’m not too sure if the ME621, the one that I have seems to be - ref the photo below, though in the schematic RT9013-33 is listed as the regulator)

Both LDO’s will happily output a pretty stable voltage all the way down to 3.3V from Vin max if you are using a LiPo.

Hard agree on the Vmax spec, for both LDR’s though as the voltage falls past what it has been designed to output it will close to linearly fall off
image

(Source - P12)

From there all that is required is a diode from between the battery to Vsys so that the battery doesn’t explode and seamless switchover from USB-Battery can occur.

Other interesting resources:
Powering from above 12V: WiFi Garage Door Controller with Raspberry Pi Pico W - Tutorial Australia
Another more complex example of switching to battery power, the P-FET will have a lower voltage drop => less power lost CE-PiicoDev-LiPo-Expansion-Board-for-Raspberry-Pi-Pico/schematic.pdf at main · CoreElectronics/CE-PiicoDev-LiPo-Expansion-Board-for-Raspberry-Pi-Pico · GitHub

2 Likes

Sorry I am bit confused, Is it possible and safe to power this board waveshare RP2040-Zero from the 5v line, using 5v input? I have one of these boards and a hoping to use it with a battery / solar panel i also already have a 5v step down voltage regulator. I am a bit of a noob to all this, so any help to understand is very much appreciated.

cheers

Tested this board.
Powered via the USB-C connector, RGB Led flashed three colours.
Disconnected the USB-C connector and connected a 5V power supply to 5V & GND, RGB Led flashed.

So the answer would be Yes it is ok.
But, DO NOT connect both USB-C and separate power supply at the same time.
As @Liam120347 mentioned you need a diode to ensure one supply does not overload the other.

Also make sure it is +5V and the right polarity when you connect a separate supply or the board may die.

BTW the 3.3V is an output, you cannot power it via this pin.

Regards
Jim

2 Likes

I would like to connect a USB-C cable in order to set the RTC via a serial connection and at the same time power the RP2040-Zero via a battery. I would prefer not to add a diode to the board. Is it possible to disconnect the power line on the USB cable and still maintain serial communication? If so should I keep the ground connected? If a diode is required could it be connected in the USB cable and could you recommend a suitable diode?

@Jonathan151973 The problem with the RP2040-Zero design is the 5V from the USB and the VSYS pin are the same and connect to the input to a 3V3 regulator. It is difficult to place a diode where it needs to be.

The Pico design has the diode before the 5V connects to the regulator. Any connected battery is being charged while the USB is connected. (VSYS is the battery connection)

You could try it with the VBUS pins (both of them) disconnected using a USB-C breakout. All the other pins need to be in place. The breakout would have to carry them through.

RP2040-Zero USB-C connector.

image

This is the best way to isolate VBUS & VSYS as @Liam120347 linked above. When VBUS is present the mosfet switches off and disconnects the battery.

The design of the Pico is NOT the best way to do it considering a non rechargeable battery could be used. A low charge battery would try to drag VBUS down resulting in high current flow. Might be why one of my Pico’s no longer works, the regulator just gets hot and the Pico does not run.

The projects I have built using the RP2040-Zero have a switch in the battery connection; so it can be isolated for when I want to connect USB. (which is not very often) If you have the USB-C connected all the time there is no need for a battery. Depends on what you are doing.

Cheers
Jim

2 Likes

Hi Jim,

Thank you for the prompt response to my question.

I will try disconnecting both VBUS pins.

Just to let you know, the application I am experimenting with the RP2040-Zero is a very small, lightweight data logger. It should maintain a reasonably accurate clock for the time of each log. It is possible to set the clock while it is connected to the USB via serial communication or file transfer but the battery must not be disconnected afterward otherwise the clock will reset. If you are aware of any other way to achieve this please let me know.

Thanks again,

Jonathan

1 Like

If you have link to the datalogger can you please provide. All RTC devices I have seen use a button cell or supercap (piicodev & makerverse) to keep the clock running. The device you have may be very different.

The reason not to connect VBUS & VSYS; is the voltages are likely to be different. VBUS will be 5V & VSYS can be as low as 3V. The regulator on the RP2040-Zero can work down to 2.2V.

It may be possible to keep power to the device using a mosfet. If I know more about it I might find a way.

Regards
Jim

1 Like

I was looking at using the SparkFun Qwiic OpenLog that I also purchased from Core Electronics but since I started playing with the RP2040-Zero I found that it is and has up to 2M of Flash. If I can manage to keep the program size down then this might be enough for the logging. I have written some CircuitPython test code and it seems feasible. The RP2040-Zero also has an onboard RTC but no battery so if it is unplugged from the PC the clock will reset. I have also written some test code that enables the user to set the time and date of the RTC from the PC. I purchased a few button batteries with a holder and intend to connect it to the board. This is why I think that I also need to disconnect VBUS & VSYS first. I just need to maintain the power supply after it is unplugged from the PC.

I don’t know a lot about MOSFETs but I wouldn’t think it would be possible to use one in this scenario.

Thanks again for your help.

Jonathan

2 Likes

Ahh, I see what your doing now. Pretty good and device is small size.
I’ll have a think about this and see what I can come up with, I will test it to prove it works.

The 2M flash is also used by CircuitPython. I use MicroPython and Thonny can show how much memory is left after OS and program. Probably will be plenty.

I will be using a LiPo as the battery in my design.
The current I measured when the RP2040 is running was 22mA.
I have played with putting a Pico to sleep but have never got it to the level of a ATMega328P (uA).

Regards
Jim

1 Like

I was not expecting you to actually set up a test to prove it but appreciate it very much.

It is the first time that I have written anything with CircuitPython an I am using the Mu IDE but only because it is the first thing I came across.

I also used the Arduino IDE to test a few things and to set the Flash size. I still have not worked out how to do it with the Mu IDE or even better in code.

Here is the code that I used to test the RTC. It gives the user 5 seconds to enter each date/time value in the serial input and only sets the time and date if they enter a value.

import sys
import rtc
import time
import select

TIMEOUT = 5
DEFAULT_YEAR = 24
DEFAULT_MONTH = 1
DEFAULT_DAY = 1
DEFAULT_HOUR = 0
DEFAULT_MIN = 1

userSetDateTime = False
rp2040RTC = rtc.RTC()

def getUserInputWithTimeout(prompt, default, timeout):
print(prompt)
userEnteredValue = False

i, o, e = select.select([sys.stdin], , , 10)
if (i):
val = str(sys.stdin.readline()).strip()
userEnteredValue = True
else:
val = str(default).strip()

if val == “”:
val = default

if val == “\n”:
val = default

try:
val = int(val)

except Exception:
print(“Warning the value ({}) can’t be converted to int”.format(val))
val = default

return val, userEnteredValue

isUserValue = False
yr, isUserValue = getUserInputWithTimeout(
“Year({}):”.format(rp2040RTC.datetime.tm_year),
rp2040RTC.datetime.tm_year, TIMEOUT
)
if isUserValue:
userSetDateTime = True

mth, isUserValue = getUserInputWithTimeout(
“Month({}):”.format(rp2040RTC.datetime.tm_mon),
rp2040RTC.datetime.tm_mon, TIMEOUT
)
if isUserValue:
userSetDateTime = True

d, isUserValue = getUserInputWithTimeout(
“Day({}):”.format(rp2040RTC.datetime.tm_mday),
rp2040RTC.datetime.tm_mday, TIMEOUT
)
if isUserValue:
userSetDateTime = True

hr, isUserValue = getUserInputWithTimeout(
“Hour({}):”.format(rp2040RTC.datetime.tm_hour),
rp2040RTC.datetime.tm_hour, TIMEOUT
)
if isUserValue:
userSetDateTime = True

m, isUserValue = getUserInputWithTimeout(
“Minute({}):”.format(rp2040RTC.datetime.tm_min),
rp2040RTC.datetime.tm_min, TIMEOUT
)
if isUserValue:
userSetDateTime = True

print(“The year = {}”.format(yr))
print(“The month = {}”.format(mth))
print(“The day = {}”.format(d))
print(“The hour = {}”.format(hr))
print(“The minute = {}”.format(m))

try:
if userSetDateTime:
rp2040RTC.datetime = time.struct_time((yr, mth, d, hr, m, 0, 0, -1, -1))

okToRun = True

except Exception as e:
print(“Error attempting to set the time {}”.format(e))
okToRun = False

while True:
timeformat = “{:02}-{:02}-{:02} {:02}:{:02}:{:02}”
currentTime = timeformat.format(
rp2040RTC.datetime.tm_year,
rp2040RTC.datetime.tm_mon,
rp2040RTC.datetime.tm_mday,
rp2040RTC.datetime.tm_hour,
rp2040RTC.datetime.tm_min,
rp2040RTC.datetime.tm_sec
)
print(currentTime)
time.sleep(1)

2 Likes

This is not as easy as I thought; because VBUS (5V) from the USB-C connector is the same as VSYS (battery connection). Modifying the RP2040-Zero board is not an option, too much risk of damaging it. Use of a mosfet is not possible. The solution was to disconnect the VBUS power provided by the USB-C connector.

I built a board using two USB-A sockets with a jumper to connect 5V.
GND, D+, D- were connected straight through.

120mAH LiPo connected to VSYS and GND.
USB-C to USB-A cable connected the RP2040-Zero to the board.
USB-A to USB-A cable connected the board to the PC.

You could do the same with a USB-C breakout and different cables.

The RP2040-Zero worked ok with just the battery and connection to the PC worked ok with VBUS disconnected. I think this option has been discussed previously, now I can confirm it works.

Regards
Jim

2 Likes

Thank you very much for testing it out and confirming that it will work. It gives me the confidence to try it too.

I think that it’s a bit of a design fault in the board. I can’t imagine why you would use the RTC without disconnecting the board from the PC. Using a USB-C breakout to set the clock still leaves the risk for someone to plug it directly to the PC with the battery still connected and potentially fry something.

In any case the RP2040-Zero is still a great little development board.

Thanks again

2 Likes

Agree. I see no other way due to the design of the board.
Probably it was a compromise due to available pins and space on the board.

If the board is powered by a LiPo, (4.2V max) and 5V from the USB-C is connected.
It would severely damage the LiPo and place a large drain on the 5V supply.

I have used this board in a number of projects and this power problem has always been an issue.
In the end I have used a switch to disconnect the battery. Also a risk if you forget to turn it off when connecting a USB-C cable.

BTW the RP2040 drags about 22mA idle, I tested 4 different boards. As a data logger it would quickly drain a battery unnecessarily when no data is being logged.

Regards
Jim

1 Like

Just looking at the RP2040-One and it should be easier to modify the board to disconnect the power from the USB A connection. It also has 4MB of Flash. I’m not sure exactly how I would connect the battery. Probably directly to the 5V pin and GND pins but perhaps also add a small switch to reconnect the USB power.

I suspect this board will draw the same power as the RP2040-Zero. Have you tried putting it into sleep mode and if so did it make any difference?

Thank you
Jonathan

1 Like

The RP2040-One would be ideal to remove VBUS. Solder USB-A cable to USB tabs, maybe ??

This is the post where I placed my experience of getting the Pico to sleep. Should work for the RP2040-One. You will need to keep the RTC clock going and maybe some others too. It’s possible this won’t work for your project. There may also be some changes to Micropython that make it easier.
It is python accessing the registers using assembler instructions. The RP2040 wakes on a GPIO pin.

This is the code I eventually used.

################################################################################
#
#			Pi Pico - Dormant function
#
#	Use these functions to put the Pico to sleep.
#	Power consumption drops to about 0.3mA.
#
# 	def dormant_until_pin(gpio_pin, edge=True, level=True):
#
#	gpio_pin - the GPIO pin interrupt that will wake the Pico
#	edge =  True  - triggers on an edge
#	edge =  False - triggers on a level
#	level = True  - rising edge or High level
#	level = False - falling edge or Low level
#
#   Created 10 Jan 2022
#  
#################################################################################
# Address & Register definitions
##############################################################################################
# GPIO Register start address, GPIO pin determines actual register
#    calculated by int(gpio / 8) * 4
IO_BANK0_BASE = 0x40014000
# Register offsets
IO_BANK0_INTR0 = 0x0f0
IO_BANK0_DORMANT_WAKE_INTE0 = 0x160
# Bit determines type of interrupt, 4 bits per register, 8 registers in each 32 bit word
#     Bit position for GPIO is calculated by event << 4 * (gpio % 8)
#         event is one of 4 options below
LEVEL_LOW =  0x00000001
LEVEL_HIGH = 0x00000002
EDGE_FALL =  0x00000004
EDGE_RISE =  0x00000008

# XOSC Register start address
XOSC_BASE = 0x40024000
XOSC_DORMANT = 0x08
XOSC_STATUS = 0x04
# Values to write to set dormant mode, wake value is set by default
XOSC_DORMANT_VALUE = 0x636f6d61
XOSC_WAKE_VALUE = 0x77616b65
# bit to check indicating XOSC is stable
XOSC_STATUS_STABLE_BIT = 0x80000000
# ROSC Registers start address
ROSC_BASE = 0x40060000

# Clock Registers start address
CLOCKS_BASE = 0x40008000
# Register offsets
CLK_REF_CTRL = 0x30
CLK_SYS_CTRL = 0x3C
CLK_PERI_CTRL = 0x48
CLK_USB_CTRL = 0x54
CLK_ADC_CTRL = 0x60
CLK_RTC_CTRL = 0x6C
PLL_SYS_BASE = 0x40028000
PLL_USB_BASE = 0x4002c000
PLL_PWR = 0x4

##############################################################################################
# Assember routines to directly access registers
##############################################################################################
@micropython.asm_thumb
def _read_bits(r0):
    ldr(r0, [r0, 0])

@micropython.asm_thumb
def _write_bits(r0, r1):
    str(r1, [r0, 0])

##############################################################################################
# Set dormant mode and activate
#     Found it better to put all the register manipulation in the same Python def()
##############################################################################################
def dormant_until_pin(gpio_pin, edge=True, level=True):
# convert edge and level to event
    if not edge and not level:
        event = LEVEL_LOW
    if not edge and level:
        event = LEVEL_HIGH
    if edge and not level:
        event = EDGE_FALL
    if edge and level:
        event = EDGE_RISE
#check for valid gpio
    if gpio_pin < 0 or gpio_pin > 27:
        raise RuntimeError("Invalid value for pin " + str(gpio_pin) + " (expect int between 0 and 27)")
# clear interrrupts
    _write_bits(IO_BANK0_BASE + IO_BANK0_INTR0 + int(gpio_pin / 8) * 4, event << 4 * (gpio_pin % 8))
# Enable Wake-up from GPIO IRQ
    _write_bits(IO_BANK0_BASE + IO_BANK0_DORMANT_WAKE_INTE0 + int(gpio_pin / 8) * 4, event << 4 * (gpio_pin % 8))
# Setup clocks for dormant
    _write_bits(CLOCKS_BASE + CLK_REF_CTRL, 0x02)
    _write_bits(CLOCKS_BASE + CLK_SYS_CTRL, 0x00)
    _write_bits(CLOCKS_BASE + CLK_USB_CTRL, 0x00)
    _write_bits(CLOCKS_BASE + CLK_ADC_CTRL, 0x00)
    _write_bits(CLOCKS_BASE + CLK_RTC_CTRL, 0x60)
    _write_bits(CLOCKS_BASE + CLK_PERI_CTRL, 0x00)
    _write_bits(PLL_USB_BASE + PLL_PWR, 0x2D)
    _write_bits(ROSC_BASE, 0xD1EAA0)
# go dormant
    _write_bits(XOSC_BASE + XOSC_DORMANT, XOSC_DORMANT_VALUE)
####################################
# execution stops here
####################################
# Normalise clocks
    _write_bits(CLOCKS_BASE + CLK_REF_CTRL, 0x02)
    _write_bits(CLOCKS_BASE + CLK_SYS_CTRL, 0x01)
    _write_bits(CLOCKS_BASE + CLK_USB_CTRL, 0x800)
    _write_bits(CLOCKS_BASE + CLK_ADC_CTRL, 0x800)
    _write_bits(CLOCKS_BASE + CLK_RTC_CTRL, 0x800)
    _write_bits(CLOCKS_BASE + CLK_PERI_CTRL, 0x800)
    _write_bits(PLL_USB_BASE + PLL_PWR, 0x04)
    _write_bits(ROSC_BASE, 0xfffaa0)
# Check for stable XOSC after wake up
    while not _read_bits(XOSC_BASE + XOSC_STATUS) & XOSC_STATUS_STABLE_BIT:
         pass
# clear interrupts
    _write_bits(IO_BANK0_BASE + IO_BANK0_INTR0 + int(gpio_pin / 8) * 4, event << 4 * (gpio_pin % 8))

#################################################################################

Regards
Jim

1 Like