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.