第六次培训任务:esp8266(3)学习AT指令相关编程

提前准备:

在CSDN上面有关AT指令的文章基本上都会用板子,但是目前我手上没有板子,这就很不知所措了。

可以用云服务器解决这个问题,这里分享一个链接。可以用云服务器模仿esp8266的传输过程。

链接: https://pan.baidu.com/s/1jdp7apV4Ro-HvB1itHVu2A

提取码: 8he5

另外(与本文无关):

esp8266 WiFi库文件   在我的电脑上这个位置:D:\ESP8266\Arduino-master\libraries\esp8266\examples

arduino下载esp8266开发板用家里的WiFi很慢,换成手机热点就快很多了。

AT指令发送步骤+编程:

4种开发方式

1:使用乐鑫AT 固件,使用时,单片机通过串口用AT指令来实现wifi连接、网络通迅,例如arduino uno+esp8266他们间使用AT指令来交互,输入AT指令,要注意大小写,还有前后中间都不能有空格,以及符号必须是英文符号。

2:使用乐鑫SDK开发包,直接用C编程。例如果云esp8266 sdk开发之类。直接开发BIN文件。
3:使用NODEMCU固件,这是国内大能 在SDK基础上,加入了LUA语言

现在,出现了第4种开发方式,arduino直接编程,原理还是在SDK基础上开发,不过已经封装为我们熟的Arduino语言了。注意已经不需要ARDUINO硬件了,而是利用arduino软件平台来编译8266的源码。

开始扩展4种开发方式的第一条,开始介绍步骤

1.下面所有的命令,不做特殊说明,命令结尾处都要加/r/n装换成ASCII就是0x0d,0x0a。在编程中,这个很重要。我们的这个文档主要针对的也是编程过程。

2.AT命令,编程实现和用串口调试有很大的区别,主要体现在时间的延时上,在编程中,很多AT命令都需要相对应的延时,有些命令的延时需要长一些,而有一些则需要尽量的短,而这时间和实际环境也相关。所以,编程实现ESP8266的功能需要大量的时间来调试。

3.每个人用的模块的硬件电路可能有差异,所以如果对硬件不熟悉,就不能完全照抄别人的代码。当然,本质都是一样的,我们也得学习学习别人写好的那些调试代码,看他们的思路与设计过程,集众家之所长。

4.对于ESP8266的AT命令函数,网上能找到很多写好的库的函数,下载下来直接用就可以,都是开源的代码,结合自己的需求进行修改。注意,这个AT的库函数并不是官方的,官方是没有的,这个是别人写的,所以可能带有一些错误,但基本都是正确的,如果不确定,就先不用库函数,而是自己写简单的发送代码。

5.初次调试时,需要单步调试,观察每一步得到的返回字符,看是否正确。

6.涉及的命令很少,ESP8266本身AT命令也不多,主要用的是STA模式和AP模式,最后的目的便是网关(也就是ESP8266模块)和服务器的通信,通信才是重点,当然,肯定是不会直接通信的,必须依靠网络发送协议,也就是MQTT了,对于初次学习,这个协议有些难。

ESP8266连接WIFI,也就是上网用的无线信号:

我们这里的无线信号为:lm930126    密码:123456

第一步:ESP8266 复位

复位分两种,第一种是由AT指令实行:AT+RST,延时2s

第二种由硬件执行:此处不做详细说明,这是各个模块的硬件设计决定的。

我们建议使用第一种。

这个命令不会返回什么信息

第二步:AT+CWMODE=1(2.AP 3.station+AP) 

AP模式指的是可以将网卡设置为路由器用来共享流量或有线网络给别人使用,STA模式指的是当做网卡连接路由器上网

设置STA模式,延时2.5s。

这个命令发出去之后,会得到返回的信息:

AT+CWMODE=1  0x0d 0x0d 0x0a 0x0d 0x0a  OK 0x0d 0x0a

注意:这是一条字符串,中间是没有空格的,0x0d与0x0a是换行和回车的ascii码,其实就是字符’/r’  ‘/n’

AT+CWMODE=1 使我们发出去的命令,但是同样返回了,这个叫回显。回显是可以通过命令关闭的。

不同的设备可能会有差异,但是成功了肯定是有OK的。

第三步:AT+CWLAP,延时1s//没有查看无线信号的需求的可以不要这一步

这个命令发出去返回的字符串很长

这条命令的意思是列出现在能够查到的wifi信号。可以仔细看一看,你的无线信号都会成字符串列在其中。在整个字符串的最后,同样会有OK。

