ble_listen.py
Côté PC, la bibliothèque bleak découvre et se connecte au service BLE de la Nano ESP32 : chaque notification de la caractéristique 2A6E s'affiche en direct. Le chaînon pour enregistrer, afficher ou alerter sur les mesures BLE sans application mobile.
Matériel requis
Un Arduino Nano ESP32 (ESP32-S3 double cœur, Wi-Fi 2,4 GHz + Bluetooth Low Energy, brochage physique compatible Nano, USB natif, broches 3,3 V uniquement). PC Linux/Windows/macOS avec Bluetooth LE, Python 3 et bleak ; carte publiant le service (ble-capteur.ino).
Câblage
Aucun ; rapprochez la carte du PC pour le premier appairage.
Fonctionnement
find_device_by_name filtre l'advertising, start_notify abonne la callback à la caractéristique via ATT. Le contexte async with déconnecte proprement après les 30 s d'écoute.
Exécution
Installez le package Arduino ESP32 Boards (ou le guide Nano ESP32 officiel), sélectionnez Arduino Nano ESP32, téléversez. Les broches sont en 3,3 V : n'envoyez jamais 5 V sur une entrée. Le moniteur série utilise l'USB natif.
Variantes
Poussez les mesures vers MQTT/InfluxDB dans la callback, ou gardez la connexion ouverte en reconnexion automatique pour un enregistrement continu.
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())