Beacon Advertising-Paket-Design und Payload-Optimierung
Jedes Bluetooth-Beacon steht oder fällt mit seinem Advertising-Paket. Das Paket ist die Stimme des Beacons — ein 31-Byte-Flüstern bei Legacy-BLE oder ein 255-Byte-Schrei bei Extended Advertising. Wie diese Bytes gepackt werden, bestimmt, ob ein Empfänger Ihren Beacon in 50 ms oder 500 ms erkennt, ob die Batterie 18 Monate oder 3 Jahre hält, und ob 200 Beacons im selben Raum ein sauberes Signal oder ein kollisionsversehrtes Chaos erzeugen.
Das Legacy 31-Byte Advertising-Paket
Ein Legacy-BLE-Advertising-Paket (BLE 4.x) hat genau 31 Byte Payload-Speicherplatz, aufgeteilt in AD-Strukturen (Advertising Data). Jede AD-Struktur verbraucht 2 Byte Overhead (Länge + Typ), was 29 Byte für tatsächliche Daten lässt — aber nur bei Verwendung einer einzigen AD-Struktur. In der Praxis benötigt man mindestens zwei:
| AD-Struktur | Typ | Zweck | Verbrauchte Bytes |
|---|---|---|---|
| Flags | 0x01 | LE General Discoverable, BR/EDR nicht unterstützt | 3 (2 Header + 1 Daten) |
| Manufacturer Specific | 0xFF | Company ID + benutzerdefinierter Payload | 2 + 2 + N |
| Complete Local Name | 0x09 | Gerätenamenszeichenkette | 2 + Namenslänge |
| TX Power Level | 0x0A | Vorzeichenbehaftetes Int8, -127 bis +127 dBm | 3 |
| Service UUID (128-bit) | 0x07 | Vollständige Liste der 128-Bit-UUIDs | 18 |
Nach Flags (3 Byte) und dem obligatorischen Manufacturer Specific Header (4 Byte für Typ+Länge+Company ID) bleiben 24 Byte für den tatsächlichen Beacon-Payload. Das ist das Budget für UUID, Major, Minor, TX-Leistung und jegliche Sensordaten. Das iBeacon-Format verwendet alle 24 Byte für UUID (16) + Major (2) + Minor (2) + TX Power (1) + reserviert (3), ohne Raum für Sensordaten.
Rahmenformat-Vergleich
| Format | Company ID | Payload-Layout | Sensordaten? | Ökosystem-Bindung |
|---|---|---|---|---|
| iBeacon | 0x004C (Apple) | UUID(16) + Major(2) + Minor(2) + TX(1) | Nein — feste 21 Byte | Nur Apple-Ökosystem |
| Eddystone-UID | 0x00AA (Google) | Namespace(10) + Instance(6) + TX(1) | Nein — feste 17 Byte | Google Nearby (eingestellt) |
| Eddystone-TLM | 0x00AA (Google) | Version(1) + Batt(2) + Temp(2) + AdvCnt(4) + SecCnt(4) | Ja — Batterie & Temp | Google-Ökosystem |
| Benutzerdefiniert (Offen) | 0xXXXX (zugewiesen) | Beliebiges Layout — Sie definieren das Schema | Ja — flexibel | Keine — eigener Empfänger |
Die praktische Empfehlung für die meisten Bereitstellungen: ein benutzerdefiniertes Rahmenformat verwenden. Man erhält volle Kontrolle über die 24 Byte, kann Sensordaten direkt in das Advertising-Paket einbetten (Vermeidung von GATT-Verbindungen) und ist nicht an ein Ökosystem gebunden, das möglicherweise eingestellt wird (wie Google 2021 mit Nearby tat).
Benutzerdefinierten Payload Entwerfen: Sensoren in 24 Byte
| Feld | Offset | Größe | Bereich / Auflösung | Beschreibung |
|---|---|---|---|---|
| Frame Version | 0 | 1 Byte | 0–255 | Protokollversion für Vorwärtskompatibilität |
| Device ID | 1 | 6 Byte | 14 Billionen IDs | Eindeutige Gerätekennung (MAC-abgeleitet) |
| Battery Level | 7 | 1 Byte | 0–100% (1% Aufl.) | Unsigned, 0xFF = nicht verfügbar |
| Temperature | 8 | 1 Byte | -40 bis +85°C (0,5°C) | Int8, raw = temp × 2 + 40 |
| Humidity | 9 | 1 Byte | 0–100% (0,4% Aufl.) | Unsigned, raw = humidity × 2,55 |
| Accelerometer | 10 | 3 Byte | ±16g (0,125g) | 3 × int8, XYZ gepackt |
| Button / Event | 13 | 1 Byte | 0–255 Ereignisse | Zähler für Tastendruck / Manipulation |
| Tamper Flag | 14 | 1 Byte | 0 = OK, 1 = manipuliert | Physischer Manipulationsstatus |
| TX Power | 15 | 1 Byte | -127 bis +127 dBm | Vorzeichenbehaftetes Int8 für RSSI@1m-Kalibrierung |
| Sequence Counter | 16 | 4 Byte | 0–4 Milliarden | Anti-Replay, Uptime-Schätzung |
| Reserved | 20 | 4 Byte | — | Zukünftige Verwendung / CRC / Erweiterung |
Codierungs-Tricks zum Komprimieren von Daten:
// Temperatur: -40 bis +85°C in 1 Byte (0,5°C Auflösung)
uint8_t encode_temp(float temp_c) {
int16_t raw = (int16_t)((temp_c + 40.0) * 2.0);
if (raw < 0) raw = 0;
if (raw > 250) raw = 250;
return (uint8_t)raw;
}
float decode_temp(uint8_t raw) {
return (raw / 2.0) - 40.0;
}
// Luftfeuchtigkeit: 0-100% in 1 Byte (0,4% Auflösung)
uint8_t encode_humidity(float rh) {
return (uint8_t)(rh * 2.55);
}
// Beschleunigungssensor: ±16g in 3 Byte (0,125g pro LSB)
void encode_accel(float x_g, float y_g, float z_g, uint8_t out[3]) {
out[0] = (uint8_t)(x_g / 0.125 + 128);
out[1] = (uint8_t)(y_g / 0.125 + 128);
out[2] = (uint8_t)(z_g / 0.125 + 128);
}
Extended Advertising: BLE 5.0 Durchbricht die 31-Byte-Barriere
BLE 5.0 führte Extended Advertising ein und erweiterte den Payload von 31 auf 255 Byte. Dies ist ein Wendepunkt für Sensor-Beacons — man kann nun vollständige Telemetrie, Multi-Sensor-Daten, verschlüsselte Payloads und sogar Firmware-Update-URLs in einem einzigen Paket ohne GATT-Verbindungen übertragen.
| Merkmal | Legacy (4.x) | Extended (5.0+) |
|---|---|---|
| Max. Payload | 31 Byte | 255 Byte |
| PHY-Optionen | Nur 1M | 1M, 2M, Coded (125k/500k) |
| Advertising-Sets | 1 | Bis zu 10 gleichzeitig |
| TX-Leistungs-Reporting | Manuell | Auto in AUX_SYNC_IND |
| RSSI-Stabilität | ±4 dB typisch | ±2 dB mit Coded PHY |
Allerdings ist die Akzeptanz begrenzt: Nur ~60 % der Smartphones unterstützen 2025 das BLE 5.0 Extended Advertising Scanning. Wenn Ihre Bereitstellung auf Consumer-Smartphones abzielt, benötigen Sie weiterhin einen Legacy-Fallback. Für Infrastruktur-Bereitstellungen (dedizierte Gateways, RTLS-Anker) ist Extended Advertising die klare Wahl.
Advertising-Intervall: Die Batterielebensdauer-Gleichung
Das Advertising-Intervall ist der einflussreichste Parameter für die Batterielebensdauer. Jedes übertragene Paket kostet Energie; das Intervall bestimmt, wie viele Pakete pro Sekunde:
// nRF52-Stromverbrauch pro Advertising-Ereignis
// (3 Kanäle × 1M PHY, 0 dBm TX)
const float TX_CURRENT_MA = 4.6;
const float TX_TIME_MS = 0.376; // 376 µs pro Kanal
const float SLEEP_CURRENT_UA = 1.5;
// Energie pro Ereignis (3 Kanäle)
float energy_per_event_uC = (TX_CURRENT_MA * 1000) * (TX_TIME_MS * 3 / 1000);
// = 5.19 µC pro Ereignis
// Durchschnittsstrom bei 100 ms (10 Ereignisse/Sek)
float avg_current_100ms_uA = (5.19 * 10) + 1.5;
// = 53.4 µA
// Durchschnittsstrom bei 1000 ms (1 Ereignis/Sek)
float avg_current_1s_uA = (5.19 * 1) + 1.5;
// = 6.69 µA
// CR2477-Batterie: 1000 mAh
// 100 ms: ~781 Tage
// 1000 ms: ~6235 Tage (theoretisch)
| Intervall | Durchschnittsstrom | CR2477 (1000 mAh) Lebensdauer | Erkennungs-Latenz | Anwendungsfall |
|---|---|---|---|---|
| 100 ms | 53,4 µA | ~26 Monate | ≤100 ms | RTLS, Echtzeit-Tracking |
| 300 ms | 18,8 µA | ~71 Monate | ≤300 ms | Einzelhandel, interaktiv |
| 1000 ms | 6,7 µA | ~6 Jahre* | ≤1 s | Asset-Tracking, Telemetrie |
| 5000 ms | 2,5 µA | ~16 Jahre* | ≤5 s | Kühlkette, stromsparend |
*Theoretisch — die Selbstentladung von CR-Batterien begrenzt die praktische Lebensdauer auf 5–7 Jahre unabhängig vom Stromverbrauch.
Die wesentliche Erkenntnis: Verdopplung des Intervalls halbiert nicht die Batterielebensdauer. Der Ruhestrom (1,5 µA) ist ein fester Boden. Bei 100 ms dominiert TX (51,9 µA vs. 1,5 µA Ruhestrom). Bei 5000 ms dominiert Ruhe (1,0 µA TX vs. 1,5 µA Ruhe). Der Schnittpunkt, bei dem TX-Strom gleich dem Ruhestrom ist, liegt bei etwa 3,5 Sekunden — darüber hinaus bringt eine weitere Intervallverlängerung abnehmende Erträge.
Kollisionswahrscheinlichkeit: Wenn Zu Viele Beacons Gleichzeitig Sprechen
In einer dichten Bereitstellung (Lager, Krankenhaus, Konferenzsaal) teilen sich Hunderte von Beacons dieselben drei Advertising-Kanäle (37, 38, 39). Jeder Beacon sendet auf allen drei Kanälen gleichzeitig. Wenn zwei Übertragungen zeitlich auf demselben Kanal überlappen, werden beide Pakete beschädigt — eine Kollision.
import math
def collision_prob(n_beacons, interval_ms, packet_time_us=376):
T = packet_time_us / 1e6
I = interval_ms / 1e3
load = n_beacons * T / I
p_collision = 1 - math.exp(-2 * load)
return p_collision
# Beispiele:
# 50 Beacons, 1000 ms: P = 3,7%
# 200 Beacons, 1000 ms: P = 14,0%
# 200 Beacons, 300 ms: P = 39,7%
# 500 Beacons, 1000 ms: P = 31,3%
| Beacons | Intervall | Kanal-Last | P(Kollision) | P(Empfang beim 1. Scan)* |
|---|---|---|---|---|
| 50 | 1000 ms | 1,9% | 3,7% | 96,3% |
| 200 | 1000 ms | 7,5% | 14,0% | 86,0% |
| 200 | 300 ms | 25,1% | 39,7% | 60,3% |
| 500 | 1000 ms | 18,8% | 31,3% | 68,7% |
| 500 | 300 ms | 62,7% | 71,5% | 28,5% |
*Wahrscheinlichkeit, während eines 1-Sekunden-Scan-Fensters mindestens ein sauberes Paket zu empfangen.
Minderungsstrategien für dichte Bereitstellungen:
- Zufälliger Jitter: ±20% zufälligen Jitter zum Intervall jedes Beacons hinzufügen. Dies dekorreliert die Sendezeit und bricht periodische Kollisionsmuster. Reduziert P(Kollision) in der Praxis um 30–50%.
- Adaptives Intervall: Beacons erkennen Stauung (durch Zählen empfangener Pakete von Nachbarn) und ziehen sich zurück. Ähnlich CSMA/CA, aber für verbindungsloses Advertising.
- Kanal-Präferenz: Einige Implementierungen überspringen Kanal 37 (am stärksten durch Wi-Fi-Kanal-1-Überlappung belastet) und advertise nur auf 38+39. Reduziert Wi-Fi-Interferenz auf Kosten der Erkennungswahrscheinlichkeit.
- Extended Advertising: BLE 5.0-Sekundärkanäle arbeiten auf einem von 37 Datenkanälen und verteilen die Last viel dünner als die 3 Primärkanäle.
Mehr Rahmen-Advertising: Payload-Rotation
Wenn mehr Daten gesendet werden müssen, als in ein einziges 31-Byte-Paket passen (Legacy), oder Erkennungslatenz mit Telemetrie-Aktualität ausbalanciert werden soll, wird Rahmenrotation verwendet. Der Beacon durchläuft verschiedene Rahmentypen bei aufeinanderfolgenden Advertising-Ereignissen:
| Slot | Rahmentyp | Inhalt | Zweck |
|---|---|---|---|
| 1 (jedes Ereignis) | Identität | Device ID + TX + seq | Schnelle Erkennung, RSSI-Ranging |
| 2 (jedes 3.) | Telemetrie | Batterie + Temp + Feuchte | Umweltüberwachung |
| 3 (jedes 10.) | Beschleunigung | XYZ + Ereigniszähler + Manipulation | Bewegungs-/Stoßerkennung |
| 4 (jedes 30.) | Info | FW-Version + Config-Hash | OTA-Verwaltung, Flotten-Audit |
Bei einem Basisintervall von 1000 ms wird der Identitätsrahmen jede Sekunde, Telemetrie alle 3 Sekunden, Beschleunigung alle 10 Sekunden und Info alle 30 Sekunden gesendet. Ein Scanner, der 3 Sekunden lauscht, erfasst Identität und Telemetrie; ein 10-Sekunden-Scan erfasst alles außer dem Info-Rahmen. Dieser Ansatz multiplext effektiv 4 logische Beacons auf ein einziges physisches Gerät mit minimalem Batterie-Overhead.
Fazit
Advertising-Paket-Design ist die Engineering-Entscheidung mit dem größten Hebel in einer Beacon-Bereitstellung. Ein gut gestalteter Payload eliminiert GATT-Verbindungen, reduziert die Scanner-Verweildauer und verlängert die Batterielebensdauer um Größenordnungen. Die Prinzipien sind einfach: Identität und Telemetrie in den kleinstmöglichen Raum packen, Rahmenrotation für Überlauf verwenden, Jitter hinzufügen, um dichte Bereitstellungen zu überstehen, und das Intervall wählen, das zum Latenzbudget passt — nicht schneller.
Für die meisten Asset-Tracking- und Umweltüberwachungs-Bereitstellungen ist der optimale Punkt ein benutzerdefinierter 24-Byte-Legacy-Rahmen bei 1000 ms Intervall mit ±20% Jitter und 4-Slot-Rahmenrotation. Diese Konfiguration liefert 6-Sekunden-Erkennungslatenz (99. Perzentil), 5+ Jahre Batterielebensdauer mit CR2477 und Kollisionsraten unter 5% bis zu 200 Beacons pro Zone — Zahlen, die keine Standard-iBeacon-Konfiguration erreichen kann.
BLE-Beacons sind nur so effektiv wie die Bytes, die sie senden. Entwerfen Sie das Paket, bevor Sie die Bereitstellung entwerfen.