Bluetooth Low Energy für den Raspberry Pi

Aus LinuxUser 10/2022

Bluetooth Low Energy für den Raspberry Pi

© Alexander Sikov / 123RF.com

Sparfunk

Bluetooth Low Energy eignet sich ideal für das Vernetzen batteriegestützter Sensoren. Wir zeigen, wie Sie es auf dem Raspberry Pi nutzen.

Bluetooth LE oder kurz BLE bringt neben neuer Technologie eine ganz eigene Begriffswelt mit. Bevor es also um praktische Beispiele geht, fällt etwas Theorie an. Ohne Kenntnis der allgegenwärtigen Begriffe können Sie die vielen Anwendungsbeispiele aus dem Internet nicht einordnen und für die eigenen Bedürfnisse anpassen.

Bei Bluetooth handelt es sich um eine Nahfunktechnik für den Einsatz zwischen zwei Geräten [1]. Bevor eine Verbindung steht, kann ein System entweder ein Peripheriegerät (Peripheral Device) oder ein Zentralgerät (Central Device) sein. Leistungsfähige Devices wie PCs, Tablets und Laptops können beide Rollen einnehmen, schwächere Geräte beschränken sich auf die Rolle als Peripherie.

Jedes Peripheriegerät sendet in regelmäßigen Abständen Werbebotschaften (“Advertisements”) aus, etwa “ich bin der Sensor ABC und biete Herzfrequenzdaten an”. Alternativ kann die Botschaft aber auch lauten: “Ich bin der Sensor XYZ und möchte die aktuelle Zeit wissen”. Herzfrequenzdaten (Heart Rate) und aktuelle Zeit (Current Time) sind sogenannte Services. Bei den beiden handelt es sich um standardisierte Services, aber Hersteller sind frei darin, eigene, proprietäre Dienste zu verwenden. Dazu später mehr.

Abbildung 1: Ein Beispiel für Advertisements aus dem Bluetooth Low Energy Primer der Bluetooth SIG.

Abbildung 1: Ein Beispiel für Advertisements aus dem Bluetooth Low Energy Primer der Bluetooth SIG.

Die Abbildung 1 aus dem BLE-Primer der Bluetooth SIG [2] zeigt, dass Geräte für Advertisements mehrere vordefinierte Kanäle des Spektrums nutzen. Wenn Sie sich für technische Details rund um BLE interessieren, sollten Sie dieses Dokument auf alle Fälle lesen.

Verbindungsaufbau

Zentralgeräte scannen ihre Umgebung auf solche Advertisements. Findet sie etwas Interessantes, baut die Zentrale eine Verbindung zum entsprechenden Gerät auf. Sobald die Verbindung steht, stellt das Peripheriegerät den Versand der Werbebotschaften ein. Das ganze Verfahren läuft unter dem Begriff GAP (Generic Access Profile) und ist hier etwas verkürzt dargestellt.

Einmal verbunden, geht es um den Datenaustausch zwischen beiden Geräten. Der zugehörige Standard heißt GATT (Generic Attribute Profile) und regelt, welche Bytes das eine Gerät über Funk zum anderen Gerät sendet. Auch wenn die Verbindung immer von der Zentrale zur Peripherie aufgebaut wird, bedeutet das nicht, dass die Daten nur in eine Richtung fließen. Auch ein bidirektionaler Datenfluss ist möglich, etwa beim UART-Service. BLE definiert dazu die Begriffe Server und Client. Der Client greift lesend respektive schreibend auf den Server zu, der wiederum Daten (mit oder ohne Antwort) an den Client senden kann. Dabei hält der Server die Definition der Ressourcen bereit.

Der Herzfrequenzsensor aus dem vorigen Beispiel wäre der Server. Das Peripheriegerät, das nach der aktuellen Zeit fragt, hätte nach dem Verbindungsaufbau dagegen die Client-Rolle inne. Es kann seinerseits nur hoffen, dass eine Zentrale in die Server-Rolle schlüpft.

Profile und mehr

Ein zentraler Begriff in der BLE-Welt ist der sogenannte Service, der Daten und Verhalten festlegt. Jeder Service trägt eine eindeutige Nummer, die UUID (Universal Unique ID). Die von der Bluetooth SIG standardisierten Services haben 16-Bit-UUIDs, private Services nutzen 128-Bit-UUIDs. Ein offizielles Dokument [3] legt alle standardisierten UUIDs fest. Der Heart Rate Service trägt zum Beispiel die UUID 0x180D.

Mithilfe dieser UUIDs kann eine Zentrale beim Scannen nach Advertisements nur die für sie interessanten Sensoren ausfiltern. Eine App, die den Herzschlag visualisieren will, kann sich somit gezielt mit den geeigneten Sensoren verbinden. Wenn sich jeder an den Standard hält, klappt das sogar herstellerübergreifend.

Eine logische Klammer um mehrere Services stellt das sogenannte Profile dar. Das Heart Rate Profile enthält zum Beispiel zusätzlich noch den Device Information Service (Abbildung 2). Der entsprechende Standard definiert auch die beiden Rollen Collector (Client) und Sensor (Server). Darüber hinaus legt er diverse mehr oder minder wichtige Details fest, etwa dass der Device-Name des Sensors optional überschreibbar sein darf.

Abbildung 2: Ein Beispiel für das Heart Rate Profile aus dem Bluetooth Low Energy Primer der Bluetooth SIG.

Abbildung 2: Ein Beispiel für das Heart Rate Profile aus dem Bluetooth Low Energy Primer der Bluetooth SIG.

Innerhalb eines Services gibt es mehrere logische Attribute beziehungsweise Funktionen, die in der BLE-Terminologie Characteristic heißen. Der Heart Rate Service enthält als Pflicht die Heart Rate Measurement Characteristic und optional unter anderem die Body Sensor Location Characteristic. Jede Characteristic umfasst wiederum benannte Felder mit den eigentlichen Daten.

Scan mich!

Nach so viel Theorie wird es Zeit für ein paar einfache Beispiele. Auf dem Raspberry Pi benötigen Sie dafür nur Python. Die Bibliothek Bleak stellt eine Abstraktionsschicht bereit, die die Anwendung stark vereinfacht. Das Akronym steht etwas gestelzt für BLE Platform Agnostic Klient und weist darauf hin, dass das Paket auf Linux, MacOS und Windows läuft. Für die Programmentwicklung benötigen Sie also nicht unbedingt einen RasPi, auf jeden Fall aber Python ab Version 3.7.

Bleak ziehen Sie einfach über den Befehl pip3 install bleak auf den Rechner. Zusätzlich sollten Sie den Quellcode samt Beispielen über das Github-Repo [4] des Projekts auf die Platte laden. Die Beispiele sind als Vorlagen für eigene Anwendungen sehr nützlich.

Als Alternative zu Bleak bietet sich CircuitPython mittels Blinka an. Auf dem RasPi zusammen mit den passenden BLE-Bibliotheken installiert (Listing 1), vereinfacht diese Kombination insbesondere die Kommunikation mit eigenen Mikrocontrollern, auf denen ebenfalls CircuitPython läuft. Allerdings gibt es hier eine Einschränkung, die in vielen Szenarien allerdings nicht stört: Der Raspberry Pi kann mit Blinka nur die Rolle der Zentrale übernehmen. Die Quellen zu den BLE-Bibliotheken zu CircuitPython finden Sie ebenfalls auf Github, unterhalb des Adafruit-Accounts. Auch hier gibt es viele nützliche Beispiele.

Listing 1

Blinka mit BLE

$ sudo apt-get update
$ sudo apt-get install python3-pip
$ pip3 install \
  adafruit-blinka-bleio \
  adafruit-circuitpython-ble

Das Programm in Listing 2 implementiert einen sehr einfachen BLE-Scanner. Die Endlosschleife in den Zeilen 7 bis 11 scannt alle zehn Sekunden nach Advertisements. Für jeden Treffer gibt das Programm die Bluetooth-MAC-Adresse sowie den Namen aus. Letzterer muss allerdings nicht verfügbar sein. Wenn Sie an der tatsächlichen Byte-Folge der Nachricht interessiert sind, dann geben Sie im print-Statement zusätzlich noch repr(adv) aus.

Listing 2

Einfacher BLE-Scanner

#!/usr/bin/python3
import time
import _bleio
import adafruit_ble
from adafruit_ble.advertising.standard import Advertisement
ble = adafruit_ble.BLERadio()
while True:
  print("Scanning...")
  for adv in ble.start_scan(timeout=5):
    print(adv.address,adv.complete_name)
  time.sleep(10)

Die Bleak-Installation installiert in /usr/local/bin/ das Programm bleak-lescan, das denselben Funktionsumfang wie unser einfacher BLE-Scanner hat. Die Logik ist allerdings in einem Modul versteckt und deshalb nicht so aufschlussreich wie Listing 2.

Abbildung 3 zeigt die Ausgabe des einfachen BLE-Scanners. Neben der Open-Source-Smartwatch (Bangle.js) des Autors und seinem Smartphone (HV10BB) funken noch einige Geräte aus der Nachbarwohnung.

Abbildung 3: Eine Scan-Ausgabe des einfachen BLE-Scanners aus <a href="#artRef-l2">Listing&nbsp;2</a>.

