一:MQTT的初始化
1 利用AT+QMTCFG指令为阿里云配置设备信息
其后面有五个参数,如果要进行阿里云的设备配置那么第一个参数是固定的一定是"ALIAUTH",第二个参数是Will标志为,如果为0那么忽略Will参数的配置,一般情况下下为0;剩下的三个则是阿里云必须的三元素即:product_key、device_name、device_secret这三个参数可以在阿里云端创建设备之后非常容易的获得。
eg:
printf("AT+QMTCFG=\"aliauth\",0,\"%s\",\"%s\",\"%s\"\r\n",ProductKey,DeviceName,DeviceSecret);
2 AT+QMTOPEN指令为MQTT客户端打开网络
< tcpconnectID>这个参数是MQTT套接字标识符,范围是0-5一般默认为0。
<host_name>是服务器的域名,MQTT协议这个参数即支持域名也支持IP地址,写哪一个都可以。
<port>是端口号,一般阿里云的默认端口号是1883,也可以自己设置。
eg:
printf("AT+QMTOPEN=0,\"a11eLpiBnRR.iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883\r\n")
AT+QMTOPEN指令本质上是用TCP协议来配置MQTT协议
如果收到回复:QMTOPEN: 0,0 则证明成功的连接到网络
3再就是客户端请求连接到MQTT服务器,利用 AT+QMTCONN指令
<tcpconnectID>和上面的相同,一般默认为0
<clientID>客户端标识字符串,可以自己设置。
eg:
printf("AT+QMTCONN=0,\"clientExample_1981\"\r\n")
如果收到QMTCONN: 0,0,0,则证明登陆成功。
这样在完成上述三条AT指令之后,MQTT协议的初始化也就完成了
二:发送数据到阿里云
因为要发上阿里云所需要的数据格式都是Josn格式,所以要对需要上传的数据进行一个格式的转换:
转换函数:
eg:
uint8_t Mqttaliyun_Savedata(uint8_t *t_payload,uint8_t temp,uint8_t humi)
{
char json[]="{\"id\":\"26\",\"version\":\"1.0\",\"sys\":{\"ack\":0},\"params\":{\"CurrentTemperature\":{\"value\":%d},\"CurrentHumidity\":{\"value\":%d},\"jingweidu\":{\"value\":%d}},\"method\":\"thing.event.property.post\"}";
// 这是Josn的数据格式,如果要加入新的参数就要按照标识符和value值的格式来添加,前后的格式不需要不变动
char t_json[200]; //定义一个字符类型的数组
unsigned short json_len; //定义一天个变量来放数组的长度
sprintf(t_json, json, temp, humi); //
sprintf函数的功能是将指定的变量的值打印到字符串里面。拿这个具体的例子来说
t_json是要放字符串的起始位置;
josn是转换时需要的格式,即后面的参数都按照josn里面留的参数的格式转换;
temp,humi即需要转换的参数,这个参数的个数不限量,可以无限的增多,但是必须要和前面的格式里面预留的参数相对应。
这样就把参数按照josn[]的格式转换完成,并且以字符串的形式存放在了t_josn这个数组中。
json_len = strlen(t_json)/sizeof(char); //测量一下t_json数组的长度
memcpy(t_payload, t_json, json_len); //将t_josn数组的所有数据复制到t_payoad中,因为t_payload这个变量是个指针型变量,所以他本身就发生了转换,里面的数据就成功的转换成了josn类型的数据。
return json_len; //函数返回的是数组的长度
}
2数据转换完成之后,要把数据发送到阿里云上
void aliyunMQTT_PUBdata(uint8_t temp,uint8_t humi) //发送函数
{
uint8_t t_payload[200],len;
len=Mqttaliyun_Savedata(t_payload,temp,humi);
//这条命令,即把转换好的josn格式放到了t_payload里面,也返回了t_payload的数据长度
t_payload[len]=0;
printf("AT+QMTPUB=0,0,0,0,%s,%s\r\n",PubTopic,t_payload);// 运用了AT指令来发布主题
HAL_Delay(300);
strx=strstr((const char*)RxBuffer,(const char*)"+QMTPUB: 0,0,0");//验证一下返回的状态,看一下是不是上传成功。
while(strx==NULL)
{
strx=strstr((const char*)RxBuffer,(const char*)"+QMTPUB: 0,0,0");//
}
HAL_Delay(500);
//Clear_Buffer();
}
发送AT+QMTPUB指令的详解:
该命令用于将客户端的消息发布到服务器,以便分发给感兴趣订阅者。
<tcpconnectID>MQTT套接字标识符,范围是0-5,一般写0;
<msgID>数据报的消息识别符,范围是0-65535,只有当<qos>是0的时候才为0;
<qos>客户端希望发送消息的Qos级别:
0 :至多一次
1:最少一次
2:恰好一次
<retain>在将消息发送给服务器后,服务器要不要保存改消息。
0不保存消息
1保存消息
<topic>即需要发布的主题
<msg>需要发布的信息
eg:
AT+QMTPUB=0,0,0,0,%s,%s\r\n",PubTopic,t_payload
如果返回的是 QMTPUB: 0,0,0,那么证明发送数据成功
3数据发送成功后,如果返回的消息中有+QMTRECV,那么证明接收到了阿里云平台
void BC26_RECData(void)
{
uint8_t recdata[250];
Uart1_SendStr(RxBuffer);
strx=strstr((const char*)RxBuffer,(const char*)"+QMTRECV:");//·如果返回的信息里面有QMTRECV这表明传输成功
if(strx)
{
strx=strstr((const char*)RxBuffer,(const char*)"}\"");
// 有}出现则代表数据接收完成
if(strx)
{
memcpy(recdata, RxBuffer, Rxcouter);// 将接收的信息保存
CParsejson(recdata);
}
memset(recdata, 0, 250); // 对recdata变量做一个初始化,即清空recdata
} //
Rxcouter=0;
}