(一)使用AT指令 arduino uno r3+esp8266+mqtt+阿里云 远程数据-Arduino中文社区 - Powered by Discuz! Archiver

jiangzhiwei 发表于 2018-11-25 15:52

(一)使用AT指令 arduino uno r3+esp8266+mqtt+阿里云 远程数据

本帖最后由 jiangzhiwei 于 2019-10-16 23:01 编辑

前排提示,纯小白请绕路,本篇幅不涉及基础知识,纯小白请绕路。至少需要对8266AT指令和arduiono串口通信有一定的熟悉程度。因为玩了这么久的arduino +8266,
觉得可以发个贴子来整理下自己这么久所学到的一些东西
还有一部分就是,我当时在社区里想找用AT指令开发MQTT 的教程,发现了许多有用的,
但是包括在百度上,都很少有用arduino 连接8266用at指令去连接mqtt的。
因为我从一开始就是在用uno+8266去做的一个项目,并没有用8266 -01之类的WiFi开发板,而且试过烧录固件什么的方法,都用过,可能是因为手残吧,都不起反应。
然后现在最终选择去搞懂mqtt协议,用at指令去开发。


(注: 近期学业繁忙
本帖暂时停止维护,如有问题恕不能回复,望谅解)


然后现在开始写过程
需要准备的材料 :
      一个云服务器--->搭建了mqtt服务端(至于怎么搭建的,如果有需要可以留言 我在下次发帖发搭建的          教程,其实百度有一大把里)
         Arduinouno r3板子一块
            ESP8266 WiFi模块一块
            杜邦线   若干
             网络调试助手(电脑软件)
         一个能上网的WiFi 或者热点

在弄MQTT之前,先了解TCP协议,既然我们使用的是AT指令,要知道在8266的AT指令集中,是可以通过AT指令去配置8266本身当做一个TCP客户端或者TCP服务端的,对于TCP怎么建立的还不明白的话,可以参考8266AT指令集,跟着去配置一下。

然后,mqtt是基于TCP的一个协议,也就是说在TCP连接之后,经过另一层次协议,便可以连接上MQTT,


什么意思呢   我来用调试助手操作一下就知道了,首先知道搭建好的mqtt的ip 和端口号

点击“启动”
我们可以看到mqtt连接已经建立
当然这是我们直接用网络调试助手,当然可以直接连接。



现在我们试着
再打开一个网络调试助手(建立一个局域网内的 TCP 服务端)记住这个ip和端口号
然后启动服务器,就开始监听这个不要动!!!!!!!把这个挂在后台,


然后打开这个,把IP和端口号改为上面的,点击启动,

之后你会发现刚刚后台挂着的TCP服务端加入了一个客户端,并且接受到了75个字节的数据!!!(十六进制显示)





这说明MQTT就是一个基于TCP的连接,并且发送了一段16进制的数据,而这一段数据就是请求连接的数据。


现在我们把这段数据复制下来


再建立一个TCP客户端,IP和端口号是自己搭建的MQTT的ip和端口号





点击连接,会发现连接上了~~~~~
然后发送刚刚复制那段(16进制发送)
你会发现,它收到来自mqqt(服务端)的4个字节的数据,说明连接成功!如果你没在规定的时间内发送这串数据,那么mqtt那边会主动断开你的连接。

这就是连接MQTT的过程!先建立一个TCP客户端连接,然后再规定的时间内发送一串16进制数,示意我请求的是mqtt,这串16进制数代表什么我们后面再说,反正就是,我和MQTT建立了TCP连接,然后MQTT(服务端)需要你在规定时间内出示你的身份,否则会断开连接,
所以你建立TCP后连接后,发送的第一串数据就是你需要建立MQTT的身份证,(还需要说明下,不一定是75字节,取决于你的身份信息的长度:用户名密码等,这些等会会说到)。


上面是说明了一下MQTT的连接过程,不知道有没有表达明白,首先你要对TCP服务端和客户端的连接了解后才好理解。


理解了上面的就好办了,
接下来第一件事就是在用arduinouno r3和esp8266连接,
然后写代码,先用AT指令建立TCP客户端



这一段是我做MQTT之前的,arduino +8266作为TCP的客户端连电脑(或手机)接服务端,然后传输DHT11温湿度传感器的数据到服务端的代码,凑合着看吧,其实连接的代码就中间那么一小段,后面的都是dht11的传感器的数据处理函数。

