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 abonnieren, was dazu führt, dass der Client für jede Änderung in der Herzrate eine Nachricht erhält.

Wie man auf Charakteristiken zugreifen kann, regeln die Properties, also Eigenschaften der Charakteristik:

Propertie Erläuterung
Write without response Schreiben einer Charakteristik (Client überträgt Daten an das Peripheral). Die Charakteristik hat hinterher den Wert, welcher vom Client gesendet wurde.
Write Wie „write without response“, nur dass in diesem Fall das Peripheral die Antwort quittieren muss. Der BLE Stack reicht die Nachricht an die Applikation des Peripherals weiter, diese muss die Nachricht bestätigen. Anschließend wird die Antwort gesendet. Der Client kann keinen weiteren Wert schreiben bevor, er die Antwort nicht erhalten hat.
Notification Charakteristiken mit dieser Propertie können vom Client abonniert werden. Anschließend sendet der Server eine Nachricht an den Client, wann immer sich der Wert der Charakteristik ändert (oder einfach in bestimmten Intervallen).
Indication Wie Notification, aber mit dem Unterschied, dass Indications bestätigt werden müssen bevor eine neue Indication gesendet werden kann. Der Unterschied zwischen Notification und Indication verhält sich damit ähnlich wie der Unterschied zwischen write und write without respons. Nur eben anders herum.
Read Lesen einer Charakteristik. Der Client sendet eine Anfrage an den Server, dieser antwortet anschließend mit dem aktuellen Wert der Charakteristik.

Um Latenzen zu reduzieren macht es Sinn, die korrekten Properties auszuwählen.

In der Regel fährt man mit write without response für Übertragungen von Client zu Server, sowie notifications für Übertragungen von Server zu Client am besten.

Da diese Properties nicht bestätigt werden müssen, können die entsprechenden Aktivitäten deutlich schneller hintereinander ausgeführt werden. Wie ja schon erwähnt gehen BLE Nachrichten auch ohne Response nicht einfach verloren.  Write und Indications bieten lediglich eine Möglichkeit auf einer höheren Ebene als dem Link Layer unberechtigte oder falsche Zugriffe abzulehnen (Beispiel: Client schreibt einen ungültigen Wert in die Characteristik). Für die Absicherung der BLE Übertragung bringt der Vorgang keine weitere Sicherheit.

Übertragung von unnötigen Daten vermeiden

Wie beschrieben, werden BLE Pakete so lange erneut übertragen, bis diese angekommen sind oder die Verbindung beendet wird. So etwas wie eine maximale Anzahl an Retransmissions ist im BLE Standard nicht vorgesehen. Das ist gut, wenn man sicher gehen will, dass alle Informationen die man senden möchte auch auf der Gegenstelle ankommen. Auf der anderen Seite blockieren Retransmission neue Übertragungen, da es keine Möglichkeit gibt Nachrichten zu priorisieren. In einer gestörten Verbindung kann es durchaus zu mehreren Retransmissions einer Nachricht kommen. Sendet man in so einer Umgebung mit zu hoher Datenrate, stauen sich irgendwann die Nachrichten und es kommt der Punkt, an dem der BLE Stack die Annahme von weiteren Nachrichten ablehnt.

Es empfiehlt sich daher in Sicherheitskritischen Bereichen wirklich nur die unbedingt notwendigen Nachrichten zu senden.

So vermeidet man, dass wichtige Nachrichten auf unwichtige warten müssen.

Viele BLE Stacks bieten zudem eine Möglichkeit, die Anzahl der maximalen Elemente in den Queues für Notification und Write Prozesse zu konfigurieren. In der Regel sind Daten, die einmal an den BLE Stack übergeben wurden, nicht mehr zu stoppen. Würde man die Queue also zu groß wählen, könnten sich in gestörten Umgebungen große Mengen an Daten im Stack anstauen. Daher empfiehlt sich oft ein niedriger Wert, so dass der BLE Stack in gestörten Umgebungen früh anfängt Nachrichten abzulehnen. Wenn dies geschieht können die abgelehnten Nachrichten auf Anwendungseben zurückgehalten werden und durch aktuellere oder höher priorisierte Nachrichten ersetzt werden.

