找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8286|回复: 3
打印 上一主题 下一主题
收起左侧

arduino对接esp8266的mqtt协议实现代码

  [复制链接]
跳转到指定楼层
楼主
感谢众大网友的无私奉献,在mqtt协议的编码本分采集了网友们的mqtt协议解码分享。程序主要实现在arduino上的整合部分,写程序的时候水平有限,请大家多多原谅!

单片机源程序如下:
  1. /*************************************************
  2. *程序描述:esp8285透传串口处理系统
  3. **************************************************/

  4. #include "esp.h"
  5. #include "mqtt.h"
  6. //#include <SoftwareSerial.h>
  7. //信息缓冲区大小
  8. #define read_num 64
  9. #define send_num 50

  10. //信息缓冲区
  11. unsigned char buff[send_num];
  12. unsigned char read_buff[read_num];
  13. unsigned char msgas[50];
  14. int lenstr=0;
  15. //定时器0的时间定义
  16. unsigned long time_ding=0;
  17. unsigned long time_ms=0;
  18. int ding=0;      

  19. //定时器1的时间定义
  20. unsigned long time_ding1=0;
  21. unsigned long time_ms1=0;
  22. int ding1=0;

  23. //定时器2的时间定义
  24. unsigned long time_ding2=0;
  25. unsigned long time_ms2=0;
  26. int ding2=0;

  27. //mqtt服务器的定时器时间定义
  28. unsigned long timeoutt=0;
  29. unsigned long timeoutr=0;

  30. //设备标志定义
  31. bool wf=0;                  //wifi连接标志位
  32. bool tcps=0;                //tcp发送标志位
  33. bool tcpc=0;                //tcp连接标志位
  34. int led=0;
  35. int error=0;                //异常代码

  36. //mqtt服务器定义
  37. bool mqttc=0;       //mqtt服务器连接标志
  38. //SoftwareSerial woshi(2, 3);

  39. void setup()
  40. {
  41.   Serial.begin(115200);
  42. //  woshi.begin(9600);
  43.   pinMode(13,OUTPUT);
  44.   pinMode(2,OUTPUT);
  45. //  digitalWrite(2,HIGH);
  46. }


  47. void loop()
  48. {
  49.   while(1)
  50.   {
  51.     net();
  52.     bendi_loop();
  53.   }
  54. }

  55. /*
  56. * 函数:void bendi_loop()
  57. * 功能:管理本地事物
  58. */
  59. void bendi_loop()                           //处理本地事务
  60. {
  61.   if(ding1>0)
  62.   {
  63.     if((millis()-time_ding1)>time_ms1)                //如果定时器到时间了就执行,否则就跳出
  64.     {
  65.       switch(ding1)                        //选自跳转的位置
  66.       {
  67.         case 1:
  68.           ding1=0;

  69.          
  70.           break;  
  71.         default:
  72.           break;  
  73.       }
  74.     }
  75.     else                              //定时器没有到时间就跳出
  76.       return ;
  77.   }



  78.   
  79. }


  80. void net()
  81. {
  82.   int msgnum;
  83.   if(error>0)                       //错误代码处理
  84.   {
  85.     error_chuli(error);
  86.   }
  87.   if(ding>0)
  88.   {
  89.     if((millis()-time_ding)>time_ms)                //如果定时器到时间了就执行,否则就跳出
  90.     {
  91.       switch(ding)                        //选自跳转的位置
  92.       {
  93.         case 1:
  94.           ding=0;
  95.           goto one;
  96.           break;
  97.         case 2:
  98.           ding=0;
  99.           goto two;
  100.           break;
  101.         case 3:
  102.           ding=0;
  103.           goto three;
  104.           break;
  105.         default:
  106.           break;  
  107.       }
  108.     }
  109.     else                              //定时器没有到时间就跳出
  110.       return ;
  111.   }
  112.   
  113.   if(wf)                                //判断wifi是否连接
  114.   {
  115.     if(tcpc)                            //判断tcp是否连接
  116.     {
  117.       if(tcps)                          //判断是否在透传中
  118.       {
  119.           mqtt_loop();
  120.       }
  121.       else                        //进入透传模式
  122.       {
  123.         three:if(tcp_begin_send())
  124.         {
  125.           tcps=1;
  126.         }
  127.         else
  128.         {
  129.           delay_ms(500,3);
  130.           error=3;
  131.         }
  132.       }
  133.       
  134.     }
  135.     else                        //tcp连接
  136.     {
  137.       two:if(tcp_client())
  138.       {
  139.         tcpc=1;
  140.       }
  141.       else
  142.       {
  143.         delay_ms(1000,2);
  144.       }
  145.     }
  146.    
  147.   }
  148.   else                            //wifi检测
  149.   {
  150.     one:if(ap_can())
  151.     {
  152.       wf=1;
  153.     }
  154.     else
  155.     {
  156.       delay_ms(3000,1);
  157.     }
  158.   }
  159. }










  160. bool mqtt_subscribe(const char *da,unsigned int Nu,unsigned char RequestedQo)
  161. {
  162.   int num;
  163.   qing_buff();
  164.   num=GetDataSUBSCRIBE(buff,da,Nu,RequestedQo);
  165.   Serial.write(buff,num);
  166.   qing_buff();
  167.   delay(500);
  168.   if(serial_can()==2)
  169.   {
  170.     qing_read();
  171.     return 1;
  172.   }
  173.   else
  174.   {
  175.     qing_read();
  176.     return 0;
  177.   }
  178. }


  179. void mqtt_publish(unsigned char du, unsigned char qo,unsigned char retai,const char *topi ,const char *ms)
  180. {
  181.   int num;
  182.   qing_buff();
  183.   num=GetDataPUBLISH(buff,du,qo,retai,topi,ms);
  184.   Serial.write(buff,num);
  185.   qing_buff();
  186. }

  187. void msg_chuli()
  188. {
  189.   int len=0,i;

  190.   if((msgas[23]=='o')&&(msgas[24]=='n'))
  191.   {
  192.     digitalWrite(2,HIGH);
  193.     mqtt_publish(0,0,0,MQTT_Topic,"on");

  194.    
  195.   }
  196.   if((msgas[23]=='o')&&(msgas[24]=='f'))
  197.   {
  198.     digitalWrite(2,LOW);
  199.     mqtt_publish(0,0,0,MQTT_Topic,"off");
  200.   }
  201.   for(i=0;i<50;i++)msgas[i]='\0';
  202.   
  203. //  mqtt_publish(0,0,0,MQTT_Topic,msg);
  204. //  len=strlen(msg);
  205. //  if((msg[0]=='o')&&(msg[1]=='n'))
  206. //  {
  207. //    digitalWrite(13,HIGH);
  208. //    mqtt_publish(0,0,0,MQTT_Topic,"on");
  209. //   
  210. //  }
  211. //  else if((msg[0]=='o')&&(msg[1]=='f'))
  212. //  {
  213. //    digitalWrite(13,LOW);
  214. //    mqtt_publish(0,0,0,MQTT_Topic,"off");
  215. //  }
  216. }


  217. void mqtt_loop()
  218. {
  219.   char *msgg=NULL;
  220.   int num;
  221.   if(ding2>0)
  222.   {
  223.     if((millis()-time_ding2)>time_ms2)                //如果定时器到时间了就执行,否则就跳出
  224.     {
  225.       switch(ding2)                        //选自跳转的位置
  226.       {
  227.         case 1:
  228.           ding2=0;
  229.           goto one;
  230.           break;
  231.         default:
  232.           break;  
  233.       }
  234.     }
  235.     else                              //定时器没有到时间就跳出
  236.       return ;
  237.   }
  238.                                                
  239.   if(mqttc==0)              //判断服务器是否连接上
  240.   {
  241.     one:if(mqtt_client())
  242.     {
  243.       mqttc=1;
  244.       timeoutr=millis();
  245.       timeoutt=millis();
  246.       mqtt_subscribe(mqtt_Stopic,0,0);
  247.       delay(1000);
  248.       mqtt_publish(0,0,0,MQTT_Topic,"wo");
  249.     }
  250.     else
  251.     {
  252.     delay_ms2(5000,1);  
  253.     }  
  254.   }
  255.   else
  256.   {
  257.     if((millis()-timeoutt)>5000)
  258.     {
  259.       mqtt_ping();
  260.       timeoutt=millis();
  261.     }
  262.     if((millis()-timeoutr)>30000)
  263.     {
  264.        mqttc=0;
  265.     }
  266.   }
  267.   if(Serial.available())
  268.   {
  269.     delay(300);
  270.     num=serial_can();
  271.     switch(num)
  272.     {
  273.       case 3:
  274.         timeoutr=millis();
  275.         timeoutt=millis();
  276.         break;
  277.       case 4:
  278.         msg_chuli();
  279.         break;
  280.       default:
  281.         esp_cpu(num);
  282.         break;
  283.     }
  284.   }
  285. }


  286. void mqtt_ping()
  287. {
  288.   int len;
  289.   len=GetDataPINGREQ(buff);
  290.   Serial.write(buff,len);
  291.   qing_buff();
  292. }


  293. bool mqtt_client()                //服务器连接
  294. {
  295.   int num;
  296.   int i;
  297.   qing_buff();
  298.   num=GetDataConnet(buff);
  299.   Serial.write(buff,num);
  300.   qing_buff();
  301.   delay(1000);
  302.   if(Serial.available())
  303.   {
  304.     if(serial_can()==1)
  305.     {
  306.       qing_read();
  307.       return 1;  
  308.     }
  309.     else
  310.     {
  311.       return 0;  
  312.     }  
  313.   }
  314.   else
  315.   {
  316.     return 0;
  317.   }
  318. }

  319. /**********************************************************
  320. 函数名称:serial_can()
  321. 函数功能:判断串口数据类型
  322. 返回值:
  323. 0   没有匹配到任何值
  324. 1       mqtt连接成功
  325. 2       mqtt订阅回应包
  326. 3       mqtt心跳包
  327. 4       mqtt消息包
  328. 6   wifi断开连接

  329. **********************************************************/
  330. int serial_can()                  //判断返回值
  331. {
  332.   int i;
  333.   int num;
  334.   qing_read();
  335.   num=Serial.available();
  336.   for(i=0;Serial.available()>0;i++)read_buff[i]=Serial.read();
  337.   if((read_buff[0]==0x20)&&(read_buff[1]==0x02))
  338.   {
  339.     return 1;
  340.   }
  341.   if(read_buff[0]==0x90)
  342.   {
  343.     return 2;
  344.   }
  345.   if((read_buff[0]==0xd0)&&(read_buff[1]==0x00))
  346.   {
  347.     return 3;
  348.   }
  349. //  if(strstr(read_buff,mqtt_Stopic)!=NULL)
  350.    if(read_buff[0]==0x30)
  351.   {
  352.     lenstr=num;
  353.     for(i=0;i<num;i++)msgas[i]=read_buff[i];
  354.     return 4;
  355.   }
  356.   if(strstr(read_buff,"disconnect from ssid")!=NULL)
  357.   {
  358.   return 6;
  359.   }
  360.   qing_read();
  361.   return 0;
  362. }


  363. void esp_cpu(int num)                       //设备处理
  364. {
  365.   switch(num)
  366.   {
  367.     case 6:                       //wifi断开连接处理
  368.       error_chuli(1);
  369.       break;
  370.     default:
  371.       break;
  372.   }
  373. }


  374. /*************************************************
  375. 函数名称:void error_chuli(int k)  
  376. 函数功能:错误处理
  377. 输入参数:
  378. 1       //错误代码1   WiFi断开连接
  379. 3       //错误代码3   透传模式失败


  380. *************************************************/
  381. void error_chuli(int k)
  382. {
  383.   switch(k)
  384.   {
  385.     case 1:                     //错误代码1     wifi断开连接
  386.       esp_res();
  387.       break;
  388.     case 3:                     //错误代码3     透传模式开启失败
  389.       error=0;
  390.       break;  
  391.     default:
  392.       break;
  393.   }
  394.   
  395. }




  396. void esp_res()
  397. {
  398.   wf=0;
  399.   tcpc=0;
  400.   mqttc=0;
  401.   tcps=0;
  402.   tcp_stop_send();
  403.   Serial.println(at_esp_ret);
  404.   delay(3000);
  405.   qing_buff();
  406.   qing_read();
  407.   while(Serial.read() >= 0);
  408. }

  409. bool tcp_begin_send()             //开始透传
  410. {
  411.   int i;
  412.   while(Serial.read() >= 0);
  413.   Serial.println(at_tcp_mode);
  414.   delay(300);
  415.   while(Serial.read() >= 0);
  416.   Serial.println(at_tcp_send);
  417.   delay(300);
  418.   if(Serial.available())
  419.   {
  420.     for(i=0;Serial.available()>0;i++)read_buff[i]=Serial.read();
  421.     if(strstr(read_buff,"OK")!=NULL)
  422.     {
  423.       qing_read();
  424.       tcps=1;
  425.       return 1;
  426.     }
  427.     else
  428.     {
  429.       qing_read();
  430.       return 0;
  431.     }
  432.   }
  433.   else
  434.   {
  435.     return 0;  
  436.   }
  437. }

  438. void tcp_stop_send()              //退出透传模式
  439. {
  440.   if(tcps==1)
  441.   {
  442.     Serial.print(at_tcp_ssend);
  443.     tcps=0;
  444.   }
  445. }


  446. bool tcp_client()
  447. {
  448.   int i;
  449.   while(Serial.read() >= 0);
  450.   Serial.println(at_tcp_client);
  451.   delay(4000);
  452.   if(Serial.available())
  453.   {
  454.     qing_read();
  455.     for(i=0;Serial.available()>0;i++)read_buff[i]=Serial.read();
  456.     if(strstr(read_buff,"CONNECT")!=NULL)
  457.     {
  458.       qing_read();
  459.       return 1;
  460.     }
  461.     else if(strstr(read_buff,"ALREADY CONNECTED")!=NULL)
  462.     {
  463.       qing_read();
  464.       return 1;
  465.     }
  466.     else
  467.     {
  468.       qing_read();
  469.       return 0;
  470.     }
  471.    
  472.    
  473.   }
  474.   else
  475.   {
  476.     qing_read();
  477.     return 0;
  478.   }
  479.   
  480.   
  481. }

  482. bool ap_can()
  483. {
  484.   int i;
  485. ……………………

  486. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
arduino对接esp8266版本4.0.zip (8.99 KB, 下载次数: 77)



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:419584 发表于 2019-10-5 19:20 | 只看该作者
谢谢分享谢谢分享
回复

使用道具 举报

板凳
ID:375092 发表于 2019-12-14 17:01 | 只看该作者
楼主你好,我下载了打不开,报错误了。看见了希望回复我一下,需要你的帮助
回复

使用道具 举报

地板
ID:58730 发表于 2020-3-30 19:25 | 只看该作者

谢谢分享谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表