Wake on Bluetooth Connect (alternatively, power consumption)

I have a hobbyist project build a weather sensor based on Xiao ESP32C6. The sensor will be polled every 5 minutes or so by another device (…actually a repurposed Raspberry Pi Zero2W..) via bluetooth. I poll so infrequently because I need the sensor to have a battery life of weeks or even months from a small 320mAh battery.

My problem is getting the ESP32C6 to wake from light sleep when the Pi connects via bluetooth. After reading posts here, I know the device can’t wake from deep sleep on BT connect, but it also seems it won’t even wake from light sleep on BT connect. So, I have a series of questions:

  1. Is it really not possible to wake the ESP32C6 from any sleep on bluetooth connect?
  2. Do any of the other Xiao devices support both BLE and wake on connect? (I’d happily swap chips for an easier life!)
  3. The problem with using a timer to wake from sleep is getting the timing right with such infrequent polling. Does anyone have any suggestions about best strategy to wake up fopr external polling?

TIA for any helpful suggestions

Steve

Consider posting the values on the Raspberry Pi. The strategy is: sleep as much as reasonable, then make the Xiao establish a connection to the Pi. Note that the Pi (or Xiao) can be both a BLA server and client at the same time.

Ever easier on the battery life: set up a beacon profile on the Xiao and include (up to 32bytes) the sensor data into the beacon payload. If privacy is an issue then you can encode the payload. Note that this way the Xiao will not know if anybody will receive the message.

I used both methods for a soil humidity sensor. I programmed the Xiao to read the sensor every hour but to send the information only if there was a change of 10%, and I have it working on a 18650 for almost a year.

Hi there,

So, The physics and BLE spec don’t really allow that unless you have some always-on external companion chip doing the listening. and Yeah, the instinct about “put the data in the advertisement and keep the Central awake” is actually the most realistic workaround here. Let’s go through the constraints and then talk about what does work in practice.

1. Can ESP32-C6 wake from sleep on BLE connect?

Short answer: no, not the way you’d like.

On the ESP32 family (including C6), BLE activity cannot be used as a wake source from deep sleep, and in practice you also don’t get a clean “wake on connect” from light sleep in the way a low-power peripheral would ideally behave.

  • Deep sleep: only RTC GPIO, timer, ULP / coprocessor, etc., can wake the chip. BLE radio is completely off.
  • Light sleep: Wi-Fi / BT can sometimes be used while napping the CPU, but the radio has to remain in a mode that keeps power higher and requires active stack participation. For ultra-low-duty battery devices (weeks/months on 320 mAh) it’s not suitable.

So: you cannot rely on “Pi connects → C6 wakes from true low-power sleep”. To do that, the radio would already have to be awake and listening, which wipes out your battery budget. Definitely NOT with a coin Cell

2. Other XIAO boards that can “wake on connect”?

Even on Nordic chips (nRF52 / nRF54) used in XIAO boards, the pattern is basically the same:

  • BLE cannot wake from full power-off–style deep sleep (where RAM and radio are off).
  • You can keep the radio in a low-duty connected mode or periodic advertising, and sleep the CPU between events, but that’s not the same as “true deep sleep” – current is usually in the 10s–100s of µA range, not nA.

So swapping to another XIAO (nRF52840, nRF54L15, ESP32-S3, etc.) won’t magically give you “wake from totally dead by BLE connect”.
You can do very efficient always-advertising or always-connected-but-idling on something like nRF52 and still get months of life on a coin cell, but that’s a different operating mode than full deep sleep.

3. Practical strategy for your :index_pointing_at_the_viewer: use case :grin:

Your constraints:

  • Battery: ~320 mAh
  • Poll interval: ~every 5 minutes
  • Central: Raspberry Pi Zero2W
  • Peripheral: XIAO ESP32-C6
  • Desired behavior: Central “asks”, Peripheral wakes, sends data

Given what the hardware can do, the simplest, robust, low-power design is this:

Option A – Broadcast weather in advertisements

Have the ESP32-C6 act as a pure advertising beacon: (@Sergio_J 'Idea)
I believe @msfujino did something similar in a project as well..

  1. Every 5 minutes (or whatever interval you like):
  • Wake from deep sleep by timer.
  • Take sensor readings.
  • Encode the latest readings into the advertising payload (or scan response).
  • Advertise for a short window (e.g., 5–10 seconds).
  • Go back to deep sleep.
  1. On the Pi side:
  • Keep BLE scanning always on, or in a periodic scan pattern.
  • When you see your sensor’s advertisements, parse the data and log it.
  • No GATT connection needed at all.

Why this is good:

  • The ESP32-C6 stays in real deep sleep ~99% of the time. Wake → measure → advertise → sleep.
  • You don’t care about “waking on connect” anymore. The Central simply listens for the broadcast.
  • Battery life can reach many weeks/months if you keep the active window short and RTC timer interval long.

Trade-offs:

  • You’re limited to ~31 bytes in the main advertising payload minus overhead, but that’s still plenty for:
    • Temperature, humidity, pressure
    • Battery level
    • A sensor ID / version / flags

For a small weather station, this is absolutely enough.

You can do some other options that work but require more thought.
i.e. Schedule a connection Window
If you really want a connection (for bigger payloads or config), you can do:

  • ESP32-C6 wakes every 5 minutes:
    • Starts advertising and stays up for a fixed window (say 10–20 seconds) waiting for a Pi connection.
  • Pi:
    • Runs a job every 5 minutes that scans and connects during that window.

This still uses RTC timer for wake, not BLE, but from the user’s perspective:

  • “Pi polls every 5 minutes” :white_check_mark:
  • “Sensor is mostly asleep” :white_check_mark:

Downside: requires the Pi and C6 clocks not to drift too much, or you make the window a bit generous (at the cost of some battery life).
or an ALWAYS ON situ
i.e. keep the Central always on and let the Peripheral wake & advertise. That’s actually the best inversion for your topology:

  • The Pi Zero2W is mains-powered or at least has much more battery than 320 mAh.
  • Leave the Pi scanning 24/7.
  • Let the ESP32-C6 do ultra-aggressive sleeping and only pop up briefly to shout weather updates.
    This workaround is not just possible, it’s the correct architecture. :+1:

I have seen * A simple ESP32-C6 Arduino or IDF example: wake via timer every 5 minutes, read BME280/whatever, shove data into manufacturer data field of the advertising packet, advertise for X seconds, then deep sleep.

  • And a Python script on the Pi using bleak to scan and parse those advertisements.
  • Basic’s don’t over think it.

HTH
GL :slight_smile: Pj :v: