BLE [Errno 12] ENOMEM

The official PYBD running MicroPython, and its accessories.
Target audience: Users with a PYBD
Post Reply
monquarter
Posts: 14
Joined: Sat Jan 11, 2020 2:31 pm

BLE [Errno 12] ENOMEM

Post by monquarter » Wed Aug 05, 2020 6:17 pm

I have been working with the ble_temperature and ble_temperature_central examples (https://github.com/micropython/micropyt ... /bluetooth). I have 2 PYBD-SF6W running MicroPython v1.12-652-gcaaaa2b1f , running a file on each one of them. I am running the ble_temperature_central.py file without any modifications, and modify the paramaters in the while loop at the bottom of ble_temperature.py

Code: Select all

def demo():
    ble = bluetooth.BLE()
    temp = BLETemperature(ble)

    t = 25
    i = 0

    while True:
        # Write every second, notify every 10 seconds.
        i = (i + 1) % 1
        temp.set_temperature(t, notify=i == 0, indicate=False)
        # Random walk the temperature.
        t += random.uniform(-0.5, 0.5)
        time.sleep_ms(50)
My understanding is that this would send a notification to the central every 50 ms. On the board running the central, I get an OSError: [Errno 12] ENOMEM error.

Code: Select all

>>> ble_tc.demo()
Found sensor: 0 b'HJ0\x01\xe5\xd2' mpy-temp
Connected
16.39
14.04
13.16
11.9
13.55
11.55
8.74
10.99
10.48
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ble_tc.py", line 251, in demo
  File "ble_tc.py", line 209, in read
OSError: [Errno 12] ENOMEM
Additionally, when I reduce the loop to something like 20 ms on ble_temperature file, I get the OSError: [Errno 12] ENOMEM error on the peripheral.

Code: Select all

>>> ble_temperature.demo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ble_temperature.py", line 86, in demo
  File "ble_temperature.py", line 67, in set_temperature
OSError: [Errno 12] ENOMEM
If I do not use notifications, and simply write , then I don't see any errors on either the central or peripheral, even with 20 ms updates.

Code: Select all

def demo():
    ble = bluetooth.BLE()
    temp = BLETemperature(ble)

    t = 25
    i = 0

    while True:
        # Write every second, notify every 10 seconds.
        i = (i + 1) % 1
        temp.set_temperature(t, notify=False, indicate=False)
        # Random walk the temperature.
        t += random.uniform(-0.5, 0.5)
        time.sleep_ms(20)
        
Is there a way to check if memory is available before issuing a notification?

User avatar
jimmo
Posts: 2232
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: BLE [Errno 12] ENOMEM

Post by jimmo » Thu Sep 03, 2020 6:13 am

monquarter wrote:
Wed Aug 05, 2020 6:17 pm
On the board running the central, I get an OSError: [Errno 12] ENOMEM error.
It's a bit confusing that ENOMEM here likely means that the BLE stack didn't have enough room in its buffers to handle an operation, and this is completely unrelated to the Python heap.

At least for the notifications case, my guess here is that it's just sending too fast and NimBLE can't send the notifications out fast enough. One of the problems here is that MicroPython polls the HCI controller on a 128ms interval. I sent a PR to fix this a week or so ago (it hooks the RX IRQ from the UART), but it hasn't been merged yet. https://github.com/micropython/micropython/pull/6343

Post Reply