ble_listen.py

Arduino Nano ESP32 · Archivo : ble_listen.py · Lenguaje : Python · Uso : Écouter les notifications BLE depuis un PC

En el PC, la librería bleak descubre y conecta el servicio BLE de la Nano ESP32: cada notificación de la característica 2A6E se imprime en directo. El eslabón para registrar, mostrar o alertar sobre medidas BLE sin app móvil.

Hardware

Un Arduino Nano ESP32 (ESP32-S3 de doble núcleo, Wi-Fi 2,4 GHz + Bluetooth Low Energy, formato físico compatible con el Nano, USB nativo, pines de 3,3 V únicamente). PC Linux/Windows/macOS con Bluetooth LE, Python 3 y bleak; placa publicando el servicio (ble-capteur.ino).

Cableado

Ninguno; acerca la placa al PC para el primer emparejamiento.

Funcionamiento

find_device_by_name filtra la publicidad, start_notify suscribe la callback a la característica vía ATT. El contexto async with desconecta limpiamente tras los 30 s de escucha.

Ejecución

Instala el paquete Arduino ESP32 Boards (o sigue la guía oficial del Nano ESP32), selecciona Arduino Nano ESP32 y carga. Los pines son de 3,3 V: nunca envíes 5 V a una entrada. El monitor serie usa el USB nativo.

Variantes

Envía las medidas a MQTT/InfluxDB dentro de la callback o mantén la conexión abierta con reconexión automática para registro continuo.

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())

← Volver a la ficha