第四步:AT+CIPMUX=0 , 设置成单路连接模式,延时1s

第五步: AT+CWJAP=”lm930126”, “123456”

这一步便是连接wifi,延时的时间要长一些,否则会等不到返回的信息。我们测试时延时18s,成功了会有OK的返回。

你可以将这步的延时时间改了,进入调试状态,看存储器,会发现接收了一半就没有了,所以这里延时的时间很重要。

 这一命令发出去后,会立刻受到一个WIFI DISCONNECTED 的字符串,不用急,等一会会有WIFI CONNECTED 的字符串,连上网络是需要一定的时间的。

ESP8266连接TCP,也就是连接服务器:

1.AT+CIPSTART= “TCP”, “192.168.43.88”, 8080

这一步的参数需要根据自己的ip的地址来设置,成功了会返回OK。延时4秒.

2.  AT+CIPMODE=1  AT+CIPSEND

这两个依次发出去。

第一句的意思是设置为透传模式,第二句 则是进入透传模式。进入透传模式成功,会返回‘>’符号。

一旦进入透传模式,那么发送AT命令就失效了。

这两个命令各延时2s,我们建议第一步之后再延时一秒,更加稳定,这里需要根据自己的代码和硬件进行调试。

 ESP8266设置成服务器,通俗讲就是ESP8266设置一个热点:

1.AT+RST  复位

2.AT+CWMODE=2  设置为AP模式

3.AT+RST

这里需要注意,第一步的复位是退出其他的设置,准备AP设置

而这一步的复位是必须加的,否则第二步的设置就没有用。

4.AT+CWSAP=”ESP8266”,”123456”,1,4

设置ESP8266的热点名称和密码。

5.AT+CIPMUX=1

6.AT+CIPSERVER=1,8086

AT+CIPSTO=5000

第一条指令是设置本地端口号,也就是之后连接上这个热点后,需要设置的一个端口号。

7.AT+CIFSR

这是列出IP地址,也是等连接上热点后需要设置用来通信的。这是AP模式下的设置,设置完成后就可以连接ESP8266的热点了,网上下载一个网络串口调试器就可发送数据了。

 

程序(Arduino UNO跟ESP8266结合)

电路

 

1. 第一步——Arduino引用软串口库

基本的只引用软串口,所谓软串口库,就是用 gpio pin 模拟出来一个串口,即softwareserial。

#include <SoftwareSerial.h>
 
SoftwareSerial mySerial(10, 11); // RX, TX 配置10、11为软串口

把会用到的信息先定义出来。

#include <SoftwareSerial.h>
// 软串口
SoftwareSerial WIFISerial(6, 7); // RX, TX交叉接线

#define OK "OK"
#define SENDOK "SEND OK"
#define WIFIPIN 4 //配网按键,按住2秒配网
bool WIFIPINAvailable = true;// 配网按钮是否可用
bool wifiLinked = false;// WIFI是否连接上AP
bool serverLinked = false;// 服务器是否连接
unsigned long lastTime;

2. 第二步——初始化

void setup() {
  pinMode(WIFIPIN, INPUT);

  // 硬件串口 initialize serial for debugging
  Serial.begin(115200);
  while (!Serial) {}
  // 软串口 initialize serial for ESP module
  WIFISerial.begin(57600);
  //  WIFISerial.println("AT+UART_DEF=57600,8,1,0,0");//解决乱码
  //  delay(1000);
  while (!WIFISerial) {}
  WIFISerial.listen();// 开始监听

  Serial.println(F("---setup start---"));

  // 查询网络连接状态,等待wifi连网几秒
  bool _link = false;
  int _i = 0;
bgnwifi:
  for (int i = 0; i < 3; i++) {
    // STATUS 2:获得 IP ,3:已连接,4:断开连接,5:未连接到 WiFi
    if (doCMD(F("AT+CIPSTATUS"), F("STATUS:2|STATUS:3"), 3000)) {
      _link = true;
      break;
    }
    delay(1000);
  } 
  if (!_link && _i == 0) {
    doCMD(F("AT+RST"), F("ready"), 3000);// 重启wifi模块
    delay(4000);// 等待连接
    _i++;
    goto bgnwifi;
  } 
  if (!_link) {
    smartConfig();// 启动一键配网
  }else {
    wifiLinked = true;
  }

  lastTime = millis();
  Serial.println(F("---setup end---"));
}

3. 第三步——开始使用loop函数

·简单 直接在arduino IDE中的串口监视器中进行AT指令的发送


void loop() //循环
{
  if (mySerial.available())
    Serial.write(mySerial.read());//mySerial检测到了信号,就输出检测到的信号
  if (Serial.available())
    mySerial.write(Serial.read());//同理
    }

·复杂 使用一些封装的函数,然后再进行loop 的使用
找到的一个封装公共函数–飘易封装的公共函数

// 执行AT指令
// cmd AT指令,返回值包含flag则true(2个以|分割),timeout超时时间ms(200的整数倍)
bool doCMD(String cmd, String flag, long timeout) {
  String str = "";
  WIFISerial.println(cmd);    //发送AT指令
  delay(300);
  flag.toLowerCase();// 小写
  // 限期时间
  long deadline = millis() + timeout;  
 //mills(),此函数用于返回的Arduino板开始运行当前程序时的毫秒数。这个数字在大约50天后溢出,即回到零


  while (millis() < deadline)   //8266正常运行时,执行这个while循环
  {
    str = "";                   //没有收到信号
    while (WIFISerial.available()) {//开始收到信号了,把信号编程char类型,赋值给str
      str += (char)WIFISerial.read();
      delay(2);
    }


    if (str != "") {
      Serial.println(str);// 打印输出
      str.toLowerCase();// 小写
      // 判断 flag 是否需要切割,以 | 切割,逻辑或关系
      String flag1 = "", flag2 = "";
      int commaPosition = flag.indexOf('|');
//int indexOf(String str): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字//符,则返回 -1。
      if (commaPosition > -1)                       //flag里面有‘|’,开始切割
      {
        flag1 = flag.substring(0, commaPosition);
        flag2 = flag.substring(commaPosition + 1, flag.length());
      }
//substring() 方法用于提取字符串中介于两个指定下标之间的字符
      if (flag1 != "" && flag2 != "") {                  //如果可以切割
        if (str.indexOf(flag1) > -1 || str.indexOf(flag2) > -1 ) {
          return true;                      
//如果flag1或2有要找的索引/字符,返回true,进行切割
        }
      }
      if (str.indexOf(flag) > -1) {        //如果flag有要找的索引,切割
        return true;
      }
    }
    delay(100);
  }
  return false;
}



// 一键配网 smartconfig
void smartConfig() {
  // 启动smartconfig之前,先停止一下,以避免上次未复位
  doCMD(F("AT+CWSTOPSMART"), OK, 3000);
  // SmartConfig 仅支持在 ESP8266 单 station 模式下调用
  if (!doCMD(F("AT+CWMODE_DEF=1"), OK, 3000)) {}
  // 上电自动连接AP
  if (!doCMD(F("AT+CWAUTOCONN=1"), OK, 3000)) {}
  // 启动smartconfig,支持ESP-Touch和Airkiss智能配网
  // 在 SmartConfig 过程中请勿执行其他指令
  Serial.println(F("~~ Start SmartConfig ~~"));
  bool res = doCMD(F("AT+CWSTARTSMART=3"), F("WIFI GOT IP"), 60000);// 60秒超时
  if (res) {
    wifiLinked = true;
    Serial.println(F("SmartConfig OK"));
  } else {
    wifiLinked = false;
    Serial.println(F("SmartConfig Fail"));
  }
  doCMD(F("AT+CWSTOPSMART"), OK, 3000);// 无论配网是否成功,都释放快连所占的内存
}



// 连接TCP服务器                  
bool connectTcp() {
  bool linkOk = true;
  //连接服务器
  String s(F("AT+CIPSTART=\"TCP\",\"tcp.x.com\",9960"));// 字符串存入FLASH
  if (!doCMD(s, F("OK|CONNECTED"), 3000)) {
    linkOk = false;
  }
  if (linkOk) {
    // 登录,也是心跳包,1分钟内必须上报一次,如有其他定时上报,则可不使用本心跳包
    s = F("{\"method\": \"update\",\"gatewayNo\": \"01\",\"userkey\": \"123\"}&^!");// 字符串存入FLASH
    doCMD("AT+CIPSEND=" + String(s.length()), ">", 3000);      //doCMD执行操作指令
    if (!doCMD(s, SENDOK, 3000)) {
      linkOk = false;
    }
  }
  if (!linkOk) {
    Serial.println(F("!!SERVER NOT CONNECTED!!"));
  } else {
  }
  serverLinked = linkOk;
  return linkOk;
}

实例

执行的业务逻辑是:每50秒为一个循环,在每个循环的第5秒上报传感器的温度和湿度值给云端。当用户按下wifi配网按钮时,wifi模组进入一键配网流程重新设置wifi的ssid和密码信息。

