官方提供了http的例子,我把例子修改了一下,可以发布消息了,这里放上来,希望大佬提出宝贵建议。
建立MQTT服务器
要想实现mqtt收发数据,最好是自己建立一个mqtt服务器,这样方便调试,我这里是使用emqtx来建立服务器,具体安装教程大家可以到官方查询,这里不多描述,如果有要帮助的可以私信我。
建立mqtt服务器后打面控制页面,以便监控模块是否连上服务器了。
下载示例代码
示例代码在挑战赛的的资料包里:
下载好资料包后,可以用e2studio,也可以参照示全,用rasc建立自己的工程。我由于jlink没有,还是用MDK+STLINK来开发。参照示例工程,建立MDK工程,把工程里的da16200_AT.c/h以及dialog_wifi_demo.c/h拷到自己的工程目录下面,并添加到keil工程里,这里不仔细,如果有需要帮助,请私信我。
为了方便监控信息,我这里按照前面的printf工程,用uart9配置了用于打印的UART。具体的代码与实现方式参见uart_debug工程。
MQTT 的主要指令
1、要实现mqtt工能,首先要设置wifi 的station模式,这里跟示例里的http里一样的
AT+WFMODE=0
Set Station mode
2、连接到AP
AT+WFJAP
AT+WFJAP=SSID,4,2,pwsswd ; WPA2 security
3、连接到mqtt服务器 AT+NWMQTBR
4、订阅消息主题 AT+NWMQTS
5、发布消息主题 AT+NWMQTP
6、使能MQTT AT+NWMQCL
7、发帖消息 AT+NWMQMSG
发送消息的流程大至如下:
【注】当然这里没有考虑异常情况,根据demo的示例,如果出现错误就返回,重启模块,再重装连接AP以及服务器。
代码
1、增加da16200_at_cmd_index如下:
typedef enum da16200_at_cmd_index
{
DA16200_AT_CMD_INDEX_ATZ = 0,
DA16200_AT_CMD_INDEX_ATE,
DA16200_AT_CMD_INDEX_AT_ATF,
DA16200_AT_CMD_INDEX_AT_TMRFNOINIT,
DA16200_AT_CMD_INDEX_AT_WFMODE,
DA16200_AT_CMD_INDEX_AT_RESTART,
DA16200_AT_CMD_INDEX_AT_WFJAP,
DA16200_AT_CMD_INDEX_AT_TRTC,
DA16200_AT_CMD_INDEX_AT_SEND_DATA,
DA16200_AT_CMD_INDEX_AT_WFCC,
DA16200_AT_CMD_INDEX_AT_WFSAP,
DA16200_AT_CMD_INDEX_AT_NWIP,
DA16200_AT_CMD_INDEX_AT_NWDHS,
DA16200_AT_CMD_INDEX_AT_NWDHR,
DA16200_AT_CMD_INDEX_AT_TRTS,
DA16200_AT_CMD_INDEX_AT_TRSAVE,
DA16200_AT_CMD_INDEX_AT_NWMQTCL,
DA16200_AT_CMD_INDEX_AT_NWMQTT,
DA16200_AT_CMD_INDEX_AT_NWMQBR,
DA16200_AT_CMD_INDEX_AT_NWMQTS,
DA16200_AT_CMD_INDEX_AT_NWMQTP,
DA16200_AT_CMD_INDEX_AT_NWMQCID,
DA16200_AT_CMD_INDEX_AT_NWMQMSG,
} da16200_at_cmd_index_t;
2、增加da16200_at_cmd_set_t g_da16200_cmd_set[]内容如下:
[ DA16200_AT_CMD_INDEX_AT_NWMQTCL ] =
{
.p_cmd = (uint8_t *) "AT+NWMQCL=1\r\n",
.p_success_resp = (uint8_t *) "OK",
.max_resp_length = DA16200_STR_LEN_128,
.retry = DA16200_RETRY_VALUE_5,
.retry_delay = DA16200_DELAY_200MS
},
[ DA16200_AT_CMD_INDEX_AT_NWMQTT ] =
{
.p_cmd = (uint8_t *) "AT+NWMQTT=192.168.3.192,1883,ds16200_sub,da16200,pub,0,0\r\n",
.p_success_resp = (uint8_t *) "+NWMQCL:1",
.max_resp_length = DA16200_STR_LEN_128,
.retry = DA16200_RETRY_VALUE_5,
.retry_delay = DA16200_DELAY_200MS
},
[ DA16200_AT_CMD_INDEX_AT_NWMQBR ] =
{
.p_cmd = (uint8_t *) "AT+NWMQBR=192.168.3.192,1883\r\n",
.p_success_resp = (uint8_t *) "OK",
.max_resp_length = DA16200_STR_LEN_64,
.retry = DA16200_RETRY_VALUE_5,
.retry_delay = DA16200_DELAY_500MS
},
[ DA16200_AT_CMD_INDEX_AT_NWMQTS ] =
{
.p_cmd = (uint8_t *) "AT+NWMQTS=1,da16k_sub\r\n",
.p_success_resp = (uint8_t *) "OK",
.max_resp_length = DA16200_STR_LEN_64,
.retry = DA16200_RETRY_VALUE_5,
.retry_delay = DA16200_DELAY_500MS
},
[ DA16200_AT_CMD_INDEX_AT_NWMQTP ] =
{
.p_cmd = (uint8_t *) "AT+NWMQTP=da16k_pub\r\n",
.p_success_resp = (uint8_t *) "OK",
.max_resp_length = DA16200_STR_LEN_64,
.retry = DA16200_RETRY_VALUE_5,
.retry_delay = DA16200_DELAY_500MS
},
[ DA16200_AT_CMD_INDEX_AT_NWMQCID ] =
{
.p_cmd = (uint8_t *) "AT+NWMQCID=Lugl_Test1\r\n",
.p_success_resp = (uint8_t *) "OK",
.max_resp_length = DA16200_STR_LEN_64,
.retry = DA16200_RETRY_VALUE_5,
.retry_delay = DA16200_DELAY_500MS
},
[ DA16200_AT_CMD_INDEX_AT_NWMQMSG ] =
{
.p_cmd = (uint8_t *) "AT+NWMQMSG=Lugl_Test1\r\n",
.p_success_resp = (uint8_t *) "OK",
.max_resp_length = DA16200_STR_LEN_64,
.retry = DA16200_RETRY_VALUE_5,
.retry_delay = DA16200_DELAY_500MS
}
对应的功能函数如下:
/************************************************************************************
* Name: wifi_command_AT_NWMQTCL
* Function: Operate AT+NWMQTCL command
* Parameters: none
* Return: AT command operation status
************************************************************************************/
static fsp_err_t wifi_command_AT_NWMQTCL(void)
{
uint16_t bytes_read = 0U;
uint16_t bytes_write;
uint8_t resp_buff[DA16200_STR_LEN_32] =
{0};
fsp_err_t retval = FSP_ERR_ASSERTION;
fsp_err_t result;
uint8_t retry_count = 0U;
da16200_at_cmd_set_t * p_cmd_set = g_da16200_cmd_set;
uint8_t expected_resp_present;
do
{
// AT MODODR command
bytes_write = (uint16_t) strlen((char *) p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTCL].p_cmd);
wifi_serial_write((uint8_t*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTCL].p_cmd,bytes_write);
bytes_read = p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTCL].max_resp_length;
// Clear respond memory
memset (resp_buff, 0 , sizeof(resp_buff));
result = wifi_serial_read(resp_buff, &bytes_read, 1000);
if((FSP_SUCCESS == result) || (FSP_ERR_TIMEOUT == result))
{
expected_resp_present = is_str_present((const char *)resp_buff, (const char*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTCL].p_success_resp);
if(SF_WIFI_TRUE == expected_resp_present)
{
retval = FSP_SUCCESS;
break;
}
}
R_BSP_SoftwareDelay(p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTCL].retry_delay,BSP_DELAY_UNITS_MILLISECONDS);
++retry_count;
}
while(retry_count < p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTCL].retry);
return retval;
}
/************************************************************************************
* Name: wifi_command_AT_NWMQBR
* Function: Operate AT+NWMQBR command
* Parameters: none
* Return: AT command operation status
************************************************************************************/
static fsp_err_t wifi_command_AT_NWMQBR(void)
{
uint16_t bytes_read = 0U;
uint16_t bytes_write;
uint8_t resp_buff[DA16200_STR_LEN_32] =
{0};
fsp_err_t retval = FSP_ERR_ASSERTION;
fsp_err_t result;
uint8_t retry_count = 0U;
da16200_at_cmd_set_t * p_cmd_set = g_da16200_cmd_set;
uint8_t expected_resp_present;
do
{
// AT MODODR command
bytes_write = (uint16_t) strlen((char *) p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQBR].p_cmd);
wifi_serial_write((uint8_t*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQBR].p_cmd,bytes_write);
bytes_read = p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQBR].max_resp_length;
// Clear respond memory
memset (resp_buff, 0 , sizeof(resp_buff));
result = wifi_serial_read(resp_buff, &bytes_read, 1000);
if((FSP_SUCCESS == result) || (FSP_ERR_TIMEOUT == result))
{
expected_resp_present = is_str_present((const char *)resp_buff, (const char*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQBR].p_success_resp);
if(SF_WIFI_TRUE == expected_resp_present)
{
retval = FSP_SUCCESS;
break;
}
}
R_BSP_SoftwareDelay(p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQBR].retry_delay,BSP_DELAY_UNITS_MILLISECONDS);
++retry_count;
}
while(retry_count < p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQBR].retry);
return retval;
}
/************************************************************************************
* Name: wifi_command_AT_NWMQTT
* Function: Operate AT+NWMQTT command
* Parameters: none
* Return: AT command operation status
************************************************************************************/
static fsp_err_t wifi_command_AT_NWMQTT(void)
{
uint16_t bytes_read = 0U;
uint16_t bytes_write;
uint8_t resp_buff[DA16200_STR_LEN_32] =
{0};
fsp_err_t retval = FSP_ERR_ASSERTION;
fsp_err_t result;
uint8_t retry_count = 0U;
da16200_at_cmd_set_t * p_cmd_set = g_da16200_cmd_set;
uint8_t expected_resp_present;
do
{
// AT MODODR command
bytes_write = (uint16_t) strlen((char *) p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTT].p_cmd);
wifi_serial_write((uint8_t*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTT].p_cmd,bytes_write);
bytes_read = p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTT].max_resp_length;
// Clear respond memory
memset (resp_buff, 0 , sizeof(resp_buff));
result = wifi_serial_read(resp_buff, &bytes_read, 1000);
if((FSP_SUCCESS == result) || (FSP_ERR_TIMEOUT == result))
{
expected_resp_present = is_str_present((const char *)resp_buff, (const char*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTT].p_success_resp);
if(SF_WIFI_TRUE == expected_resp_present)
{
retval = FSP_SUCCESS;
break;
}
}
R_BSP_SoftwareDelay(p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTT].retry_delay,BSP_DELAY_UNITS_MILLISECONDS);
++retry_count;
}
while(retry_count < p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTT].retry);
return retval;
}
/************************************************************************************
* Name: wifi_command_AT_NWMQTS
* Function: Operate AT+NWMQTS command
* Parameters: none
* Return: AT command operation status
************************************************************************************/
static fsp_err_t wifi_command_AT_NWMQTS(void)
{
uint16_t bytes_read = 0U;
uint16_t bytes_write;
uint8_t resp_buff[DA16200_STR_LEN_32] =
{0};
fsp_err_t retval = FSP_ERR_ASSERTION;
fsp_err_t result;
uint8_t retry_count = 0U;
da16200_at_cmd_set_t * p_cmd_set = g_da16200_cmd_set;
uint8_t expected_resp_present;
do
{
// AT MODODR command
bytes_write = (uint16_t) strlen((char *) p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTS].p_cmd);
wifi_serial_write((uint8_t*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTS].p_cmd,bytes_write);
bytes_read = p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTS].max_resp_length;
// Clear respond memory
memset (resp_buff, 0 , sizeof(resp_buff));
result = wifi_serial_read(resp_buff, &bytes_read, 1000);
if((FSP_SUCCESS == result) || (FSP_ERR_TIMEOUT == result))
{
expected_resp_present = is_str_present((const char *)resp_buff, (const char*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTS].p_success_resp);
if(SF_WIFI_TRUE == expected_resp_present)
{
retval = FSP_SUCCESS;
break;
}
}
R_BSP_SoftwareDelay(p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTS].retry_delay,BSP_DELAY_UNITS_MILLISECONDS);
++retry_count;
}
while(retry_count < p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTS].retry);
return retval;
}
/************************************************************************************
* Name: wifi_command_AT_NWMQTP
* Function: Operate AT+NWMQTP command
* Parameters: none
* Return: AT command operation status
************************************************************************************/
static fsp_err_t wifi_command_AT_NWMQTP(void)
{
uint16_t bytes_read = 0U;
uint16_t bytes_write;
uint8_t resp_buff[DA16200_STR_LEN_32] =
{0};
fsp_err_t retval = FSP_ERR_ASSERTION;
fsp_err_t result;
uint8_t retry_count = 0U;
da16200_at_cmd_set_t * p_cmd_set = g_da16200_cmd_set;
uint8_t expected_resp_present;
do
{
// AT MODODR command
bytes_write = (uint16_t) strlen((char *) p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTP].p_cmd);
wifi_serial_write((uint8_t*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTP].p_cmd,bytes_write);
bytes_read = p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTP].max_resp_length;
// Clear respond memory
memset (resp_buff, 0 , sizeof(resp_buff));
result = wifi_serial_read(resp_buff, &bytes_read, 1000);
if((FSP_SUCCESS == result) || (FSP_ERR_TIMEOUT == result))
{
expected_resp_present = is_str_present((const char *)resp_buff, (const char*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTP].p_success_resp);
if(SF_WIFI_TRUE == expected_resp_present)
{
retval = FSP_SUCCESS;
break;
}
}
R_BSP_SoftwareDelay(p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTP].retry_delay,BSP_DELAY_UNITS_MILLISECONDS);
++retry_count;
}
while(retry_count < p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQTP].retry);
return retval;
}
/************************************************************************************
* Name: wifi_command_AT_NWMQTP
* Function: Operate AT+NWMQTP command
* Parameters: none
* Return: AT command operation status
************************************************************************************/
fsp_err_t wifi_command_AT_NWMQCID(void)
{
uint16_t bytes_read = 0U;
uint16_t bytes_write;
uint8_t resp_buff[DA16200_STR_LEN_32] =
{0};
fsp_err_t retval = FSP_ERR_ASSERTION;
fsp_err_t result;
uint8_t retry_count = 0U;
da16200_at_cmd_set_t * p_cmd_set = g_da16200_cmd_set;
uint8_t expected_resp_present;
do
{
// AT MODODR command
bytes_write = (uint16_t) strlen((char *) p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQCID].p_cmd);
wifi_serial_write((uint8_t*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQCID].p_cmd,bytes_write);
bytes_read = p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQCID].max_resp_length;
// Clear respond memory
memset (resp_buff, 0 , sizeof(resp_buff));
result = wifi_serial_read(resp_buff, &bytes_read, 1000);
if((FSP_SUCCESS == result) || (FSP_ERR_TIMEOUT == result))
{
expected_resp_present = is_str_present((const char *)resp_buff, (const char*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQCID].p_success_resp);
if(SF_WIFI_TRUE == expected_resp_present)
{
retval = FSP_SUCCESS;
break;
}
}
R_BSP_SoftwareDelay(p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQCID].retry_delay,BSP_DELAY_UNITS_MILLISECONDS);
++retry_count;
}
while(retry_count < p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQCID].retry);
return retval;
}
/************************************************************************************
* Name: wifi_command_AT_NWMQMSG
* Function: Operate AT+NWMQMSG command
* Parameters: none
* Return: AT command operation status
************************************************************************************/
fsp_err_t wifi_command_AT_NWMQMSG(void)
{
uint16_t bytes_read = 0U;
uint16_t bytes_write;
uint8_t resp_buff[DA16200_STR_LEN_32] =
{0};
fsp_err_t retval = FSP_ERR_ASSERTION;
fsp_err_t result;
uint8_t retry_count = 0U;
da16200_at_cmd_set_t * p_cmd_set = g_da16200_cmd_set;
uint8_t expected_resp_present;
do
{
// AT MODODR command
bytes_write = (uint16_t) strlen((char *) p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQMSG].p_cmd);
wifi_serial_write((uint8_t*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQMSG].p_cmd,bytes_write);
bytes_read = p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQMSG].max_resp_length;
// Clear respond memory
memset (resp_buff, 0 , sizeof(resp_buff));
result = wifi_serial_read(resp_buff, &bytes_read, 1000);
if((FSP_SUCCESS == result) || (FSP_ERR_TIMEOUT == result))
{
expected_resp_present = is_str_present((const char *)resp_buff, (const char*)p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQMSG].p_success_resp);
if(SF_WIFI_TRUE == expected_resp_present)
{
retval = FSP_SUCCESS;
break;
}
}
R_BSP_SoftwareDelay(p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQMSG].retry_delay,BSP_DELAY_UNITS_MILLISECONDS);
++retry_count;
}
while(retry_count < p_cmd_set[DA16200_AT_CMD_INDEX_AT_NWMQMSG].retry);
return retval;
}
增加mqtt_set函数
fsp_err_t wifi_mqtt_set(void)
{
fsp_err_t status = FSP_SUCCESS;
printf("begin_command_AT_TMRFNOINIT\r\n");
status = wifi_command_AT_TMRFNOINIT();
if(status != FSP_SUCCESS)
{
printf("wifi_command_AT_TMRFNOINIT ERROR\r\n");
return status;
}
printf("begin wifi_command_AT_WFMODE\r\n");
R_BSP_SoftwareDelay(100,BSP_DELAY_UNITS_MILLISECONDS);
status = wifi_command_AT_WFMODE();
if(status != FSP_SUCCESS)
{
printf("wifi_command_AT_WFMODE ERROR\r\n");
return status;
}
printf("begin wifi_command_AT_RESTART\r\n");
R_BSP_SoftwareDelay(100,BSP_DELAY_UNITS_MILLISECONDS);
status = wifi_command_AT_RESTART();
if(status != FSP_SUCCESS)
{
printf("wifi_command_AT_RESTART ERROR\r\n");
return status;
}
printf("begin wifi_command_AT_WFJAP\r\n");
R_BSP_SoftwareDelay(100,BSP_DELAY_UNITS_MILLISECONDS);
status = wifi_command_AT_WFJAP();
if(status != FSP_SUCCESS)
{
printf("wifi_command_AT_WFJAP ERROR\r\n");
return status;
}
R_BSP_SoftwareDelay(100,BSP_DELAY_UNITS_MILLISECONDS);
printf("begin client mqtt server \r\n");
status = wifi_command_AT_NWMQBR();
if(status != FSP_SUCCESS)
{
printf("client server fail \r\n");
return status;
}
printf("mqtt client server sucsecc!!\r\n");
printf("begin set mqtt sub \r\n");
status = wifi_command_AT_NWMQTS();
if(status != FSP_SUCCESS)
{
printf("set mqtt sub fail \r\n");
return status;
}
printf("begin set mqtt pub \r\n");
status = wifi_command_AT_NWMQTP();
if(status != FSP_SUCCESS)
{
printf("set mqtt pub fail \r\n");
return status;
}
status = wifi_command_AT_NWMQTCL();
if(status != FSP_SUCCESS)
{
printf("enable mqtt state faile\r\n");
return status;
}
printf("begin pub msg \r\n");
status = wifi_command_AT_NWMQMSG();
if(status != FSP_SUCCESS)
{
printf("mqtt pub msg faile\r\n");
return status;
}
return status;
}
测试功能函数如下:
void dialog_mqtt_demo(void)
{
static unsigned char operation = 0;
static uint8_t cnt=0;
fsp_err_t err;
while(1)
{
switch(operation)
{
case 0:
g_ioport.p_api->pinWrite(g_ioport.p_ctrl, LED1, BSP_IO_LEVEL_HIGH);
wifi_init();
printf("start wifi setting\r\n");
err = wifi_mqtt_set();
g_ioport.p_api->pinWrite(g_ioport.p_ctrl, LED1, BSP_IO_LEVEL_LOW);
if(err)
{
printf("start wifi setting ERROR\r\n");
R_BSP_SoftwareDelay(500,BSP_DELAY_UNITS_MILLISECONDS);
}
else
{
printf("start wifi setting OK\r\n");
R_BSP_SoftwareDelay(500,BSP_DELAY_UNITS_MILLISECONDS);
operation = 1;
}
break;
case 1:
wifi_command_AT_NWMQMSG();
R_BSP_SoftwareDelay(500,BSP_DELAY_UNITS_MILLISECONDS);
break;
default:
operation = 0;
break;
}
}
}
然后在hal_entry.c中启用。服务器成功收到数据:
【总结】AT处理收发函数,串口接收的回调函数实现起来比较麻烦,有时模块会发回一些乱码数据。官方提供的da16200的demo非常有借鉴,但是网上也有很多AT的模块化函数,这需要慢慢的磨练。