adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.02k stars 1.19k forks source link

ESP32-S3 BLE unable to reconnect to device after forgetting connection #9435

Closed BlitzCityDIY closed 3 weeks ago

BlitzCityDIY commented 1 month ago

CircuitPython version

Adafruit CircuitPython 9.1.0 on 2024-07-10; Adafruit Feather ESP32S3 No PSRAM with ESP32S3

Code/REPL

import time
import adafruit_ble
from adafruit_ble.advertising.standard import SolicitServicesAdvertisement
from adafruit_ble_apple_media import AppleMediaService

# PyLint can't find BLERadio for some reason so special case it here.
radio = adafruit_ble.BLERadio()  # pylint: disable=no-member
a = SolicitServicesAdvertisement()
a.solicited_services.append(AppleMediaService)

if not radio.connected:
    print("advertising")
    radio.start_advertising(a)
else:
    print("already connected")
    print(radio.connected)
# print(gc.mem_free())
while True:
    while not radio.connected:
        pass
    known_notifications = set()

    i = 0
    while radio.connected:
        for connection in radio.connections:
            if not connection.paired:
                connection.pair()
                print("paired")

            ams = connection[AppleMediaService]
            print("App:", ams.player_name)
            print("Title:", ams.title)
            print("Album:", ams.album)
            print("Artist:", ams.artist)
            if ams.playing:
                print("Playing")
            elif ams.paused:
                print("Paused")

            if i > 3:
                ams.toggle_play_pause()
                i = 0
        print()
        time.sleep(3)
        i += 1

    print("disconnected")
    print("advertising")
    radio.start_advertising(a)
    print("reconnected")

Behavior

I think this is edge case behavior but wanted to mention that when CircuitPython is freshly installed and I connect my iOS device to it, it connects fine and runs the code as expected:

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
advertising
App: None
Title: None
Album: None
Artist: None

App: Music
Title: Undercover Martyn
Album: Tourist History
Artist: Two Door Cinema Club
Paused

if i forget the CP device on my iOS device and try to reconnect, the CP device will show as half connected on iOS and the code never completes on the Feather:

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
advertising
paired
Traceback (most recent call last):
  File "code.py", line 41, in <module>
  File "adafruit_ble/__init__.py", line 104, in __getitem__
  File "adafruit_ble/__init__.py", line 68, in _discover_remote
ConnectionError: Connection has been disconnected and can no longer be used. Create a new connection.

Code done running.

in order to reconnect i need to reinstall CircuitPython (UF2 works, don't need to erase flash with esptool)

Description

No response

Additional information

No response

dhalbert commented 1 month ago

If you power-cycle does that work?

A way to clear the pairing/bonding info so you don't have reinstall is to do:

import _bleio
_bleio.adapter.erase_bonding()
BlitzCityDIY commented 1 month ago

power-cycling does not work. i did not know about erase_bonding() and that did work, thanks!

tannewt commented 3 weeks ago

This isn't a bug. Needing device side erase_bonding() is expected.