🛠 Service batterie BLE 5 avec notification
Objectives
Leverage the Bluetooth 5 LE of the ESP32-S3 (absent in the classic ESP32, which only has BLE 4.2) by exposing the standard Battery service (UUID 0x180F) with its Level characteristic (0x2A19) for reading and notifications. You will use the BLE stack embedded in the Arduino core (BLEDevice/NimBLE), declare the service in the advertising, and simulate a battery level drop followed by notifications to a smartphone equipped with an app like "nRF Connect".
Hardware
- 1 ESP32-S3 board (Wi-Fi + BLE 5 embedded, no external antenna needed on WROOM)
- 1 Android/iOS smartphone with nRF Connect (or equivalent)
- 1 USB cable for uploading and console access
Complete code
// Service batterie BLE 5 : UUID 180F / niveau 2A19 en READ + NOTIFY
#include "BLEDevice.h"
#include "BLEServer.h"
#include "BLEUtils.h"
#include "BLE2902.h"
BLECharacteristic* pLevel = nullptr;
uint8_t percent = 100;
uint32_t derniereNotif = 0;
class ServCb : public BLEServerCallbacks {
void onConnect(BLEServer* s) override { Serial.println("Client connecte"); }
void onDisconnect(BLEServer* s) override {
Serial.println("Client deconnecte, reprise advertising");
BLEDevice::getAdvertising->start; // indispensable
}
};
void setup {
Serial.begin(115200);
BLEDevice::init("S3-batterie");
BLEServer* srv = BLEDevice::createServer;
srv->setCallbacks(new ServCb);
BLEService* bat = srv->createService("180F"); // Battery
pLevel = bat->createCharacteristic("2A19",
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
pLevel->addDescriptor(new BLE2902); // CCCD
pLevel->setValue(&percent, 1);
bat->start;
BLEAdvertising* adv = BLEDevice::getAdvertising;
adv->addServiceUUID("180F");
adv->setScanResponse(true);
adv->start;
Serial.println("Advertising S3-batterie lance");
}
void loop {
if (millis - derniereNotif > 5000) {
derniereNotif = millis;
percent = percent > 0 ? percent - 1 : 100; // fausse descente
pLevel->setValue(&percent, 1);
pLevel->notify;
Serial.printf("niveau = %u %%\n", percent);
}
delay(100);
}
Expected verification
In nRF Connect, the "S3-batterie" device appears; connecting reveals the Battery service 180F. After subscribing (enable notifications on 2A19), the level decrementing by 1% every 5 seconds arrives in real time. The S3 supports 2 Mbps PHY and Coded PHY (long range) where a classic ESP32 remains at 1 Mbps; under NimBLE, these PHYs are configurable via the stack options.
Common errors
- Forgetting to restart advertising upon disconnection: the device becomes invisible after a connection; this is the role of the onDisconnect callback.
- Forgetting the BLE2902 descriptor (CCCD): without it, the app cannot subscribe to notifications.
- Expecting Bluetooth Classic: the S3, like any recent ESP32 except the classic series, only has BLE; no SPP/HFP.
- Confusing 16-bit and 128-bit UUIDs: "180F" is the Bluetooth SIG assigned UUID; an app displays it as 0000180F-0000-1000-8000-00805F9B34FB.
- Memory pressure: the BLE + Wi-Fi stacks running simultaneously consume a lot of RAM; disable Wi-Fi if not needed.
- Wrong board selected during build: the service does not depend on the board, but USB flashing does; keep "ESP32S3 Dev Module" and USB CDC enabled.
Other tutorials for this board
Code examples for this board
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinodht22.inoArduinooled-i2c.inoArduinoserveur-web.inoArduino