micropython-lib icon indicating copy to clipboard operation
micropython-lib copied to clipboard

Timeout when activating ble on RP2040 (Pi Pico W)

Open griffinsteffy19 opened this issue 2 years ago • 5 comments

I am running a bluetooth service that currently just as a rx service with write and capture both set to true. I am getting in consent results when reloading the device after awhile without being powered. I continue to get the following error... File "App/TX1/bleService.py", line 50, in __init__ File "aioble/server.py", line 328, in register_services File "aioble/core.py", line 38, in ensure_active OSError: [Errno 110] ETIMEDOUT

# Ble Service Module

# Module Includes

# Common Application Modules
from App.common.logModule import Log

# Core Libaries
import bluetooth
import uasyncio as asyncio
from micropython import const
import aioble
import random
import struct

# Ble Provision Service Logger
log = Log("bleS", 'TRACE')

# Module Defines
RX_TIMEOUT_MS = 5000

# Uart Service UUID
UART_SERVICE_UUID = bluetooth.UUID(UART_UUID)

# RX Characteristic UUID
UART_RX_CHARACTERISTIC_UUID = bluetooth.UUID(RX_UUID)

# How frequently to send advertising beacons.
_ADV_INTERVAL_MS = 250_000


class BLEService:
    def __init__(self, dataCb, advName="CTdvc"):
        self.name = advName
        self.dataCb = dataCb
        self.isStarted = False
        self.advTask = None
        self.rxCbTask = None

        # Register GATT server.
        self.uart_service = aioble.Service(UART_SERVICE_UUID)
        self.rx_characteristic = aioble.Characteristic(
            self.uart_service, UART_RX_CHARACTERISTIC_UUID, write=True, capture=True
        )
        log.debug('Registering Services...')
        aioble.register_services(self.uart_service)
        log.info('Services Registered')

    async def rxCb(self):
        while True:
            await self.rx_characteristic.written()
            try:
                data = self.rx_characteristic.read().decode('utf-8')
                print(f"written: {data}")
                if(None != self.dataCb):
                    await self.dataCb(data)
            except UnicodeError:
                log.error('Unicode Error during decode')
        self.rxCbTask = None

    async def advertisingTask(self):
        while True:
            async with await aioble.advertise(
                _ADV_INTERVAL_MS,
                name=self.name,
                services=[UART_SERVICE_UUID],

            ) as connection:
                print("Connection from", connection.device)

                await connection.disconnected()

        self.advTask = None

    def started(self):
        return self.isStarted

    async def start(self):
        log.trace('start')
        if(not self.isStarted):

            log.debug("staring BLE with name=%s" % self.name)
            self.rxCbTask = asyncio.create_task(self.rxCb())
            self.advTask = asyncio.create_task(self.advertisingTask())
            self.isStarted = True
        else:
            log.debug('already started')

        while True:
            asyncio.sleep(0.5)

    async def stop(self):
        log.trace('stop')
        self.isStarted = False

        if(None != self.advTask):
            self.advTask.cancel()
            self.advTask = None

        if(None != self.rxCbTask):
            self.rxCbTask.cancel()
            self.rxCbTask = None

Above this module I have initialize it, then call start within a running while loop task

griffinsteffy19 avatar Sep 24 '23 19:09 griffinsteffy19

It looks like this might be coming form the underlying bluetooth library:

>>> import bluetooth
>>> ble = bluetooth.BLE()
>>> ble.active(True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 110] ETIMEDOUT

Here is the UF2 I am running: v1.20.0-198-g0eacdeb1c

I found a previous issue here which mentioned activating wifi first, but that did not seem to help. However that was for a ESP32...

>>> import network
>>> wlan = network.WLAN(network.STA_IF)
>>> wlan.active(True)
None
>>> ble.active(True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 110] ETIMEDOUT

griffinsteffy19 avatar Sep 24 '23 19:09 griffinsteffy19

Did you figure out the problem?

MattyBoy4444 avatar Oct 25 '23 18:10 MattyBoy4444

No, most consistent way to fix the issue is to reload the uf2 file.

I have seen this issue with the latest RPI_PICO_W-20231005-v1.21.0.uf2 file as well (I think that is the right link....regardless I have seen the issue on 1.21.0 with ble enabled)

griffinsteffy19 avatar Oct 25 '23 18:10 griffinsteffy19

There was a recent fix https://github.com/micropython/micropython/pull/12647 that might explain this? Do you see the same issue on the preview builds?

jimmo avatar Oct 26 '23 00:10 jimmo

I haven't ran any of the recent preview builds (after 1.21.0). I'll do some testing tomorrow with the latest preview and see what happens.

griffinsteffy19 avatar Oct 26 '23 02:10 griffinsteffy19