Response Reference
This page documents the response packet formats received from the S120 device.
Response Overview
Section titled “Response Overview”Responses arrive via BLE notifications on two characteristics:
| Characteristic | Purpose | Type |
|---|---|---|
| 0xAE02 | Measurement data, device info | Notify |
| 0xAE05 | Errors, status updates | Indicate |
Response Prefixes
Section titled “Response Prefixes”| Prefix | Category | Description |
|---|---|---|
F1 01 01 | ACK | Continuous measure started |
F1 02 01 | Data | Single measurement data |
F1 02 02 | Data | Angle data |
F1 02 04 | Data | Continuous measurement data |
F1 03 00 | Info | MAC address |
F1 03 01 | Info | History record |
F1 03 02 | Info | Device version (JSON) |
F1 04 01 | Result | Measurement result |
F1 04 02 | Status | Status update |
F1 04 04 | History | History data |
F1 04 05 | Error | Error notification |
F1 04 06 | Warning | Warning notification |
F1 05 01 | Error | Device error event |
MAC Address Response
Section titled “MAC Address Response”Command: GET_DEVICE_MAC (F1 03 02 05)
Response format:
f1 03 00 LL DD DD DD DD DD DD DD DD DD DD DD DD CS CS│ │ │ │ └──────────────────────────────────┴──┴── MAC (ASCII) + checksum│ │ │ └────────────────────────────────────────── Length (0x0C = 12 bytes)│ │ └───────────────────────────────────────────── Response code: 00 (MAC)│ └──────────────────────────────────────────────── Type: 03 (info)└─────────────────────────────────────────────────── Frame: F1Live capture example:
f1 03 00 0c 35 62 61 36 38 36 33 38 66 61 63 61 03 a1 │ │ │ │ │ │ │ │ │ │ │ │ 5 b a 6 8 6 3 8 f a c a (ASCII)Decoded: MAC = 5b:a6:86:38:fa:ca
Device Version Response
Section titled “Device Version Response”Command: GET_DEVICE_VERSION (F1 03 03 06)
Response format: JSON string (may span multiple BLE packets)
Live capture example:
{"bv":"V1.2.2","fv":"1.0.07","m":"s120"}| Field | Value | Description |
|---|---|---|
bv | ”V1.2.2” | Bootloader version |
fv | ”1.0.07” | Firmware version |
m | ”s120” | Model identifier |
History Record Response
Section titled “History Record Response”Command: SYNC_HISTORY_DATA (F1 03 01 14 18)
Response format (per record):
f1 03 01 SS MM UU FF FF FF VH VL SH SL CS│ │ │ │ │ │ │ │ │ └──┴──┴──┴──┴── Value + checksum│ │ │ │ │ │ └──┴──┴─────────────── Constant: 01 31 50│ │ │ │ │ └──────────────────────── Unit code│ │ │ │ └─────────────────────────── Mode code│ │ │ └────────────────────────────── Status (00 = valid)│ │ └───────────────────────────────── Response: 01 (history)│ └──────────────────────────────────── Type: 03 (info)└─────────────────────────────────────── Frame: F1Value decoding:
value_raw = (VH << 8) | VL # Big-endian 16-bitdistance_mm = value_raw # In millimetersdistance_m = value_raw / 1000 # In metersLive capture examples:
| Hex | VH | VL | Raw | Distance |
|---|---|---|---|---|
02 79 | 0x02 | 0x79 | 633 | 0.633 m |
04 81 | 0x04 | 0x81 | 1153 | 1.153 m |
0a 18 | 0x0A | 0x18 | 2584 | 2.584 m |
Measurement Response
Section titled “Measurement Response”Full packet structure (23 bytes):
Byte: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ┌───────────────┬───────────────┬───────────────┬───────────────┬───────────────┬────────────┐ │ RecDataH3 │ RecDataH2 │ RecDataH1 │ RecDataMain │ Attributes │ Para │ │ (4 bytes) │ (4 bytes) │ (4 bytes) │ (4 bytes) │ (4 bytes) │ (3 bytes) │ └───────────────┴───────────────┴───────────────┴───────────────┴───────────────┴────────────┘Field Definitions (Metric)
Section titled “Field Definitions (Metric)”| Field | Bytes | Format | Description |
|---|---|---|---|
| RecDataH3 | 0-3 | uint32 BE | Third dimension (height) |
| RecDataH2 | 4-7 | uint32 BE | Second dimension (width) |
| RecDataH1 | 8-11 | uint32 BE | First dimension (length) |
| RecDataMain | 12-15 | uint32 BE | Primary result |
Field Definitions (Imperial - when unit_Len == 5)
Section titled “Field Definitions (Imperial - when unit_Len == 5)”| Field | Byte | Format | Description |
|---|---|---|---|
| *.Fra | 0 | uint8 | Fraction (1/32”) |
| *.In | 1 | uint8 | Inches |
| *.FT | 2-3 | uint16 BE | Feet |
Parameter Bytes (20-22)
Section titled “Parameter Bytes (20-22)”| Byte | Bits | Field | Description |
|---|---|---|---|
| 20 | 0-4 | mode | Measurement mode (0x00-0x13) |
| 20 | 6-7 | continuemode | Continuous flag |
| 21 | 0 | unit_angle | Angle unit (0=degrees) |
| 21 | 1-3 | AddDecMode | Decimal mode |
| 21 | 4-7 | standbot | Datum point |
| 22 | 0-3 | modestep | Mode step |
| 22 | 4 | msign | Sign (0=+, 1=-) |
| 22 | 5-7 | unit_Len | Length unit |
Conversion Factors
Section titled “Conversion Factors”| Data Type | Divisor | Example |
|---|---|---|
| Length | ÷ 1,000 | 81600 → 81.6 m |
| Area | ÷ 1,000,000 | 5000000 → 5.0 m² |
| Volume | ÷ 1,000,000,000 | 1000000000 → 1.0 m³ |
| Angle | ÷ 10 | 450 → 45.0° |
Data Usage by Mode
Section titled “Data Usage by Mode”| Mode | RecDataMain | H1 | H2 | H3 |
|---|---|---|---|---|
| Single (0x01) | Distance | - | - | - |
| Continuous (0x02) | Distance | - | - | - |
| Area (0x03) | Area | Length | Width | - |
| Volume (0x04) | Volume | Length | Width | Height |
| Angle+Height (0x07) | Height | Base dist | Angle | - |
| Pythagorean (0x08-0x0A) | Result | Side A | Side B | Side C |
Error Responses
Section titled “Error Responses”Errors are sent on 0xAE05 with prefix F1 05 01:
f1 05 01 XX XX XX XX ... └──────────── Error data (from byte 8 onwards)Common errors (displayed on device):
| Error | Meaning |
|---|---|
Err 1 | Target too far |
Err 2 | Target too close |
Err 3 | Excessive ambient light |
Err 4 | Out of measurement range |
Parsing Examples
Section titled “Parsing Examples”def parse_mac_response(data: bytes) -> str: """Parse GET_DEVICE_MAC response.""" if data[:3] != bytes([0xF1, 0x03, 0x00]): raise ValueError("Invalid MAC response prefix")
length = data[3] mac_ascii = data[4:4+length].decode('ascii')
# Insert colons: "5ba68638faca" -> "5b:a6:86:38:fa:ca" mac = ':'.join(mac_ascii[i:i+2] for i in range(0, len(mac_ascii), 2)) return mac
def parse_distance_response(data: bytes) -> float: """Parse single measurement response.""" # Assuming metric, distance is in RecDataMain (bytes 12-15) raw = int.from_bytes(data[12:16], 'big') return raw / 1000 # Convert to meters
def parse_history_record(data: bytes) -> dict: """Parse history record response.""" if data[:3] != bytes([0xF1, 0x03, 0x01]): raise ValueError("Invalid history response prefix")
return { 'status': data[3], 'mode': data[4], 'unit': data[5], 'value_raw': (data[9] << 8) | data[10], 'distance_m': ((data[9] << 8) | data[10]) / 1000 }function parseMacResponse(data) { const view = new DataView(data.buffer); if (view.getUint8(0) !== 0xF1 || view.getUint8(1) !== 0x03 || view.getUint8(2) !== 0x00) { throw new Error('Invalid MAC response prefix'); }
const length = view.getUint8(3); const macAscii = new TextDecoder().decode(data.slice(4, 4 + length));
// Insert colons return macAscii.match(/.{2}/g).join(':');}
function parseDistanceResponse(data) { const view = new DataView(data.buffer); const raw = view.getUint32(12, false); // Big-endian return raw / 1000; // Meters}Related Pages
Section titled “Related Pages”- Command Reference - Send commands
- BLE Service Reference - GATT setup