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

aioble: Not all characteristics are shown

Open ukena opened this issue 1 year ago • 6 comments

I have a problem with aioble on my pico w. I have created two services, but at most seven characteristics are displayed. For example, for the truncated code section below, only the seven characteristics up to the # TODO comment are displayed. I have already tried lowering the mtu size and creating a third service and registering the characteristics there. Changing the order doesn't solve the problem, i.e. if I move self.wind above self.colors, the wind characteristics are advertised, but there are still only seven characteristics in total. If I clear all characteristics values there are still only seven characteristics advertised so I don't think that it is due to size limitations.

import gc
import aioble
import asyncio
import ujson
import micropython_ota
from bluetooth import UUID

from helpers import load_json, json_has_keys


class BLE:
    def __init__(self, config):
        aioble.config(mtu=512)
        
        self.config = config
        
        self.service_meta = aioble.Service(UUID("ba7f1568-b2ea-4fda-8d5b-9e5f5fe6925f"))

        self.sku = aioble.Characteristic(self.service_meta, UUID("374ce939-0e41-4ca3-8023-450a5d7cc868"), read=True, capture=True)
        self.id = aioble.Characteristic(self.service_meta, UUID("3b85c350-d60d-4213-ac83-12f4b33de750"), read=True, capture=True)
        self.version = aioble.Characteristic(self.service_meta, UUID("89b9c4ce-afc8-446b-908f-6ab44b95bc3d"), read=True, write=True, capture=True)

        self.service_settings = aioble.Service(UUID("771cf459-392a-4100-9d8c-b3c7e32883bc"))
        
        self.wifi_init_scan = aioble.Characteristic(self.service_settings, UUID("bc004c3e-48de-4496-9465-c8ea1c4ae8cf"), write=True)
        self.wifi_available_networks = aioble.Characteristic(self.service_settings, UUID("d7a96f45-c135-4cee-a053-cf50b621bfa5"), read=True, notify=True)
        self.wifi = aioble.Characteristic(self.service_settings, UUID("16a5d9f1-ab50-476e-a9fc-1a20230beedf"), read=True, write=True, capture=True)
        
        self.colors = aioble.Characteristic(self.service_settings, UUID("038e91b7-eb88-4ecd-acfd-811797ce6c00"), read=True, write=True, capture=True)

        # TODO: Not all characteristics are shown
        self.wind = aioble.Characteristic(self.service_settings, UUID("e03f403e-0e21-41b9-91d4-2075608c7bc9"), read=True, write=True, capture=True)

        self.times = aioble.Characteristic(self.service_settings, UUID("a5342786-ad90-404b-bc51-cfcf6d465051"), read=True, write=True, capture=True)
        
        self.ota = aioble.Characteristic(self.service_settings, UUID("ae8d0e7f-ff36-4da7-a720-93ed8cf9f5f5"), read=True, write=True, capture=True)
        
        self.brightness = aioble.Characteristic(self.service_settings, UUID("c011b876-5414-4f5e-aad9-1050fa77e88e"), read=True, write=True, capture=True)
        
        aioble.register_services(
            self.service_meta,
            self.service_settings
        )
                
        gc.collect()

    async def advertise(self):
        while True:
            gc.collect()
            
            async with await aioble.advertise(
                250_000,
                name=f"{self.config.get('sku')}_{self.config.get('id')}",
                services=[UUID("ba7f1568-b2ea-4fda-8d5b-9e5f5fe6925f")]
            ) as connection:
                await connection.exchange_mtu(512)
                print("Connection from", connection.device)

                self.init()
                self.update()
                
                asyncio.create_task(self.watch_brightness())
                asyncio.create_task(self.watch_colors())
                asyncio.create_task(self.watch_wifi_init_scan())
                asyncio.create_task(self.watch_wifi())
                asyncio.create_task(self.watch_times())
                asyncio.create_task(self.watch_ota())
                gc.collect()
                
                await connection.disconnected(timeout_ms=None)

I stumbled across this issue and even though its for ESP32 and Arduino the issue is the same. I already looked into the definitions of aioble but I did not found anything related to this.

Do you have any suggestions?

ukena avatar Aug 24 '24 14:08 ukena

Anyone know why this could be or how to configure a higher limit?

jonnor avatar Oct 12 '24 09:10 jonnor

aioble.Service(UUID("ba7f1568-b2ea-4fda-8d5b-9e5f5fe6925f"), 30) ???? maybe ???

littlefroginnovations avatar Oct 13 '24 14:10 littlefroginnovations

aioble.Service(UUID("ba7f1568-b2ea-4fda-8d5b-9e5f5fe6925f"), 30) ???? maybe ???

Does not look like it: https://github.com/micropython/micropython-lib/blob/master/micropython%2Fbluetooth%2Faioble%2Faioble%2Fserver.py#L71

ukena avatar Oct 13 '24 15:10 ukena

The RPI Pico uses BTStack for Bluetooth. It has a compiled in setting for how much ram is allocated to the services and characteristics DB called MAX_ATT_DB_SIZE at https://github.com/micropython/micropython/blob/82e69df33e379bf491bea647e217d6d56c5b8090/extmod/btstack/btstack_config_common.h#L41

If you make this number larger and recompile micropython you'll be able to define more.

andrewleech avatar Oct 13 '24 17:10 andrewleech

The RPI Pico uses BTStack for Bluetooth. It has a compiled in setting for how much ram is allocated to the services and characteristics DB called MAX_ATT_DB_SIZE at https://github.com/micropython/micropython/blob/82e69df33e379bf491bea647e217d6d56c5b8090/extmod/btstack/btstack_config_common.h#L41

If you make this number larger and recompile micropython you'll be able to define more.

Thanks a lot, this did the trick.

ukena avatar Oct 14 '24 08:10 ukena

After changing MAX_ATT_DB_SIZE from 512 to 1024, the characteristics are shown but I receive [Errno 110] ETIMEDOUT from time to time on my Pico 2 W (RP2350). After some research it appears to be a Bluetooth issue with custom build firmware, see:

  • https://github.com/micropython/micropython/issues/12617
  • https://github.com/micropython/micropython-lib/issues/734

@andrewleech are you aware of any additional changed I need to do after changing MAX_ATT_DB_SIZE to 1024 or do you know any other possible cause of this issue?

ukena avatar May 13 '25 08:05 ukena