Frame structure
Last updated
Last updated
The Waspmote Frame was designed in order to create sensor data frames with a specific format. This data protocol is supported by Meshlium (Meshlium can decode these data frames), so this is the format to be used in order to transmit data to Meshlium.
There are two kinds of frames: ASCII and Binary.
Besides, a special frame format was designed in order to send sensor data via low bit-rate protocols with short payload sizes. This frame type is called 'Tiny' frame. The user must keep in mind that this protocol is not integrated into Meshlium (in fact, this frame type is mainly designed for constrained radios like Sigfox or LoRaWAN, and when operating with these protocols the receiver is not Meshlium, but a Sigfox or LoRaWAN base station).
These frames are supposed to facilitate the comprehension of the data to be sent. As the frame is composed of ASCII characters is easier to understand all the fields included within the payload.
It is possible to identify two different parts inside the frame. The first one corresponds to the header and its structure is always the same. The second one corresponds to the payload and it is where the sensor values are included.
The following figure describes the ASCII Frame structure:
The structure fields are described below with an example:
A → Start Delimiter [3 bytes]: It is composed of three characters: "<=>". This is a 3-byte field and it is necessary to identify each frame starting.
B → Frame type [1 byte]: This field is used to determine the frame type. There are two kinds of frames: Binary and ASCII. But it also defines the aim of the frame such as event frames or alarm frames. This field will be explained in the following sections.
C → Number of Fields [1 byte]: This field specifies the number of sensor fields sent in the frame. This helps to calculate the frame length.
D → Separator [1 byte]: The '#' character defines a separator and it is put before and after each field of the frame.
E → Serial ID [16 bytes]: This is a 16-byte field that identifies each Waspmote device uniquely. The serial ID is taken from a specific chip integrated into Waspmote that gives a different identifier to each Waspmote device. So, it is only readable and can not be modified.
F → Waspmote ID [0..16 bytes]: This is a string defined by the user which may identify each Waspmote inside the user\'s network. The field size is variable [from 0 to 16 bytes]. When the user does not want to give any identifier, the field remains empty between frame\'s separators: "##".
G → Frame sequence [1..3 bytes]: This field indicates the number of sequence frame. This counter is 8-bit, so it goes from 0 to 255. However, as it is an ASCII frame, the number is converted to a string in order to be understood. This is the reason the length of this field varies between one and three bytes. Each time the counter reaches the maximum 255, it is reset to 0. This sequence number is used in order to detect loss of frames.
Note: There is only one frame counter, so in the case two communication modules are used, this counter is incremented each time a new frame is created. If each module needs to create a new frame, the counter will be incremented by 2 in the same loop, one for each frame creation.
The frame payload is composed of several sensor data. All data sent in these fields correspond to a predefined sensor data type in the sensor table. This sensor table is stored in Meshlium (gateway of the network) and it will be used in order to interact with the database.
There are three types of ASCII sensor data:
Simple Data: The sensor field is composed of a single sensor value. The format is: "\:\" and a separator character [#] is set at the end of the value. For example, a temperature field indicating 23 ºC would be as follows:
TC:23#
Complex Data: This is the format used to send sensor fields composed of two or three values. The format is: "<sensor_id>:<value>;<value>;<value>" and a separator character [#] is set at the end of the last value. Accelerometer and GPS measurements are some examples:
ACC:996;-250;-100#
GPS:41.680616;-0.886233#
Special Data: Date and time are defined in a special format.
Date is defined as “ yy-mm-dd ” where:
yy: year
mm: month
dd: day of the month
Example: #DATE:13-01-01#
Time is formatted as "hh-mm-ss+GMT
" where:
hh: hours
mm: minutes
ss: seconds
GMT: GMT is added after hh-mm-ss. It is possible to avoid this information in order to save frame size.
Example without GMT: TIME:12-24-16#
Example with GMT: TIME:12-24-16+1#
This frame type has been designed to create more compressed frames. The main goal of defining binary fields is to save bytes in frame\'s payload in order to send as much information as possible. The main disadvantage is the legibility of the frame.
As the ASCII frames, the Binary frames are also composed of two different parts: header and payload. The header of the Binary frame is quite similar to the ASCII frame except for the frame sequence number and the separator at the end of the header.
The following figure describes the Binary Frame structure:
The structure fields are described below with an example:
A → Start Delimiter [3 bytes]: It is composed of three characters: "\<=>". This is a 3-byte field and it is necessary to identify each frame starting.
B → Frame Type [1 byte]: This field is used to determine the frame type. There are two kinds of frames: Binary and ASCII. But it also defines the aim of the frame such event frames or alarm frames. This field will be explained in the following sections.
C → Number of bytes [1 byte]: This field specifies the number of bytes after this field until the end of the payload is found.
D → Separator [1 byte]: The '#' character defines a separator and it is put between some fields which length is not specified. This helps to parse the different fields in reception.
E → Serial ID [8 byte]: This is a 8-byte field which identifies each Waspmote device uniquely. The serial ID is taken from a specific chip integrated in Waspmote that gives a different identifier to each Waspmote device. So, it is only readable and it can not be modified. Note that the Serial ID is sent as a binary field too.
F → Waspmote ID [variable]: This is a string defined by the user which may identify each Waspmote inside the user\'s network. The field size is variable [from 0 to 16 bytes]. When the user do not want to give any identifier, the field remains empty indicated by a unique '#' character.
G → Frame sequence [1 byte]: This field indicates the number of sent frame. This counter is 8-bit, so it goes from 0 to 255. Each time it reaches the maximum 255 is reset to 0. This sequence number is used in order to detect loss of frames.
Note: There is only one frame counter, so in the case two communication modules are used, this counter is incremented each time a new frame is created. If each module needs to create a new frame, the counter will be incremented by 2 in the same loop, one for each frame creation.
The frame payload might be composed of several sensor data. All data sent in these fields correspond to a predefined sensor data type in the sensor table. Regarding the binary format, each sensor in the sensor table determines the number of necessary bytes to express the sensor value. The sensor table is stored in Meshlium (gateway of the network) and it will be used in order to interact with the database.
There are three types of Binary sensor fields:
Simple Data: The sensor field is composed of a single sensor value. The format of this field is: the first byte codifies the sensor identifier. Following the first byte and according to the sensor table, there is a number of bytes which correspond to the sensor value. For example, the temperature sensor is a float number, so it is a 4-byte field. Thus, the sensor field for 27 ºC will be set as follows:
Note: Floats are codified so they are not a simple conversion.
Complex Data: This is the format used to send sensor data composed of more than one value. The format of this field is: the first byte codifies the sensor type. Then, the different values are codified using as many bytes as they specify in the sensor table. For example, the GPS field is composed of both latitude and longitude floats, which means that 8 bytes are needed for both float values:
Note: Floats are codified so they are not a simple conversion.
String: This is the only field that is formed differently: the first byte codifies the sensor type, the second byte defines the string length, and the rest of the bytes belong to the string itself according to the length previously defined. For example, the string "hello" is formatted as follows:
This type of frame has been designed to create short frames with data. The purpose of implementing tiny frames is to be able to create sensor data frames which can be sent via short-payload protocols, like Sigfox or LoRaWAN. The main disadvantage is that Meshlium does not support this frame format. However, as short-payload protocols send data directly to a Cloud system through a base station, the tiny frame format is perfect for these applications.
Tiny frames generation is based on a previously created binary frame. The goal is to create a full binary frame, and then generate different tiny frames from the original binary frame. So the steps involved in tiny frame creation are:
Step 1: The user must create a single binary frame
Step 2: Add sensor data as usual
Step 3: Finally, generate tiny frames from the current contents of the binary frame
In order to generate new tiny frames the following functions are described.
The setTinyLength()
function allows the user to configure the maximum payload of the tiny frames to be generated. By default, the maximum payload size is 12 bytes. The range of this parameter goes from 10 to 100 bytes.
The generateTinyFrame()
function allows the user to generate a new tiny frame from an original binary frame. The contents of the tiny frame are stored in the bufferTiny
buffer. The length of this buffer is provided by the lengthTiny
variable. This function returns the number of pending sensor fields to be filled in a tiny frame from the original binary frame. So, this function should be called several times until no more pending fields are returned.
The following figure describes the tiny frame structure:
The structure fields are described below with an example:
A → Frame sequence [1 byte]: This field indicates the sequence number. This is an 8-bit counter, so it goes from 0 to 255. Each time it reaches the maximum 255, it is reset to 0. This sequence number is used in order to detect loss of frames. All tiny frames generated from the same original binary frame have the same sequence number. So, this can be understood as frame fragmentation.
B → Length [1 byte]: This is the total number of bytes of the tiny frame including both header and payload. In other words, the total length stored in the lengthTiny
variable.
As it was said before, there is a specific field in the header which specifies the frame type. This field is defined by a byte noted as the sequence of the following bits: b7,b6,b5,b4,b3,b2,b1,b0:
b7: The most significant bit specifies if the frame is ASCII (b7=1) or Binary (b7=0).
b6-b0: The rest of the bits determine the frame type which might be an event frame, a time out frame, etc.
The following table describes all possible sensor fields.
Reference: This column refers to the sensor reference given by Libelium to each sensor in the sensor catalog.
Sensor TAG: This column defines the constants needed to add each sensor to the frame using addSensor() function.
SENSOR ID: Each sensor field has its own identifier. Depending on the Sensor TAG chosen, a different identifier will be set as sensor identifier. ASCII frames use a string label as sensor identifier. Binary frames use a byte as sensor identifier so as to save frame size.
Number of Fields: Defines the number of different fields a sensor value presents. Most sensors only need a unique field. But there are some cases which need more than one, i.e. the GPS module which needs 2 fields for both latitude and longitude measurements.
Type and Size: Indicates the variable type which has to be used for each sensor. The possibilities are: uint8_t (1 byte), int (2 bytes), float (4 bytes), unsigned long (4 bytes), string (variable size). ASCII frames do not have constraints when adding sensor fields in order to facilitate the user to insert new sensor data.
Default Decimal Precision: Defines for each sensor the number of decimals used in ASCII frames when using float variable types.
Units: This column defines the units used for each sensor.
4Figure. Field types for Smart Water Xtreme
< |