Abbildung 3: Eine Scan-Ausgabe des einfachen BLE-Scanners aus Listing 2.

Apropos Smartphone: Es gibt mehrere Apps in den Stores von Apple und Google, die beim Einstieg in BLE und beim Testen helfen. Dazu gehört etwa die App nRF Connect for Mobile von Nordic Semiconductor (Abbildung 4). Der in Sachen Bluetooth-Chips führende Hersteller bietet auf seiner Webseite [5] viele nützliche Dokumente sowie Tools und Software rund um das Thema an.

Abbildung 4: Der Verlauf der Signalst&auml;rke, gemessen mit nRF Connect.

Abbildung 4: Der Verlauf der Signalstärke, gemessen mit nRF Connect.

Eine weitere nützliche App ist Bluefruit LE Connect von Adafruit. Von diesem Anbieter gibt es nicht nur Hardware, sondern auch eine sehr große Sammlung von Tutorials auf Englisch zu allen möglichen hardwarenahen IT-Themen. Die App und ihre praktische Anwendung sind deshalb sehr gut dokumentiert.

Spezielle Mikrocontroller von Adafruit mit Bluetooth, wie etwa der Feather nRF52840 Express, eignen sich besonders gut zum Zusammenspiel mit dieser App: Sie empfängt nicht nur Daten, sondern kann auch die MCU steuern, sofern dort ein geeignetes Programm läuft.

UART

Die serielle Schnittstelle gehört zum Urgestein der IT und hat es über viele Generationen geschafft, auf immer neuen Trägertechnologien weiterzuleben. Auch für BLE gibt es einen UART-Service, den NUS (Nordic UART Service). Für viele Anwendungen spielt UART die Rolle eines Zwischenprotokolls. Das ist zwar nicht ganz im Sinne der Erfinder von Bluetooth, aber simpel. Entwickler können insbesondere bestehende Anwendungen leicht portieren.

Das Listing 3 zeigt ein Beispiel. Ein Mikrocontroller liest einen angeschlossenen BME280-Sensor aus, verpackt das Ergebnis in eine Zeichenkette und schreibt diese in die serielle Schnittstelle. Besonders gut für den Einstieg eignet sich ein XIAO nRF5280 als Mikrocontroller, denn er ist preiswert und unterstützt alle gängigen Sprachen.

Listing 3

Sensordaten mit UART übertragen

import time
import board
from adafruit_bme280 import advanced as adafruit_bme280
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
i2c = board.I2C()
#BME280 sensor:
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c,address=0x76)
[...]
BLERadio.name = "BME280_Sensor"
ble  = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)
while True:
  print("starting advertisement")
  ble.start_advertising(advertisement)
  while not ble.connected:
    pass
  print("connected")
  while ble.connected:
    measurement = "{0:0.1f},{1:0.1f},{2:0.1f}\n".format(
      bme280.temperature,
      bme280.humidity,
      bme280.pressure/alt_fac
      )
    print(measurement,end='')
    uart.write(measurement.encode("utf-8"))
    time.sleep(10)

Der Code fällt dank der CircuitPython-Bibliotheken sehr kompakt aus, aber auch mit anderen Programmiersprachen gestaltet sich das Ganze nicht viel komplizierter. Auf Client-Seite ist die Logik ähnlich. Statt der Advertisements scannt die Zentrale auf angebotene UART-Services, verbindet sich mit dem Sensor und liest von der seriellen Schnittstelle. Den kompletten Code für Server und Client finden Sie im Projekt-Repository [6] des Autors.

Über die Probleme des UART-Verfahrens stolpert man spätestens dann, wenn weitere Geräte im Netz den NUS anbieten. Das umgeht das Client-Programm dadurch, dass es den Advertisement-Namen BME280_Sensor abfragt, aber elegant ist das nicht. Sinnvoller wäre ein eigener Service, der die Datenstruktur festlegt.

Den Vorteil von UART dagegen zeigt die Abbildung 5. Adafruits App kann UART-Daten im CSV-Format auslesen, ohne die Details der Daten zu kennen; bei der Darstellung haben Sie die Wahl zwischen einer Textausgabe oder einem Plot. Für die BME280-Sensordaten eignet sich der gemeinsame Plot allerdings nicht wirklich. Die Werte für Temperatur, Luftfeuchte (zweistelliger Bereich) und Druck (vierstellig) liegen so weit auseinander, dass Details verloren gehen. Bei geeigneten Daten erweist sich die schnelle Visualisierung der Messwerte mittels UART-Plot aber als sehr nützlich.

Abbildung 5: Die UART-Ausgabe als Plot mit Bluefruit LE Connect.

Abbildung 5: Die UART-Ausgabe als Plot mit Bluefruit LE Connect.

Broadcasts

