使用ARDUINO UNO通过MQTT协议连接ONENET(8266透传)

使用ARDUINO UNO通过MQTT协议连接ONENET(8266透传)

  • 连线方式
  • 实现方式
  • 具体代码

连线方式

ARDUINO UNO --> 8266(使用软串口连接)
数字端口8(RX) --> TX
数字端口9(TX) --> RX
3V3 --> VCC
GND --> GND
GND --> CHPD

实现方式

想让ARDUINO UNO使用MQTT连接到ONENET,最简单的办法是直接使用ARDUINO IDE或者MICROPYTHON烧录8266,然后ARDUINO UNO通过软串口监听8266的通信。
那么今天来说8266透传的方式,主要还是把具体的逻辑说一下,以便更好地理解MQTT协议的优势。
后面代码的逻辑如下:
1、先用数组形式定义MQTT的协议内容,这个主要是为了方便后面用十六进制方式向ONENET服务器发送数据
2、ARDUINO通过软串口打开8266的透传模式
3、发送MQTT协议

具体代码

#include 
SoftwareSerial mySerial(8, 9); // RX, TX

void (* resetFunc) () = 0;

int v_w_test=0;
int v_w_cnt=0;
int v_w_test_result=0;
int v_w_transfer=0;
int v_w_transfer_result=0;
int v_s_c=0;
int i=0;
int j=0;
int k=0;

unsigned char uart_Receive_Buff [ 80 ]; //定义缓冲buff 
unsigned int uart_Receive_Index = 0; //收到的字节实际长度  

char Serial_val;  // 储存接受数据  
unsigned char Serial_val1;  // 储存接受数据  
String Serial_str="" ;   //设置一个空的字符串,用于打印串口输出结果

unsigned char data[42] = {0x10,  //上线报头
                          0x28,  //后面的字符数以十六进制表示
                          0x00,0x04,0x4D,0x51,0x54,0x54, //固定的发送MQTT字符	
                          0x04,0xC2, //固定
                          0x00,0x78, //上线时间120秒,后面通过心跳来保持这个链接
                          0x00,0x09,//设备ID长度
                          0x35,0x36,0x33,0x33,0x32,0x38,0x30,0x37,0x**,  //设备ID
                          0x00,0x06, //产品ID长度
                          0x32,0x37,0x38,0x36,0x30,0x**,  //产品ID 
                          0x00,0x09, //鉴权长度
                          0x6D,0x71,0x74,0x74,0x62,0x31,0x30,0x32,0x** //鉴权ID
                          };  //模块上线
                          
unsigned char data_1[2] = {0xC0,0x00 }; //心跳,发送内容是固定的

unsigned char data_2[18] = {0x82,0x10, //订阅报头与后面字符长度
                          0x00,0x0A,  //订阅标题
                          0x00,0x0B,  //订阅长度
                          0x6D,0x6D,0x6E,0x6E,0x5F,0x74,0x6F,0x70,0x69,0x63,0x31,//订阅内容mmnn_topic1
                          0x00 //订阅等级
                          };

void setup()
{ Serial.begin(9600);        //串口速率同步
  mySerial.begin(9600);      //串口速率同比
  mySerial.print("+++");     //8266退出串口模式 主要供初始化使用
  while ( v_s_c != 5 ) 
        { delay(1000); Serial.print("*");  v_s_c++;}     //等待5秒8266启动时间
  v_w_test_result=wifi_test();   //连接状态检测
  if(v_w_test_result==5) 
        { v_w_transfer_result=wifi_transfer() ;}    //启动传输
  if(v_w_transfer_result==5) 
        {Serial.println("INITIALIZATION COMPLETED;"); Serial.println("WIFI TRANSFER OPEN");}
  if(v_w_test_result!=5 || v_w_transfer_result!=5) {Serial.println("Resetting Arduino Programmatically"); resetFunc();}

      Serial.println("!!!");
}

