1. Basic Information
1.1 UUID
Type | UUID |
Service | 8FE4E987-0824-8B2C-2E59-22C7287395C3 |
Host to Device | 8FE4E988-0824-8B2C-2E59-22C7287395C3 |
Device to Host | 8FE4E989-0824-8B2C-2E59-22C7287395C3 |
1.2 MAC Address
First 24 bits are fixed:
50:C0:F0Last 24 bits are random
1.3 Advertising Packet
Type | Data | Description |
0x01 | 0x06 | Advertising flag |
0x09 | C01 | Device name |
0x02 | 16-bit UUID | First two bytes of the 128-bit UUID: |
0xFF | MAC | Device MAC address |
1.4 About iOS
After pairing with the iOS system, due to the presence of the ANCS protocol, iOS will maintain the BLE central connection even after the app is closed and removed from the background.
1.5 About the Bike Computer
To be compatible with the bike computer, the data sent from the device to the app must not exceed 17 bytes per transmission. If the data exceeds this limit, it will be split into multiple packets.
2. Protocol Format
2.1 Protocol Structure
Protocol ID | Version | Command | CRC | Data Length | Data |
2 bytes | 1 byte | 1 byte | 2 bytes | 2 bytes | N bytes |
Multi-byte data uses big-endian format.
Protocol ID = Fixed value:
E987Protocol Version = Current version:
0x04Command = Refer to section 3. Protocol Commands
CRC = CRC-16-IBM of the “Data” field
Data Length = Byte length of the “Data” field
Data = Actual data content
//crc
unsigned short crc_IBM(unsigned char *ptr, int len)
{
unsigned int i;
unsigned short crc = 0x0000;
while(len--)
{
crc ^= *ptr++;
for (i = 0; i < 8; ++i)
{
if (crc & 1)
crc = (crc >> 1) ^ 0xA001;
else
crc = (crc >> 1);
}
}
return crc;
}
Example
Function: Get all device info 0xe98703000000000100
Protocol ID: 0xe9, 0x87 (2 bytes) Version: 0x03 (1 byte) Command: 0x00 (1 byte) [Get device info] CRC: 0x00, 0x00 (2 bytes) Data Length: 0x00, 0x01 (2 bytes) Data: 0x00 (1 byte) [0x00 = all info]
2.2 Protocol Version Conflict
0x00010x0105
These two commands must not be modified.
When a protocol version mismatch is detected, only these two commands are allowed to be used to prompt firmware upgrade.
3. Protocol Commands
🟩 Green highlights indicate repeatable data.
🔵 Blue highlights indicate repeat count.
0x00 Get Device Info
The host sends a request with a specific type, and the device replies with the corresponding information. If the device info changes, the device will proactively send updates.
Host Sends:
Length | Value | Description |
1 byte |
| All information |
1 byte |
| Version info |
1 byte |
| Battery info |
1 byte |
| Brightness info |
1 byte |
| Volume info |
1 byte |
| Device SN |
1 byte |
| Display status |
Device Replies:
0x00 All Information
The device will sequentially send all types of data listed above.
0x01 Version Info (Fixed, cannot be modified)
Length | Value | Description |
1 byte |
| Version info |
1 byte |
| Major version |
1 byte |
| Minor version |
1 byte |
| Patch version |
1 byte |
| Compile year |
1 byte |
| Compile month |
1 byte |
| Compile day |
Data Example: 0xe9870300b6f600070100012619031c
Packet Header:
0xe9, 0x87 (2 bytes), 0x03 (1 byte), 0x00 (1 byte), 0xb6, 0xf6 (2 bytes), 0x00, 0x07 (1 byte)
Data: 0x01 00 01 26 19 03 1C 【0x01 corresponds to version information】
Converted to decimal:
0 (first version number)
1 (second version number)
38 (third version number)
25 (year)
3 (month)
28 (day)
0x02 Battery Information
Length | Value | Description |
1 byte |
| Battery Information |
1 byte |
| Battery Percentage (%) |
1 byte |
| Discharging/Charging |
0x03 Brightness Information
Length | Value | Description |
1 byte |
| Brightness Information |
1 byte |
| Brightness Level (%) |
0x04 Volume Information
(Volume changes made on the phone system are sent back to the app)
(Note: On iOS, volume can be obtained via AMS if AVRCP is not available)
Length | Value | Description |
1 byte |
| Volume Information |
1 byte |
| Volume Level (%) |
0x05 Device Serial Number (SN) (Fixed, cannot be modified)
Length | Value | Description |
1 byte |
| Device SN Identifier |
14 bytes | ASCII | Serial Number String |
0x06 Display Status
Bits are interpreted from least significant bit (LSB) to most significant bit (MSB)
Bit | Value | Description |
1 bit |
| Music Hidden |
|
| Music Shown |
1 bit |
| Incoming Call Hidden |
|
| Incoming Call Shown |
1 bit |
| Message Hidden |
|
| Message Shown |
1 bit |
| Left Dashboard Hidden |
|
| Left Dashboard Shown |
1 bit |
| Right Dashboard Hidden |
|
| Right Dashboard Shown |
3 bits | — | Reserved |
0x07 Get UI Mode
Retrieves the current UI display mode of the device.
Length | Value | Description |
1 byte |
| Get UI Mode Command |
1 byte |
| Mode 1 (Standard) |
|
| Mode 2 (Dashboard Mode) |
|
| Mode 3 (Focus Mode) |
0x08 Get Screen Sleep Timeout
Retrieves the screen sleep timeout duration. If the value is less than or equal to 5 seconds, the screen will be treated as "always on" (no timeout).
Length | Value | Description |
1 byte |
| Get Screen Sleep Timeout Command |
2 bytes |
| Timeout duration in seconds |
0x09 Get Activation Status
Length | Value | Description |
1 byte |
| Get Activation Status Cmd |
1 byte |
| Not Activated/Activated |
0x0A Get Accessory Binding
Retrieves accessory binding information.
Length | Value | Description |
1 byte |
| Get Accessory Binding Cmd |
1 byte |
| Helmet Device |
4 bytes |
| Group ID (0 = Not Bound) |
0x0B Get Unit System (Metric/Imperial)
Retrieves the current unit system setting.
Length | Value | Description |
1 byte |
| Get Unit System Cmd |
1 byte |
| Metric System/Imperial System |
0x01 Set Device Info
The host sends corresponding information to synchronize with the device.
0x00 Set Volume
Length | Value | Description |
1 byte |
| Volume Command |
1 byte |
| Volume Level (%) |
0x01 Set Brightness
Length | Value | Description |
1 byte |
| Brightness Command |
1 byte |
| Brightness Level (%) |
0x02 Sync Time to Device
Length | Value | Description |
1 byte |
| Time Command |
8 bytes | Timestamp | Unix Timestamp |
0x03 Factory Reset
Length | Value | Description |
1 byte |
| Factory Reset |
0x04 Set Display Status
Sets the visibility of various UI elements.
Bits are interpreted from least significant bit (LSB) to most significant bit (MSB).
Bit | Value | Description |
1 bit |
| Music Hidden |
|
| Music Shown |
1 bit |
| Incoming Call Hidden |
|
| Incoming Call Shown |
1 bit |
| Message Hidden |
|
| Message Shown |
1 bit |
| Left Gauge Hidden |
|
| Left Gauge Shown |
1 bit |
| Right Gauge Hidden |
|
| Right Gauge Shown |
3 bits | — | Reserved |
0x05 Enter ADFU Mode
Enters firmware upgrade (ADFU) mode.
This command is fixed and must not be modified.
Length | Value | Description |
1 byte |
| Enter ADFU Mode Command |
0x06 Switch UI Mode
Switches the device's UI display mode.
Length | Value | Description |
1 byte |
| Switch UI Mode Command |
1 byte |
| Mode 1 (Default) |
|
| Mode 2 (Gauge Mode) |
|
| Mode 3 (Minimal Mode) |
0x02 Activity Data
The host sends activity-related data. Data is sent field by field. If the value is 0xFFFFFFFF or the device is disconnected, display --. If the field name or value is empty, it will not be displayed. After switching via remote control, the corresponding field data will be sent.
Length | Value | Description |
1 byte |
| Empty (not displayed) |
1 byte |
| Duration (deprecated) |
1 byte |
| Distance |
1 byte |
| Speed |
1 byte |
| Cadence |
1 byte |
| Heart Rate |
1 byte |
| Power |
1 byte |
| Altitude & Climb |
1 byte |
| Calories Burned |
1 byte |
| Slope |
1 byte |
| Incline |
1 byte |
| Acceleration |
1 byte |
| Heading |
0x00 Activity Field Value
Sends the value of a specific activity field. If the field value is 0xFF or empty, it will not be displayed.
Because of processing speed constraints, continuous updates are limited to intervals of 500 milliseconds or more.
Length | Value | Description |
1 byte |
| Activity Field Value Cmd |
1 byte |
| Length of field value (N) |
0~10 bytes | — | Field value (string) |
...N*4 | — | Repeated N*4 if needed |
0x06 Switch Field
Switches the displayed field and its unit/value. If a field name or unit is not available, set its length to 0xFF or 0x00 .
Because of processing speed constraints, continuous updates are limited to intervals of 1000 milliseconds or more.
Length | Value | Description |
1 byte |
| Switch Field Command |
1 byte |
| Field name length (N) |
0~25 bytes | — | Field name (string) |
1 byte |
| Field unit length (U) |
0~10 bytes | — | Field unit (string) |
1 byte |
| Field value length (V) |
0~10 bytes | — | Field value (string) |
...N*4 | — | Repeated N*4 if needed |
Data Transmission Example
<E9 87 03 02 E0 E0 00 2E 06 04 44 69 73 74 02 4B 6D 00 03 53 50 44 04 6B 6D 2F 68 00 04 47 52 41 44 01 25 00 0B 4C 41 50 20 41 56 47 20 53 50 44 04 6B 6D 2F 68 00>
Corresponding content (in order):
First field:
Field Name: Dist
Unit: Km
Value: -- (value length is 0, so not displayed)
Second field:
Field Name: SPD
Unit: km/h
Value: -- (value length is 0)
Third field:
Field Name: GRAD
Unit: %
Value: -- (value length is 0)
Fourth field:
Field Name: LAP AVG SPD
Unit: km/h
Value: -- (value length is 0)
Notes:
All data is converted from string to byte, including field values.
For example, if the original field value is of type int, it must first be converted to a string, and then to bytes before transmission.
0x01 Activity Goal Achieved Data (Popup Goal Data)
When an activity goal is achieved, this command is used to send a popup message to the device.
Length | Value | Description |
1 byte |
| Activity Goal Achieved Cmd |
1 byte | N | Length of the content |
N bytes | — | Goal achievement content |
0x02 Activity Dashboard Field Data
Sends data for the left and right dashboard fields during an activity. Field types refer to the field mapping table.
Length | Value | Description |
1 byte |
| Dashboard Field Command |
1 byte | Field ID | Left Dashboard Field ID |
4-Byte Float (IEEE 754 Standard) | Field Value | Left Field Value |
1 byte | Field ID | Right Dashboard Field ID |
4-Byte Float (IEEE 754 Standard) | Field Value | Right Field Value |
0x03 Activity Field Average Value Update
Sends the status of average value changes for activity fields. When this command is sent, the corresponding status will be displayed temporarily, then automatically hidden.
Length | Value | Description |
1 byte |
| Average Value Update Command |
1 byte | 0 / 1 / 2 | Variable Field 1 Status (None/Up/Down) |
1 byte | 0 / 1 / 2 | Variable Field 2 Status |
1 byte | 0 / 1 / 2 | Variable Field 3 Status |
1 byte | 0 / 1 / 2 | Variable Field 4 Status |
1 byte | 0 / 1 / 2 | Dashboard Field 1 Status |
1 byte | 0 / 1 / 2 | Dashboard Field 2 Status |
0: No change1: Value increased2: Value decreased
0x04 Activity Progress
Sends the current progress of the activity as a percentage.
Length | Value | Description |
1 byte |
| Activity Progress Command |
1 byte | 0~100 | Progress Percentage (%) |
0x05 Activity Time
Sends the current activity status and elapsed time. The time is synchronized every 30 seconds or when the status changes.
Length | Value | Description |
1 byte |
| Activity Time Command |
1 byte |
| Activity Ended |
|
| Activity Started |
|
| Activity Paused |
4 bytes | Time (s) | Elapsed Time in Seconds |
0x03 AI Data
The host sends AI-related status and data.
When the status changes, only 1 byte is sent.
When transmitting AI content, status 0x04 is used, followed by data type and content.
Fast mode is used for auto-start AI scenarios, and the display will remain visible.
0x00 / 0x05 AI Start (Normal / Fast)
Length | Value | Description |
1 byte |
| Enter AI Listening Mode |
0x01 / 0x06 AI End (Normal / Fast)
Length | Value | Description |
1 byte |
| Exit AI Mode |
0x02 / 0x07 Start Voice Capture (Normal / Fast)
Length | Value | Description |
1 byte |
| Start Capturing Voice Input |
0x03 / 0x08 Load Answer (Normal / Fast)
Length | Value | Description |
1 byte |
| Load Answer State |
0x04 / 0x09 Display Content (Normal / Fast)
If no correction is needed, send only the new text to append. If correction is needed, send the full updated text.
Length | Value | Description |
1 byte |
| Display Answer Content |
1 byte |
| Question Content (deprecated) |
|
| End of Question (deprecated) |
|
| Answer Content |
|
| End of Answer |
2 bytes | N | Data Length |
N bytes | — | Text Data (UTF-8) |
0x0A AI Reminder (Button Triggered) 0x0B (Auto Triggered)
AI Reminder Data
Length | Value | Description |
1 byte | 0x0A / 0x0B | AI Reminder Command (Button/Auto) |
1 byte | 0~25 / 0xFF | Field Name Length (N) |
0~25 bytes | — | Field Name (string) |
1 byte | 0~10 / 0xFF | Field Value Length (V) |
0~10 bytes | — | Field Value (string) |
1 byte | 0 / 1 / 2 | Average Value Status: |
| 0 | No Change |
| 1 | Increased |
| 2 | Decreased |
0x04 Accessory Status Sync
Synchronizes and displays the status of connected accessories.
0x00 Camera Status
Length | Value | Description |
1 byte |
| Camera Status Command |
1 byte |
| Camera Stopped |
|
| Camera Started |
|
| Camera Paused |
2 bytes | — | Duration in minutes (reserved, not sent) |
0x01 Remote Control Signal
Length | Value | Description |
1 byte |
| Remote Control Command |
1 byte |
| Turn Left Signal |
|
| Turn Right Signal |
|
| Brake Signal |
0x02 Radar Signal
0xFF indicates no radar signal.
Length | Value | Description |
1 byte |
| Radar Signal Command |
8 bytes |
| Distance of 8 radar points |
8 bytes | — | Angle of 8 radar points |
8 bytes | — | Speed of 8 radar points |
0x03 Pair/Unpair Broadcast Accessory
After pairing starts, the device will scan for the first helmet's group ID and store it.
Subsequent pairing attempts will only match this stored group ID.
Pairing lasts for 1 minute.
If pairing is successful, the group ID will be returned.
A group ID of 0 indicates unbound
Length | Value | Description |
1 byte |
| Pair/Unpair Accessory Command |
1 byte |
| Helmet Device |
1 byte |
| Unpair/Pair |
0x05 Notification Data
Sends notification data to the device, which will display it as a popup.
This is only used on Android. iOS uses ANCS (Apple Notification Center Service) instead.
Length | Value | Description |
2 bytes |
| App Name Length |
N bytes |
| App Name (string) |
2 bytes |
| Title Length |
M bytes |
| Title (string) |
0x06 Virtual Button
0x00 From App
Length | Value | Description |
1 byte | 0x00 | Source: From App |
1 byte | 0x01 | Left Button |
| 0x02 | Right Button |
| 0x03 | Power Button |
0x01 From Device
Length | Value | Description |
1 byte | 0x01 | Source: From Device |
1 byte | 0x01 | Left Handlebar Pressed |
| 0x02 | Left Handlebar Released |
| 0x03 | Right Handlebar Pressed |
| 0x04 | Right Handlebar Released |
0x07 Contact Lookup
The app synchronizes the contact list to the phone.
When the device receives a phone number, it sends it back to the app for comparison.
The app then returns the corresponding contact name.
0x00 Device Requests Name
Length | Value | Description |
1 byte |
| Device Requests Name |
1 byte |
| Phone Number Length |
N bytes |
| Phone Number (string) |
0x01 App Returns Name
Length | Value | Description |
1 byte | 0x01 | App Returns Name |
1 byte |
| Contact Name Length (0 if empty) |
N bytes |
| Contact Name (string) |
0x08 Navigation Data
Navigation data is displayed within a 130×80 pixel area.
All coordinates are based on this display area using (x, y) values.
0x00 Navigation Start/End
Length | Value | Description |
1 byte |
| Navigation Start/End Command |
1 byte |
| Navigation End |
|
| Navigation Start |
1 byte |
| Total Number of Route Coordinates |
0x01 Full Route Map
Length | Value | Description |
1 byte |
| Full Route Map Command |
2 bytes |
| Number of Route Coordinates (N) |
1 byte |
| X Coordinate (per point) |
1 byte |
| Y Coordinate (per point) |
...N*N | ...N*N | ...N*N |
0x02 Route
If the number of passed coordinates equals the total route coordinates, it means the route is completed. The number will never exceed the full route count.
Length | Value | Description |
1 byte |
| Passed Route Command |
2 bytes |
| Number of Passed Coordinates |
1 byte |
| Last Passed X Coordinate |
1 byte |
| Last Passed Y Coordinate |
0x03 Route Info Text
Length | Value | Description |
1 byte |
| Route Info Command |
1 byte |
| Text Length (N) |
N bytes | - | Info Text (UTF-8 string) |
0x04 Navigation Position Text
Length | Value | Description |
1 byte |
| Navigation Position Command |
1 byte |
| Text Length (N) |
N bytes | — | Position Text (UTF-8 string) |
0x05 Navigation Info
Length | Value | Description |
1 byte |
| Navigation Info Command |
1 byte |
| Icon ID |
1 byte |
| Text Length (N) |
N bytes | — | Instruction Text (UTF-8 string) |
Below is a list of all 87 PNG files under the light theme directory (src/png/light), along with their corresponding type, modifier, and Chinese meaning.
Each file name represents an icon name, with a unified prefix direction_ and suffix .png.
All PNG files have been packaged and attached at the bottom of this documentation.
No | Type | Modifier | PNG Name |
2 | arrive | left | direction_arrive_left.png |
3 | arrive | right | direction_arrive_right.png |
4 | arrive | straight | direction_arrive_straight.png |
5 | close | — | direction_close.png |
7 | continue | left | direction_continue_left.png |
8 | continue | right | direction_continue_right.png |
9 | continue | slight_left | direction_continue_slight_left.png |
10 | continue | slight_right | direction_continue_slight_right.png |
11 | continue | straight | direction_continue_straight.png |
12 | continue | uturn | direction_continue_uturn.png |
14 | depart | left | direction_depart_left.png |
15 | depart | right | direction_depart_right.png |
16 | depart | straight | direction_depart_straight.png |
17 | end_of_road | left | direction_end_of_road_left.png |
18 | end_of_road | right | direction_end_of_road_right.png |
19 | flag | — | direction_flag.png |
20 | fork | — | direction_fork.png |
21 | fork | left | direction_fork_left.png |
22 | fork | right | direction_fork_right.png |
23 | fork | slight_left | direction_fork_slight_left.png |
24 | fork | slight_right | direction_fork_slight_right.png |
25 | fork | straight | direction_fork_straight.png |
26 | invalid | — | direction_invalid.png |
34 | merge | right | direction_merge_right.png |
35 | merge | slight_left | direction_merge_slight_left.png |
36 | merge | slight_right | direction_merge_slight_right.png |
40 | new_name | sharp_left | direction_new_name_sharp_left.png |
41 | new_name | sharp_right | direction_new_name_sharp_right.png |
45 | notificaiton | sharp_right | direction_notificaiton_sharp_right.png |
46 | notification | left | direction_notification_left.png |
47 | notification | right | direction_notification_right.png |
48 | notification | sharp_left | direction_notification_sharp_left.png |
49 | notification | slight_left | direction_notification_slight_left.png |
50 | notification | slight_right | direction_notification_slight_right.png |
51 | notification | straight | direction_notification_straight.png |
53 | off_ramp | right | direction_off_ramp_right.png |
54 | off_ramp | slight_left | direction_off_ramp_slight_left.png |
55 | off_ramp | slight_right | direction_off_ramp_slight_right.png |
56 | on_ramp | left | direction_on_ramp_left.png |
57 | on_ramp | right | direction_on_ramp_right.png |
58 | on_ramp | sharp_left | direction_on_ramp_sharp_left.png |
59 | on_ramp | sharp_right | direction_on_ramp_sharp_right.png |
60 | on_ramp | slight_left | direction_on_ramp_slight_left.png |
61 | on_ramp | slight_right | direction_on_ramp_slight_right.png |
62 | on_ramp | straight | direction_on_ramp_straight.png |
63 | rotary | — | direction_rotary.png |
64 | rotary | left | direction_rotary_left.png |
65 | rotary | right | direction_rotary_right.png |
66 | rotary | sharp_left | direction_rotary_sharp_left.png |
67 | rotary | sharp_right | direction_rotary_sharp_right.png |
68 | rotary | slight_left | direction_rotary_slight_left.png |
69 | rotary | slight_right | direction_rotary_slight_right.png |
70 | rotary | straight | direction_rotary_straight.png |
71 | roundabout | — | direction_roundabout.png |
72 | roundabout | left | direction_roundabout_left.png |
73 | roundabout | right | direction_roundabout_right.png |
87 | uturn | — | direction_uturn.png |
The naming convention and retrieval method can be found in the Mapbox directions-icons README. The meanings of type and modifier correspond to the enumerations defined in the Mapbox Directions SDK documentation.
0x09 Personalized Layout Adjustment
Used to customize the position of UI modules.
The full screen resolution is 640 × 480 pixels.
Module Definitions
Module ID | Name | Width | Height |
| Low Battery | 188 | 24 |
| Ride 1 | 114 | 46 |
| Ride 2 | 114 | 46 |
| Ride 3 | 114 | 46 |
| Ride 4 | 114 | 46 |
| Info Bar | 100 | 45 |
| Goal Achieved | 400 | 38 |
| Indicator Bar | 24 | 272 |
| Message | 250 | 80 |
| Direction Prompt | 74 | 36 |
| Radar | 22 | 220 |
| Phone | 220 | 36 |
| AI | 640 | 164 |
| Pause | 27 | 27 |
| Track | 150 | 120 |
| Navigation | 266 | 100 |
| Left Gauge | 150 | 100 |
| Right Gauge | 150 | 100 |
| All Modules |
|
|
0x00 Set Module Coordinates
Sets the position and visibility of UI modules for a specific UI mode. Multiple modules can be configured in a single command.
Length | Value | Description |
1 byte |
| Set Module Coordinates Command |
1 byte |
| Mode 1 (Standard Mode) |
|
| Mode 2 (Dashboard Mode) |
|
| Mode 3 (Focus Mode) |
1 byte |
| Number of modules to configure |
1 byte |
| Module ID |
1 byte |
| Visibility (0 = Hidden, 1 = Shown) |
2 bytes |
| X Coordinate |
2 bytes |
| Y Coordinate |
... |
| Repeat for N modules |
0x01 Get Module Coordinates
Length | Value | Description |
1 byte |
| Get Module Coordinates Command |
1 byte |
| Mode 1 (Standard Mode) |
|
| Mode 2 (Dashboard Mode) |
|
| Mode 3 (Focus Mode) |
1 byte |
| Module ID |
1 byte |
| Visibility (0 = Hidden, 1 = Shown) |
2 bytes |
| X Coordinate |
2 bytes |
| Y Coordinate |
0x02 Reset Layout
Resets the layout of a specific module or all modules to the default configuration for the selected UI mode.
Length | Value | Description |
1 byte |
| Reset Layout Command |
1 byte |
| Mode 1 (Standard Mode) |
|
| Mode 2 (Dashboard Mode) |
|
| Mode 3 (Focus Mode) |
1 byte |
| Module ID to reset |
0xFF Test Command
This command is used for testing specific features. Some features may require specific firmware versions to function properly.
0x01 Debug Brightness
Length | Value | Description |
1 byte |
| Debug Brightness Command |
2 bytes |
| Current Adjustment (mA) |
2 bytes |
| Brightness Adjustment (level) |
