From e42552ee8fc8bf7f36f52c942bfb77a5f5c63c28 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 27 Apr 2021 22:47:27 +0200 Subject: [PATCH] Portenta: Add BLE example. --- .../41-Bluetooth/ble_temperature.py | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 scripts/examples/Arduino/Portenta-H7/41-Bluetooth/ble_temperature.py diff --git a/scripts/examples/Arduino/Portenta-H7/41-Bluetooth/ble_temperature.py b/scripts/examples/Arduino/Portenta-H7/41-Bluetooth/ble_temperature.py new file mode 100644 index 000000000..7a48d0c91 --- /dev/null +++ b/scripts/examples/Arduino/Portenta-H7/41-Bluetooth/ble_temperature.py @@ -0,0 +1,97 @@ +# This example demonstrates a simple temperature sensor peripheral. +# +# The sensor's local value updates every second, and it will notify +# any connected central every 10 seconds. + +import bluetooth +import random +import struct +import time +from ble_advertising import advertising_payload + +from micropython import const + +_IRQ_CENTRAL_CONNECT = const(1) +_IRQ_CENTRAL_DISCONNECT = const(2) +_IRQ_GATTS_INDICATE_DONE = const(20) + +_FLAG_READ = const(0x0002) +_FLAG_NOTIFY = const(0x0010) +_FLAG_INDICATE = const(0x0020) + +# org.bluetooth.service.environmental_sensing +_ENV_SENSE_UUID = bluetooth.UUID(0x181A) +# org.bluetooth.characteristic.temperature +_TEMP_CHAR = ( + bluetooth.UUID(0x2A6E), + _FLAG_READ | _FLAG_NOTIFY | _FLAG_INDICATE, +) +_ENV_SENSE_SERVICE = ( + _ENV_SENSE_UUID, + (_TEMP_CHAR,), +) + +# org.bluetooth.characteristic.gap.appearance.xml +_ADV_APPEARANCE_GENERIC_THERMOMETER = const(768) + + +class BLETemperature: + def __init__(self, ble, name="PORTENTA_BLE"): + self._ble = ble + self._ble.active(True) + self._ble.irq(self._irq) + ((self._handle,),) = self._ble.gatts_register_services((_ENV_SENSE_SERVICE,)) + self._connections = set() + self._payload = advertising_payload( + name=name, services=[_ENV_SENSE_UUID], appearance=_ADV_APPEARANCE_GENERIC_THERMOMETER + ) + self._advertise() + + def _irq(self, event, data): + # Track connections so we can send notifications. + if event == _IRQ_CENTRAL_CONNECT: + conn_handle, _, _ = data + self._connections.add(conn_handle) + elif event == _IRQ_CENTRAL_DISCONNECT: + conn_handle, _, _ = data + self._connections.remove(conn_handle) + # Start advertising again to allow a new connection. + self._advertise() + elif event == _IRQ_GATTS_INDICATE_DONE: + conn_handle, value_handle, status = data + + def set_temperature(self, temp_deg_c, notify=False, indicate=False): + # Data is sint16 in degrees Celsius with a resolution of 0.01 degrees Celsius. + # Write the local value, ready for a central to read. + self._ble.gatts_write(self._handle, struct.pack("