ESP8266与ARDUINO UNO的连接及使用笔记

ARDUINO UNO跟ESP8266结合

电路

程序

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

基本的只引用软串口

#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() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  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;
  while (millis() < deadline)
  {
    str = "";
    while (WIFISerial.available()) {
      str += (char)WIFISerial.read();
      delay(2);
    }
    if (str != "") {
      Serial.println(str);// 打印输出
      str.toLowerCase();// 小写
      // 判断 flag 是否需要切割,以 | 切割,逻辑或关系
      String flag1 = "", flag2 = "";
      int commaPosition = flag.indexOf('|');
      if (commaPosition > -1)
      {
        flag1 = flag.substring(0, commaPosition);
        flag2 = flag.substring(commaPosition + 1, flag.length());
      }
      if (flag1 != "" && flag2 != "") {
        if (str.indexOf(flag1) > -1 || str.indexOf(flag2) > -1 ) {
          return true;
        }
      }
      if (str.indexOf(flag) > -1) {
        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);
    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) {
    // 判断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);
  }

}

 

  • 2
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值