RA4M2挑战赛分享:
【RA4M2设计挑战赛】1. RASC配置FreeRTOS
【RA4M2设计挑战赛】2. 硬件IIC读取HS3003的温湿度数据
【RA4M2设计挑战赛】3. 硬件IIC读取ISL29035采集光照强度
【RA4M2设计挑战赛】4. DA14531蓝牙模块使用
【瑞萨RA4系列开发板体验】5. DA16200 wifi模块操作
本文主要是讲解如何使用DA16200通过TCP透传的方式连接到Onenet云平台,并且讲解onenet云平台的功能以及操作方式。
DA16200支持TCP服务,具体可以参考手册:
《REN_UM-WI-003_DA16200_DA16600_AT-Command_Rev_2v12_MAS_20220808.pdf》
使用下面的命令可以连接TCP服务器:
AT+TRTC
当成功连接了TCP服务器之后,
使用下面的命令发送TCP数据
<ESC>S
这里需要特别说明:
接收来自TCP服务器的数据格式为:
+TRDTC
可以通过识别关键字解析出数据.
注意:数据包含了remote_ip以及remote_port以及数据长度等信息,需要处理。
关于WIFI模块作为服务器使用,不在本文讨论范围内。
多协议接入网址(需登录):
关于onenet tcp透传,使用该方式可以参考官方文档
如下新建设备,先不要关注脚本解析和关联脚本,后面会说如何编写。
查看设备详情,下面的两个信息很重要,TCP透传的身份鉴别需要使用。
数据流的名称比较中要,Lua解析脚本会使用到。
现在都准备好了,可以开始编写Lua脚本了。
TCP透传的数据是通过Lua脚本来解析的。可以下载的官方的示例脚本,我们做修改即可,主要需要实现两个函数的内容
device_timer_init:设备周期性下发命令,这个可以不用编写任何代码
device_data_analyze:用户上传数据分析处理函数,在这个里面解析我们上传的数据就可以了。
关于每个函数的意义在Lua脚本中有详细的说明,参考就可以,或者参考上述官方教程中的说明。
我的Lua脚本实现如下:
function device_data_analyze(dev)
local t={}
local a=0
-- 添加用户自定义代码 --
-- 例如: --
local s = dev:size()
local temp = 0
local str_end = 0
local humi = 0
local lux = 0
local mq5_ppm = 0
local lamp_pwm = 0
-- 找到关键字 --
-- T后面是温度,单位摄氏度 --
-- H后面是湿度,单位百分比 --
-- L后面是环境光亮度,单位Lux --
-- M后面是环境可燃气体浓度,单位是ppm --
-- P后面是台灯亮度,单位百分比 --
temp, str_end = string.find(dev:bytes(1, s), "T")
humi, str_end = string.find(dev:bytes(1, s), "H")
lux, str_end = string.find(dev:bytes(1, s), "L")
mq5_ppm, str_end = string.find(dev:bytes(1, s), "M")
lamp_pwm, str_end = string.find(dev:bytes(1, s), "P")
add_val(t, "temp", a, dev:bytes(temp+1, humi-temp-1))
add_val(t, "humi", a, dev:bytes(humi+1, lux-humi-1))
add_val(t, "Lux", a, dev:bytes(lux+1, mq5_ppm-lux-1))
add_val(t, "combustible_gas", a, dev:bytes(mq5_ppm+1, lamp_pwm-mq5_ppm-1))
add_val(t, "DeskLampBrightness", a, dev:bytes(lamp_pwm+1, s-lamp_pwm))
-- 成功收到数据后的响应 --
dev:response()
dev:send("received")
-- dev:send("received" .. dev:bytes(1, s) .. '|' .. tostring(temp) .. '|' .. tostring(humi) .. '|' .. tostring(lux) ..'|' .. tostring(mq5_ppm) .. '|' .. tostring(lamp_pwm))
-- return $1,$2 --
-- 例如: --
return s,to_json(t)
end
脚本代码说明:
我自己定义了一个数据格式:
T+$温度+H+$湿度+L+$光照强度+M+$可燃气体浓度+P+$台灯亮度
举例,如果上传的温度为35.2度,湿度为56.2%,光照强度为123Lux,可燃气体浓度3000ppm,台灯亮度为65%,为则数据格式应该为:
T35.2H56.2L123M3000P65
OneNet收到上述数据之后会进行解析之后,分别显示在不同的数据流中。
收到了上述格式的数据之后,脚本就会识别出关键字 T H L M P并分别解析出后面的数字加载到对应的数据流中。
local s = dev:size()
表示获取收到的数据长度
最后的返回值return s,to_json(t)为解析的数据长度以及json格式的数据流数据。
我们每次解析的长度都是s,这个固定的,to_json就是将解析出来的数据以json格式放到对应的数据流中。
OneNet平台的设备创建好了之后就是下位机代码的编写了
使用了TCP透传,详细代码如下:
app_wifi.c
/*
@hehung
2023-2-8
转载请注明出处,版权由@hehung所有
email: 1398660197@qq.com
wechat: hehung95
*/
#include "app_wifi.h"
#include "da16200_AT.h"
#include "hal_data.h"
#include "app_led.h"
#include "app_common.h"
#include "app_rtc.h"
#include "app_isl29035.h"
#include "app_hs300x.h"
#include "app_mq5.h"
#include <stdio.h>
#include <string.h>
#define WIFI_DEBUG
#ifdef WIFI_DEBUG
#define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define LOG(fmt, ...)
#endif
#define WIFI_ATF_EN (COMM_ON)
#define WIFI_CHECK_AP_CONN_STA_EN (COMM_OFF)
#define WIFI_PERIOD (20U) // RTOS period is 20ms
// Check AP connect status period
#define WIFI_CONN_STA_CHK_PERIOS (200000U)
#define WIFI_CONN_PREIOD ((uint32_t)((WIFI_CONN_STA_CHK_PERIOS) / (WIFI_PERIOD))) // 10s
#define WIFI_RESET_PIN (BSP_IO_PORT_06_PIN_08)
typedef struct
{
int sec;
int min;
int hour;
int mday;
int mon;
int year;
} s_Da16200TimeType;
#define WIFI_TCP_DATA_LEN (128U)
static e_WifiOptType wifi_opt_mode = WIFI_OPT_INIT;
static e_WifiOptType wifi_opt_mode_pre = WIFI_OPT_INIT;
static e_ApConnectStatusType wifi_conn_status = WIFI_DISEONNECTED;
static e_WifiIotConnStaType wifi_iot_conn_status = WIFI_ONENET_DISCONNECTED;
static uint16_t wifi_conn_sta_check_cnt = 0U;
static uint16_t wifi_tcp_send_cnt = 0U;
static char wifi_tcp_str[WIFI_TCP_DATA_LEN];
// TCP transmittion head '<ESC>S'
static char *wifi_tcp_head = "S1";
// IP address and port in Onenet TCP transparent transmission
static char *wifi_tcp_ip_port = ",183.230.40.40,1811,";
// User information in Onenet TCP transparent transmission
static char *wifi_tcp_info = "*575047#ra4m2info#ra4m2*\r\n";
static fsp_err_t Wifi_Setting(void);
static fsp_err_t Wifi_ConnectToAp(void);
static fsp_err_t Wifi_ConnectToTcp(void);
static fsp_err_t Wifi_SntpStart(void);
static fsp_err_t Wifi_GetTime(void);
static void Wifi_OperateModeManage(void);
#if (WIFI_CHECK_AP_CONN_STA_EN == STD_ON)
static void Wifi_JudgeConnectStatusPeriod(void);
#endif
static e_ApConnectStatusType Wifi_GetAPConnectStatus(void);
// Da16200 wifi initialization
void Wifi_Init(void)
{
// reset wifi module first
R_IOPORT_PinWrite(&g_ioport_ctrl, WIFI_RESET_PIN, BSP_IO_LEVEL_LOW);
DELAY_MS(10);
R_IOPORT_PinWrite(&g_ioport_ctrl, WIFI_RESET_PIN, BSP_IO_LEVEL_HIGH);
// Initialize the timer for counter
g_timer0.p_api->open(g_timer0.p_ctrl, g_timer0.p_cfg);
g_timer0.p_api->start(g_timer0.p_ctrl);
// Initialize the uart for AT command communication
g_uart0.p_api->open(g_uart0.p_ctrl, g_uart0.p_cfg);
wifi_opt_mode = WIFI_OPT_SETTING;
LOG("Wifi: Wifi initialization success\n");
}
// setting wifi module da16200
static fsp_err_t Wifi_Setting(void)
{
fsp_err_t status = FSP_ERR_ASSERTION;
uint8_t resp_buf[DA16200_STR_LEN_128];
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
// ATZ command
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_ATZ, resp_buf);
if(status != FSP_SUCCESS)
{
LOG("Wifi: Da16200 ATZ command failed!\n");
return status;
}
DELAY_MS(10);
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
// ATE command
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_ATE, resp_buf);
if(status != FSP_SUCCESS)
{
LOG("Wifi: Da16200 ATE command failed!\n");
return status;
}
DELAY_MS(10);
#if (WIFI_ATF_EN == COMM_ON) // do not clear ap information
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
// ATF command
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_ATF, resp_buf);
if(status != FSP_SUCCESS)
{
LOG("Wifi: Da16200 ATF command failed!\n");
return status;
}
DELAY_MS(10);
#endif
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_TMRFNOINIT, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
DELAY_MS(10);
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_WFMODE, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
DELAY_MS(10);
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_RESTART, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
DELAY_MS(10);
return status;
}
// control wifi module connecting to AP
static fsp_err_t Wifi_ConnectToAp(void)
{
fsp_err_t status = FSP_ERR_ASSERTION;
uint8_t resp_buf[DA16200_STR_LEN_128];
#if (WIFI_ATF_EN == COMM_OFF)
// update the AP connection status
wifi_conn_status = Wifi_GetAPConnectStatus();
DELAY_MS(10);
#endif
// not connected
if (WIFI_DISEONNECTED == wifi_conn_status)
{
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_WFJAP, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
/* Wifi connected to AP */
wifi_conn_status = WIFI_CONNECTED;
}
DELAY_MS(10);
// check DHC
/** Clear respond memory **/
// memset (resp_buf, 0 , sizeof(resp_buf));
// status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_NWDHC, resp_buf);
// if(status != FSP_SUCCESS)
// {
// return status;
// }
// DELAY_MS(10);
return status;
}
// setting sntp
static fsp_err_t Wifi_SntpStart(void)
{
fsp_err_t status = FSP_ERR_ASSERTION;
uint8_t resp_buf[DA16200_STR_LEN_32];
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_TZONE_GET, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
DELAY_MS(10);
//+TZONE:28800: 8h for sync to bejing time
if (SF_WIFI_TRUE != is_str_present((const char *)resp_buf, "+TZONE:28800"))
{
// sync to time zone to beijing time
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_TZONE_SET, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
DELAY_MS(10);
}
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_NWSNTP_STATUS, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
DELAY_MS(10);
if (SF_WIFI_TRUE == is_str_present((const char *)resp_buf, (const char*)"+NWSNTP:1"))
{
// sntp is started, stop it now
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_NWSNTP_STOP, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
DELAY_MS(10);
}
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_NWSNTP_START, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
DELAY_MS(10);
return status;
}
// get da16200 time
static fsp_err_t Wifi_GetTime(void)
{
fsp_err_t status = FSP_ERR_ASSERTION;
uint8_t resp_buf[DA16200_STR_LEN_64];
// time prase
s_Da16200TimeType cur_t = {0,0,0,0,0,0};
uint8_t i;
uint8_t flag = 0;
uint8_t j = 0;
// get latest time
rtc_time_t sntp_t;
time_t sntp_t_stamp;
/** Clear respond memory **/
memset (resp_buf, 0 , sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_TIME_GET, resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
for (i = 0; i < DA16200_STR_LEN_64; i++)
{
if ((resp_buf[i] == '+') && (resp_buf[i+1] == 'T') && (resp_buf[i+2] == 'I') &&
(resp_buf[i+3] == 'M'))
{
// find '+TIME:'
flag = 1;
i += 6;
}
else if (resp_buf[i] == '\n')
{
// stop
flag = 0;
if (flag != 0)
{
break;
}
}
if (flag == 1) // year
{
cur_t.year = cur_t.year * 10 + (resp_buf[i] - '0');
j++;
if (j == 4)
{
j = 0;
flag ++;
i++;
}
}
else if (flag == 2) // month
{
cur_t.mon = cur_t.mon * 10 + (resp_buf[i] - '0');
j++;
if (j == 2)
{
j = 0;
flag ++;
i++;
}
}
else if (flag == 3) // day
{
cur_t.mday = cur_t.mday * 10 + (resp_buf[i] - '0');
j++;
if (j == 2)
{
j = 0;
flag ++;
i++;
}
}
else if (flag == 4) //hour
{
cur_t.hour = cur_t.hour * 10 + (resp_buf[i] - '0');
j++;
if (j == 2)
{
j = 0;
flag ++;
i++;
}
}
else if (flag == 5) //minute
{
cur_t.min = cur_t.min * 10 + (resp_buf[i] - '0');
j++;
if (j == 2)
{
j = 0;
flag ++;
i++;
}
}
else if (flag == 6) //second
{
cur_t.sec = cur_t.sec * 10 + (resp_buf[i] - '0');
j++;
if (j == 2)
{
j = 0;
flag ++;
i++;
}
}
}
LOG("Time is %d-%d-%d,%d:%d:%d\n", cur_t.year,
cur_t.mon,
cur_t.mday,
cur_t.hour,
cur_t.min,
cur_t.sec);
sntp_t.tm_year = cur_t.year - 1900;
sntp_t.tm_mon = cur_t.mon - 1;
sntp_t.tm_mday = cur_t.mday;
sntp_t.tm_hour = cur_t.hour;
sntp_t.tm_min = cur_t.min;
sntp_t.tm_sec = cur_t.sec;
// convert the sntp time to timestamp
sntp_t_stamp = mktime(&sntp_t);
LOG("SNTP timestamp is %d\n", sntp_t_stamp);
// compare the sntp time and system rtc time
rtc_time_t rtc_t;
time_t rtc_t_stamp;
rtc_t = Rtc_GetDateTime();
// convert it to timestamp
rtc_t_stamp = mktime(&rtc_t);
LOG("RTC timestamp is %d\n", rtc_t_stamp);
// if sntp time is a latest time, then update it to rtc
if (rtc_t_stamp < sntp_t_stamp)
{
// update time to rtc
Rtc_SetDateTime(&sntp_t);
}
else if (rtc_t_stamp > sntp_t_stamp)
{
// failed
return FSP_ERR_ASSERTION;
}
return status;
}
// Judge the AP connection status
static e_ApConnectStatusType Wifi_GetAPConnectStatus(void)
{
fsp_err_t status = FSP_SUCCESS;
e_ApConnectStatusType ret_val = WIFI_DISEONNECTED;
uint8_t resp_buf[DA16200_STR_LEN_32];
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_WFSTA, resp_buf);
if(status == FSP_SUCCESS)
{
if (SF_WIFI_TRUE == is_str_present((const char *)resp_buf, "+WFSTA:1"))
{
// Connect AP successfully
ret_val = WIFI_CONNECTED;
}
}
return ret_val;
}
// Connect TCP server
static fsp_err_t Wifi_ConnectToTcp(void)
{
fsp_err_t status = FSP_ERR_ASSERTION;
char resp_buf[DA16200_STR_LEN_128];
/** Clear respond memory **/
memset (resp_buf, 0, sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_TRTRM, (uint8_t*)resp_buf);
// Do not need response due to this command may be return ERROR:-99
// if((status != FSP_SUCCESS))
// {
// return status;
// }
/** Clear respond memory **/
memset (resp_buf, 0, sizeof(resp_buf));
status = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_TRTC, (uint8_t*)resp_buf);
if(status != FSP_SUCCESS)
{
return status;
}
// send user information
if (pdTRUE == xSemaphoreTake(wifi_mutex, portMAX_DELAY))
{
/** Clear respond memory **/
memset (resp_buf, '\0', sizeof(resp_buf));
sprintf(resp_buf, "%s%d%s%s", wifi_tcp_head, 24, wifi_tcp_ip_port, wifi_tcp_info);
/** AT MODODR command **/
wifi_serial_write((uint8_t *)resp_buf, (uint16_t)strlen(resp_buf));
LOG("==>%s\n", resp_buf);
DELAY_MS(1000);
LOG("Sent TCP user info(ONENET info)\n");
wifi_iot_conn_status = WIFI_ONENET_CONNECTED;
// release the mutex, unlock
(void)xSemaphoreGive(wifi_mutex);
}
return status;
}
// update the Data to Server
/*
使用的是OneNet透传,数据格式是我自定义的。
数据格式为,onenet的Lua脚本会解析这个格式的数据并显示在云平台:
T+温度+H+湿度+L+亮度+M+可燃气体浓度ppm+P+台灯光亮度
举例:
T26.20H89.20L1234M2456P100:
表示温度为26.20摄氏度
湿度为89.20%
亮度为1234Lux
可燃气体浓度为2456ppm
台灯亮度为100%
##############################################################################
Lua脚本(需要实现device_data_analyze函数即可):
function device_data_analyze(dev)
local t={}
local a=0
-- 添加用户自定义代码 --
-- 例如: --
local s = dev:size()
local temp = 0
local str_end = 0
local humi = 0
local lux = 0
local mq5_ppm = 0
local lamp_pwm = 0
-- 找到关键字 --
-- T后面是温度,单位摄氏度 --
-- H后面是湿度,单位百分比 --
-- L后面是环境光亮度,单位Lux --
-- M后面是环境可燃气体浓度,单位是ppm --
-- P后面是台灯亮度,单位百分比 --
temp, str_end = string.find(dev:bytes(1, s), "T")
humi, str_end = string.find(dev:bytes(1, s), "H")
lux, str_end = string.find(dev:bytes(1, s), "L")
mq5_ppm, str_end = string.find(dev:bytes(1, s), "M")
lamp_pwm, str_end = string.find(dev:bytes(1, s), "P")
add_val(t, "temp", a, dev:bytes(temp+1, humi-temp-1))
add_val(t, "humi", a, dev:bytes(humi+1, lux-humi-1))
add_val(t, "Lux", a, dev:bytes(lux+1, mq5_ppm-lux-1))
add_val(t, "combustible_gas", a, dev:bytes(mq5_ppm+1, lamp_pwm-mq5_ppm-1))
add_val(t, "DeskLampBrightness", a, dev:bytes(lamp_pwm+1, s-lamp_pwm))
-- 成功收到数据后的响应 --
dev:response()
dev:send("received")
-- return $1,$2 --
-- 例如: --
return s,to_json(t)
end
*/
static void Wifi_UpdateSensorData(void)
{
uint32_t lux = Isl29035_ReadData();
s_Hs300xDataType humi_temp = Hs300x_ReadData();
uint32_t mq5_ppm = Mq5_GetGasPpmValue();
uint32_t lamp_pwm = Led_LampPwmGet();
uint8_t data_len;
uint16_t bytes_read = 0U;
uint8_t resp_buff[DA16200_STR_LEN_64] = {0};
char temp[64];
fsp_err_t result;
/** Clear respond memory **/
memset (wifi_tcp_str, '\0', WIFI_TCP_DATA_LEN);
// send the data to onenet
sprintf(temp, "T%.2fH%.2fL%dM%dP%d", humi_temp.temp, humi_temp.humi, lux, mq5_ppm, lamp_pwm);
data_len = (uint8_t)strlen((const char *)temp);
sprintf(wifi_tcp_str, "%s%d%s%s\r\n", wifi_tcp_head, data_len, wifi_tcp_ip_port, temp);
LOG ("Send data to TCP server: %s\n", wifi_tcp_str);
/** Clear respond memory **/
memset (resp_buff, '\0', bytes_read);
// setting mutex for lock wifi uart
if (pdTRUE == xSemaphoreTake(wifi_mutex, portMAX_DELAY))
{
/** AT MODODR command **/
wifi_serial_write((uint8_t *)wifi_tcp_str, (uint16_t)strlen(wifi_tcp_str));
bytes_read = DA16200_STR_LEN_64;
result = wifi_serial_read(resp_buff, &bytes_read, (const char *)"received", 1000);
if (FSP_SUCCESS != result)
{
// Go to check the AP connect status when failed
wifi_opt_mode_pre = wifi_opt_mode;
wifi_opt_mode = WIFI_OPT_CONNECT_STATUS;
}
else
{
}
// release the mutex, unlock
(void)xSemaphoreGive(wifi_mutex);
}
}
// Operation mode of wifi running
static void Wifi_OperateModeManage(void)
{
fsp_err_t err;
switch(wifi_opt_mode)
{
case WIFI_OPT_SETTING:
{
err = Wifi_Setting();
if(err)
{
LOG("Wifi: Fail to setting\nRetry Start...\n");
DELAY_MS(2000);
}
else
{
LOG("Wifi: Sucess to setting\n");
wifi_opt_mode_pre = wifi_opt_mode;
wifi_opt_mode = WIFI_OPT_CONNECT;
}
break;
}
case WIFI_OPT_CONNECT:
{
err = Wifi_ConnectToAp();
if(err)
{
LOG("Wifi: Fail to connected to AP\nRetry Start...\n");
DELAY_MS(500);
}
else
{
LOG("Wifi: Sucess to connected to AP\n");
wifi_opt_mode_pre = wifi_opt_mode;
wifi_opt_mode = WIFI_OPT_SNTP_SETTING;
}
break;
}
case WIFI_OPT_SNTP_SETTING:
{
err = Wifi_SntpStart();
if(err)
{
LOG("Wifi: Fail to start SNTP\nRetry Start...\n");
DELAY_MS(500);
}
else
{
LOG("Wifi: Sucess to start SNTP\n");
wifi_opt_mode_pre = wifi_opt_mode;
wifi_opt_mode = WIFI_OPT_GET_TIME;
}
break;
}
case WIFI_OPT_GET_TIME:
{
// update the time
err = Wifi_GetTime();
if(err)
{
LOG("Wifi: Fail to get time from da16200\nRetry Start...\n");
DELAY_MS(1000);
}
else
{
LOG("Wifi: Sucess to get time from da16200\n");
wifi_opt_mode_pre = wifi_opt_mode;
wifi_opt_mode = WIFI_OPT_CONNECT_TCP;
}
break;
}
case WIFI_OPT_CONNECT_TCP:
{
// Connect onenet Iot
err = Wifi_ConnectToTcp();
if(err)
{
LOG("Wifi: Fail to connect to the TCP server\nRetry Start...\n");
DELAY_MS(500);
}
else
{
LOG("Wifi: Sucess to connect to the TCP server\n");
wifi_opt_mode_pre = wifi_opt_mode;
wifi_opt_mode = WIFI_OPT_WORKING;
wifi_tcp_send_cnt = 0U;
}
break;
}
case WIFI_OPT_WORKING:
{
// Used for connect with ONENET TCP server
if (wifi_tcp_send_cnt >= 30U)
{
wifi_tcp_send_cnt = 0U;
// send the sensor data every 5s
Wifi_UpdateSensorData();
}
else
{
wifi_tcp_send_cnt ++;
}
Da16200_FeedbackHandle();
DELAY_MS(100);
break;
}
case WIFI_OPT_CONNECT_STATUS:
{
// update the AP connection status
wifi_conn_status = Wifi_GetAPConnectStatus();
// re-try to connecting the AP
if (WIFI_DISEONNECTED == wifi_conn_status)
{
// re-try to connecting the AP
wifi_opt_mode = WIFI_OPT_CONNECT;
wifi_opt_mode_pre = wifi_opt_mode;
}
else
{
// switch to previous operate mode
wifi_opt_mode = wifi_opt_mode_pre;
wifi_opt_mode_pre = WIFI_OPT_CONNECT_STATUS;
}
DELAY_MS(1);
break;
}
default:
{
LOG("Wifi: Error operation");
DELAY_MS(1000);
break;
}
}
}
#if (WIFI_CHECK_AP_CONN_STA_EN == STD_ON)
// check the connect status
static void Wifi_JudgeConnectStatusPeriod(void)
{
// not in wifi initialization mode
if ((wifi_opt_mode != WIFI_OPT_INIT) &&
(wifi_opt_mode != WIFI_OPT_SETTING) &&
(wifi_opt_mode != WIFI_OPT_CONNECT)// &&
// (wifi_opt_mode != WIFI_OPT_WORKING)
)
{
if (wifi_conn_sta_check_cnt >= WIFI_CONN_PREIOD)
{
wifi_conn_sta_check_cnt = 0U;
LOG("Wifi: Check cnnect status");
wifi_opt_mode_pre = wifi_opt_mode;
wifi_opt_mode = WIFI_OPT_CONNECT_STATUS;
}
}
}
#endif
// Wifi working main interface for task
void Wifi_RunningEntry(void)
{
Wifi_OperateModeManage();
#if (WIFI_CHECK_AP_CONN_STA_EN == STD_ON)
Wifi_JudgeConnectStatusPeriod();
#endif
vTaskDelay(pdMS_TO_TICKS(WIFI_PERIOD));
}
e_ApConnectStatusType Wifi_GetApConnStatus(void)
{
return wifi_conn_status;
}
e_WifiIotConnStaType Wifi_GetIotConnStatus(void)
{
return wifi_iot_conn_status;
}
void WIfi_CheckPreiodLoop(void)
{
if (wifi_conn_sta_check_cnt < WIFI_CONN_PREIOD)
{
wifi_conn_sta_check_cnt ++;
}
}
/*
使用的是OneNet的TCP透传,数据格式是我自定义的。
控制台灯的数据命令是:Lamp:+百分比台灯亮度
比如:
Lamp:100 - 表示台灯打开,亮度为100%
Lamp:0 - 表示关闭台灯
Lamp:80 - 表示台灯亮度设置为80%
*/
void Da16200_TRDTC_response(char *resp_data, uint16_t resp_data_len)
{
char *sub_str_ptr;
int command = -1;
(void)resp_data_len;
// find the sub-string 'Lamp'
sub_str_ptr = strstr((const char *)resp_data, "Lamp");
if (NULL != sub_str_ptr)
{
// parse the control command
sscanf(sub_str_ptr, "Lamp:%d", &command);
if ((command >= 0) && (command <= 100))
{
// the command is valid
Led_LampPwmCtrl((uint8_t)command);
LOG ("Wifi: Lamp control command is %d\n", command);
}
else
{
LOG ("Wifi: Invalid Lamp control command\n");
}
}
}
app_wifi.h
/*
@hehung
2023-2-8
转载请注明出处,版权由@hehung所有
email: 1398660197@qq.com
wechat: hehung95
*/
#ifndef APP_WIFI_H_
#define APP_WIFI_H_
#include "app_common.h"
typedef enum
{
WIFI_OPT_INIT = 0,
WIFI_OPT_SETTING,
WIFI_OPT_CONNECT,
WIFI_OPT_SNTP_SETTING,
WIFI_OPT_CONNECT_TCP,
WIFI_OPT_WORKING,
WIFI_OPT_CONNECT_STATUS,
WIFI_OPT_GET_TIME
} e_WifiOptType;
typedef enum
{
WIFI_ONENET_CONNECTED = 0,
WIFI_ONENET_DISCONNECTED
} e_WifiIotConnStaType;
typedef enum
{
WIFI_CONNECTED = 0,
WIFI_DISEONNECTED
} e_ApConnectStatusType;
extern void Wifi_Init(void);
extern void Wifi_RunningEntry(void);
extern e_ApConnectStatusType Wifi_GetApConnStatus(void);
extern e_WifiIotConnStaType Wifi_GetIotConnStatus(void);
extern void WIfi_CheckPreiodLoop(void);
extern void Da16200_TRDTC_response(char *resp_data, uint16_t resp_data_len);
#endif /* APP_WIFI_H_ */
详细代码实现可以参考我的项目提交:【RA4M2设计挑战赛】作品提交 - 环境检测网关设备
更多回帖