ble_listen.py
On the PC side, the bleak library discovers and connects to the Nano ESP32 BLE service: each notification of characteristic 2A6E prints live. The missing link to log, display or alert on BLE readings without a mobile app.
Hardware
An Arduino Nano ESP32 (dual-core ESP32-S3, 2.4 GHz Wi-Fi + Bluetooth Low Energy, Nano-compatible physical pinout, native USB, 3.3 V pins only). Linux/Windows/macOS PC with Bluetooth LE, Python 3 and bleak; board advertising the service (ble-capteur.ino).
Wiring
None; bring the board close to the PC for the first pairing.
How it works
find_device_by_name filters advertising, start_notify subscribes the callback to the characteristic over ATT. The async with context disconnects cleanly after the 30 s listen.
Running it
Install the Arduino ESP32 Boards package (or follow the official Nano ESP32 guide), select Arduino Nano ESP32, upload. Pins are 3.3 V: never feed 5 V into an input. The serial monitor uses native USB.
Variants
Push readings to MQTT/InfluxDB inside the callback, or keep the connection open with auto-reconnect for continuous logging.
ble_listen.py
#!/usr/bin/env python3
"""Ecoute les notifications du service 181A (ble-capteur.ino).
Pre-requis : pip install bleak ; Bluetooth LE sur le PC.
"""
import asyncio
from bleak import BleakClient, BleakScanner
NOM = "NanoESP32-Capteur"
CHAR_MESURE = "2a6e" # caractéristique BLENotify du croquis
def sur_notification(_, donnees: bytearray) -> None:
print(f"mesure = {donnees[0]}/255")
async def principal() -> None:
print("Recherche de", NOM, "...")
peripherique = await BleakScanner.find_device_by_name(NOM, timeout=15)
if peripherique is None:
print("introuvable : la carte publie-t-elle ?")
return
async with BleakClient(peripherique) as client:
print("connecte :", client.address)
await client.start_notify(CHAR_MESURE, sur_notification)
await asyncio.sleep(30) # 30 s d'ecoute
await client.stop_notify(CHAR_MESURE)
if __name__ == "__main__":
asyncio.run(principal())