0

Based on the official peripheral sensor example, I need to also receive data.

Here is what I tried:

from micropython import const
import uasyncio as asyncio
import bluetooth
import aioble
import struct
import random
import json
import time


_ENV_SENSE_UUID = bluetooth.UUID("90D3D000-C950-4DD6-9410-2B7AEB1DD7D8")
_ENV_SENSE_TEMP_UUID = bluetooth.UUID("90D3D001-C950-4DD6-9410-2B7AEB1DD7D8")
_ENV_SENSE_RECV_UUID = bluetooth.UUID("90D3D002-C950-4DD6-9410-2B7AEB1DD7D8")
_ADV_APPEARANCE_GENERIC_THERMOMETER = const(768)
_ADV_INTERVAL_US = 250_000

# Register GATT server.
device_service = aioble.Service(_ENV_SENSE_UUID)
temp_characteristic = aioble.Characteristic(device_service, _ENV_SENSE_TEMP_UUID, read=True, notify=True)
recv_characteristic = aioble.Characteristic(device_service, _ENV_SENSE_RECV_UUID, write=True, read=True, notify=True)

aioble.register_services(device_service)

async def temp_sensor():
    # This would be periodically polling a hardware sensor.
    t = 24.5
    while True:
        data = {'t': t}
        data_encoded = bytes(json.dumps(data), 'utf8')
        temp_characteristic.write(data_encoded, send_update=True)
        t += random.uniform(-0.5, 0.5)
        await asyncio.sleep_ms(1000)

# FIXME: This is not working: data is always None.
async def recv_actor():
    print('READING', recv_characteristic)
    while True:
        data = await recv_characteristic.read()
        await asyncio.sleep(1)

# Serially wait for connections. Don't advertise while a central is connected.
async def peripheral_task():
    while True:
        async with await aioble.advertise(
            _ADV_INTERVAL_US,
            name="MicroIO_BLE",
            services=[_ENV_SENSE_UUID],
            appearance=_ADV_APPEARANCE_GENERIC_THERMOMETER,
        ) as connection:
            print("Connection from:", connection.device)
            global _connected_timer_start
            _connected_timer_start = time.ticks_ms()
            #await connection.disconnected() # Don't use this as it crashes everything after 60 seconds when timeout happens.
            while connection.is_connected() == True:
                #print(f'Connection status: {connection.is_connected()}')
                await asyncio.sleep_ms(1000)
            print('Connection lost. switching back to advertising mode')


async def main():
    print('Starting Bluetooth sensor example.')
    await asyncio.gather(
        asyncio.create_task(temp_sensor()),
        asyncio.create_task(recv_actor()),
        asyncio.create_task(peripheral_task()),
    )
    print('Example finished.')

asyncio.run(main())

The data is sent by Javascript navigator.bluetooth API using:

characteristic.writeValueWithoutResponse(value);

also tried using:

characteristic.writeValue(value);

My problem is that I don't receive any data in aioble.

Damien
  • 1,624
  • 2
  • 19
  • 26

1 Answers1

0

you need to use written() instead of read(). in case you are actually interested in the data as well you need to enable capture when creating the characteristic

recv_characteristic = aioble.Characteristic(device_service, _ENV_SENSE_RECV_UUID, write=True, read=True, notify=True, capture=True)

and the receive it with

connection, data = await recv_characteristic.written()
Tobi
  • 1