感谢众大网友的无私奉献,在mqtt协议的编码本分采集了网友们的mqtt协议解码分享。程序主要实现在arduino上的整合部分,写程序的时候水平有限,请大家多多原谅!
单片机源程序如下:
- /*************************************************
- *程序描述:esp8285透传串口处理系统
- **************************************************/
- #include "esp.h"
- #include "mqtt.h"
- //#include <SoftwareSerial.h>
- //信息缓冲区大小
- #define read_num 64
- #define send_num 50
- //信息缓冲区
- unsigned char buff[send_num];
- unsigned char read_buff[read_num];
- unsigned char msgas[50];
- int lenstr=0;
- //定时器0的时间定义
- unsigned long time_ding=0;
- unsigned long time_ms=0;
- int ding=0;
- //定时器1的时间定义
- unsigned long time_ding1=0;
- unsigned long time_ms1=0;
- int ding1=0;
- //定时器2的时间定义
- unsigned long time_ding2=0;
- unsigned long time_ms2=0;
- int ding2=0;
- //mqtt服务器的定时器时间定义
- unsigned long timeoutt=0;
- unsigned long timeoutr=0;
- //设备标志定义
- bool wf=0; //wifi连接标志位
- bool tcps=0; //tcp发送标志位
- bool tcpc=0; //tcp连接标志位
- int led=0;
- int error=0; //异常代码
- //mqtt服务器定义
- bool mqttc=0; //mqtt服务器连接标志
- //SoftwareSerial woshi(2, 3);
- void setup()
- {
- Serial.begin(115200);
- // woshi.begin(9600);
- pinMode(13,OUTPUT);
- pinMode(2,OUTPUT);
- // digitalWrite(2,HIGH);
- }
- void loop()
- {
- while(1)
- {
- net();
- bendi_loop();
- }
- }
- /*
- * 函数:void bendi_loop()
- * 功能:管理本地事物
- */
- void bendi_loop() //处理本地事务
- {
- if(ding1>0)
- {
- if((millis()-time_ding1)>time_ms1) //如果定时器到时间了就执行,否则就跳出
- {
- switch(ding1) //选自跳转的位置
- {
- case 1:
- ding1=0;
-
- break;
- default:
- break;
- }
- }
- else //定时器没有到时间就跳出
- return ;
- }
-
- }
- void net()
- {
- int msgnum;
- if(error>0) //错误代码处理
- {
- error_chuli(error);
- }
- if(ding>0)
- {
- if((millis()-time_ding)>time_ms) //如果定时器到时间了就执行,否则就跳出
- {
- switch(ding) //选自跳转的位置
- {
- case 1:
- ding=0;
- goto one;
- break;
- case 2:
- ding=0;
- goto two;
- break;
- case 3:
- ding=0;
- goto three;
- break;
- default:
- break;
- }
- }
- else //定时器没有到时间就跳出
- return ;
- }
-
- if(wf) //判断wifi是否连接
- {
- if(tcpc) //判断tcp是否连接
- {
- if(tcps) //判断是否在透传中
- {
- mqtt_loop();
- }
- else //进入透传模式
- {
- three:if(tcp_begin_send())
- {
- tcps=1;
- }
- else
- {
- delay_ms(500,3);
- error=3;
- }
- }
-
- }
- else //tcp连接
- {
- two:if(tcp_client())
- {
- tcpc=1;
- }
- else
- {
- delay_ms(1000,2);
- }
- }
-
- }
- else //wifi检测
- {
- one:if(ap_can())
- {
- wf=1;
- }
- else
- {
- delay_ms(3000,1);
- }
- }
- }
- bool mqtt_subscribe(const char *da,unsigned int Nu,unsigned char RequestedQo)
- {
- int num;
- qing_buff();
- num=GetDataSUBSCRIBE(buff,da,Nu,RequestedQo);
- Serial.write(buff,num);
- qing_buff();
- delay(500);
- if(serial_can()==2)
- {
- qing_read();
- return 1;
- }
- else
- {
- qing_read();
- return 0;
- }
- }
- void mqtt_publish(unsigned char du, unsigned char qo,unsigned char retai,const char *topi ,const char *ms)
- {
- int num;
- qing_buff();
- num=GetDataPUBLISH(buff,du,qo,retai,topi,ms);
- Serial.write(buff,num);
- qing_buff();
- }
- void msg_chuli()
- {
- int len=0,i;
- if((msgas[23]=='o')&&(msgas[24]=='n'))
- {
- digitalWrite(2,HIGH);
- mqtt_publish(0,0,0,MQTT_Topic,"on");
-
- }
- if((msgas[23]=='o')&&(msgas[24]=='f'))
- {
- digitalWrite(2,LOW);
- mqtt_publish(0,0,0,MQTT_Topic,"off");
- }
- for(i=0;i<50;i++)msgas[i]='\0';
-
- // mqtt_publish(0,0,0,MQTT_Topic,msg);
- // len=strlen(msg);
- // if((msg[0]=='o')&&(msg[1]=='n'))
- // {
- // digitalWrite(13,HIGH);
- // mqtt_publish(0,0,0,MQTT_Topic,"on");
- //
- // }
- // else if((msg[0]=='o')&&(msg[1]=='f'))
- // {
- // digitalWrite(13,LOW);
- // mqtt_publish(0,0,0,MQTT_Topic,"off");
- // }
- }
- void mqtt_loop()
- {
- char *msgg=NULL;
- int num;
- if(ding2>0)
- {
- if((millis()-time_ding2)>time_ms2) //如果定时器到时间了就执行,否则就跳出
- {
- switch(ding2) //选自跳转的位置
- {
- case 1:
- ding2=0;
- goto one;
- break;
- default:
- break;
- }
- }
- else //定时器没有到时间就跳出
- return ;
- }
-
- if(mqttc==0) //判断服务器是否连接上
- {
- one:if(mqtt_client())
- {
- mqttc=1;
- timeoutr=millis();
- timeoutt=millis();
- mqtt_subscribe(mqtt_Stopic,0,0);
- delay(1000);
- mqtt_publish(0,0,0,MQTT_Topic,"wo");
- }
- else
- {
- delay_ms2(5000,1);
- }
- }
- else
- {
- if((millis()-timeoutt)>5000)
- {
- mqtt_ping();
- timeoutt=millis();
- }
- if((millis()-timeoutr)>30000)
- {
- mqttc=0;
- }
- }
- if(Serial.available())
- {
- delay(300);
- num=serial_can();
- switch(num)
- {
- case 3:
- timeoutr=millis();
- timeoutt=millis();
- break;
- case 4:
- msg_chuli();
- break;
- default:
- esp_cpu(num);
- break;
- }
- }
- }
- void mqtt_ping()
- {
- int len;
- len=GetDataPINGREQ(buff);
- Serial.write(buff,len);
- qing_buff();
- }
- bool mqtt_client() //服务器连接
- {
- int num;
- int i;
- qing_buff();
- num=GetDataConnet(buff);
- Serial.write(buff,num);
- qing_buff();
- delay(1000);
- if(Serial.available())
- {
- if(serial_can()==1)
- {
- qing_read();
- return 1;
- }
- else
- {
- return 0;
- }
- }
- else
- {
- return 0;
- }
- }
- /**********************************************************
- 函数名称:serial_can()
- 函数功能:判断串口数据类型
- 返回值:
- 0 没有匹配到任何值
- 1 mqtt连接成功
- 2 mqtt订阅回应包
- 3 mqtt心跳包
- 4 mqtt消息包
- 6 wifi断开连接
- **********************************************************/
- int serial_can() //判断返回值
- {
- int i;
- int num;
- qing_read();
- num=Serial.available();
- for(i=0;Serial.available()>0;i++)read_buff[i]=Serial.read();
- if((read_buff[0]==0x20)&&(read_buff[1]==0x02))
- {
- return 1;
- }
- if(read_buff[0]==0x90)
- {
- return 2;
- }
- if((read_buff[0]==0xd0)&&(read_buff[1]==0x00))
- {
- return 3;
- }
- // if(strstr(read_buff,mqtt_Stopic)!=NULL)
- if(read_buff[0]==0x30)
- {
- lenstr=num;
- for(i=0;i<num;i++)msgas[i]=read_buff[i];
- return 4;
- }
- if(strstr(read_buff,"disconnect from ssid")!=NULL)
- {
- return 6;
- }
- qing_read();
- return 0;
- }
- void esp_cpu(int num) //设备处理
- {
- switch(num)
- {
- case 6: //wifi断开连接处理
- error_chuli(1);
- break;
- default:
- break;
- }
- }
- /*************************************************
- 函数名称:void error_chuli(int k)
- 函数功能:错误处理
- 输入参数:
- 1 //错误代码1 WiFi断开连接
- 3 //错误代码3 透传模式失败
- *************************************************/
- void error_chuli(int k)
- {
- switch(k)
- {
- case 1: //错误代码1 wifi断开连接
- esp_res();
- break;
- case 3: //错误代码3 透传模式开启失败
- error=0;
- break;
- default:
- break;
- }
-
- }
- void esp_res()
- {
- wf=0;
- tcpc=0;
- mqttc=0;
- tcps=0;
- tcp_stop_send();
- Serial.println(at_esp_ret);
- delay(3000);
- qing_buff();
- qing_read();
- while(Serial.read() >= 0);
- }
- bool tcp_begin_send() //开始透传
- {
- int i;
- while(Serial.read() >= 0);
- Serial.println(at_tcp_mode);
- delay(300);
- while(Serial.read() >= 0);
- Serial.println(at_tcp_send);
- delay(300);
- if(Serial.available())
- {
- for(i=0;Serial.available()>0;i++)read_buff[i]=Serial.read();
- if(strstr(read_buff,"OK")!=NULL)
- {
- qing_read();
- tcps=1;
- return 1;
- }
- else
- {
- qing_read();
- return 0;
- }
- }
- else
- {
- return 0;
- }
- }
- void tcp_stop_send() //退出透传模式
- {
- if(tcps==1)
- {
- Serial.print(at_tcp_ssend);
- tcps=0;
- }
- }
- bool tcp_client()
- {
- int i;
- while(Serial.read() >= 0);
- Serial.println(at_tcp_client);
- delay(4000);
- if(Serial.available())
- {
- qing_read();
- for(i=0;Serial.available()>0;i++)read_buff[i]=Serial.read();
- if(strstr(read_buff,"CONNECT")!=NULL)
- {
- qing_read();
- return 1;
- }
- else if(strstr(read_buff,"ALREADY CONNECTED")!=NULL)
- {
- qing_read();
- return 1;
- }
- else
- {
- qing_read();
- return 0;
- }
-
-
- }
- else
- {
- qing_read();
- return 0;
- }
-
-
- }
- bool ap_can()
- {
- int i;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
arduino对接esp8266版本4.0.zip
(8.99 KB, 下载次数: 77)
|