Eine besondere Art von Advertisements sind Broadcasts. Hier schickt das Peripheriegerät mit dem Advertisement gleich Nutzdaten mit. Andere Geräte müssen also gar nicht erst eine Verbindung aufbauen. Broadcasts sind die einzige Art, Daten von einem Gerät an viele andere zu senden.

Beliebt sind diese Broadcasts in der Indoor-Navigation mittels sogenannter Beacons oder in Museen. Hier enthält das Advertisement typischerweise eine URL zu einer Webseite, die ein Exponat näher erläutert. Ist der Sender in Bildnähe und funkt mit schwacher Leistung, empfangen passende Apps nur relevante Informationen.

In unserem Fall dient wieder das Setup mit Mikrocontroller und BME280-Sensor als Anwendungsbeispiel, Listing 4 zeigt die zugehörige Implementation. Auch dieses Programm einschließlich des passenden Clients, der die Daten ausliest, finden Sie im Projekt-Repository [6].

Listing 4

Advertisement mit Daten

import time
import board
from adafruit_bme280 import advanced as adafruit_bme280
import adafruit_ble_broadcastnet
print("This is BroadcastNet sensor:", adafruit_ble_broadcastnet.device_address)
i2c = board.I2C()
#BME280 sensor:
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c,address=0x76)
[...]
while True:
  measurement = adafruit_ble_broadcastnet.AdafruitSensorMeasurement()
  measurement.temperature       = bme280.temperature
  measurement.relative_humidity = bme280.humidity
  measurement.pressure          = bme280.pressure/alt_fac
  print(measurement)
  adafruit_ble_broadcastnet.broadcast(measurement)
  time.sleep(10)

Die Klasse AdafruitSensorMeasurement, eine Unterklasse von Advertisement, hat eine Reihe von vordefinierten Feldern, die das Programm mit den Messwerten des BME280 füllt (Zeilen 11 bis 14). Hinter dem Befehl aus Zeile 16 versteckt sich letztlich das Aussenden des Advertisements.

Beliebige andere Geräte können das Advertisement per Scan empfangen und die Daten extrahieren, sofern sie die interne Struktur kennen. Falls die Felder der Klasse AdafruitSensorMeasurement für Ihre eigenen Projekte nicht passen, dann kopieren Sie einfach die Klasse und passen Sie für Ihre Bedürfnisse an. Das klappt auch, wenn man nicht alle Details versteht.

Fazit

Bluetooth Low Energy eignet sich ideal für das Vernetzen von batteriegestützten Sensoren. Das Datenblatt für den kombinierten Bluetooth- und Wi-Fi-Chip CYW43439 auf dem neuen Raspberry Pi Pico W gibt zum Beispiel für BLE einen um den Faktor 1000 geringeren Energieverbrauch an als für WLAN (TX: 234 bis 351 µA versus 270 bis 320 mA).

Solange BLE auf dem Chip aber noch nicht freigeschaltet ist, müssen Sie zu anderen Mikrocontrollern greifen. Ganz so günstig wie beim Pico W kommen Sie dabei nicht weg, aber mit gut 10 Euro für den oben erwähnten XIAO nRF5280 bleibt BLE trotzdem erschwinglich. Da Smartphones den Funkstandard auch beherrschen, gibt es aber auch noch andere nette Projektideen. So könnte etwa der Raspberry Pi eine Anwendung nur dann freigeben, wenn ein bestimmtes Smartphone in der Nähe ist. (jlu)

Der Autor

Bernhard Bablok arbeitet bei der Allianz Technology SE als SAP-HR Entwickler. Wenn er nicht gerade Musik hört oder mit dem Rad respektive zu Fuß unterwegs ist, beschäftigt er sich mit Themen rund um Linux, Programmierung und Kleincomputer. Sie erreichen ihn unter mailto:mail@bablokb.de.

Glossar

Bluetooth SIG

Bluetooth Special Interest Group. Interessengemeinschaft von mehr als 30 000 Unternehmen zur Entwicklung und Verbreitung der Bluetooth-Technologie.

Infos

  1. Bluetooth-Kommunikation: Bernhard Bablok, “Kommunikationsfreudig”, RPG 08/2022, S. 40, https://www.raspi-geek.de/47207

  2. Bluetooth Low Energy Primer: https://www.bluetooth.com/bluetooth-resources/the-bluetooth-low-energy-primer/

  3. Offizielle UUIDs für standardisierte Profile und Services: https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf

  4. Bleak: https://github.com/hbldh/bleak

  5. Entwicklerbereich bei Nordic Semiconductor: https://devzone.nordicsemi.com/

  6. Github-Repository zum Artikel: https://github.com/bablokb/ble-playground

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 10/2022 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben