Preface:
We at aconno use BLE advertising to send sensor data and other information to interested listeners such as mobile apps, gateways, and other receivers.
Before continuing to read this document please make sure you understand the basics of BLE advertising by reading some of the available literature or studying the content on these pages:
BLE Advertising primer
BLE advertising – a beginners tutorial
Also, get some BLE tools that show you the raw and interpreted data.
Our Sensorics App is a good starting point to this topic: Google Play link
Sources: GitHub repository
Also, our BLE Sniffer is a great help to read and understand this data.
Sources: GitHub repository
Or you just go with the good old NRF connect
How we use the BLE Advertisement:
The BLE advertisement has 37 bytes of which some are fixed/reserved and others are for us free to use.
Here is how a sample advertisement can look like.
0xA0 | 0xB1 | 0x55 | 0x21 | 0x45 | 0x09 | 0x07 | 0x09 | H | E | L | L | O |
The first 6 bytes are reserved for the MAC Address (here in the sample A0:B1:55:21:45:09). This part of the advertisement is the only part that will remain always remain in the same place and be the same size. After the MAC fields of different types can follow. Every field starts with a length byte and a type.
In the above example, we have the 0x07 telling us that the next 7 bytes, including this one length byte, belong together. After the length byte, the field type is announced, in our case 0x09 which stands for the complete name of the beacon.
Sample of a typical AcnSensa advertisement (not complete):
0xA0 | 0xB1 | 0x55 | 0x21 | 0x45 | 0x09 | 0x1F | 0xff | 0X59 | 0X00 | 0X69 | 0X08 | 0x80 | 0X00 | 0X01 | 0X10 | 0X01 | 0X21 | 0X22 | 0X11 |
At aconno we use the field called manufacturer data (0xFF). This is a free block where the first two bytes after the 0XFF are reserved for the HW Manufacturer, in this case, Nordic. The bytes following describes which aconno product it is and what version of firmware it has.
See the table for more info:
Field Name | Size | Description |
---|---|---|
MSD Size | 1B | Size |
MSD ID | 1B | 0xFF |
Nordic ID | 2B | 0x5900 |
Aconno ID | 1B | 0x69 |
Product ID | 1B | 0x08 |
Settings support | 1b | 0b1 |
Version Number | 7b | 0x0 |
Data | Up to 24B | Data |
Data field:
This advertisement contains all the data for 3D values (gyro, accelerometer, and magnetometer). Additionally, this advertisement also contains the scaling factor for the accelerometer.
Field Name | Size | Description |
---|---|---|
Advertisement ID | 1B | 0x00 |
Gyroscope (X axis) | 2B | int16 data |
Gyroscope (Y axis) | 2B | int16 data |
Gyroscope (Z axis) | 2B | int16 data |
Accelerometer (X axis) | 2B | int16 data |
Accelerometer (Y axis) | 2B | int16 data |
Accelerometer (Z axis) | 2B | int16 data |
Magnetometer (X axis) | 2B | int16 data |
Magnetometer (Y axis) | 2B | int16 data |
Magnetometer (Z axis) | 2B | int16 data |
Accelerometer LSB value | 2B | uint16 data |
In order to standardize the advertisement format between different devices we have defined a description format for this data using JSON which Apps, Gateways and others can read and interpret thy bytes into meaningful numbers and characters. The so-called deserializers define the position, length, and order of bytes to be interpreted as a data type and the name for it. Sounds complicated huh?
No worries, here is an example:
In this snippet of an actual deserialize you see, that e.g. Gyroscope X is a SINT16, a two byte signed integer, on the position 6 and 7 (the 8 is exclusive) and is reversed (little endian->the 2 bytes get swapped). Also inside is a formula that describes how to calculate the value before displaying it.
Here is a list of available deserializers:













