From a82569d9f3b409eb39e9abba5135f9c94f9b4c8e Mon Sep 17 00:00:00 2001 From: daishengdong Date: Thu, 2 Jan 2020 18:57:31 +0800 Subject: [PATCH] add Tencent Cloud explorer lora demo develop guide, see http://iwiki.oa.com/pages/viewpage.action?pageId=46342556 --- devices/rhf76_lora/RHF76.c | 144 +++++++++++++----- devices/rhf76_lora/RHF76.h | 9 +- examples/LoRaWAN/lora_demo.c | 120 ++++++++++++--- net/lora_module_wrapper/lora_module_wrapper.c | 21 ++- net/lora_module_wrapper/lora_module_wrapper.h | 23 ++- 5 files changed, 242 insertions(+), 75 deletions(-) diff --git a/devices/rhf76_lora/RHF76.c b/devices/rhf76_lora/RHF76.c index 18eb2d27..6ad51cad 100644 --- a/devices/rhf76_lora/RHF76.c +++ b/devices/rhf76_lora/RHF76.c @@ -1,7 +1,9 @@ #include "RHF76.h" #include "tos_hal.h" -static mcps_indication_t rhf76_mcps_indication; +static const char RHF76_LOWPOWER_SET[] = { + 0xFF,0xFF,0xFF,0xFF,'A','T','+','L','O','W','P','O','W','E','R','=','a','u','t','o','o','f','f','\r','\n' +}; static int rhf76_exit_low_power(void) { @@ -120,13 +122,29 @@ static int rhf76_set_class(lora_class_t lora_class) return -1; } +static int rhf76_set_band(void) +{ + int try = 0; + at_echo_t echo; + + tos_at_echo_create(&echo, NULL, 0, RHF76_ATCMD_REPLY_BAND_CN470); + + while (try++ < 10) { + tos_at_cmd_exec(&echo, 3000, RHF76_ATCMD_SET_BAND_CN470); + if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) { + return 0; + } + } + return -1; +} + static int rhf76_set_chanel(void) { int try = 0; at_echo_t echo; tos_at_echo_create(&echo, NULL, 0, "+CH: NUM"); - + while (try++ < 10) { tos_at_cmd_exec(&echo, 3000, RHF76_ATCMD_SET_CHANNEL); if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) { @@ -178,11 +196,70 @@ static int rhf76_set_mode(lora_mode_t mode) return -1; } -int rhf76_join(void) +int rhf76_join_otaa(const char *deveui, const char *appkey) { int try = 0; at_echo_t echo; + if (rhf76_set_mode(LORA_MODE_LWOTAA) != 0) { + printf("rhf76 set mode FAILED\n"); + return -1; + } + + if (rhf76_set_id(LORA_ID_TYPE_DEVEUI, (char *)deveui) != 0) { + printf("rhf76 set deveui FAILED\n"); + return -1; + } + + if (rhf76_set_key(LORA_KEY_TYPE_APPKEY, (char *)appkey) != 0) { + printf("rhf76 set appkey FAILED\n"); + return -1; + } + + at_delay_ms(2000); + + tos_at_echo_create(&echo, NULL, 0, "+JOIN: Network joined"); + while (try++ < 10) { + tos_at_cmd_exec(&echo, 14000, RHF76_ATCMD_JOIN); + if (echo.status == AT_ECHO_STATUS_OK || echo.status == AT_ECHO_STATUS_EXPECT) { + return 0; + } + } + return -1; +} + +int rhf76_join_abp(const char *deveui, const char *devaddr, const char *nwkskey, const char *appskey) +{ + int try = 0; + at_echo_t echo; + + if (rhf76_set_mode(LORA_MODE_LWABP) != 0) { + printf("rhf76 set mode FAILED\n"); + return -1; + } + + if (rhf76_set_id(LORA_ID_TYPE_DEVEUI, (char *)deveui) != 0) { + printf("rhf76 set deveui FAILED\n"); + return -1; + } + + if (rhf76_set_id(LORA_ID_TYPE_DEVADDR, (char *)devaddr) != 0) { + printf("rhf76 set devaddr FAILED\n"); + return -1; + } + + if (rhf76_set_key(LORA_KEY_TYPE_NWKSKEY, (char *)nwkskey) != 0) { + printf("rhf76 set nwkskey FAILED\n"); + return -1; + } + + if (rhf76_set_key(LORA_KEY_TYPE_APPSKEY, (char *)appskey) != 0) { + printf("rhf76 set appskey FAILED\n"); + return -1; + } + + at_delay_ms(2000); + tos_at_echo_create(&echo, NULL, 0, "+JOIN: Network joined"); while (try++ < 10) { tos_at_cmd_exec(&echo, 14000, RHF76_ATCMD_JOIN); @@ -195,9 +272,6 @@ int rhf76_join(void) static int rhf76_init(void) { - char *key = "2B7E151628AED2A6ABF7158809CF4F3C"; - char *appeui = "70B3D57ED00E0017"; - printf("Init RHF76 LoRa ...\n" ); at_delay_ms(1000); @@ -216,6 +290,11 @@ static int rhf76_init(void) return -1; } + if (rhf76_set_band() != 0) { + printf("rhf76 set band FAILED\n"); + return -1; + } + if (rhf76_set_chanel() != 0) { printf("rhf76 set chanel FAILED\n"); return -1; @@ -226,22 +305,7 @@ static int rhf76_init(void) return -1; } - if (rhf76_set_mode(LORA_MODE_LWOTAA) != 0) { - printf("rhf76 set mode FAILED\n"); - return -1; - } - - if (rhf76_set_id(LORA_ID_TYPE_APPEUI, appeui) != 0) { - printf("rhf76 set appeui FAILED\n"); - return -1; - } - - if (rhf76_set_key(LORA_KEY_TYPE_APPKEY, key) != 0) { - printf("rhf76 set appkey FAILED\n"); - return -1; - } - - at_delay_ms(3000); + at_delay_ms(2000); printf("Init RHF76 LoRa done\n"); return 0; @@ -268,7 +332,7 @@ __STATIC__ void __asciistr2hex(char *in, uint8_t *out, int len) { } } -__STATIC__ char incoming_data_buffer[128]; +__STATIC__ char incoming_data_buffer[128]; __STATIC__ uint8_t hex_stream[128]; __STATIC__ void rhf76_incoming_data_process(void) @@ -288,9 +352,11 @@ __STATIC__ void rhf76_incoming_data_process(void) break; } } - + ret = 0; + memset(incoming_data_buffer, 0x00, 512); + while (1) { tos_at_uart_read(&data, 1); if (data == '"') { @@ -300,17 +366,19 @@ __STATIC__ void rhf76_incoming_data_process(void) } printf("rhf76_incoming_data_process %d: %s\n", ret, incoming_data_buffer); - + __asciistr2hex(incoming_data_buffer, hex_stream, strlen(incoming_data_buffer)); - rhf76_mcps_indication(hex_stream, strlen(incoming_data_buffer)/2); + + extern lora_module_t lora_module_rhf76; + if (lora_module_rhf76.recv_callback) { + lora_module_rhf76.recv_callback(hex_stream, strlen(incoming_data_buffer) / 2); + } } at_event_t rhf76_at_event[] = { { "+CMSGHEX: PORT:", rhf76_incoming_data_process }, }; - - static char __num2hex(uint8_t num) { if (num <= 0x9) { @@ -345,26 +413,20 @@ static int rhf76_send(const void *buf, size_t len) return -1; } __hex2str((uint8_t *)buf, str_buf, len); - + char cmd[100] = {0}; at_echo_t echo; 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, "+CMSG: ACK Received"); + tos_at_echo_create(&echo, NULL, 0, "+CMSG: ACK Received"); 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_recv_register(void* mcps_indication) -{ - rhf76_mcps_indication = (mcps_indication_t)mcps_indication; - return 0; -} - static int rhf76_close(void) { return 0; @@ -372,10 +434,11 @@ static int rhf76_close(void) lora_module_t lora_module_rhf76 = { .init = rhf76_init, - .join = rhf76_join, + .join_otaa = rhf76_join_otaa, + .join_abp = rhf76_join_abp, .send = rhf76_send, - .recv_register = rhf76_recv_register, - .close = rhf76_close + .close = rhf76_close, + .recv_callback = K_NULL, }; int rhf76_lora_init(hal_uart_port_t uart_port) @@ -398,4 +461,3 @@ int rhf76_lora_init(hal_uart_port_t uart_port) return 0; } - diff --git a/devices/rhf76_lora/RHF76.h b/devices/rhf76_lora/RHF76.h index a8524dc5..7b713366 100644 --- a/devices/rhf76_lora/RHF76.h +++ b/devices/rhf76_lora/RHF76.h @@ -50,10 +50,6 @@ typedef enum lora_key_type { LORA_KEY_TYPE_NWKSKEY, } lora_key_type_t; - -const char RHF76_LOWPOWER_SET[] = { - 0xFF,0xFF,0xFF,0xFF,'A','T','+','L','O','W','P','O','W','E','R','=','a','u','t','o','o','f','f','\r','\n' -}; #define RHF76_ATCMD_SET_CLASS_A "AT+CLASS=A\r\n" #define RHF76_ATCMD_SET_CLASS_B "AT+CLASS=B\r\n" #define RHF76_ATCMD_SET_CLASS_C "AT+CLASS=C\r\n" @@ -72,9 +68,12 @@ const char RHF76_LOWPOWER_SET[] = { #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_SET_BAND_CN470 "AT+DR=CN470\r\n" +#define RHF76_ATCMD_REPLY_BAND_CN470 "+DR: CN470" + #define RHF76_ATCMD_SET_CHANNEL "at+ch=num,0-7\r\n" #define RHF76_ATCMD_SET_ADR_OFF "at+adr=off\r\n" -#define RHF76_ATCMD_JOIN "AT+join\r\n" +#define RHF76_ATCMD_JOIN "AT+join\r\n" #define RHF76_ATCMD_SET_MODE_LWOTAA "AT+MODE=LWOTAA\r\n" #define RHF76_ATCMD_SET_MODE_LWABP "AT+MODE=LWABP\r\n" diff --git a/examples/LoRaWAN/lora_demo.c b/examples/LoRaWAN/lora_demo.c index 29c02105..6becb5c5 100644 --- a/examples/LoRaWAN/lora_demo.c +++ b/examples/LoRaWAN/lora_demo.c @@ -1,30 +1,116 @@ #include "lora_demo.h" +#include "HTS221.h" +#include "RHF76.h" -void lorawan_demo(void) +/* + ================================================================================== + data template: + + Type Name Token DataType RW Attribute + property temperature temperature integer readonly range: [-100, 155] + initial: 0 + step: 1 + unit: centigrade + + property humidity humidity integer readonly range: [-0, 100] + initial: 0 + step: 1 + unit: % + + 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; + } + + ================================================================================== + 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; + } + + */ + +uint16_t report_period = 3000; + +typedef struct device_data_st { + uint8_t temperature; + uint8_t humidity; + uint16_t period; +} __PACKED__ dev_data_t; + +typedef struct device_data_wrapper_st { + union { + dev_data_t dev_data; + uint8_t serialize[sizeof(dev_data_t)]; + } u; +} dev_data_wrapper_t; + +dev_data_wrapper_t dev_data_wrapper; + +void recv_callback(uint8_t *data, uint8_t len) { - int count = 1; - extern int rhf76_lora_init(hal_uart_port_t uart_port); + int i = 0; - rhf76_lora_init(HAL_UART_PORT_1); - tos_lora_module_join(); + printf("len: %d\n", len); - while (1) { - if (count % 20 == 0) { - - printf("############task1 count is %d \r\n",count++); - tos_lora_module_send("test data",sizeof("test data")); - } - count++; - osDelay(500); + for (i = 0; i < len; ++i) { + printf("data[%d]: %d\n", i, data[i]); } -} + if (len == 1) { + report_period = data[0]; + } else if (len >= 2) { + report_period = data[0] | (data[1] << 8); + } + printf("report_period: %d\n", report_period); +} void application_entry(void *arg) { - lorawan_demo(); + int16_t temperature; + int16_t humidity; + + HTS221_Init(); + + rhf76_lora_init(HAL_UART_PORT_1); + tos_lora_module_recvcb_register(recv_callback); + + tos_lora_module_join_otaa("8cf957200000fa57", "8cf957200000fa572059aaaaad204a72"); + while (1) { - printf("This is a lorawan demo!\r\n"); - tos_task_delay(1000); + HTS221_Get_Temperature(&temperature); + HTS221_Get_Humidity(&humidity); + + printf("temperature: %2.1f\n", temperature / 10.0); + printf("humidity : %2.1f\n", humidity / 10.0); + + dev_data_wrapper.u.dev_data.temperature = temperature / 10; + dev_data_wrapper.u.dev_data.humidity = humidity / 10; + dev_data_wrapper.u.dev_data.period = report_period; + + tos_lora_module_send(dev_data_wrapper.u.serialize, sizeof(dev_data_t)); + tos_task_delay(report_period); } } + diff --git a/net/lora_module_wrapper/lora_module_wrapper.c b/net/lora_module_wrapper/lora_module_wrapper.c index 2c427a27..82d64ded 100644 --- a/net/lora_module_wrapper/lora_module_wrapper.c +++ b/net/lora_module_wrapper/lora_module_wrapper.c @@ -20,10 +20,18 @@ int tos_lora_module_init(void) return -1; } -int tos_lora_module_join(void) +int tos_lora_module_join_otaa(const char *deveui, const char *appkey) { - if (g_lora_module && g_lora_module->join) { - return g_lora_module->join(); + if (g_lora_module && g_lora_module->join_otaa) { + return g_lora_module->join_otaa(deveui, appkey); + } + return -1; +} + +int tos_lora_module_join_abp(const char *deveui, const char *devaddr, const char *nwkskey, const char *appskey) +{ + if (g_lora_module && g_lora_module->join_abp) { + return g_lora_module->join_abp(deveui, devaddr, nwkskey, appskey); } return -1; } @@ -36,10 +44,11 @@ int tos_lora_module_send(const void *buf, size_t len) return -1; } -int tos_lora_module_recv_register(void* mcps_indication) +int tos_lora_module_recvcb_register(lora_recv_callback_t recv_callback) { - if (g_lora_module && g_lora_module->recv_register) { - return g_lora_module->recv_register(mcps_indication); + if (g_lora_module) { + g_lora_module->recv_callback = recv_callback; + return 0; } return -1; } diff --git a/net/lora_module_wrapper/lora_module_wrapper.h b/net/lora_module_wrapper/lora_module_wrapper.h index 5ef184e4..b5d95c1d 100644 --- a/net/lora_module_wrapper/lora_module_wrapper.h +++ b/net/lora_module_wrapper/lora_module_wrapper.h @@ -21,18 +21,20 @@ #include #include -typedef void (*mcps_indication_t)(uint8_t* data, uint8_t len); +typedef void (*lora_recv_callback_t)(uint8_t *data, uint8_t len); typedef struct lora_module_st { int (*init)(void); - int (*join)(void); + int (*join_otaa)(const char *deveui, const char *appkey); + + int (*join_abp)(const char *deveui, const char *devaddr, const char *nwkskey, const char *appskey); int (*send)(const void *buf, size_t len); - int (*recv_register)(void *mcps_indication); - int (*close)(void); + + lora_recv_callback_t recv_callback; } lora_module_t; /** @@ -62,7 +64,16 @@ int tos_lora_module_init(void); * * @return errcode */ -int tos_lora_module_join(void); +int tos_lora_module_join_otaa(const char *deveui, const char *appkey); + +/** + * @brief Join a lora gateway. + * + * @attention None + * + * @return errcode + */ +int tos_lora_module_join_abp(const char *deveui, const char *devaddr, const char *nwkskey, const char *appskey); /** * @brief Send data by lora module. @@ -85,7 +96,7 @@ int tos_lora_module_send(const void *buf, size_t len); * * @return errcode */ -int tos_lora_module_recv_register(void* mcps_indication); +int tos_lora_module_recvcb_register(lora_recv_callback_t recv_callback); /** * @brief Close the lora module.