BLE Communication Specification (WhizToys Bluetooth Control Box)
This document defines the BLE (Bluetooth Low Energy) GATT Profile used by the WhizToys Bluetooth Control Box, intended for third-party developers and system integrators.
1. WhizToys Profile Architecture
The WhizToys Bluetooth Control Box operates as a BLE Peripheral, broadcasting advertising packets while waiting for a phone or other Central device to connect. Broadcasting stops once a connection is established. The Profile architecture is as follows:
| Level | Item |
|---|---|
| Profile | WhizToys Profile |
| ├ Service | GAP Service (0x1800) |
| ├ Service | GATT Service (0x1801) |
| └ Service | Custom Service (0000FEE0-0000-1000-8000-00805F9B34FB) |
| ├ Characteristic | Layout Information |
| ├ Characteristic | Sensor Information |
| └ Characteristic | LED Control Information |
2. GAP Service (0x1800)
A mandatory standard BLE service containing the device name, appearance, and connection parameters.
| Characteristic | UUID | Properties | Value | Description |
|---|---|---|---|---|
| Device Name | 0x2A00 | Read | Write | Array | Read/write the device name |
| Appearance | 0x2A01 | Read | Array | Read the device appearance |
| Peripheral Preferred Connection Parameters | 0x2A04 | Read | Array | Read the peripheral's preferred connection parameters |
3. GATT Service (0x1801)
A GATT Profile-defined service containing the "Service Changed" characteristic. When the GATT attribute layout of a Service changes (added or removed), the Server can notify the Client through this characteristic.
4. Custom Service (0xFEE0)
UUID: 0000FEE0-0000-1000-8000-00805F9B34FB
The core service for WhizToys hardware, providing pressure sensor data and LED light control. After powering on, the mat tiles automatically perform a Mapping Layout to discover the relative positions between tiles.
This service contains three Characteristics:
| Characteristic | UUID | Properties | Description |
|---|---|---|---|
| Layout Information | 0000FEE1-0000-1000-8000-00805F9B34FB | Read | Read the mat tile layout |
| Sensor Information | 0000FEE2-0000-1000-8000-00805F9B34FB | Notify | Notify on sensor value changes |
| LED Control Command | 0000FEE3-0000-1000-8000-00805F9B34FB | Write | Write LED light control commands |
5. Characteristic Value Definitions
5.1 Layout Information (0xFEE1) — Read
After the mat tiles complete the Mapping process, they enter sensing and standby mode. The Layout information is stored in the control box and does not change until the device is restarted. It is designed as a one-time Read operation.
Packet format (20 bytes):
| Byte 0 | Byte 1 | Byte 2 | ... | Byte n-1 |
|---|---|---|---|---|
| Layout Row and Column | 4 Sensor States | 4 Sensor States | ... | Check Sum |
Layout Row and Column (Byte 0)
A single byte split into two 4-bit nibbles:
- High 4 bits: Layout Row (number of rows)
- Low 4 bits: Layout Col (number of columns)
For example, 00010001₂ = 0x11: Row = 1, Col = 1, representing one row and one column.
4 Sensor States (Byte 1 ~ n-2)
Each byte represents the states of 4 sensors, with 2 bits per sensor:
| Binary | Decimal | Sensor State |
|---|---|---|
00 | 0 | No tile connected |
01 | 1 | No pressure |
10 | 2 | Pressure detected |
The 4 sensors are arranged in horizontal order.
Example — Two tiles arranged in a 1x2 layout. The 8 sensor states obtained from the data are arranged left to right, top to bottom:
Data: [00010010, 01011010, 01011010, checksum]
Layout parsed: Row=1, Col=2 (one row, two columns)
Sensor matrix (4 sensors per tile):
┌──────────┬──────────┐
│ 01 01 │ 10 10 │
│ │ │
│ 01 01 │ 10 10 │
└──────────┴──────────┘
Tile 1 Tile 2
(No press) (Pressed)
Check Sum (Last byte)
An XOR checksum of all data bytes to ensure data integrity during transmission.
5.2 Sensor Information (0xFEE2) — Notify
After enabling Notify, sensor value change notifications are triggered when a mat tile is stepped on or when the foot is lifted.
Packet format (20 bytes, in groups of 2 bytes):
| Byte 0 | Byte 1 | Byte 2 | Byte 3 | ... |
|---|---|---|---|---|
| Sensor Change Position (1) | 4 Sensor States (1) | Sensor Change Position (2) | 4 Sensor States (2) | ... |
Sensor Change Position
A single byte split into two 4-bit nibbles:
- High 4 bits: Layout Row Index (starting from 0)
- Low 4 bits: Layout Col Index (starting from 0)
For example, 00010000₂ = 0x10: Row Index = 1, Col Index = 0, representing the tile in the second row, first column.
4 Sensor States
A single byte split into 4 groups of 2 bits, representing the sensor states at the top-left, bottom-left, bottom-right, and top-right positions:
| Value | Sensor State |
|---|---|
00 | No pressure |
01 | Level 1 |
10 | Level 2 |
11 | Level 3 |
For example, 00001100₂ = 0x0C: top-left = no pressure, bottom-left = no pressure, bottom-right = Level 3, top-right = no pressure.
5.3 LED Control Command (0xFEE3) — Write
The client sends LED light control commands via Write.
Packet format (20 bytes):
| Byte 0 | Byte 1~3 | Byte 4~6 | ... | Byte 3n+1 |
|---|---|---|---|---|
| Subsequent data length | Light control command | Light control command | ... | Check Sum |
Each light control command consists of 3 bytes:
| Byte | Field | Description |
|---|---|---|
| 0 | Location | LED position in the Layout |
| 1 | Mode | Light control mode |
| 2 | Color | Color code |
Location
Same format as the Sensor Change Position: high 4 bits = Row Index, low 4 bits = Col Index.
Mode (8-bit breakdown)
| Bit | Purpose | Range | Value Description |
|---|---|---|---|
| 1~3 | Light position | 0~7 | 0 Entire tile lit, 1 Top-left only, 2 Bottom-left only, 3 Bottom-right only, 4 Top-right only, 5 All individually lit |
| 4 | Trigger mechanism | 0~1 | 0 Trigger feedback once immediately, 1 Trigger on step |
| 5~7 | Feedback mode | 0~7 | 0 Unspecified (direct light control), 1 No feedback on step, 2 Basic, 3 Blink, 4 Marquee, 5 Breathing light, 6 Neon light |
| 8 | Feedback duration | 0~1 | 0 Short, 1 Long (affects blink and marquee speed) |
When bits 1~3 are set to 0 (entire tile lit), all 4 LEDs will light up together regardless of which position sensor is triggered.
Color (Color Code)
A 1-byte color code index mapped to a predefined 62-color RGB palette:
| Code | R | G | B | Color |
|---|---|---|---|---|
| 00 | 0 | 0 | 0 | Black (off) |
| 01 | 255 | 0 | 0 | Red |
| 02~10 | 255 | 25~225 | 0 | Red to Yellow gradient |
| 11 | 255 | 255 | 0 | Yellow |
| 12~20 | 225~25 | 255 | 0 | Yellow to Green gradient |
| 21 | 0 | 255 | 0 | Green |
| 22~30 | 0 | 255 | 25~225 | Green to Cyan gradient |
| 31 | 0 | 255 | 255 | Cyan |
| 32~40 | 0 | 225~25 | 255 | Cyan to Blue gradient |
| 41 | 0 | 0 | 255 | Blue |
| 42~50 | 25~225 | 0 | 255 | Blue to Purple gradient |
| 51 | 255 | 0 | 255 | Purple |
| 52~60 | 255 | 0 | 225~25 | Purple to Red gradient |
| 61 | 255 | 255 | 255 | White |
Full 62-Color RGB Reference Table
| Code | R | G | B | Color |
|---|---|---|---|---|
| 00 | 0 | 0 | 0 | — |
| 01 | 255 | 0 | 0 | Red |
| 02 | 255 | 25 | 0 | |
| 03 | 255 | 50 | 0 | |
| 04 | 255 | 75 | 0 | |
| 05 | 255 | 100 | 0 | |
| 06 | 255 | 125 | 0 | |
| 07 | 255 | 150 | 0 | |
| 08 | 255 | 175 | 0 | |
| 09 | 255 | 200 | 0 | |
| 10 | 255 | 225 | 0 | |
| 11 | 255 | 255 | 0 | Yellow |
| 12 | 225 | 255 | 0 | |
| 13 | 200 | 255 | 0 | |
| 14 | 175 | 255 | 0 | |
| 15 | 150 | 255 | 0 | |
| 16 | 125 | 255 | 0 | |
| 17 | 100 | 255 | 0 | |
| 18 | 75 | 255 | 0 | |
| 19 | 50 | 255 | 0 | |
| 20 | 25 | 255 | 0 | |
| 21 | 0 | 255 | 0 | Green |
| 22 | 0 | 255 | 25 | |
| 23 | 0 | 255 | 50 | |
| 24 | 0 | 255 | 75 | |
| 25 | 0 | 255 | 100 | |
| 26 | 0 | 255 | 125 | |
| 27 | 0 | 255 | 150 | |
| 28 | 0 | 255 | 175 | |
| 29 | 0 | 255 | 200 | |
| 30 | 0 | 255 | 225 | |
| 31 | 0 | 255 | 255 | Cyan |
| 32 | 0 | 225 | 255 | |
| 33 | 0 | 200 | 255 | |
| 34 | 0 | 175 | 255 | |
| 35 | 0 | 150 | 255 | |
| 36 | 0 | 125 | 255 | |
| 37 | 0 | 100 | 255 | |
| 38 | 0 | 75 | 255 | |
| 39 | 0 | 50 | 255 | |
| 40 | 0 | 25 | 255 | |
| 41 | 0 | 0 | 255 | Blue |
| 42 | 25 | 0 | 255 | |
| 43 | 50 | 0 | 255 | |
| 44 | 75 | 0 | 255 | |
| 45 | 100 | 0 | 255 | |
| 46 | 125 | 0 | 255 | |
| 47 | 150 | 0 | 255 | |
| 48 | 175 | 0 | 255 | |
| 49 | 200 | 0 | 255 | |
| 50 | 225 | 0 | 255 | |
| 51 | 255 | 0 | 255 | Purple |
| 52 | 255 | 0 | 225 | |
| 53 | 255 | 0 | 200 | |
| 54 | 255 | 0 | 175 | |
| 55 | 255 | 0 | 150 | |
| 56 | 255 | 0 | 125 | |
| 57 | 255 | 0 | 100 | |
| 58 | 255 | 0 | 75 | |
| 59 | 255 | 0 | 50 | |
| 60 | 255 | 0 | 25 | |
| 61 | 255 | 255 | 255 | White |
6. Recommended Connection Flow
sequenceDiagram
participant App
participant ControlBox as Control Box
App->>ControlBox: Scan BLE advertisements
App->>ControlBox: Initiate connection
ControlBox-->>App: Connection established, stop advertising
App->>ControlBox: Read GAP Service (device name, connection parameters)
App->>ControlBox: Read Layout Information (0xFEE1)
App->>ControlBox: Enable Sensor Information Notify (0xFEE2)
ControlBox-->>App: Push sensor change data
App->>ControlBox: Write LED Control Command (0xFEE3)
7. Development Notes
- Mapping Timing: The control box automatically performs Mapping Layout after powering on. Do not step on the mat tiles during this process. Layout information can only be read after Mapping is complete.
- Data Length: The packet length for Layout information, sensor information, and LED control commands is always 20 bytes.
- Check Sum: The last byte of every packet is an XOR checksum. The receiver should verify data integrity.
- Index Starting Value: Both Row Index and Col Index start from 0.
- Android Permissions: Android 12+ requires
BLUETOOTH_SCANandBLUETOOTH_CONNECTpermissions; Android 11 and below requiresACCESS_FINE_LOCATION. - iOS Limitations: iOS does not support reading the BLE MAC Address. Use the advertising name or Service UUID for device identification.
Version History
| Version | Date | Description |
|---|---|---|
| 1.0 | 2023-03-02 | Original WhizToys custom Bluetooth specification document |
| 1.1 | 2026-04-08 | Converted to online documentation format |
For the complete SDK or technical integration inquiries, please contact: support@seda-gtech.com.tw