XIAO ESP32-S3 detect USB power with code

How do I detect through code if USB power is plugged in? (Arduino IDE)

I can tell with my own eyes if the USB is plugged in. I can upload and run code fine. I can see the red light.

What I’m trying to do is detect through code if USB power is plugged in, while the XIAO is running. I want to use this to run a different LED animation when the USB power is plugged in, to indicate the battery is charging.

PS. I already know how to read the battery level, that’s not what I’m asking here.

your question is pretty interesting. but since you mention that you already know how to read the battery level I’d be very happy if you can give me a hint. (i’m struggling with that)
kind regards
Arsenio

Hi there,
I have this working NOW on the Xiao Nrf52840 Sense, Tells you if the Device is charging or if unplugged.
Pretty sure the PMI or the BMU is similar in the ESP32 so look at that for starters.

HTH
GL :slight_smile: PJ

1 Like

nice! well done!

i tried to use a similar approach on a ESP32S3, it leads to crashes :frowning:

Hi there,
I read the WiKi and looked at schematic. not Possible , You can’t do it on the Seeed Xiao ESP32S3 ? which is nutz. imho :man_bowing:

HTH
GL :slight_smile: PJ

The 5V output is direct from USB, it should only be active when plugged in. Set up the same resistor schematic as with the battery level reading to split the 5v into a digital or analog input.
I’m trying to find the same without needing to use a port, but so far no luck. Hope this helps.

As you mention, you know how to read the battery level, so can you please explain? I want to read it.

It’s mentioned in the Getting Started.

You have to use a gpio. Run a resistor from the positive battery pad to a gpio (100k is fine) and another similar resistor from gpio to ground. This gives you a simple voltage divider which makes it safe to measure on a gpio. Use a gpio that has an adc and isn’t a boot pin.

In code, read as AnalogReadMilliVolts * 0.002 to get your actual voltage. Typically it runs between 3.1 and 4.1 V (clamp the level between these values for realistic margins) and subtract 3.1 to give you a fairly realistic battery percentage accurate to the nearest 10%

Hi there,

And Welcome here, But hold the HIGHJACK Phone …

This tittle of the thread ? is ? Threads get sidetracked so quickly, and shifting from a simple USB detection question straight into external battery voltage dividers is a classic forum detour. Post a new thread… :+1:

If we are strictly talking about the XIAO ESP32-S3 and checking whether that USB-C cable is powered up, the good news is you still don’t need any of that external hardware or the resistors Bram was talking about.

The two software-only methods from before are the absolute easiest ways to handle it directly on the ESP32-S3 chip:

Method 1: Reading VBUS directly (No external circuits)

Because the ESP32-S3 chip handles the USB communication natively, its internal USB peripheral knows exactly when VBUS (the 5V USB power line) is live. You can poll this directly using the native ESP32 USB library

#include "USB.h"

void setup() {
    Serial.begin(115200);
    USB.begin(); // Fires up the native USB stack
}

void loop() {
    // True if the USB-C cable is plugged into a power source
    if (USB.vbusPresent()) { 
        Serial.println("USB-C is plugged in!");
    } else {
        Serial.println("Running on battery / no USB power.");
    }
    delay(1000);
}

or this,
Method 2: Checking for an Active Serial Connection

If you specifically want to know if the USB-C is plugged into a computer (instead of just a wall charger) so you can do debugging, you can use the standard serial check:

void loop() {
    // True if the USB is plugged into a PC and the Serial Monitor is open
    if (Serial) { 
        Serial.println("Connected to a host computer!");
    }
    delay(1000);
}

using the internal USB.vbusPresent() function completely bypasses the pins and reads the status straight from the internal ESP32-S3 USB hardware architecture.

HTH
GL :slight_smile: PJ :v:

Sadly your AI forgets another option…

USB Power only, no “hub”, no “Serial”, no “USB”.

The XIAO +5V (or VBus Pin 14) “potential divider/voltage detection to GPIO” is still the only “reliable” option.

I would not use the battery connector unless wanting battery voltage, but to get a reliable “USB detect”, eg for a “wake”, the +5V and a more “logical (+5V => 3v3)” potential divider is required.