Niedrige Latenzen mit Bluetooth Low Energy

Bluetooth Low Energy (BLE) hat sich in den letzten Jahren zu dem Kommunikationsstandard für stromsparende kabellose Kommunikation entwickelt. In den Anfangszeiten war BLE vor allem in Consumer-Anwendungen vertreten. Wir haben in vergangenen Projekten allerdings festgestellt, das BLE inzwischen auch in der Welt der Medizinprodukte angekommen ist. Der Einsatz bei körpernaher Sensorik liegt nahe, da bei den hier verwendeten Sensorknoten meistens Batterielaufzeit entscheidend ist. Wir haben allerdings festgestellt, dass auch zunehmend kritischere Signale über BLE übertragen werden. Oft ist dabei ein Parameter besonders im Fokus: Die Latenz. Wenn ich in diesem Artikel von Latenz spreche meine ich den zeitlichen Abstand zwischen dem ersten Versuch einer Übertragung (das Übergeben der Nachricht an den BLE Stack), zum Empfangen der Nachricht beim Verbindungspartner (Übergabe der Nachricht vom BLE Stack an die Applikation).

Dieser Artikel bespricht:

  • Wodurch entstehen Latenzen bei der BLE Kommunikation?
  • Welche Parameter haben Einfluss auf die Latenz?
  • Welche Latenz kann ich mit BLE erreichen?
  • Welche Nachteile hat eine auf Latenz optimierte BLE Kommunikation?
  • Wie gehe ich mit Latenzen in Sicherheitskritischen Bereichen um?

Wer noch nicht viel Erfahrung mit dem Thema BLE hat, dem empfehle ich einen Blick in einen älteren Blog-Artikel von mir:

https://medtech-ingenieur.de/ble-ein-kurze-einstiegshilfe-in-die-welt-von-bluetooth-low-energy/

Hier werden einige Grundlagen zu BLE besprochen. Da wir in diesem Artikel tief in BLE einsteigen empfiehlt es sich, sich vorher mit den Grundlagen vertraut zu machen.

Da das Thema Latenz doch etwas komplex ist, ist dieser Artikel ziemlich lang geraten. Ich habe daher versucht die wichtigsten Punkte hervorzuheben. Wer also wenig Zeit hat kann sich zunächst auf die hervorgehobenen Texte fokussieren.

Wer allerdings verstehen möchte warum eine bestimmte Einstellung getroffen werden sollte, dem bleibt leider nichts anderes übrig als den ganzen Artikel zu lesen.

Warum sollte ich mich überhaupt mit der Latenz von BLE Verbindungen beschäftigen?

Ich kenne viele sehr interessante Artikel die sich eingehend mit dem Thema Datendurchsatz bei BLE beschäftigen. Ich kenne allerdings wenig Artikel, die sich mit der Optimierung von Latenzen beschäftigen. Eine optimierte Latenz führt nicht unbedingt zu einer hohen Datenrate und andersherum. Gerade in sicherheitskritischen Bereichen wie der Medizintechnik werden zum Teil wenig Daten übertragen. Dafür ist oft die Zeit mit der eine einzige Nachricht übertragen wird entscheidend. Stellen wir uns folgendes (zugegebenermaßen sehr weit hergeholte) Szenario vor:

Ein Defibrillator soll über eine kabellose Fernbedienung gesteuert werden. Die Fernbedienung hat einen Knopf, mit dessen Hilfe der behandelnde Arzt einen Schock auslösen kann. Der Knopf soll natürlich nur freigeschaltet werden, wenn der Defibrillator einen schockbaren Rhythmus im EKG erkennt. Um den Nutzer dies zu signalisieren, wird eine LED verwendet die dem Nutzer anzeigt, wann der Knopf aktiv ist.

