Difference between revisions of "MCU/SensorBox"
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
= Introduction = | = Introduction = | ||
<div style="margin-left:0.75cm;margin-right:0cm;"> | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
− | Sensor Box has general interface to collect sensor data and it | + | Sensor Box has general interface to collect sensor data and it will benefit the user easy to use. |
</div> | </div> | ||
= Architecture = | = Architecture = | ||
<div style="margin-left:0.75cm;margin-right:0cm;"> | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
− | + | [[File:Sb_software_architecture_e01.png|center|Sb_software_architecture_e01.png]] | |
</div> | </div> | ||
= Source tree = | = Source tree = | ||
<div style="margin-left:0.75cm;margin-right:0cm;"> | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
− | + | ||
</div> | </div> | ||
Line 26: | Line 26: | ||
|- | |- | ||
| style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | sensor_lib_cfg.sh | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | sensor_lib_cfg.sh | ||
− | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | The script used to configure which sensor | + | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | The script used to configure which sensor enabled or disabled. |
|} | |} | ||
= Sensor list = | = Sensor list = | ||
<div style="margin-left:0.75cm;margin-right:0cm;"> | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
− | Currently, these sensors are ported into sensor box as default. | + | Currently, these sensors are ported into sensor box as default. Note that the user needs to prepare the H/W for the sensor by yourself. |
* HDC1080 - Digital Temperature/Humidity Sensor | * HDC1080 - Digital Temperature/Humidity Sensor | ||
Line 46: | Line 46: | ||
|- | |- | ||
| style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | Pin-defined | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | Pin-defined | ||
− | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | | + | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | [http://advgitlab.eastasia.cloudapp.azure.com/WISE-IoT/SensorBox/blob/master/sensor_driver/HDC1080/HDC1080.lib/hdc1050.cpp#L5 "hdc1050.cpp"] |
|}<br/> | |}<br/> | ||
Line 62: | Line 62: | ||
|- | |- | ||
| style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | Pin-defined | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | Pin-defined | ||
− | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | | + | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | [http://advgitlab.eastasia.cloudapp.azure.com/WISE-IoT/SensorBox/blob/master/sensor_driver/DS18B20/DS1820_api.cpp#L14-23 DS1820_api.cpp] |
|}<br/> | |}<br/> | ||
− | |||
* VL53L0X - Time-of-Flight ranging sensor | * VL53L0X - Time-of-Flight ranging sensor | ||
Line 79: | Line 78: | ||
|- | |- | ||
| style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | Pin-defined | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | Pin-defined | ||
− | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | | + | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | [http://advgitlab.eastasia.cloudapp.azure.com/WISE-IoT/SensorBox/blob/master/sensor_driver/VL53L0X/VL53L0X_api.cpp#L31 VL53L0X_api.cpp] [http://advgitlab.eastasia.cloudapp.azure.com/WISE-IoT/SensorBox/blob/master/sensor_driver/VL53L0X/VL53L0X_api.cpp#L18-24 shutdown_pin] |
|}<br/> | |}<br/> | ||
Line 95: | Line 94: | ||
|- | |- | ||
| style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | Pin-defined | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | Pin-defined | ||
− | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | | + | | style="border:0.5pt solid #00000a;padding-top:0cm;padding-bottom:0cm;padding-left:0.199cm;padding-right:0.191cm;" | [http://advgitlab.eastasia.cloudapp.azure.com/WISE-IoT/SensorBox/blob/master/sensor_driver/HPMA215S0/HPMA215S0_api.cpp#L27 HPMA215S0_api.cpp] |
|}<br/> | |}<br/> | ||
Line 103: | Line 102: | ||
= API = | = API = | ||
<div style="margin-left:0.75cm;margin-right:0cm;"> | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
− | + | These are commonly APIs of sensor box. | |
− | < | + | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> |
int SBox_iInit(void); | int SBox_iInit(void); | ||
− | </ | + | </syntaxhighlight> |
*Brief | *Brief | ||
:Initialize sensor box | :Initialize sensor box | ||
Line 117: | Line 116: | ||
<br/> | <br/> | ||
− | < | + | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> |
int SBox_iUnInit(void); | int SBox_iUnInit(void); | ||
− | </ | + | </syntaxhighlight> |
*Brief | *Brief | ||
:Uninitialize sensor box | :Uninitialize sensor box | ||
Line 129: | Line 128: | ||
<br/> | <br/> | ||
− | < | + | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> |
int SBox_iGetAllData(TSBDataFmt *_ptDataSet); | int SBox_iGetAllData(TSBDataFmt *_ptDataSet); | ||
− | </ | + | </syntaxhighlight> |
*Brief | *Brief | ||
:Update all sensors and get all data of sensors | :Update all sensors and get all data of sensors | ||
Line 139: | Line 138: | ||
:On success, eSErr_None is returned. | :On success, eSErr_None is returned. | ||
:On error, other is returned. | :On error, other is returned. | ||
+ | <br/> | ||
+ | :Note that each sensor has different data type of sensor data, the user can review sensor_cfg.h to know which sensor has what data type of sensor data. | ||
<br/> | <br/> | ||
− | + | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | |
− | <syntaxhighlight lang="C" style="border:1px solid lightgrey; "> | ||
int SBox_iGetData(int _iModelName, TSBDataFmt *_ptData); | int SBox_iGetData(int _iModelName, TSBDataFmt *_ptData); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
*Brief | *Brief | ||
:Update only one sensor and get data | :Update only one sensor and get data | ||
Line 158: | Line 153: | ||
:On success, eSErr_None is returned. | :On success, eSErr_None is returned. | ||
:On error, other is returned. | :On error, other is returned. | ||
+ | <br/> | ||
+ | :Note that each sensor has different data type of sensor data, the user can review sensor_cfg.h to know which sensor has what data type of sensor data. | ||
+ | <br/> | ||
+ | |||
+ | These macros are used to get index depended on model name and data name of sensors. | ||
+ | |||
+ | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | SB_GET_INDEX(model_name); | ||
+ | </syntaxhighlight> | ||
+ | *Brief | ||
+ | :Get the index with the model name of sensor. | ||
+ | *Parameters | ||
+ | :model_name: the model name that is defined in the sensor_cfg.h. | ||
+ | *Return | ||
+ | :The number is returned. | ||
+ | <br/> | ||
+ | |||
+ | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | SB_GET_DATA_INDEX(model_name, data_name); | ||
+ | </syntaxhighlight> | ||
+ | *Brief | ||
+ | :Get the index with the data of sensor. | ||
+ | *Parameters | ||
+ | :model_name: the model name that is defined in the sensor_cfg.h. | ||
+ | :data_name: the name of sensor data that is defined in the sensor_cfg.h. | ||
+ | *Return | ||
+ | :The number is returned. | ||
<br/> | <br/> | ||
Line 165: | Line 187: | ||
= Get sensor box = | = Get sensor box = | ||
<div style="margin-left:0.75cm;margin-right:0cm;"> | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
− | + | Please click [http://advgitlab.eastasia.cloudapp.azure.com/WISE-IoT/SensorBox "Link to source"] to get source code of Sensor Box and review the file "README.md" to know how use it. | |
</div> | </div> | ||
= Example = | = Example = | ||
<div style="margin-left:0.75cm;margin-right:0cm;"> | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
− | + | * Single sensor | |
+ | |||
+ | <syntaxhighlight lang="C" style="width:100%; border:1px solid lightgrey; "> | ||
+ | #include "mbed.h" | ||
+ | #include <stdio.h> | ||
+ | #include "sbox_api.h" | ||
+ | #include "sbox_dbg.h" | ||
+ | #include "sbox_error.h" | ||
+ | |||
+ | static TSBDataFmt g_atData[eSD_Data_Total]; | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | int ret; | ||
+ | int cnt=0; | ||
+ | |||
+ | SB_MSG_PRINT("Initialize sensor box...\n\r"); | ||
+ | |||
+ | ret = SBox_iInit(); | ||
+ | if(ret != eSErr_None) { | ||
+ | SB_MSG_PRINT("API init failed!\n\r"); | ||
+ | SB_MSG_PRINT("[Error]->:%d, str:%s\n\r", ret, Sbox_strErr2str(ret)); | ||
+ | while(1); | ||
+ | } | ||
+ | |||
+ | while(1) | ||
+ | { | ||
+ | ret = SBox_iGetData(SB_GET_INDEX(SB_MN_HDC1080), g_atData); | ||
+ | if(ret == eSErr_None) { | ||
+ | SB_MSG_PRINT("get temp: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HDC1080, SB_HDC1080_DATA1_NAME)].fData); | ||
+ | SB_MSG_PRINT("get humi: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HDC1080, SB_HDC1080_DATA2_NAME)].u16Data); | ||
+ | } | ||
+ | else { | ||
+ | SB_MSG_PRINT("[Error]->:%d, str:%s\n\r", ret, Sbox_strErr2str(ret)); | ||
+ | } | ||
+ | |||
+ | SB_MSG_PRINT("cnt:%d\n\n\r", cnt++); | ||
+ | Thread::wait(2000); | ||
+ | } | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | <br/> | ||
+ | |||
+ | * Multiple sensors | ||
+ | |||
+ | <syntaxhighlight lang="C" style="width:100%; border:1px solid lightgrey; "> | ||
+ | #include "mbed.h" | ||
+ | #include <stdio.h> | ||
+ | #include "sbox_api.h" | ||
+ | #include "sbox_dbg.h" | ||
+ | #include "sbox_error.h" | ||
+ | |||
+ | static TSBDataFmt g_atData[eSD_Data_Total]; | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | int ret; | ||
+ | int cnt=0; | ||
+ | |||
+ | SB_MSG_PRINT("Initialize sensor box...\n\r"); | ||
+ | |||
+ | ret = SBox_iInit(); | ||
+ | if(ret != eSErr_None) { | ||
+ | SB_MSG_PRINT("API init failed!\n\r"); | ||
+ | SB_MSG_PRINT("[Error]->:%d, str:%s\n\r", ret, Sbox_strErr2str(ret)); | ||
+ | while(1); | ||
+ | } | ||
+ | |||
+ | while(1) | ||
+ | { | ||
+ | ret = SBox_iGetAllData(g_atData); | ||
+ | if(ret == eSErr_None) { | ||
+ | // HDC 1080 | ||
+ | #if defined(SB_MN_HDC1080) | ||
+ | SB_MSG_PRINT("get temp: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HDC1080, SB_HDC1080_DATA1_NAME)].fData); | ||
+ | SB_MSG_PRINT("get humi: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HDC1080, SB_HDC1080_DATA2_NAME)].u16Data); | ||
+ | #endif | ||
+ | |||
+ | // DS18B20 | ||
+ | #if defined(SB_MN_DS18B20) | ||
+ | SB_MSG_PRINT("get temp1: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_DS18B20, SB_DS18B20_DATA1_NAME)].fData); | ||
+ | #if SB_DS18B20_MAX_SENSOR_NUM >= 2 | ||
+ | SB_MSG_PRINT("get temp2: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_DS18B20, SB_DS18B20_DATA2_NAME)].fData); | ||
+ | #endif | ||
+ | #if SB_DS18B20_MAX_SENSOR_NUM >= 3 | ||
+ | SB_MSG_PRINT("get temp3: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_DS18B20, SB_DS18B20_DATA3_NAME)].fData); | ||
+ | #endif | ||
+ | #endif | ||
+ | |||
+ | // VL53L0X | ||
+ | #if defined(SB_MN_VL53L0X) | ||
+ | SB_MSG_PRINT("get Middle: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_VL53L0X, SB_VL53L0X_DATA1_NAME)].u32Data); | ||
+ | SB_MSG_PRINT("get Right : %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_VL53L0X, SB_VL53L0X_DATA2_NAME)].u32Data); | ||
+ | SB_MSG_PRINT("get Left : %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_VL53L0X, SB_VL53L0X_DATA3_NAME)].u32Data); | ||
+ | #endif | ||
+ | |||
+ | // HPMA215S0 | ||
+ | #if defined(SB_MN_HPMA215S0) | ||
+ | SB_MSG_PRINT("get pm2.5: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HPMA215S0, SB_HPMA215S0_DATA1_NAME)].u16Data); | ||
+ | SB_MSG_PRINT("get pm1.0: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HPMA215S0, SB_HPMA215S0_DATA2_NAME)].u16Data); | ||
+ | #endif | ||
+ | } | ||
+ | else { | ||
+ | SB_MSG_PRINT("[Error]->:%d, str:%s\n\r", ret, Sbox_strErr2str(ret)); | ||
+ | } | ||
+ | |||
+ | SB_MSG_PRINT("cnt:%d\n\n\r", cnt++); | ||
+ | Thread::wait(2000); | ||
+ | } | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
</div> | </div> | ||
= How to porting new sensor into sensor box = | = How to porting new sensor into sensor box = | ||
<div style="margin-left:0.75cm;margin-right:0cm;"> | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
− | + | This chapter is described for how to porting new sensor. The user needs to set configuration, implement HAL instance and sensor driver. Please follow the below in more detailed.<br/> | |
+ | </div> | ||
+ | |||
+ | == Add new configuration with the model name and sensor data == | ||
+ | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
+ | When the user intends to add new sensor into sensor box, the user needs to modify both files "sensor_cfg.h" and "sensor_index.h" located at the folder "sensor_api", then follows the below for how to do. | ||
+ | <br/><br/> | ||
+ | '''Step01: ''' Define the model name: | ||
+ | :Please define the model name by the macro that is based on naming rule of "SN_MN" + "DRIVER_FOLDER" in the file "sensor_cfg.h". | ||
+ | :*"SB_MN_" is fixed string as prefix. | ||
+ | :*"DRIVER_FOLDER" is the name of directory of specified sensor driver and it's located at the folder "sensor_driver". | ||
+ | :For example as below: | ||
+ | |||
+ | ::<syntaxhighlight lang="C" style="width:60%; border:1px solid lightgrey; "> | ||
+ | #define SB_MN_HDC1080 Hdc1080 | ||
+ | </syntaxhighlight> | ||
+ | ::<syntaxhighlight lang="C" style="width:60%; border:1px solid lightgrey; "> | ||
+ | #define SB_MN_DS18B20 Ds18b20 | ||
+ | </syntaxhighlight> | ||
+ | <br/> | ||
+ | |||
+ | '''Step02: ''' Define the sensor data: | ||
+ | :Please define the name of sensor data by the macro that is based on naming rule of "SB_" + "DRIVER_FOLDER" + "_DATA" + N + "_NAME" in the file "sensor_cfg.h". | ||
+ | :*"SB_" is fixed string as prefix. | ||
+ | :*"DRIVER_FOLDER" is the name of directory of specified sensor driver and it's located at the folder "sensor_driver". | ||
+ | :*"_DATA" is fixed string. | ||
+ | :*N is serial number of this sensor that follows the convention 1...N. | ||
+ | :*"_NAME" is fixed string as postfix.<div style="margin-left:0.75cm;margin-right:0cm;"> | ||
+ | |||
+ | ::<syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | #define SB_HDC1080_DATA1_NAME Temperature | ||
+ | </syntaxhighlight> | ||
+ | ::<syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | #define SB_HDC1080_DATA2_NAME Humidity | ||
+ | </syntaxhighlight> | ||
+ | <br/> | ||
+ | |||
+ | '''Step03: ''' Create index with the sensor: | ||
+ | :The user needs to modify the file "sensor_index.h" located at the folder "sensor_api" for below steps. | ||
+ | :* Add index into "enum ESensorModelNameList" | ||
+ | ::The index of model name is defined using macro "SB_DEFINE_MN(model_name)". The model name is defined above by the user. | ||
+ | <syntaxhighlight lang="C" highlight="4-6" style="width:100%; border:1px solid lightgrey; "> | ||
+ | typedef enum ESensorModelNameList | ||
+ | { | ||
+ | // HDC 1080 | ||
+ | #if defined(SB_MN_HDC1080) | ||
+ | SB_DEFINE_MN(SB_MN_HDC1080), | ||
+ | #endif | ||
+ | |||
+ | SB_DEFINE_MN(Total) | ||
+ | }TSBModelNameList; | ||
+ | </syntaxhighlight> | ||
+ | <br/> | ||
+ | |||
+ | :* Add index into "enum ESensorDataList" | ||
+ | ::The index of sensor data is defined using macro "SB_DEFINE_DATA(model_name, sensor_data)". Both model name and sensor data are defined above by the user. | ||
+ | <syntaxhighlight lang="C" highlight="4-7" style="width:100%; border:1px solid lightgrey; "> | ||
+ | typedef enum ESensorDataList | ||
+ | { | ||
+ | // HDC 1080 | ||
+ | #if defined(SB_MN_HDC1080) | ||
+ | SB_DEFINE_DATA(SB_MN_HDC1080, SB_HDC1080_DATA1_NAME), | ||
+ | SB_DEFINE_DATA(SB_MN_HDC1080, SB_HDC1080_DATA2_NAME), | ||
+ | #endif | ||
+ | |||
+ | SB_DEFINE_DATA(Data, Total) | ||
+ | }TSBDataList; | ||
+ | </syntaxhighlight> | ||
+ | <br/> | ||
+ | </div> | ||
+ | |||
+ | == Add new HAL instance == | ||
+ | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
+ | To add new HAL instance, please create the new folder of your own sensor with uppercase in the folder "sensor_driver". The new folder it's called "DRIVER_FOLDER". there are three files include DRIVER_FOLDER_api.h, DRIVER_FOLDER_api.cpp and DRIVER_FOLDER_error.h the user needs to create and put it into the your "DRIVER_FOLDER". | ||
+ | The HAL API of sensor box with your own sensor has been implemented by the user. After the instance of HAL API completely, it is added in the array of HAL for initiation. Please also remember to define the error code for your own sensor. | ||
+ | |||
+ | |||
+ | * Define the HAL instance | ||
+ | : The user can refer to typedef struct TSensorBoxHal in the "sensor_hal.h" for creating the HAL instance. The HAL instance is defined in the DRIVER_FOLDER_api.cpp. For example, the below is the HAL instance with HDC1080 and the user will see it in the file HDC1080_api.cpp. | ||
+ | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | TSensorBoxHal gtHDC1080Hal = { | ||
+ | .SBHal_pfiInit = HDC1080_iInit, | ||
+ | .SBHal_pfiUnInit = HDC1080_iUnInit, | ||
+ | .SBHal_pfiGetData = HDC1080_iGetData | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | <br/> | ||
+ | |||
+ | * Implement HAL API | ||
+ | : Depended on your own sensor, please implement HAL APIs in the DRIVER_FOLDER_api.cpp. For example with HDC1080, we have implemented HDC1080_iInit, HDC1080_iUnInit and HDC1080_iGetData in the HDC1080_app.cpp. | ||
+ | <br/> | ||
+ | |||
+ | * Define error code | ||
+ | : Please define the set of error code with your own sensor in the DRIVER_FOLDER_error.h. For example, the below is the set of error code with HDC1080 and you will see it in HDC1080_error.h. | ||
+ | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | #if defined(SB_MN_HDC1080) | ||
+ | #define SB_ERR_HDC1080_LIST \ | ||
+ | X(eSErr_Hdc1080_Init) \ | ||
+ | X(eSErr_Hdc1080_GetData) | ||
+ | #endif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Add the set of error code into sensor_error.h | ||
+ | : For example, the below is with HDC1080. | ||
+ | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | #if defined(SB_MN_HDC1080) | ||
+ | #include "HDC1080_error.h" | ||
+ | #endif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | : Add the set of error into "enum ESensorBoxErrorList" | ||
+ | <syntaxhighlight lang="C" highlight="6-8" style="width:80%; border:1px solid lightgrey; "> | ||
+ | typedef enum ESensorBoxErrorList | ||
+ | { | ||
+ | eSErr_None = 0, | ||
+ | |||
+ | // HDC 1080 | ||
+ | #if defined(SB_MN_HDC1080) | ||
+ | SB_ERR_HDC1080_LIST | ||
+ | #endif | ||
+ | |||
+ | eSErr_Total | ||
+ | }TSensorBoxErrorList; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | : Note: the user can get the string with specified error code to know what it means by the below API. | ||
+ | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | const char *Sbox_strErr2str(int _iErr); | ||
+ | </syntaxhighlight> | ||
+ | :_iErr: the number of error code. | ||
+ | <br/> | ||
+ | |||
+ | * Add HAL instance for initialization | ||
+ | : Please align the HAL instance to the array that has elements defined by pointer to typedef struct TSensorBoxHal in function "SBoxHal_iInit" in sbox_hal.cpp. For example, the below is with HDC1080. | ||
+ | <syntaxhighlight lang="C" style="width:80%; border:1px solid lightgrey; "> | ||
+ | // HDC1080 | ||
+ | #if defined(SB_MN_HDC1080) | ||
+ | #include "HDC1080_api.h" | ||
+ | #endif | ||
+ | |||
+ | int SBoxHal_iInit(TSensorBoxHal* _atArray[]) | ||
+ | { | ||
+ | // HDC1080 | ||
+ | #if defined(SB_MN_HDC1080) | ||
+ | _atArray[SB_GET_INDEX(SB_MN_HDC1080)] = >HDC1080Hal; | ||
+ | #endif | ||
+ | |||
+ | return eSErr_None; | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | |||
+ | |||
+ | == Add new sensor driver == | ||
+ | <div style="margin-left:0.75cm;margin-right:0cm;"> | ||
+ | For various sensors, it needs different sensor driver. please put the sensor driver in your DRIVER_FOLDER. The sensor driver is used for implementation with HAL API. For example, in the directory "sensor_driver/HDC1080/", the user will see the directory "HDC1080.lib" that is sensor driver with HDC1080. | ||
</div> | </div> |
Latest revision as of 09:15, 30 August 2019
Contents
Introduction
Sensor Box has general interface to collect sensor data and it will benefit the user easy to use.
Architecture
Source tree
Directory | Description |
sensor_api | The source code of API of Sensor Box. |
sensor_driver | The source code of sensor driver. |
sensor_lib_cfg.sh | The script used to configure which sensor enabled or disabled. |
Sensor list
Currently, these sensors are ported into sensor box as default. Note that the user needs to prepare the H/W for the sensor by yourself.
- HDC1080 - Digital Temperature/Humidity Sensor
Item Description Vendor Texas Instruments Interface I2C Pin-defined "hdc1050.cpp"
- DS18B20 - 1-Wire Digital Thermometer
Item Description Vendor Maxim Interface GPIO Pin-defined DS1820_api.cpp
- VL53L0X - Time-of-Flight ranging sensor
Item Description Vendor STMicroelectronics Interface I2C Pin-defined VL53L0X_api.cpp shutdown_pin
- HPMA215S0-XXX - Particle Sensor
Item Description Vendor Honeywell Interface I2C Pin-defined HPMA215S0_api.cpp
API
These are commonly APIs of sensor box.
int SBox_iInit(void);
- Brief
- Initialize sensor box
- Parameters
- None
- Return
- On success, eSErr_None is returned.
- On error, other is returned.
int SBox_iUnInit(void);
- Brief
- Uninitialize sensor box
- Parameters
- None
- Return
- On success, eSErr_None is returned.
- On error, other is returned.
int SBox_iGetAllData(TSBDataFmt *_ptDataSet);
- Brief
- Update all sensors and get all data of sensors
- Parameters
- _ptDataSet: the pointer to data buffer that is used to get sensor data back.
- Return
- On success, eSErr_None is returned.
- On error, other is returned.
- Note that each sensor has different data type of sensor data, the user can review sensor_cfg.h to know which sensor has what data type of sensor data.
int SBox_iGetData(int _iModelName, TSBDataFmt *_ptData);
- Brief
- Update only one sensor and get data
- Parameters
- _iModelName: the index of model name to specify which sensor will be updated.
- _ptData: the pointer to data that is used to get sensor data back.
- Return
- On success, eSErr_None is returned.
- On error, other is returned.
- Note that each sensor has different data type of sensor data, the user can review sensor_cfg.h to know which sensor has what data type of sensor data.
These macros are used to get index depended on model name and data name of sensors.
SB_GET_INDEX(model_name);
- Brief
- Get the index with the model name of sensor.
- Parameters
- model_name: the model name that is defined in the sensor_cfg.h.
- Return
- The number is returned.
SB_GET_DATA_INDEX(model_name, data_name);
- Brief
- Get the index with the data of sensor.
- Parameters
- model_name: the model name that is defined in the sensor_cfg.h.
- data_name: the name of sensor data that is defined in the sensor_cfg.h.
- Return
- The number is returned.
Get sensor box
Please click "Link to source" to get source code of Sensor Box and review the file "README.md" to know how use it.
Example
- Single sensor
#include "mbed.h"
#include <stdio.h>
#include "sbox_api.h"
#include "sbox_dbg.h"
#include "sbox_error.h"
static TSBDataFmt g_atData[eSD_Data_Total];
int main ()
{
int ret;
int cnt=0;
SB_MSG_PRINT("Initialize sensor box...\n\r");
ret = SBox_iInit();
if(ret != eSErr_None) {
SB_MSG_PRINT("API init failed!\n\r");
SB_MSG_PRINT("[Error]->:%d, str:%s\n\r", ret, Sbox_strErr2str(ret));
while(1);
}
while(1)
{
ret = SBox_iGetData(SB_GET_INDEX(SB_MN_HDC1080), g_atData);
if(ret == eSErr_None) {
SB_MSG_PRINT("get temp: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HDC1080, SB_HDC1080_DATA1_NAME)].fData);
SB_MSG_PRINT("get humi: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HDC1080, SB_HDC1080_DATA2_NAME)].u16Data);
}
else {
SB_MSG_PRINT("[Error]->:%d, str:%s\n\r", ret, Sbox_strErr2str(ret));
}
SB_MSG_PRINT("cnt:%d\n\n\r", cnt++);
Thread::wait(2000);
}
return 0;
}
- Multiple sensors
#include "mbed.h"
#include <stdio.h>
#include "sbox_api.h"
#include "sbox_dbg.h"
#include "sbox_error.h"
static TSBDataFmt g_atData[eSD_Data_Total];
int main ()
{
int ret;
int cnt=0;
SB_MSG_PRINT("Initialize sensor box...\n\r");
ret = SBox_iInit();
if(ret != eSErr_None) {
SB_MSG_PRINT("API init failed!\n\r");
SB_MSG_PRINT("[Error]->:%d, str:%s\n\r", ret, Sbox_strErr2str(ret));
while(1);
}
while(1)
{
ret = SBox_iGetAllData(g_atData);
if(ret == eSErr_None) {
// HDC 1080
#if defined(SB_MN_HDC1080)
SB_MSG_PRINT("get temp: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HDC1080, SB_HDC1080_DATA1_NAME)].fData);
SB_MSG_PRINT("get humi: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HDC1080, SB_HDC1080_DATA2_NAME)].u16Data);
#endif
// DS18B20
#if defined(SB_MN_DS18B20)
SB_MSG_PRINT("get temp1: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_DS18B20, SB_DS18B20_DATA1_NAME)].fData);
#if SB_DS18B20_MAX_SENSOR_NUM >= 2
SB_MSG_PRINT("get temp2: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_DS18B20, SB_DS18B20_DATA2_NAME)].fData);
#endif
#if SB_DS18B20_MAX_SENSOR_NUM >= 3
SB_MSG_PRINT("get temp3: %.2f\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_DS18B20, SB_DS18B20_DATA3_NAME)].fData);
#endif
#endif
// VL53L0X
#if defined(SB_MN_VL53L0X)
SB_MSG_PRINT("get Middle: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_VL53L0X, SB_VL53L0X_DATA1_NAME)].u32Data);
SB_MSG_PRINT("get Right : %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_VL53L0X, SB_VL53L0X_DATA2_NAME)].u32Data);
SB_MSG_PRINT("get Left : %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_VL53L0X, SB_VL53L0X_DATA3_NAME)].u32Data);
#endif
// HPMA215S0
#if defined(SB_MN_HPMA215S0)
SB_MSG_PRINT("get pm2.5: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HPMA215S0, SB_HPMA215S0_DATA1_NAME)].u16Data);
SB_MSG_PRINT("get pm1.0: %d\n\r", g_atData[SB_GET_DATA_INDEX(SB_MN_HPMA215S0, SB_HPMA215S0_DATA2_NAME)].u16Data);
#endif
}
else {
SB_MSG_PRINT("[Error]->:%d, str:%s\n\r", ret, Sbox_strErr2str(ret));
}
SB_MSG_PRINT("cnt:%d\n\n\r", cnt++);
Thread::wait(2000);
}
return 0;
}
How to porting new sensor into sensor box
This chapter is described for how to porting new sensor. The user needs to set configuration, implement HAL instance and sensor driver. Please follow the below in more detailed.
Add new configuration with the model name and sensor data
When the user intends to add new sensor into sensor box, the user needs to modify both files "sensor_cfg.h" and "sensor_index.h" located at the folder "sensor_api", then follows the below for how to do.
Step01: Define the model name:
- Please define the model name by the macro that is based on naming rule of "SN_MN" + "DRIVER_FOLDER" in the file "sensor_cfg.h".
- "SB_MN_" is fixed string as prefix.
- "DRIVER_FOLDER" is the name of directory of specified sensor driver and it's located at the folder "sensor_driver".
- For example as below:
#define SB_MN_HDC1080 Hdc1080
#define SB_MN_DS18B20 Ds18b20
Step02: Define the sensor data:
- Please define the name of sensor data by the macro that is based on naming rule of "SB_" + "DRIVER_FOLDER" + "_DATA" + N + "_NAME" in the file "sensor_cfg.h".
- "SB_" is fixed string as prefix.
- "DRIVER_FOLDER" is the name of directory of specified sensor driver and it's located at the folder "sensor_driver".
- "_DATA" is fixed string.
- N is serial number of this sensor that follows the convention 1...N.
- "_NAME" is fixed string as postfix.
#define SB_HDC1080_DATA1_NAME Temperature
#define SB_HDC1080_DATA2_NAME Humidity
Step03: Create index with the sensor:
- The user needs to modify the file "sensor_index.h" located at the folder "sensor_api" for below steps.
- Add index into "enum ESensorModelNameList"
- The index of model name is defined using macro "SB_DEFINE_MN(model_name)". The model name is defined above by the user.
typedef enum ESensorModelNameList { // HDC 1080 #if defined(SB_MN_HDC1080) SB_DEFINE_MN(SB_MN_HDC1080), #endif SB_DEFINE_MN(Total) }TSBModelNameList;
- Add index into "enum ESensorDataList"
- The index of sensor data is defined using macro "SB_DEFINE_DATA(model_name, sensor_data)". Both model name and sensor data are defined above by the user.
typedef enum ESensorDataList { // HDC 1080 #if defined(SB_MN_HDC1080) SB_DEFINE_DATA(SB_MN_HDC1080, SB_HDC1080_DATA1_NAME), SB_DEFINE_DATA(SB_MN_HDC1080, SB_HDC1080_DATA2_NAME), #endif SB_DEFINE_DATA(Data, Total) }TSBDataList;
Add new HAL instance
To add new HAL instance, please create the new folder of your own sensor with uppercase in the folder "sensor_driver". The new folder it's called "DRIVER_FOLDER". there are three files include DRIVER_FOLDER_api.h, DRIVER_FOLDER_api.cpp and DRIVER_FOLDER_error.h the user needs to create and put it into the your "DRIVER_FOLDER". The HAL API of sensor box with your own sensor has been implemented by the user. After the instance of HAL API completely, it is added in the array of HAL for initiation. Please also remember to define the error code for your own sensor.
- Define the HAL instance
- The user can refer to typedef struct TSensorBoxHal in the "sensor_hal.h" for creating the HAL instance. The HAL instance is defined in the DRIVER_FOLDER_api.cpp. For example, the below is the HAL instance with HDC1080 and the user will see it in the file HDC1080_api.cpp.
TSensorBoxHal gtHDC1080Hal = { .SBHal_pfiInit = HDC1080_iInit, .SBHal_pfiUnInit = HDC1080_iUnInit, .SBHal_pfiGetData = HDC1080_iGetData };
- Implement HAL API
- Depended on your own sensor, please implement HAL APIs in the DRIVER_FOLDER_api.cpp. For example with HDC1080, we have implemented HDC1080_iInit, HDC1080_iUnInit and HDC1080_iGetData in the HDC1080_app.cpp.
- Define error code
- Please define the set of error code with your own sensor in the DRIVER_FOLDER_error.h. For example, the below is the set of error code with HDC1080 and you will see it in HDC1080_error.h.
#if defined(SB_MN_HDC1080) #define SB_ERR_HDC1080_LIST \ X(eSErr_Hdc1080_Init) \ X(eSErr_Hdc1080_GetData) #endif
- Add the set of error code into sensor_error.h
- For example, the below is with HDC1080.
#if defined(SB_MN_HDC1080) #include "HDC1080_error.h" #endif
- Add the set of error into "enum ESensorBoxErrorList"
typedef enum ESensorBoxErrorList { eSErr_None = 0, // HDC 1080 #if defined(SB_MN_HDC1080) SB_ERR_HDC1080_LIST #endif eSErr_Total }TSensorBoxErrorList;
- Note: the user can get the string with specified error code to know what it means by the below API.
const char *Sbox_strErr2str(int _iErr);
- _iErr: the number of error code.
- Add HAL instance for initialization
- Please align the HAL instance to the array that has elements defined by pointer to typedef struct TSensorBoxHal in function "SBoxHal_iInit" in sbox_hal.cpp. For example, the below is with HDC1080.
// HDC1080 #if defined(SB_MN_HDC1080) #include "HDC1080_api.h" #endif int SBoxHal_iInit(TSensorBoxHal* _atArray[]) { // HDC1080 #if defined(SB_MN_HDC1080) _atArray[SB_GET_INDEX(SB_MN_HDC1080)] = >HDC1080Hal; #endif return eSErr_None; }
Add new sensor driver
For various sensors, it needs different sensor driver. please put the sensor driver in your DRIVER_FOLDER. The sensor driver is used for implementation with HAL API. For example, in the directory "sensor_driver/HDC1080/", the user will see the directory "HDC1080.lib" that is sensor driver with HDC1080.