简介
这里主要讲的是进行MQTT移植,对于阿里云物联网的连接的开发,可以使用阿里云提供的代码,也可以使用标准的MQTT协议代码。
参考了网上很多的帖子,经过多方尝试,发现这两种方法都不可行,就采用了自己的方法,先用wireshark抓网络包,然后让esp8266模拟这种网络包。
MQTT.fx接入物联网平台
这部分可以参考阿里云物联网文档,即
阿里云物联网平台 > 最佳实践 > 设备接入 > 使用MQTT.fx接入物联网平台
通过wireshark监控计算机的端口1883,抓取到的MQTT数据帧有如下类型:
- Connect Command
- Connect Ack
- Subscribe Request
- Subscribe Ack
- Publish Message
- Publish Ack
- Ping Request
- Ping Respose
其中,本地发给阿里云数据帧1,则阿里云返回数据帧2;本地发给阿里云数据帧3,则阿里云返回数据帧4;本地发给阿里云5,则阿里云返回数据帧6(前提是QoS=1);本地发给阿里云数据帧7,则阿里云返回数据帧8。当阿里云向下传输数据帧5时,本地不做应答。
参考MQTT协议版本3,在抓取到的数据的基础上,仿写了类似的数据帧实现了相应的功能。
生成MQTT数据帧
在程序中定义了如下几个函数,完成connect、subscribe、publish和ping功能。
u8 iot_connect(void);
u8 iot_subscribe(void);
u8 iot_sendheart(void);
u8 iot_publishdata(float temp, float humi);
u16 cGetDataPUBLISH(u8 *buff,u8 qos,u8 *topic,u8 *msg);
注意事项
在mqtt.c文件中,用到了malloc.h文件,因为在给一个buf申请内存之前,要初始化MCU的存储空间。也就是keil工程要添加sram.c、sram.h、XMRAM.h和XMRAM.lib文件,在main函数中要有:
my_mem_init(SRAMIN); //初始化内部内存池
相关程序源码
啥也别说了,直接上代码。
mqtt.c
#include "mqtt.h"
#include <stdlib.h>
#include "string.h"
#include "malloc.h"
#include "usart3.h"
#include "usart.h"
#include "delay.h"
//连接成功服务器回应 20 02 00 00
//客户端主动断开连接 e0 00
const u8 mqtt_connetAck[] = {
0x20,0x02,0x00,0x00};
const u8 mqtt_pubAck[] = {
0x40,0x02,0x00,0x01};
const u8 mqtt_disconnet[] = {
0xe0,0x00};
const u8 mqtt_heart[] = {
0xc0,0x00};
const u8 mqtt_heartAck[] = {
0xd0,0x00};
const u8 mqtt_subAck[] = {
0x90,0x03};
uint16_t buflen=200;
unsigned char buf[200];
char ClientID[128];
u8 ClientID_len;
char Username[128];
u8 Username_len;
char Password[128];
u8 Password_len;
u8 iot_connect(void)
{
uint32_t buflen;
u16 i;
u8* buf;
buf=mymalloc(SRAMIN,200); //申请200字节内存
GetDataConnet(buf);
buflen = buf[1]+2;
// 连接两次不成功则返回0
u8 cnt=2; // 尝试发送次数
u8 wait=30; // 等待时间
while(cnt--)
{
USART3_RX_STA=0;
HAL_UART_Transmit(&UART1_Handler, buf, buflen,1000); // for DEBUG
HAL_UART_Transmit(&UART3_Handler, buf, buflen,1000);
while(wait--)
{
if(USART3_RX_STA&0x8000) // 收到应答信号,uart1转发该应答信号
{
if(USART3_RX_BUF[0]==mqtt_connetAck[0] && USART3_RX_BUF[1]==mqtt_connetAck[1]) //连接成功
{
myfree(SRAMIN,buf); //释放内存
USART3_RX_STA=0;
printf("\r\nconnect successful!\r\n");
return 1; // 连接成功
}
}
delay_ms(100);
}
}
myfree(SRAMIN,buf); //释放内存
USART3_RX_STA=0;
return 0;
}
u8 iot_subscribe(void)
{
uint32_t buflen;
u16 i;
u8* buf;
buf=mymalloc(SRAMIN,200); //申请200字节内存
GetDataSUBSCRIBE(buf,S_TOPIC_NAME,2,0);
buflen = buf[1]+2;
// 连接两次不成功则返回0
u8 cnt=2; // 尝试发送次数
u8 wait=30; // 等待时间
while(cnt--)
{
USART3_RX_STA=0;
HAL_UART_Transmit(&UART1_Handler, buf, buflen,1000); // For DEBUG
HAL_UART_Transmit(&UART3_Handler, buf, buflen,1000);
while(wait--)
{
if(USART3_RX_STA&0x8000) // 收到应答信号,uart1转发该应答信号
{
if(USART3_RX_BUF[0]==mqtt_subAck[0] && USART3_RX_BUF