Entscheidend ist, dass bei dieser Anwendung nicht das ganze EKG, inklusive aller Rohdaten, an die Fernbedienung übertragen werden muss. Eine hohe Datenrate ist von Defibrillator zu Fernbedienung also nicht erforderlich. Die Fernbedienung benötigt lediglich die Information, dass sie die LED an oder ausschalten muss. In der anderen Richtung muss die Fernbedienung dem Defibrillator nur die Information “Knopf wurde gedrückt” senden. Diese Information ist nicht sehr komplex und benötigt daher ebenfalls keine hohe Datenrate. In beiden Fällen spielt jedoch die Latenz eine große Rolle. Verzögert sich eine der beiden Informationen, wird die Behandlung des Patienten hinausgezögert, wodurch wichtige Zeit verstreicht. Wie schon erwähnt ist das beschriebene Beispiel nicht unbedingt sinnvoll, sondern soll nur erläutern, warum Latenz manchmal wichtiger als Datenrate ist.

Wodurch Latenzen bei BLE entstehen…

Um zu verstehen, wo das Problem bei BLE und Latenz liegt, sollten wir uns zunächst anschauen, was BLE überhaut “low energy” macht. Im Unterschied zum klassischen Bluetooth sind BLE Verbindungen niemals “konstant offen”. Es handelt sich also nicht um einen konstanten Datenstrom zwischen A und B. Anstatt dessen bauen A und B in bestimmten Intervallen ihre Verbindung auf und wieder ab. Diese Intervalle sind die sogenannten “Connection Intervals” (CI).

Innerhalb eines CIs haben Central und Peripheral die Möglichkeit Daten auszutauschen. Selbst wenn keine Daten ausgetauscht werden sollen, senden Central und Peripheral immer mindestens ein leeres Paket, um dem gegenüber zu signalisieren, dass Sie noch da sind. Hat keiner der beiden Partner noch etwas zu sagen, wird die Kommunikation bis zum Ende des CIs beendet. In diesem Fall müssen beide bis zum nächsten CI warten, bis Sie wieder Daten senden können. Durch das Abbauen der Verbindung wird der Stromverbrauch von BLE deutlich reduziert. Gleichzeitig bedeutet dieses Verhalten jedoch, dass man immer mindestens mit einem CI Latenz rechnen muss. Nehmen wir beim oben beschriebenen Beispiel an, das zu Beginn eines CIs ein schockbarer Rhythmus erkannt wird. Der Defibrillator möchte daher so schnell wie möglich den Befehl senden, die LED an der Fernbedienung zu aktivieren. Wurde die Verbindung allerdings bereits vom Central beendet, muss der Defibrillator mindestens einen CI warten, bis er senden kann. CIs sind konfigurierbar für jede Verbindung, können allerdings nicht weniger als 7,5 ms betragen.

Mit einer minimalen Latenz von 7,5 ms muss man daher in jedem Fall rechnen!

Außerdem sollte man noch wissen, dass BLE Nachrichten in gestörten Umgebungen nicht einfach so verloren gehen. Werden Pakete durch die Übertragung beschädigt, oder kommen diese gar nicht an, werden die Pakete grundsätzlich erneut übertragen. Dies findet in den untern Layern der BLE Architektur (Link Layer) statt. Es werden also dabei keine Nachrichten wiederholt sondern die physikalischen Pakete. Diese werden so lange erneut übertragen, bis sie entweder erfolgreich angekommen sind, oder die Verbindung durch einen der beiden Teilnehmer unterbrochen wird. Das Problem dabei: Kommt es zu einer Störung werden keine Daten mehr ausgetauscht bis zum nächsten CI. Durch das BLE Frequency Hopping Verfahren (mehr dazu weiter unten im Artikel), findet zwar jedes CI auf einer anderen Frequenz statt, so dass die Wahrscheinlichkeit recht hoch ist, dass ein Paket irgendwann auch ankommt, in der Praxis kommt es allerdings immer wieder zu mehreren Retransmissions hintereinander. Aus diesem Grund können Nachrichten gleich um mehrere CIs verzögert sein. Bei zwei Retransmissions kann man davon ausgehen das es 3 CIs braucht (also 22,5 ms) bis die Nachricht empfangen wird. Auf Grund der Retransmissions lässt sich also sagen:

Wenn wir bei BLE über Latenz reden dann handelt es sich lediglich um die minimale Latenz. Die Garantie, unter einer maximalen Latenz zu bleiben, gibt es nicht. Es lässt sich lediglich die Wahrscheinlichkeit reduzieren, dass hohe Latenzen entstehen.   