void loop()
{
     
      if (j<1) 
      {   
        for (int i = 0; i < 42; i++)
        {
                mySerial.write(data[i]); 
        }  
        for (int i = 0; i < 18; i++)
        {
                mySerial.write(data_2[i]); 
        }  
        j=1; 
      }

      uart_Receive_Index=0; 
      while (mySerial.available()>0)  //判断软串口是否有待读取数据(字符)
                                              {  
                                                Serial_val1 = mySerial.read();   //读取软串口数据(字符)到val变量
                                                uart_Receive_Buff [ uart_Receive_Index ] = Serial_val1;              //要判断是否完成传输需要使用字符串,因此将字符连接成字符串 
                                                uart_Receive_Index++;
                                              }  
      for (int i=0; i<20; i++) {Serial.print(uart_Receive_Buff[i],HEX);}
      Serial.println();
      
      for (int i=0; i <5; i++ ) { delay(1000); Serial.print("*");}     //等待5秒8266启动时间 

      for (int i=0; i <20; i++ ) {uart_Receive_Buff[i]=0x00;}

      
      if(k == 60) {  for (int m = 0; m < 2; m++)   { mySerial.write(data_1[m]);  }  k=0;  }
      delay(1000);
      k++; 
   
}

int wifi_test()   //判断WIFI连接状态
{ v_w_test=1;  //启动时要搭配5秒延迟使用
        while (v_w_test !=5 )
                     { 
                       switch (v_w_test)
                       {  
                         case 1:   if(1==1)  
                                     { Serial_str=""; mySerial.println("AT+CWJAP?");                     v_w_test=2; }    break; 
                         case 2:   if( Serial_str.indexOf("No AP\r\n\r\nOK")>0)  
                                     { Serial_str=""; mySerial.println("AT+CWJAP=\"whowho\",\"***\"");  v_w_test=3; }  
                                   if( Serial_str.indexOf("+CWJAP:")>0) 
                                     {                                                                   v_w_test=3; }    break;
                         case 3:   if( Serial_str.indexOf("OK")>0)  
                                     { Serial_str="";                                                    v_w_test=4; }    break;
                         case 4:   delay(3000) ;v_w_test=5;                                                                      break;
                         default :                                                                                        break;
                       }   
                        while (mySerial.available()>0)  //判断软串口是否有待读取数据(字符)
                                              {  
                                                Serial_val = mySerial.read();   //读取软串口数据(字符)到val变量
                                                Serial_str += Serial_val;              //要判断是否完成传输需要使用字符串,因此将字符连接成字符串
                                                Serial.print(Serial_val);       //依次打印val每个字符 
                                              }          
                       if ( Serial_str.indexOf("FAIL")>0 || Serial_str.indexOf("busy")>0 )
                          {delay(1000) ;              if (v_w_test!=9)                 {Serial_str=""; mySerial.println("AT+RST");  v_w_test=9;}  }
                       if ( v_w_test==9 )
                          {delay(1000) ;  v_w_cnt++;  if (Serial_str.indexOf("OK")>0)  {Serial_str="";                  v_w_test=1; v_w_cnt=0; }  }
                       if ( v_w_test==9 && v_w_cnt>=30)  
                          {                           if (1==1)                        {Serial_str="";                  v_w_test=8; v_w_cnt=0; }  }
                       if (millis()>60000) {Serial.println("Resetting Arduino Programmatically"); resetFunc();}
                     }
        Serial_str="";
        return v_w_test;
}


int wifi_transfer()   //开启透传函数
{ v_w_transfer=1; 
        while (v_w_transfer !=5 )
                     { 
                       switch (v_w_transfer)
                       {  
                         case 1:   if(1==1) 
                                     { Serial_str="";  mySerial.println("AT+CIPSTART=\"TCP\",\"183.230.40.39\",6002");  v_w_transfer=2; }     break;  
                         case 2:   if( Serial_str.indexOf("OK")>0 || Serial_str.indexOf("ALREADY CONNECTED")>0 ) 
                                     { Serial_str="";  mySerial.println("AT+CIPMODE=1");                              v_w_transfer=3; }     break;  
                         case 3:   if( Serial_str.indexOf("OK")>0)  
                                     { Serial_str="";  mySerial.println("AT+CIPSEND");                                v_w_transfer=4; }     break;
                         case 4:   delay(3000);   v_w_transfer=5;                                                                                            break;
                         default :                                                                                                          break;
                       }   
                        while (mySerial.available()>0)  //判断软串口是否有待读取数据(字符)
                                              {  
                                                Serial_val = mySerial.read();   //读取软串口数据(字符)到val变量
                                                Serial_str += Serial_val;              //要判断是否完成传输需要使用字符串,因此将字符连接成字符串
                                                Serial.print(Serial_val);       //依次打印val每个字符 
                                              }   
                       if (millis()>120000) {Serial.println("Resetting Arduino Programmatically"); resetFunc();}       
                      }
         Serial_str="";
         return v_w_transfer;
}

 

你可能感兴趣的:(Arduino,物联网,ESP8266)