set up 函数参考上面的,这里直接给出loop函数

void loop() {
  String info = "";

  // 定时上报给服务器 - TCP长连接
  if (millis() - lastTime == 5000) {
//mills此函数用于返回的Arduino板开始运行当前程序时的毫秒数。这个数字在大约50天后溢出,即回到零。
    // 判断wifi是否连接上
    if (!wifiLinked) {
      Serial.println(F("!!WIFI NOT CONNECTED!!"));
    } else {
      //连接TCP服务器
      if (!serverLinked) {
        connectTcp();//连接TCP服务器
      } else {
        // 上报传感器值 - 定时上报,可代替心跳包(1分钟内1次)
        String temp = String(random(10, 40));// 模拟温度
        String humi = String(random(40, 90));// 模拟湿度
        if (true) {
          String s1(F("{\"method\": \"upload\",\"data\":[{\"Name\":\"temp\",\"Value\":\""));// 字符串存入FLASH
          String s2(F("\"},{\"Name\":\"humi\",\"Value\":\""));// 字符串存入FLASH
          String s3(F("\"}]}&^!"));// 字符串存入FLASH
          info = s1 + temp + s2 + humi + s3;
          Serial.println(info);
          doCMD("AT+CIPSEND=" + String(info.length()), ">", 3000);
          if (!doCMD(info, SENDOK, 3000)) {
            serverLinked = false;
          } else {
          }
        }
      }
    }
  }
  // 恢复计时,云端限制提交频率不能低于20秒
  if (millis() - lastTime >= 50000) {
    lastTime = millis();
  }

  // 读取WIFI配网按钮是否接通
  boolean val = digitalRead(WIFIPIN);
  if (val && WIFIPINAvailable) {
    WIFIPINAvailable = false;
    Serial.println(F("WIFIPIN pressed"));
    smartConfig();// 启动一键配网
    WIFIPINAvailable = true;
  }

  // PC串口转发给wifi软串口
  while (Serial.available()) {
    WIFISerial.write(Serial.read());
  }
  // wifi软串口发送过来的信息
  String str = "";
  while (WIFISerial.available()) {
    str = str + (char)WIFISerial.read();
  }
  if (str != "") {
    Serial.println(str);
  }

}

接线图

传入代码

#include <softwareserial.h>
SoftwareSerial ESP8266(10, 11); // RX | TX
void setup() {
Serial.begin(9600);
ESP8266.begin(9600);
}
void loop()
{
    // Keep reading from ESP-01s and send to Arduino Serial Monitor
    if (ESP8266.available())
   {
     Serial.write(ESP8266.read());
    }
     // Keep reading from Arduino Serial Monitor and send to ESP-01s
    if (Serial.available())
    {
      ESP8266.write(Serial.read());
     }
}

在库文件里面找到了Blink的代码,用arduino打开,尝试编译并成功通过。具体如下:(不需要硬件的方式)

/*
  ESP8266 Blink by Simon Peter
  Blink the blue LED on the ESP-01 module
  This example code is in the public domain

  The blue LED on the ESP-01 module is connected to GPIO1
  (which is also the TXD pin; so we cannot use Serial.print() at the same time)

  Note that this sketch uses LED_BUILTIN to find the pin with the internal LED
*/

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
  // but actually the LED is on; this is because
  // it is active low on the ESP-01)
  delay(1000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
}

相关文章:esp8266 AT指令以及刷固件    AT指令详细说明stm32+ESP8266

arduino 1.8.8版本

另外(与本文无关):

·WiFiUDP库

·arduino进行串口通信的代码

void(* resetFunc) (void) = 0;//声明函数地址为0
bool kaiqi_1 = false;        //开启或关闭while(flag){}
char val;

void setup()
{
  Serial.begin(9600);         //波特率
}

 

void loop()
{
    String val = chuankou();                   
    if (val[0] == 'F')                                                 
     {
        kaiqi_1= true;
        while (kaiqi_1)
          { 
              /*****需要执行的程序********/
              val = chuankou();               
               
              if (val[0] == 'S')             
                { 
                  kaiqi_1 = false;
                  /*****停止所正在执行的程序*****/
                 }
          }
     }
      if (val[0] == 'T')  //通过指令复位主板                       
      {
       Serial.println("Reset OK");
       delay(100);
       resetFunc();
     }
}

  String chuankou()   //串口通信
{
  String val = "";    //定义空字符串
  while (Serial.available())
  {
    val += char(Serial.read());
    delay(2);
  }
  return val;      //返回这个串口的值
}

 

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页