Das ist etwas ernüchternd, ich werde aber in den kommenden Kapiteln darauf eingehen wie man zumindest die minimale und durchschnittliche Latenz so gering wie möglich halten kann.

Wie lässt sich die Latenz optimieren?

Der Connection Interval

Wie oben beschrieben bestimmt der CI maßgeblich die minimale Latenz der Verbindung.

Sofern es die genutzte Hardware, sowie der BLE Stack erlaubt, sollte man den Connection Interval der Verbindung auf 7,5 ms setzen.

Auf Smartphones beispielsweise, ist der kleinste CI in der Regel deutlich höher als 7,5 ms.

Slave Latency

Ein weiterer entscheidender Parameter ist die sogenannte Slave Latency (SL). Diese bestimmt eine Zahl von CIs, während der sich der Peripheral nicht beim Central melden muss, bevor der Central ein Problem annimmt. Grundsätzlich macht die Nutzung der SL dann Sinn, wenn ein geringer Stromverbrauch wichtig ist (also eigentlich immer).  Im vorherigen Kapitel wurde der Austausch von Paketen bei BLE beschrieben. Bei einer Slave Latency von 2, würde man, im Fall, dass es keine Daten zum Austausch gibt, folgende Kommunikation beobachten:

In diesem Fall muss der Peripheral in zwei aufeinanderfolgenden CIs weder Daten senden, noch empfangen. Hierdurch ergibt sich ein enormes Stromsparpotential. Vor allem, wenn SL sehr hoch gewählt wird. Allerdings muss man in diesem Fall bei der Latenz von Central zu Peripheral bis zu 3 CIs annehmen. Schließlich kann es ja immer sein, dass das Peripheral gerade nichts zu sagen hat und daher 2 Verbindungen aussetzt. Man sollte allerdings erwähnen, dass ein Peripheral immer Daten senden kann, wann es möchte. Die Latenz verschlechtert sich daher nur in eine Richtung.

Man kann sich also Merken:

Hat man hohe Anforderung an die Latenz von Central zu Peripheral sollte man die Slave Latency auf null setzten.

Sind die Anforderungen an die Latenz von Central zu Peripheral nicht so hoch, macht die Nutzung der SL allerdings Sinn. Außerdem: SL kann natürlich auch dynamisch angepasst werden. So kann man für gewisse Situationen, in denen keine (sicherheitskritische) Datenübertragung von Central zu Peripheral zu erwarten ist, die SL hochsetzen, um Strom zu sparen.

Protokollebene

Neben Central und Peripheral, gibt es bei BLE die Einteilung in Client und Server. Das Central übernimmt dabei meisten (aber nicht immer) die Rolle des Clients, während das Peripheral die Serverrolle übernimmt. Der Server definiert im GATT (Generic Attribute Profile) Layer Services, auf die der Client zugreifen kann. Den GATT Layer komplett zu erklären würde den Rahmen dieses Artikels sprengen. Ganz gut beschrieben wird das zum Beispiel hier:

https://learn.adafruit.com/introduction-to-bluetooth-low-energy/gatt

Um das ganze etwas zusammenzufassen: GATT bestimmt, wie BLE Geräte miteinander kommunizieren, schließlich handelt es sich um das Kommunikationsprofil von BLE. Ähnlich tut es z.B. auch das etwas bekanntere SPP (serial port profile), auch wenn dieses komplett anders funktioniert. Bei BLE findet der Datenaustausch über sogenannte Services statt. Diese haben Charakteristiken die wiederum Properties haben. Services sind Gruppen von Charakteristiken. Charakteristiken sind vereinfacht ausgedrückt Datenfelder des Servers. Als Beispiel, der Heart Rate Service hat eine Heart Rate Measurement Charakteristik, sowie eine Body Sensor Location Charakteristik (und noch weitere die ich daher an dieser Stelle nicht erwähnen werde). Durch Lesen der Heart Rate Measurement Charakteristik erhält man die Herzrate. Durch Lesen der Body Sensor Location Charakteristik erhält man den Ort, an dem der Sensor getragen werden soll (Ist das Gerät z.B. ein Brustgurt oder eine Uhr). Die Herzrate lässt sich außerdem ab