diff --git a/.gitignore b/.gitignore index dfb805f2..30bd82cf 100644 --- a/.gitignore +++ b/.gitignore @@ -32,5 +32,5 @@ board/*/MDK-ARM/*.uvguix.* board/*/MDK-ARM/EventRecorderStub.scvd board/*/MDK-ARM/*/*.htm board/*/MDK-ARM/*/*.build_log.htm -Obj/* -Debug/* +board/**/Debug/* +board/**/settings/* diff --git a/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c b/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c index 475d14a3..35583663 100644 --- a/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c +++ b/board/NUCLEO_STM32L073RZ/BSP/Src/lora_demo.c @@ -1,7 +1,8 @@ #include "lora_demo.h" #include "RHF76.h" -#include #include "bsp.h" +#include +#include /* ================================================================================== @@ -18,55 +19,121 @@ step: 1 unit: % + property pressure pressure integer read-write range: [259, 1260] + initial: 260 + step: 1 + unit: hPa + + property magnFullscale magnFullscale integer read-write range: [4, 16] + initial: 4 + step: 1 + unit: guass + + property magn_x magn_x float read-write range: [-16, 16] + initial: 0 + step: 1 + unit: guass + + property magn_y magn_y float read-write range: [-16, 16] + initial: 0 + step: 1 + unit: guass + + property magn_z magn_z float read-write range: [-16, 16] + initial: 0 + step: 1 + unit: guass + + property altitude altitude float read-write range: [-1000, 10000] + initial: 0 + step: 1 + unit: m + + property isconfirmed isconfirmed bool read-write 0: confirmed message + 1: unconfirmed message + property report_period period integer read-write range: [0, 3600] initial: 0 step: 1 unit: second - ================================================================================== up-link parser javascript: function RawToProtocol(fPort, bytes) { - var data = { - "method": "report", - "clientToken" : new Date(), - "params" : {} - }; - data.params.temperature = bytes[0]; - data.params.humidity = bytes[1]; - data.params.period = bytes[2] | (bytes[3] << 8); - return data; - } + var data ={ + "method": "report", + "clientToken": new Date(), + "params": {} + } + data.params.magnFullscale = GetMagnFullscale(bytes[0]); + + var tempSensitivity = bytes[1]; + var humiSensitivity = bytes[2] | (bytes[3]<<8); + var presSensitivity = bytes[4] | (bytes[5]<<8); + var magnSensitivity = bytes[6] | (bytes[7]<<8); + + data.params.temperature = (ConvertToInt16(bytes[8] | (bytes[9]<<8))*1.0/10).toFixed(2); + data.params.humidity = ((bytes[10] | (bytes[11]<<8))*1.0/10).toFixed(2); + data.params.magnX = (ConvertToInt16(bytes[12] | (bytes[13]<<8))*1.0/magnSensitivity).toFixed(2); + data.params.magnY = (ConvertToInt16(bytes[14] | (bytes[15]<<8))*1.0/magnSensitivity).toFixed(2); + data.params.magnZ = (ConvertToInt16(bytes[16] | (bytes[17]<<8))*1.0/magnSensitivity).toFixed(2); + data.params.period = bytes[18] | (bytes[19]<<8); + data.params.pressure = ((bytes[20] | (bytes[21]<<8) | (bytes[22]<<16) | (bytes[23]<<24))*1.0/presSensitivity).toFixed(2); + data.params.altitude = ((Math.pow(1017.92/data.params.pressure,1.0/5.257) - 1)*(data.params.temperature/10.0+273.15)/0.0065).toFixed(2); + return data; + } + + function ConvertToInt16(num) + { + var intNum = num; + if ((num & 0x8000) > 0) { + intNum = num - 0x10000; + } + return intNum; + } + + function GetMagnFullscale(fullscale){ + var MagnFullscale = { 0: 4, 1: 8, 2: 12, 3: 16 }; + return MagnFullscale[fullscale] === undefined ? 4 : MagnFullscale[fullscale]; + } ================================================================================== down-link parser javascript: function ProtocolToRaw(obj) { - var data = new Array(); - data[0] = 5;// fport=5 - data[1] = 0;// unconfirmed mode - data[2] = obj.params.period & 0x00FF; - data[3] = (obj.params.period >> 8) & 0x00FF; - return data; - } + var data = new Array(); + data[0] = 5; // fport = 5 + data[1] = 0; // unconfirmed mode + data[2] = obj.params.period & 0x00FF; + data[3] = (obj.params.period >> 8) & 0x00FF; + data[4] = GetMagnFullscale(obj.params.magnFullscale); + data[5] = obj.params.isconfirmed; + return data; + } + + function GetMagnFullscale(fullscale){ + var MagnFullscale = { 4: 0, 8: 1, 12: 2, 16: 3 }; + return MagnFullscale[fullscale]===undefined?0:MagnFullscale[fullscale]; + } */ uint16_t report_period = 10; +bool is_confirmed = true; typedef struct device_data_st { - uint8_t magn_fullscale; // fullscale of magnetometer - uint8_t temp_sensitivity; - uint16_t humi_sensitivity; - uint16_t press_sensitivity; - uint16_t magn_sensitivity; // sensitivity per fullscale - int16_t temperature; - int16_t humidity; - int16_t magn_x; // X-magnetic value in LSB - int16_t magn_y; // Y-magnetic value in LSB - int16_t magn_z; // Z-magnetic value in LSB - uint16_t period; - uint32_t pressure; + uint8_t magn_fullscale; // fullscale of magnetometer(RW) + uint8_t temp_sensitivity; // temperature sensitivity (R) + uint16_t humi_sensitivity; // humidity sensitivity (R) + uint16_t press_sensitivity; // pressure sensitivity (R) + uint16_t magn_sensitivity; // magnetic sensitivity (R) + int16_t temperature; // temperature (R) + int16_t humidity; // humidity (R) + int16_t magn_x; // X-magnetic value in LSB (R) + int16_t magn_y; // Y-magnetic value in LSB (R) + int16_t magn_z; // Z-magnetic value in LSB (R) + uint16_t period; // report period (R) + uint32_t pressure; // pressure (R) } __PACKED__ dev_data_t; typedef struct device_data_wrapper_st { @@ -80,10 +147,8 @@ dev_data_wrapper_t dev_data_wrapper; void recv_callback(uint8_t *data, uint8_t len) { - int i = 0; - printf("len: %d\n", len); - + int i = 0; for (i = 0; i < len; ++i) { printf("data[%d]: %d\n", i, data[i]); } @@ -92,8 +157,9 @@ void recv_callback(uint8_t *data, uint8_t len) report_period = data[0]; } else if (len >= 2) { report_period = data[0] | (data[1] << 8); + LIS3MDL_Set_FullScale((LIS3MDL_FullScaleTypeDef)data[2]); + is_confirmed = (bool)data[3]; } - printf("report_period: %d\n", report_period); } void print_to_screen(sensor_data_t sensor_data) @@ -112,58 +178,6 @@ void print_to_screen(sensor_data_t sensor_data) /** * @brief application entry * @modified by jieranzhi 2020/03/31 - * @note following javascript code snippet demonstrate how to correctly - * decode the data passed to Tencent cloud - ****************************** CODE START ***************************** - function RawToProtocol(fPort, bytes) - { - var data ={ - "method": "report", - "clientToken": new Date(), - "params": {} - } - var magnFullscale = bytes[0]; - switch(magnFullscale) - { - case 0: - data.params.magnFullscale = 4; - break; - case 1: - data.params.magnFullscale = 8; - break; - case 2: - data.params.magnFullscale = 12; - break; - case 3: - data.params.magnFullscale = 16; - break; - } - var tempSensitivity = bytes[1]; - var humiSensitivity = bytes[2] | (bytes[3]<<8); - var presSensitivity = bytes[4] | (bytes[5]<<8); - var magnSensitivity = bytes[6] | (bytes[7]<<8); - - data.params.temperature = (convertToInt16(bytes[8] | (bytes[9]<<8))*1.0/10).toFixed(2); - data.params.humidity = ((bytes[10] | (bytes[11]<<8))*1.0/10).toFixed(2); - data.params.magnX = (convertToInt16(bytes[12] | (bytes[13]<<8))*1.0/magnSensitivity).toFixed(2); - data.params.magnY = (convertToInt16(bytes[14] | (bytes[15]<<8))*1.0/magnSensitivity).toFixed(2); - data.params.magnZ = (convertToInt16(bytes[16] | (bytes[17]<<8))*1.0/magnSensitivity).toFixed(2); - data.params.period = bytes[18] | (bytes[19]<<8); - data.params.pressure = ((bytes[20] | (bytes[21]<<8) | (bytes[22]<<16) | (bytes[23]<<24))*1.0/presSensitivity).toFixed(2); - data.params.altitude = ((Math.pow(1017.92/data.params.pressure,1.0/5.257) - 1)*(data.params.temperature/10.0+273.15)/0.0065).toFixed(2); - data.params.fPort = fPort; - return data; - } - - function convertToInt16(num) - { - var intNum = num; - if ((num & 0x8000) > 0) { - intNum = num - 0x10000; - } - return intNum; - } - ****************************** CODE END ***************************** */ void application_entry(void *arg) { @@ -174,7 +188,7 @@ void application_entry(void *arg) rhf76_lora_init(HAL_UART_PORT_1); tos_lora_module_recvcb_register(recv_callback); - tos_lora_module_join_otaa("8cf957200000f53c", "8cf957200000f52c6d09aaaaad205a72"); + tos_lora_module_join_otaa("8cf957200000f52c", "8cf957200000f52c6d09aaaaad204a72"); while (1) { BSP_Sensor_Read(&sensor_data); @@ -193,7 +207,12 @@ void application_entry(void *arg) dev_data_wrapper.u.dev_data.pressure = (uint32_t)(sensor_data.sensor_press.pressure); dev_data_wrapper.u.dev_data.period = report_period; // send data to the server (via gateway) - tos_lora_module_send(dev_data_wrapper.u.serialize, sizeof(dev_data_t)); + if(is_confirmed){ + tos_lora_module_send(dev_data_wrapper.u.serialize, sizeof(dev_data_t)); + }else{ + tos_lora_module_send_unconfirmed(dev_data_wrapper.u.serialize, sizeof(dev_data_t)); + } + tos_task_delay(report_period * 1000); } } diff --git a/devices/rhf76_lora/RHF76.c b/devices/rhf76_lora/RHF76.c index 73f67abb..a9a956a0 100644 --- a/devices/rhf76_lora/RHF76.c +++ b/devices/rhf76_lora/RHF76.c @@ -154,6 +154,26 @@ static int rhf76_set_chanel(void) return -1; } +static int rhf76_set_repeat(uint8_t num) +{ + int try = 0; + at_echo_t echo; + char cmd[14] = {0}; + char expect[10] = {'\0'}; + snprintf(cmd, sizeof(cmd), RHF76_ATCMD_SET_REPT, num); + snprintf(expect, sizeof(expect), "+REPT: %d", num); + + tos_at_echo_create(&echo, NULL, 0, expect); + + while (try++ < 10) { + tos_at_cmd_exec(&echo, 3000, cmd); + if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) { + return 0; + } + } + return -1; +} + static int rhf76_set_adr_off(void) { int try = 0; @@ -305,9 +325,14 @@ static int rhf76_init(void) return -1; } + if(rhf76_set_repeat(1)!=0){ + printf("rhf76 set repeat times for unconfirmed message FAILED\n"); + return -1; + } + at_delay_ms(2000); printf("Init RHF76 LoRa done\n"); - + return 0; } @@ -377,6 +402,7 @@ __STATIC__ void rhf76_incoming_data_process(void) at_event_t rhf76_at_event[] = { { "+CMSGHEX: PORT:", rhf76_incoming_data_process }, + { "+MSGHEX: PORT:", rhf76_incoming_data_process } }; static char __num2hex(uint8_t num) @@ -405,7 +431,6 @@ static void __hex2str(uint8_t *in, char *out, int len) static int rhf76_send(const void *buf, size_t len) { - char *str_buf = NULL; str_buf = tos_mmheap_calloc(2 * len + 1, sizeof(char)); @@ -416,7 +441,7 @@ static int rhf76_send(const void *buf, size_t len) char cmd[100] = {0}; at_echo_t echo; - snprintf(cmd, sizeof(cmd), RHF76_ATCMD_FMT_SEND_MSGHEX, str_buf); + snprintf(cmd, sizeof(cmd), RHF76_ATCMD_FMT_SEND_CMSGHEX, str_buf); cmd[sizeof(cmd) - 1] = '\0'; tos_mmheap_free(str_buf); tos_at_echo_create(&echo, NULL, 0, "+CMSG: ACK Received"); @@ -427,18 +452,43 @@ static int rhf76_send(const void *buf, size_t len) return len; } +static int rhf76_send_unconfirmed(const void *buf, size_t len) +{ + + char *str_buf = NULL; + at_echo_t echo; + + str_buf = tos_mmheap_calloc(2 * len + 1, sizeof(char)); + if (!str_buf) { + return -1; + } + __hex2str((uint8_t *)buf, str_buf, len); + + char cmd[100] = {0}; + snprintf(cmd, sizeof(cmd), RHF76_ATCMD_FMT_SEND_MSGHEX, str_buf); + cmd[sizeof(cmd) - 1] = '\0'; + tos_mmheap_free(str_buf); + tos_at_echo_create(&echo, NULL, 0, "+MSGHEX: Done"); + tos_at_cmd_exec(&echo, 6000, cmd); + if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) { + return -1; + } + return len; +} + static int rhf76_close(void) { return 0; } lora_module_t lora_module_rhf76 = { - .init = rhf76_init, - .join_otaa = rhf76_join_otaa, - .join_abp = rhf76_join_abp, - .send = rhf76_send, - .close = rhf76_close, - .recv_callback = K_NULL, + .init = rhf76_init, + .join_otaa = rhf76_join_otaa, + .join_abp = rhf76_join_abp, + .send = rhf76_send, + .send_unconfirmed = rhf76_send_unconfirmed, + .close = rhf76_close, + .recv_callback = K_NULL, }; int rhf76_lora_init(hal_uart_port_t uart_port) diff --git a/devices/rhf76_lora/RHF76.h b/devices/rhf76_lora/RHF76.h index 79cf1dea..f5a2ec34 100644 --- a/devices/rhf76_lora/RHF76.h +++ b/devices/rhf76_lora/RHF76.h @@ -65,7 +65,10 @@ typedef enum lora_key_type { #define RHF76_ATCMD_FMT_SET_KEY_TYPE_APPKEY "AT+KEY=\"appkey\",%s\r\n" #define RHF76_ATCMD_FMT_SET_KEY_TYPE_APPSKEY "AT+KEY=\"appskey\",%s\r\n" #define RHF76_ATCMD_FMT_SET_KEY_TYPE_NWKSKEY "AT+KEY=\"nwkskey\",%s\r\n" -#define RHF76_ATCMD_FMT_SEND_MSGHEX "AT+CMSGHEX=\"%s\"\r\n" +#define RHF76_ATCMD_FMT_SEND_CMSGHEX "AT+CMSGHEX=\"%s\"\r\n" +#define RHF76_ATCMD_FMT_SEND_MSGHEX "AT+MSGHEX=\"%s\"\r\n" + +#define RHF76_ATCMD_SET_REPT "AT+REPT=%d\r\n" #define RHF76_ATCMD_SET_BAND_CN470 "AT+DR=CN470\r\n" #define RHF76_ATCMD_REPLY_BAND_CN470 "+DR: CN470" diff --git a/net/lora_module_wrapper/lora_module_wrapper.c b/net/lora_module_wrapper/lora_module_wrapper.c index 82d64ded..a5811c0d 100644 --- a/net/lora_module_wrapper/lora_module_wrapper.c +++ b/net/lora_module_wrapper/lora_module_wrapper.c @@ -44,6 +44,14 @@ int tos_lora_module_send(const void *buf, size_t len) return -1; } +int tos_lora_module_send_unconfirmed(const void *buf, size_t len) +{ + if (g_lora_module && g_lora_module->send_unconfirmed) { + return g_lora_module->send_unconfirmed(buf, len); + } + return -1; +} + int tos_lora_module_recvcb_register(lora_recv_callback_t recv_callback) { if (g_lora_module) { diff --git a/net/lora_module_wrapper/lora_module_wrapper.h b/net/lora_module_wrapper/lora_module_wrapper.h index b5d95c1d..509e3379 100644 --- a/net/lora_module_wrapper/lora_module_wrapper.h +++ b/net/lora_module_wrapper/lora_module_wrapper.h @@ -32,6 +32,8 @@ typedef struct lora_module_st { int (*send)(const void *buf, size_t len); + int (*send_unconfirmed)(const void *buf, size_t len); + int (*close)(void); lora_recv_callback_t recv_callback; @@ -87,6 +89,18 @@ int tos_lora_module_join_abp(const char *deveui, const char *devaddr, const char */ int tos_lora_module_send(const void *buf, size_t len); +/** + * @brief Send unconfirmed data (message) by lora module. + * + * @attention None + * + * @param[in] buf data to send + * @param[in] len length of the data + * + * @return errcode + */ +int tos_lora_module_send_unconfirmed(const void *buf, size_t len); + /** * @brief Register a Receive callback method by lora module. *