Außerdem empfiehlt es sich die Nachrichten so kurz wie möglich zu halten.

In einem BLE Paket können mehrere Nachrichten enthalten sein. So kann der BLE Stack mehrere Elemente seiner Queue auf einmal versenden. Andererseits können sich Nachrichten auch über mehrere Pakete erstrecken. Kommt es dabei zu Retransmissions eines oder mehrerer Pakete kann die Übertragung sehr lange dauern.

Retransmissions reduzieren (Bluetooth 5)

Wenn man auf Protokollebene und mit Hilfe korrekter Bluetooth Parameter bereits die Latenzen optimiert hat, wird es trotzdem immer wieder vorkommen, das Pakete verzögert ankommen. Schuld daran sind die Retransmissions die man niemals ganz ausschließen kann. Was kann man dagegen tun? Insgesamt sind die Möglichkeiten hierzu nicht sehr vielseitig. Seit Bluetooth 5.0 hat man aber zumindest diese beiden Möglichkeiten:

Möglichkeit 1: Adaptive Frequency Hopping.

BLE verwendet seit Bluetooth 4.0 grundsätzlich Frequency Hopping. Jeder CI findet auf einem anderen Frequenzband statt. Das Muster, nach dem die Geräte auf den Frequenzen springen wird pseudo-zufällig bei jeder neuen Verbindung festgelegt (berechnet sich unter anderem aus den Bluetooth Adressen von Central und Peripheral). Bluetooth 5.0 fügt ein so genanntes adaptive Frequency hopping hinzu. Hierbei monitored der BLE Stack kontinuierlich die Frequenzen auf denen er kommuniziert. Kommt es auf einem der Frequenzbänder zu einer Störung, wird dieses Band vorübergehend deaktiviert. Der Central erstellt so immer wieder eine neue Channel Map und überträgt diese nach jedem Update an das Peripheral. Das ist ziemlich praktisch, allerdings gibt es ein entscheidendes Problem: Viele Hersteller von BLE Stacks unterstützen kein Adaptive Frequency Hopping. Die Nordic Soft Devices z.B. können dies nicht und erfassen auch gleichzeitig keine Informationen, um etwas entsprechendes selber zu implementieren. Silicon Labs hingegen unterstützt das Feature seit Bluetooth SDK Version 2.10.

Möglichkeit 2: Auswahl des korrekten PHYs.

PHY steht hier für den physikalische Layer von BLE, beschreibt also den untersten Layer der BLE Architektur der für das Versenden und Empfangen von BLE Paketen zuständig ist. In der Regel arbeitet der Layer dabei mit einer Bitrate von 1 MHz. Seit Bluetooth 5.0 sind folgende Einstellungen hinzugekommen:

  • 2 MHz
  • Coded PHY 500 kHz
  • Coded PHY 125 kHz

Während die schnellere Einstellung vor allem dazu genutzt werden kann die Datenrate hochzukurbeln, sind die beiden langsameren Einstellungen vor allem für eine höhere Reichweite gedacht. Jetzt könnte man denken „schneller ist immer besser!“. Das Problem dabei ist allerdings das die Reichweite bei dieser Einstellung deutlich reduziert wird. Aus diesem Grund sinkt zwar die minimale Latenz (zumindest etwas), die maximale Latenz steigt allerdings. Meiner Meinung macht dieses Feature Sinn für FW Updates (wofür es auch gedacht ist). In sicherheitskritischen Bereichen würde ich es nicht unbedingt empfehlen. Interessanter sind tatsächlich die langsameren Einstellungen (Coded Phy). Hier wird die Nachricht nicht einfach langsamer gesendet, sondern (fast) jedes Bit wird tatsächlich mehrfach (bei 125 kHz 8 mal) gesendet. Dadurch erhält der Empfänger mehr Möglichkeiten zur Fehlerkorrektur, wodurch Retransmissions vermieden werden und die Wahrscheinlichkeit für sehr hohe Latenzen deutlich geringer wird. Auch hier ist aber wieder das Problem einen Stack Hersteller zu finden, der alle Einstellungen unterstützt. Während das Silicon Labs SDK alle Einstellungen unterstützt, können die Nordic Sofdevices zwar auf allen Einstellungen empfangen aber nur auf 125 kHz senden. Das ist schade, schließlich steigt der Stromverbrauch bei 125 kHz deutlich da ja jedes Bit 8 mal übertragen und empfangen werden muss. Gleichzeitig wird auch die Datenrate deutlich geringer. Die Einstellung eignet sich also nur dann, wenn man wirklich sehr geringe Datenmengen versenden will. Im Vergleich dazu bietet 500 kHz Coded Phy einen guten trade off.

