ESP32 Eddystone URL Beacon (Deep Sleep Broadcasting)

Snippet summary:
This example shows how to turn an ESP32 into a BLE beacon that broadcasts Eddystone URL frames. It periodically advertises a compressed URL, rotates between multiple URLs across wake cycles, and uses deep sleep to achieve ultra-low power operation.

Introduction

  • This example demonstrates BLE beacon broadcasting, not client/server communication
  • The ESP32 advertises a URL over BLE using the Eddystone protocol
  • No connections are required — devices simply scan and read the broadcast
  • Designed for low-power IoT and proximity-based applications

👉 Think of it as a wireless URL broadcaster

What is Eddystone URL

  • A BLE beacon format defined by Google
  • Broadcasts compressed URLs inside BLE advertisements
  • Designed for:

👉 Instead of pairing, devices just scan and decode the URL

What this example does

  • Cycles through a list of predefined URLs
  • Encodes each into Eddystone format
  • Broadcasts it for 10 seconds
  • Enters deep sleep
  • Wakes up and broadcasts the next URL

👉 Each wake cycle = different URL

URL list and rotation

String URL[] = { ... }
  • Contains multiple URLs
  • Examples include:

Selection logic:

URL[bootcount % (sizeof(URL) / sizeof(URL[0]))]
  • Uses boot count to rotate URLs
  • Every wake cycle → next URL

👉 Simple but effective state machine

Smart URL encoding

EddystoneURL.setSmartURL(...)
  • Automatically compresses URLs
  • Uses predefined prefixes:
  • Uses suffix compression where possible

👉 This reduces BLE payload size

URL limitations

  • Max length ≈ 17 bytes after encoding
  • Invalid cases:
// setSmartURL() returns 0 = error

👉 Always validate URLs before use

Advertising structure

oAdvertisementData.addData(data);
oScanResponseData.setName("ESP32 URLBeacon");
  • Advertisement → contains encoded URL
  • Scan response → contains device name

👉 Standard BLE split:

  • data → primary packet
  • name → scan response

BLE setup

BLEDevice::init("URLBeacon");
BLEDevice::setPower(BEACON_POWER);
  • Initializes BLE stack
  • Sets transmit power
#define BEACON_POWER ESP_PWR_LVL_N12

👉 Low power mode for energy efficiency

No BLE server required

// BLEServer *pServer = BLEDevice::createServer(); // not needed
  • This is important
  • Beacon mode does NOT require a server

👉 Saves:

  • RAM
  • flash
  • power

Advertising cycle

pAdvertising->start();
delay(10000);
pAdvertising->stop();
  • Advertises for 10 seconds
  • Then stops

👉 Short bursts → better battery life

Deep sleep operation

esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION);
  • ESP32 shuts down almost completely
  • Only RTC memory remains
#define GPIO_DEEP_SLEEP_DURATION 10

👉 Sleeps for 10 seconds between broadcasts

RTC memory usage

RTC_DATA_ATTR static time_t last;
RTC_DATA_ATTR static uint32_t bootcount;
  • Values persist across deep sleep
  • Used for:

👉 Essential for low-power state tracking

Boot diagnostics

Serial.printf("Start ESP32 %lu\n", bootcount++);
  • Shows how many wake cycles occurred
Serial.printf("Deep sleep (%llds since last reset...)\n");
  • Helps debug timing behavior

Runtime flow

  • ESP32 wakes up
  • Selects next URL
  • Encodes URL
  • Starts BLE advertising
  • Broadcasts for 10 seconds
  • Stops advertising
  • Goes to deep sleep
  • Repeats

👉 Fully autonomous beacon

How to scan the beacon

Use:

  • ESP32 BLE scanner example
  • nRF Connect (Android/iOS)
  • any BLE scanner with Eddystone support

Look for:

  • Service UUID: 0xFEAA
  • Frame type: URL

Real-world applications

  • proximity-based web links
  • asset tracking tags
  • smart posters / exhibits
  • retail promotions
  • IoT device discovery

👉 “tapless” interaction via BLE scanning

Limitations

  • no connection support
  • no data feedback
  • limited payload size
  • depends on scanner support

👉 Pure broadcast model

Improvements for production

  • use dynamic URLs (e.g. sensor data endpoints)
  • adjust sleep duration for battery optimization
  • increase TX power for longer range
  • add real sensor integration
  • implement configuration via OTA or BLE setup mode

Honest take

This example is:

  • simple but powerful
  • extremely efficient
  • underused in real projects

Big takeaway:

👉 BLE can replace QR codes in many cases

But:

  • requires user to have BLE scanner
  • not as universally accessible as NFC/QR

Conclusion

This example shows how to build a:

👉 low-power BLE URL broadcaster

Using:

  • Eddystone URL format
  • compressed advertising payload
  • deep sleep cycles

It’s ideal for:

  • battery-powered IoT
  • proximity-based interactions
  • lightweight wireless communication
Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *