如何使用树莓派(Python/HCI)广播Eddystone UID及解析格式
Hey there! Nice work getting Eddystone URL broadcasts up and running on your Pi already—let’s tackle the UID format specs and walk through how to implement that, either via command-line HCI tools or Python.
First: The Critical Eddystone UID Format Specs
Eddystone UID is a BLE non-connectable broadcast frame, and its structure is strict—mess up a byte length or order, and receivers won’t recognize it. Here’s the breakdown of the core service data payload (this is the part that makes it an Eddystone UID):
Service Data Structure for Eddystone UID
- AD Length:
0x16(22 total bytes for the service data section)- AD Type:
0x16(marks this as Service Data)- Service UUID:
0xFEAA(Google’s Eddystone UUID, sent as little-endian:0xAA 0xFE)- Frame Type:
0x00(tells receivers this is a UID frame, not URL or TLM)- Ranging Data: 1 byte (calibrated RSSI at 1 meter from the beacon; use
0x00if you don’t have a measured value, or input the absolute value of your 1m RSSI—e.g.,-55dBmbecomes0x37)- Namespace ID: 10 hex bytes (a unique, fixed value for your organization/use case—use a UUID prefix or custom unique string)
- Instance ID: 6 hex bytes (unique per device in your namespace, to distinguish beacons)
- RFU: 2 bytes (reserved for future use, always set to
0x00 0x00)
Key Rules: No hyphens in hex values, and lengths are non-negotiable (10 bytes for Namespace, 6 for Instance).
Option 1: Implement with HCI Command-Line Tools
This is great for quick testing without writing code. We’ll use hcitool and bluetoothctl (both pre-installed on Raspberry Pi OS).
Using hcitool
First, stop any existing BLE advertising:
sudo hciconfig hci0 noleadvConstruct your UID payload. Let’s use example values:
- Namespace:
00112233445566778899 - Instance:
AABBCCDDEEFF - Ranging Data:
0xEE(represents-18dBmat 1m)
The full broadcast command combines flags (to make the beacon discoverable) and the Eddystone UID service data:
sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 06 16 16 FE AA 00 EE 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 00 00- Namespace:
Start advertising:
sudo hciconfig hci0 leadv 3
Using bluetoothctl (Modern Alternative)
- Launch the tool:
bluetoothctl - Inside the interactive shell:
- Stop existing ads:
advertise off - Set to non-connectable mode:
advertise type non-connectable - Load your Eddystone UID payload (replace the hex string with your Namespace/Instance):
advertise service-data 0xFEAA 00EE00112233445566778899AABBCCDDEEFF0000 - Start broadcasting:
advertise on
- Stop existing ads:
Option 2: Implement with Python (Using bluepy)
For integrating UID broadcasting into a larger Python project, bluepy is a solid BLE library.
- Install the library first:
sudo pip3 install bluepy - Create a script (e.g.,
eddystone_uid.py) with this code:from bluepy.btle import Advertisement, Advertiser class EddystoneUIDAdvertisement(Advertisement): def __init__(self, namespace_id, instance_id, rssi=-18): super().__init__(advType=Advertisement.NON_CONNECTABLE) # Add required flags for discoverability self.addFlags(Advertisement.FLAG_GENERAL | Advertisement.FLAG_BREDR_NOT_SUPPORTED) # Build the Eddystone UID service data payload uid_payload = ( bytes([0x00]) + # Frame Type: UID bytes([abs(rssi)]) + # Ranging Data (1m RSSI absolute value) bytes.fromhex(namespace_id) + # 10-byte Namespace bytes.fromhex(instance_id) + # 6-byte Instance bytes([0x00, 0x00]) # Reserved RFU bytes ) self.addServiceData("feaa", uid_payload) if __name__ == "__main__": # Replace these with your custom Namespace and Instance IDs MY_NAMESPACE = "00112233445566778899" MY_INSTANCE = "AABBCCDDEEFF" try: adv = EddystoneUIDAdvertisement(MY_NAMESPACE, MY_INSTANCE) advertiser = Advertiser() advertiser.startAdvertising(adv, interval=1000) print("Broadcasting Eddystone UID... Press Ctrl+C to stop.") while True: pass except KeyboardInterrupt: advertiser.stopAdvertising() print("\nStopped broadcasting.") - Run the script with sudo (for BLE permissions):
sudo python3 eddystone_uid.py
Quick Troubleshooting Tips
- Make sure your Pi’s Bluetooth is enabled:
sudo systemctl start bluetooth - If you get permission errors with Python, run
sudo setcap 'cap_net_raw,cap_net_admin+eip' /usr/local/lib/python3.x/site-packages/bluepy/bluepy-helper(replacepython3.xwith your installed version) - Use a BLE scanner app (like nRF Connect) on your phone to verify the UID is being broadcast correctly
内容的提问来源于stack exchange,提问作者sanil mendonca

