Skip to content

Problem connecting to ESP32C3 using 5.1 ble dongle #1926

@Mateus-OT

Description

@Mateus-OT

Hi, I'm using a python script to work as client and terminal to send commands to my ESP32C3 through BLE.

Bleak version: 2.0.0
Python version: 3.13
ESP32C3 bluetooth version: 5.0 (according to datasheet)
PC bluetooth dongle version: 5.1 (according to LMP in this site, despite it says it's 5.0)

When running the code it seems to connect the ESP, but then shows this message and disconnects:
Could not get GATT services: Unreachable

I believe it has some relation to the dongle bluetooth version, because of the frames 22 to 25 in these packets:
wiresharkdebug2.txt

I changed the BT dongle to one with 4.2 BT version and the script just worked fine, but I still need to make this work with my 5.1 BT dongle.

Is this some compatibility error in the library version or something else?

Here is the full python script:

import asyncio
from bleak import BleakClient
import sys

# ======================== CONFIGURAÇÕES ========================
# SEU MAC ADDRESS QUE FUNCIONOU (CRÍTICO)
DEVICE_ADDRESS = "A0:85:E3:4A:99:66"

# UUIDs (Mesmos do ESP32)
CHARACTERISTIC_RX = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" # Enviar Comandos
CHARACTERISTIC_TX = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" # Receber Telemetria

def notification_handler(characteristic, data):
    """Callback de Telemetria"""
    try:
        # Tenta decodificar a string vinda do ESP32
        telemetry_data = data.decode('utf-8', errors='ignore').strip()
        # Imprime limpando a linha para não ficar uma bagunça se digitar junto
        print(f"\r[TELEMETRIA] {telemetry_data}            ", end='') 
    except Exception:
        pass

async def send_command(client: BleakClient, command: str):
    """Envia comando para o Hoverboard"""
    # Adiciona \n apenas por segurança, converte para bytes
    if not command.endswith(';'): command += ';' # Garante terminador
    
    command_bytes = command.encode('utf-8')
    try:
        # write_gatt_char com response=False é mais rápido e trava menos
        await client.write_gatt_char(CHARACTERISTIC_RX, command_bytes, response=False)
        # print(f"\n[CMD ENVIADO] {command}") 
    except Exception as e:
        print(f"\n[ERRO ENVIO] {e}")

async def run():
    print(f"--- TENTANDO CONECTAR DIRETAMENTE EM {DEVICE_ADDRESS} ---")
    print("Certifique-se que o ESP32-C3 está ligado.")
    
    # Timeout de 20s para garantir
    async with BleakClient(DEVICE_ADDRESS, timeout=20.0) as client:
        print(f"\n>>> CONECTADO COM SUCESSO! Status: {client.is_connected}")
        
        # O SEGREDO DO WINDOWS: PAUSA PARA RESPIRAR
        print("Aguardando 3 segundos para estabilização dos serviços...")
        await asyncio.sleep(3.0)
        
        # 1. Ativa recebimento de dados
        print("Ativando telemetria...")
        await client.start_notify(CHARACTERISTIC_TX, notification_handler)
        
        print("\n===================================================")
        print(" CONTROLE HOVERBOARD PRONTO")
        print(" Comandos: S300 (Speed), P25 (Kp), etc.")
        print(" Digite 'sair' para encerrar.")
        print("===================================================\n")

        # Loop de comandos
        while True:
            # Input do usuário (bloqueante, mas ok para teste terminal)
            # Usamos run_in_executor para não travar o loop de recebimento BLE
            user_input = await asyncio.get_event_loop().run_in_executor(None, input, "")
            
            if user_input.lower() == 'sair':
                break
            
            if user_input.strip():
                # Formata comando simples (ex: usuario digita s300 -> envia S300;)
                cmd = user_input.strip().upper()
                await send_command(client, cmd)
            
            # Pequeno delay para CPU
            await asyncio.sleep(0.05)

    print("\n--- Desconectado ---")

if __name__ == "__main__":
    if sys.platform.lower() == "win32":
        asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
    try:
        asyncio.run(run())
    except KeyboardInterrupt:
        print("\nEncerrado.")
    except Exception as e:
        print(f"\nERRO FATAL: {e}")

Metadata

Metadata

Assignees

No one assigned

    Labels

    3rd party issueThe issue is with the Bluetooth stack, the BLE device, or other 3rd party code not with Bleak itselfmore info requiredIssues does not have a reproducible test case, has insufficent logs or otherwise needs more feedback

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions