Protocol Overview
This page explains the conceptual architecture of the Huepar S120 Bluetooth Low Energy (BLE) protocol.
Architecture
Section titled “Architecture”The S120 uses a simple request-response protocol over BLE GATT:
┌─────────────┐ BLE ┌─────────────┐│ Mobile App │ ◄──────────────────► │ S120 ││ (Client) │ │ (Server) │└─────────────┘ └─────────────┘ │ │ │ 1. Write command to 0xAE01 │ │ ───────────────────────────────────► │ │ │ 2. Receive response on 0xAE02 │ │ ◄─────────────────────────────────── │ (notify) or 0xAE05 (indicate) │Protocol Layers
Section titled “Protocol Layers”Transport Layer: BLE GATT
Section titled “Transport Layer: BLE GATT”The device exposes a custom GATT service (0xAE30) with three characteristics:
| Characteristic | Direction | Purpose |
|---|---|---|
| 0xAE01 | App → Device | Command transmission (write-without-response) |
| 0xAE02 | Device → App | Measurement data (notify) |
| 0xAE05 | Device → App | Status/errors (indicate) |
Application Layer: LDMv1
Section titled “Application Layer: LDMv1”All commands follow the LDMv1 (Laser Distance Meter version 1) format:
┌────────┬──────────┬──────────┬──────────┐│ Header │ Command │ Payload │ Checksum ││ 0xF1 │ 1 byte │ 0-N bytes│ 1 byte │└────────┴──────────┴──────────┴──────────┘Checksum calculation:
checksum = sum(packet[1:]) % 256 # Skip the F1 headerWhy This Design?
Section titled “Why This Design?”- No pairing required - Reduces friction for connecting
- Simple checksum - Easy to implement on microcontrollers
- Notification-based responses - Allows async measurement updates
- Separate channels - Data (0xAE02) vs status (0xAE05) isolation
Connection Flow
Section titled “Connection Flow”1. Scan for "LDM-S120 *" devices │ ▼2. Trust the device (required on Linux/BlueZ) │ ▼3. Connect to GATT │ ▼4. Enable notifications on 0xAE02 and 0xAE05 │ ▼5. Send commands to 0xAE01 │ ▼6. Process responses from notificationsMeasurement Flow
Section titled “Measurement Flow”When you trigger a measurement:
1. App sends: F1 00 00 F1 (CLICK_MEASURE_BUTTON) │ ▼2. Device laser activates │ ▼3. Device measures distance │ ▼4. Device sends response on 0xAE02: F1 01 00 <length> <mode> <unit> <flags> <value...> <checksum> │ ▼5. App parses value and displays to userData Encoding
Section titled “Data Encoding”Distance Values
Section titled “Distance Values”Distances are encoded as 16-bit big-endian integers in millimeters:
Value bytes: 0x01 0x2C ──────── │ │ │ └─ Low byte: 0x2C = 44 └────── High byte: 0x01 = 256
Result: 256 + 44 = 300 mm = 0.300 mString Data
Section titled “String Data”Strings (like MAC addresses, firmware versions) are ASCII-encoded with a length prefix:
Response: F1 03 00 0C 35 62 61 36 ... ── ───────────── │ │ │ └─ ASCII: "5ba6..." └───── Length: 12 bytesError Handling
Section titled “Error Handling”Errors are reported on the indicate characteristic (0xAE05):
| Error | Meaning |
|---|---|
Err 1 | Target too far |
Err 2 | Target too close |
Err 3 | Excessive ambient light |
Err 4 | Out of measurement range |
The app should always subscribe to both 0xAE02 (data) and 0xAE05 (errors) to handle all device responses.
Protocol Versioning
Section titled “Protocol Versioning”The “LDMv1” designation comes from the APK code. The app also contains code for:
- LaserLevelV1/V2/V3 - Cross-line laser protocols
- LDMv2 - Potentially future devices
Each protocol variant uses different service UUIDs, allowing the app to auto-detect device types during scanning.
Next Steps
Section titled “Next Steps”- BLE Service Reference - Detailed GATT characteristics
- Command Reference - All available commands
- Connecting Guide - Practical connection instructions