Und was wenn ich immer noch gelegentlich hohe Latenzen messe?

Wie bereits erwähnt kann ich eine maximale Latenz zwar über einen längeren Zeitraum messen, aber niemals garantieren. Erhöht sich der Abstand zwischen 2 Geräten oder kommt es zu Störungen auf dem 2,4 GHz Band, steigt die maximale Latenz. In Sicherheitskritischen Bereichen ist es daher sinnvoll Maßnahmen auf Applikationsebene zu implementieren, die zumindest Störungen erkennen. Im oben beschriebenen Beispiel mit dem Defibrillator, würde es Sinn machen den Zustand des Schockknopfs in regelmäßigen Intervallen zu versenden. Kommen die Nachrichten regelmäßig an weiß der Defibrillator das alles in Ordnung und der Knopf nicht gedrückt ist. Falls die Nachrichten für längere Zeit ausbleiben, kann der Defibrillator zumindest den Nutzer alarmieren. Grundsätzlich sollte man immer ein Back Up für das angebundene BLE Gerät haben. Im Fall des Defibrillators kann dies z.B. ein zusätzlicher Schockknopf direkt am Gerät sein.

Und was sind die Nachteile?

Auf Latenz optimierte Verbindungen sind nicht unbedingt optimiert auf Datendurchsatz. Verwendet man z.B. Coded PHY leided immer die Datenrate darunter. Auch der CI muss für schnellen Datendurchsatz in der Regel nicht auf 7,5 ms eingestellt werden. Oft ist es besser lange Intervalle zu wählen, damit während einem Datenstream, die Verbindung nicht dauernd auf und wieder abgebaut wird. Für Vorgänge bei denen hohe Datenraten benötigt werden, muss ggf. ein zusätzlicher Modus implementiert werden, in dem man die Verbindung stärker auf Datendurchsatz optimiert. Zum Glück lassen sich alle BLE Parameter während einer bestehenden Verbindung ändern.

Ebenfalls sollte man beachten, das auf Latenz optimierte Verbindungen einen hohen Stromverbrauch bedeuten können. Geringe CI und SL Parameter sowie Coded PHY wirken sich allesamt negativ auf den Stromverbrauch aus.

Kontaktieren Sie uns!

Autor

  • Björn Schmitz

    Seit Juli 2017 gehöre ich zum MEDtech-Ingenieur Team und bin hier vor allem als Firmwareentwickler tätig. Schon in kürzester Zeit konnte ich an vielen spannenden Projekten aus dem Bereich Medizintechnik, aber auch aus anderen Bereichen mitwirken.

Auch interessant:

Holen Sie sich die Arbeitshilfe “Isolationsdiagramme nach 60601-1”!

In dem Buch erfahren Sie, wie man praxisorientiert Isolationsdiagramme für medizinische elektrische Geräte nach 60601-1 erstellt. Außerdem beinhaltet das Buch: Viele interessante Beispiele Erklärung der Norm-Symbole Theorie (Definition der Begrifflichkeiten) Quiz zur Abfrage des Erlernten [caption id="attachment_7047" align="aligncenter" width="204"]Arbeitshilfe "Isolationsdiagramme nach 60601-1"[/caption] Bitte machen Sie einige Angaben, um den Link…
Getagged mit: , , , ,