标题:
arduino对接esp8266的mqtt协议实现代码
[打印本页]
作者:
点击小子
时间:
2019-7-27 10:23
标题:
arduino对接esp8266的mqtt协议实现代码
感谢众大网友的无私奉献,在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黑下载附件…………
复制代码
0.png
(5.78 KB, 下载次数: 97)
下载附件
2019-7-27 22:46 上传
所有资料51hei提供下载:
arduino对接esp8266版本4.0.zip
(8.99 KB, 下载次数: 77)
2019-7-27 10:23 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
jjyytt111
时间:
2019-10-5 19:20
谢谢分享谢谢分享
作者:
609763691
时间:
2019-12-14 17:01
楼主你好,我下载了打不开,报错误了。看见了希望回复我一下,需要你的帮助
作者:
cyllife
时间:
2020-3-30 19:25
谢谢分享谢谢分享
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1