至于服务端用电脑的网络调试助手测试就好了,
/*
*1.DHT11接Arduino:vcc连3.3v,DATA连A0,GND连GND
*2.ESP8266连Arduino:TX连0,RX连1,EN和3V3连3.3v,GND连GND
*/

#include <SoftwareSerial.h>
#define DEBUG
#define _baudrate   115200

// USB TTL 检错用
#define _rxpin      0
#define _txpin      1
SoftwareSerial debug( _rxpin, _txpin ); // RX, TX

// DHT温湿度传感器
#define dht_dpin A0
byte bGlobalErr;
byte dht_dat;

// ESP8266 Wifi模块
/*#define SSID "ONEPLUS3"
#define PASS "12345678"
#define IP "192.168.43.125"*/
#define SSID "ese"
#define PASS "12345678"
#define IP "192.168.43.103"
int flame=A5;//定义火焰接口为模拟5 接口
int qiti=A3;
int val=0;//定义数字变量
int cal=0;
// 使用 GET格式
String GET = "\rRead sensor: OK\n";

void setup() {
    InitDHT();
    Serial.begin( _baudrate );
    debug.begin( _baudrate );
    delay(300);
    sendDebug("AT");
    delay(500);
    if(Serial.find("OK"))
    {
      Serial.println("RECEIVED: OK\nData ready to sent!");
      connectWiFi();
    }
    delay(700);
    }

void loop() {
ReadDHT();
switch(bGlobalErr){
   case 0:
      String TT,HH;
      HH = String(dht_dat)+'.'+String(dht_dat);
      TT = String(dht_dat)+'.'+String(dht_dat);
      val=analogRead(flame);//读取火焰传感器的模拟值
      cal=analogRead(qiti);
      Serial.println(val);
      Serial.println(cal);//输出模拟值,并将其打印出来
      updateDHT11( TT, HH );      
      #ifdef DEBUG
            debug.print("Humidity: ");
            debug.print( HH );
            debug.print(" %\t");
            debug.print("Temperature: ");
            debug.print( TT );
            debug.println(" *C\t");
      #endif
   
}
delay(500);
}

void updateDHT11( String T, String H )
{
    // 使用AT指令上传
    String cmd = "AT+CIPSTART=\"TCP\",\"";
    cmd += IP;
    cmd += "\",8080";
    sendDebug(cmd);
    delay(1000);
    if( Serial.find( "Error" ) )
    {
      Serial.print( "RECEIVED: Error\nExit1" );
      return;
    }
    cmd ="Temperature="+T+"oCHumidity="+H+"%"+ " Flame="+val+ "Qiti: "+cal+"\r\n" ;
    Serial.print( "AT+CIPSEND=" );
    Serial.println( cmd.length());
    if(Serial.find( ">" ) )
    {
      debug.print(">");
      debug.print(cmd);
      Serial.print(cmd);
    }
    else
    {
      sendDebug( "AT+CIPCLOSE" );
    }
    if( Serial.find("OK") )
    {
      debug.println( "RECEIVED: OK" );
    }
    else
    {
      debug.println( "RECEIVED: Error\nExit2" );
    }
}

void sendDebug(String cmd)
{
    // 传到 USB TTL
    debug.print("SEND: ");
    debug.println(cmd);
    Serial.println(cmd);
}

boolean connectWiFi()
{
    // 连接到Wifi
    Serial.println("AT+RST");
    delay(1000);
    Serial.println("AT+CWMODE=1");
    delay(1000);
    String cmd="AT+CWJAP=\"";
    cmd+=SSID;
    cmd+="\",\"";
    cmd+=PASS;
    cmd+="\"";
    sendDebug(cmd);
    delay(2000);
    if(Serial.find("OK"))
    {
      debug.println("RECEIVED: OK");
      return true;
    }
    else
    {
      debug.println("RECEIVED: Error");
      return false;
    }
   cmd = "AT+CIPMUX=0";
   sendDebug( cmd );
    if( Serial.find( "Error") )
    {
      debug.print( "RECEIVED: Error" );
      return false;
    }
}
void InitDHT(){
   // 初始化DHT
   pinMode(dht_dpin,OUTPUT);
   digitalWrite(dht_dpin,HIGH);
}

