Page 1 of 1

BLE [Errno 12] ENOMEM

Posted: Wed Aug 05, 2020 6:17 pm
by monquarter
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?

Re: BLE [Errno 12] ENOMEM

Posted: Thu Sep 03, 2020 6:13 am
by jimmo
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