XIAO ESP32-S3 Read built-in LED state

Is there a way to read if the built-in LED is on or off?

I tried this, always returns 1…



Hello, could you share your project or idea with us? Because it connect to the GPIO21 pin of mcu, which control by the running code, you cannot just read and write it at the same time when you at the same process, but you can know the situation by using the dual-thread,here is the show code:

#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

TaskHandle_t task1Handle;
TaskHandle_t task2Handle;

const int ledPin = LED_BUILTIN;

void task1(void *parameter) {
  while (1) {
    int ledState = digitalRead(ledPin);
    Serial.println("LED Situation: " + String(ledState));

void task2(void *parameter) {
  while (1) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin, LOW);

void setup() {

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  xTaskCreate(task1, "Task1", 10000, NULL, 1, &task1Handle);
  xTaskCreate(task2, "Task2", 10000, NULL, 1, &task2Handle);

void loop() {

My goal is to determine if the battery is currently charging.

Hello, here is a blog you can reference:XIAO_BLE_Sense(mbed 2.7.2) battery charge and voltage monitor, analogRead(P0_31) does not work

Hi, I read the blog, however I’m not trying to read the battery voltage. I’m trying to determine if the battery is currently charging (or if USB power is present).

Hi FollowTheLight,
I don’t have a XIAO_ESP32S3 so I haven’t checked, but according to the schematic, the charging LED (RED) is lit directly by the charge controller. It is not connected to the port and is not supposed to be readable.
The presence or absence of a USB power connection can be determined by the voltage on the 5V pin of the XIAO: 5V when USB is connected, 0V when not connected.

Hi msfujino, thanks for checking!

So what can I do then? Can I connect VUSB to a digital pin and do a digitalRead?

In order to connect the 5V pin to the port for digitalRead(), the voltage applied to the port must be less than 3.3V. There is a way to divide the voltage externally with resistors (e.g., 22k and 33k).

Something like

VUSB ---- 22k ---- GPIO ---- 33k ----GND


If it is for commercial use, the resistance needs to be more properly calculated.

1 Like

It’s only for a small project, I will try it! Thank you so much!

The problem you’re running into is that the built-in LED is generally configured for output, so you’re changing its behavior by setting it to INPUT mode. This is likely why you’re getting unexpected results.

Generally speaking, the built-in LED state is controlled in your code, so you should be able to keep track of its state with a variable if you need to. If the LED is turned ON using digitalWrite(LED_BUILTIN, HIGH);, then set a flag like bool isLedOn = true;. If it’s OFF, then bool isLedOn = false;. That way, you can just check the variable instead of trying to read the pin state.

If you really must read the LED state without using a flag, you’ll have to delve into low-level microcontroller features, which can be different for each platform. This can get complicated fast and isn’t generally recommended for something as simple as an LED state.

Hope this helps!

1 Like

Indeed! Thank you for the explanation :slight_smile: My mistake was thinking I could determine if the battery was currently charging by reading the LED because the charging circuit is connected to it. However, I realized that the NCHG pin from the SGM40567 chip is wired directly to the LED. Since it is not connected to a GPIO pin, there is no way to read the state of the NCHG pin. I also have no idea how to reach the NCHG pin to connect it. Schematic : https://files.seeedstudio.com/wiki/SeeedStudio-XIAO-ESP32S3/res/XIAO_ESP32S3_SCH_v1.1.pdf