void ReadDHT(){
bGlobalErr=0;
byte dht_in;
byte i;
digitalWrite(dht_dpin,LOW);
delay(20);

digitalWrite(dht_dpin,HIGH);
delayMicroseconds(40);
pinMode(dht_dpin,INPUT);

dht_in=digitalRead(dht_dpin);

if(dht_in){
   bGlobalErr=1;
   return;
   }
delayMicroseconds(80);
dht_in=digitalRead(dht_dpin);

if(!dht_in){
   bGlobalErr=2;
   return;
   }
delayMicroseconds(80);
for (i=0; i<5; i++)
   dht_dat = read_dht_dat();
pinMode(dht_dpin,OUTPUT);
digitalWrite(dht_dpin,HIGH);
byte dht_check_sum =
       dht_dat+dht_dat+dht_dat+dht_dat;
if(dht_dat!= dht_check_sum)
   {bGlobalErr=3;}
};

byte read_dht_dat(){
byte i = 0;
byte result=0;
for(i=0; i< 8; i++){
      while(digitalRead(dht_dpin)==LOW);
      delayMicroseconds(30);
      if (digitalRead(dht_dpin)==HIGH)
   result |=(1<<(7-i));
    while (digitalRead(dht_dpin)==HIGH);
    }
return result;
}




总得来说    就是将arudino当成PC串口调试助手,利用arduino 用串口通信发指令给8266,去建立一个TCP客户端




这一篇就到这里,用于理解解TCP和MQTT,后面我会再更新去讲解建立MQTT的连接的那串数据代表说明
。然后如和用AT指令   在建立了连接的基础上去连接MQTT,以及修改后的完整代码。


如果对于arduino +8266   AT指令建立TCP 客户端不了解 的的或者搭建MQTT云服务器不了解的   评论底下留言   我会教程如何搭建搭建。



在建立了TCP客户端之后,便可以开始写指令去建立MQTT连接了~~~~~以及消息的推送和接收
移步下一篇(等我更新吧~~~~)





还在不断学习中~~~~
第一次发帖,还望多多关照~~~~



从上边复制的代码自动把一个地方的中括号给清除了,所以直接复制会有编译错误,下面附件传上~


第二篇
(二)AT 指令开发MQTT    TCP--MQTT的转化
https://www.arduino.cn/forum.php?mod=viewthread&tid=82905&fromuid=162671
(出处: Arduino中文社区)







gkfly 发表于 2018-11-26 10:00

不错,刚好需要,才接触arduino不到一个月:lol

qq667121 发表于 2018-12-5 01:19

说好的阿里云呢?

jiangzhiwei 发表于 2018-12-6 13:32

qq667121 发表于 2018-12-5 01:19
说好的阿里云呢?

阿里云搭建mqtt吗?

llyyy111 发表于 2018-12-13 12:57

你好,我执行这段代码的时候出现了这个错误:In function 'void ReadDHT()',怎么解决啊

SvenGao 发表于 2018-12-13 17:10

非常好,向你学习

jiangzhiwei 发表于 2018-12-13 17:29

llyyy111 发表于 2018-12-13 12:57
你好,我执行这段代码的时候出现了这个错误:In function 'void ReadDHT()',怎么解决啊 ...

dht_dat= read_dht_dat();    这一行改成dht_dat= read_dht_dat();

(我把代码复制上去后这个括号就没有了不知道为什么.)

jiangzhiwei 发表于 2018-12-13 17:30

jiangzhiwei 发表于 2018-12-13 17:29
dht_dat= read_dht_dat();    这一行改成dht_dat= read_dht_dat();

(我把代码复制上去后这个括号就没 ...

dht_dat= read_dht_dat();

jiangzhiwei 发表于 2018-12-13 17:33

jiangzhiwei 发表于 2018-12-13 17:30
dht_dat= read_dht_dat();

代码附件已上传,这个不知道为什么我一打那个括号就不显示出来,自动给我清除了

jiangzhiwei 发表于 2018-12-13 17:34

llyyy111 发表于 2018-12-13 12:57
你好,我执行这段代码的时候出现了这个错误:In function 'void ReadDHT()',怎么解决啊 ...

代码附件已上传,这边给我自动把中括号清除了
页: [1] 2
查看完整版本: (一)使用AT指令 arduino uno r3+esp8266+mqtt+阿里云 远程数据