Arduino - ESP8266 Wifi 模块 之 搭建

本文介绍了一种使用Arduino Nano和ESP8266模块搭建的简易物联网测试环境,该环境能实现温湿度监测、LED控制等功能,并通过云平台远程控制本地设备。

用面包板搭了个简易测试环境,包括以下内容:

1、Arduino Nano主板
2、Esp8266 Wifi 模块
3、DHT11温湿度模块
4、按钮、蜂鸣器

这里写图片描述

测试要点:
1、Esp8266连接
2、硬件与云平台互动

环境功能:
1、LED、温湿度等信息变化时,与云平台实时同步。
2、按钮可控制LED状态,用于测试互动情况。
3、蜂鸣器用于反映Esp8266 AT指令执行结果。
4、云平台远程控制本地设备。

代码如下:

#include <DHT.h>
#include <Esp.h>
    //定义wifi数据
    String Qwifi="MY";
    String Qpass="MY121212";
    String Qip="192.168.100.188";
    String Qport="8081";

    //定义后台数据
    String Qapikey="c2366e5a95a25695";

    //按钮、蜂鸣器
    int Qbutton=3;
    int QpinBeep=4;

    //定义设备针脚
    int Qled=13;//板载LED灯
    int QpinDht11=5;//DHT11温湿度 

    //定义设备did
    String Qdid_led="3578";
    String Qdid_tem="3589";
    String Qdid_hum="3590";

    //定义温湿度变量
    int Qcurtem,Qcurhum;
    DHT Qdht(QpinDht11, DHT11);

    //定义其他变量
    int Qlivetime=0; //心跳时间
    String Qcmd="";  //命令文本
    int Qbstatus=0; //按钮状态
    int Qlstatus=0; //灯状态

void setup() {

    //定义设备输入输出模式
    pinMode(Qled,OUTPUT);
    pinMode(QpinBeep,OUTPUT);
    pinMode(Qbutton,INPUT_PULLUP);

    //启动温湿度传感器
    Qdht.begin();

    //上电等待esp模块启动
    delay(5000);
    Serial.begin(115200);
    while (!Serial) delay(1);

    //设置Station模式
    Beep(QpinBeep,EspStation());
    delay(1000);

    //连接wifi
    Beep(QpinBeep,EspWifi(Qwifi,Qpass));
    delay(1000);

    //连接服务器
    Beep(QpinBeep,EspTcp(Qip,Qport));
    delay(1000);

    //发送绑定请求
    Beep(QpinBeep,SendBind(Qapikey));
    delay(1000);

    //发送设备当前状态
    Beep(QpinBeep,SendUp(Qapikey,Qdid_led,"0"));

}

void loop() {

    String Ldid="",Ldata="";

    // 先处理串口接收的远程控制指令
    Ldata=GetData(); 
    if (Ldata!=""){ // 如果收到指令,则进行处理。
          // 获取led灯控制指令
              Qcmd=GetDidData(Qdid_led,Ldata); //取led灯指令数据
              if(Qcmd=="1" || Qcmd=="0"){  
                  if(Qcmd=="1"){
                     digitalWrite(Qled,HIGH); //改变设备状态
                     Qlstatus=1;
                   }else{
                     digitalWrite(Qled,LOW); //改变设备状态
                     Qlstatus=0;
                   }
                   Ldid=Ldid+Qdid_led+",";
                   Ldata=Ldata+Qcmd+",";
               }
          // 获取led灯控制指令处理完毕

          // 获取其他设备控制指令
              //Qcmd=GetDidData(Qdid_other,Ldata); // 取其他设备指令数据
              //if(Qcmd!=""){
              //}
          // 获取其他设备控制指令处理完毕

          // 发送反馈数据
          if(Ldid!=""){
               Ldid=Ldid.substring(0,Ldid.length()-1);
               Ldata=Ldata.substring(0,Ldata.length()-1);
               SendOk(Qapikey,Qdid_led,Qcmd); //发送反馈指令
          }
    }

    Ldid="";
    Ldata="";

    // 获取温湿度数据
    int Lhum =(int)Qdht.readHumidity();//读湿度
    int Ltem =(int)Qdht.readTemperature();//读温度,默认为摄氏度
    if(Ltem!=Qcurtem){
        Qcurtem=Ltem;
        Ldid=Ldid+Qdid_tem+",";
        Ldata=Ldata+(String)Ltem+",";
      }
    if(Lhum!=Qcurhum){
        Qcurhum=Lhum;
        Ldid=Ldid+Qdid_hum+",";
        Ldata=Ldata+(String)Lhum+",";
      }

    // 检测按钮状态,获取LED灯数据
    if(digitalRead(Qbutton)==LOW){
        if( Qbstatus==0 ){
            Qbstatus=1;
            Qlstatus=1-Qlstatus;
            digitalWrite(Qled,Qlstatus==0?LOW:HIGH);
            Ldid=Ldid+Qdid_led+",";
            Ldata=Ldata+(String)Qlstatus+",";
          }
      } else{ Qbstatus=0;}

    // 如果设备数据发生变化,则更新服务器数据
    if(Ldid!=""){
          Ldid=Ldid.substring(0,Ldid.length()-1);
          Ldata=Ldata.substring(0,Ldata.length()-1);
          SendUp(Qapikey,Ldid,Ldata); // 更新设备数据
      }

    // 计算心跳时间
    Qlivetime+=1;
    if(Qlivetime>60){ //60秒心跳一次
        Qlivetime=0;
        Ldid=Qdid_led+","+Qdid_tem+","+Qdid_hum;
        SendLive(Qapikey,Ldid); // 发送心跳指令
      }

    // Loop循环间隔1秒
    delay(1000);

}

void Beep(int Cbeep,boolean Ctype){
    if (Ctype){
    digitalWrite(Cbeep,HIGH);delay(500);digitalWrite(Cbeep,LOW);
    }else{
    digitalWrite(Cbeep,HIGH);delay(100);digitalWrite(Cbeep,LOW);
    }
  }

其中,我封装了一个Esp.h,代码如下:

// 取串口数据
String GetData(){
      String Ldata="";
      while (Serial.available())
      {
        Ldata+=char(Serial.read());
        delay(2);
      }
      return Ldata;
}

// 取did的指令数据
String GetDidData(String Cdid,String Cdata){
    if( Cdata.indexOf("{")!=-1 && Cdata.indexOf("}")!=-1){
        String Ldata=Cdid+":";
        int Lstart = Cdata.indexOf(Ldata);
        if (Lstart<1){ return ""; }
        Lstart+=Ldata.length();
        int Lend=Cdata.indexOf(",",Lstart);
        if (Lend<Lstart){ Lend=Cdata.length()-1; }
        return Cdata.substring(Lstart,Lend);
    }    
    return "";
}

// 发送指令,等待时间自定义
boolean SendATCmd(String CcmdString,int CdelaySecond){
      String cmdString=CcmdString;
      cmdString.replace("'","\"");
      unsigned long Lstart,Lend,Ldelay;
      Ldelay = CdelaySecond * 1000;
      while (Serial.available()){Serial.read();delay(2);}
      Serial.println(cmdString);
      char LOK[] = "OK\r\n";
      char LERROR[] = "ERROR\r\n";
      char LFAIL[] = "FAIL\r\n";
      Lstart=millis();
      Lend=millis();
      while ((Lend-Lstart)<Ldelay)
      {
              if(Serial.find(LOK))return true;//成功:返回0
              if(Serial.find(LERROR))return false;//错误:返回1
              if(Serial.find(LFAIL))return false;//失败:返回2
              delay(2);
              Lend=millis();
      }
      return false;//其他:返回-1
}

// 发送指令,等待时间5秒
boolean SendATCmd(String CcmdString){
      return SendATCmd(CcmdString,5);
}

// 发送wifi数据
boolean SendWifiString(String CWifiString){
      unsigned long Lstart,Lend,Ldelay=5000;
      while (Serial.available()){Serial.read();delay(2);}
      String len=(String)(CWifiString.length());
      Serial.println("AT+CIPSEND="+len);
      Lstart=millis();
      Lend=millis();
      while ((Lend-Lstart)<Ldelay)
      {
              if(Serial.find('>')){
                    delay(1);
                    while (Serial.available()){Serial.read();delay(2);}
                    Serial.println(CWifiString);
                    char LOK[] = "OK\r\n";
                    char LERROR[] = "ERROR\r\n";
                    char LFAIL[] = "FAIL\r\n";
                    Lstart=millis();
                    Lend=millis();
                    while ((Lend-Lstart)<Ldelay)
                    {
                        if(Serial.find(LOK))return true;//成功:返回0
                        if(Serial.find(LERROR))return false;//错误:返回1
                        if(Serial.find(LFAIL))return false;//失败:返回2
                        delay(2);
                        Lend=millis();
                    }
                    return false;//其他:返回-1
              }
              delay(2);
              Lend=millis();
      }
      return false;//其他:返回-1
}

// 发送绑定指令boolean
boolean SendBind(String CapiKey){
  String Ldata="mode=bind&apikey="+CapiKey;
  return (SendWifiString(Ldata));
}

// 发送上传指令
boolean SendUp(String CapiKey,String Cdid,String Cdata){
  String Ldata="mode=up&apikey="+CapiKey+"&did="+Cdid+"&data="+Cdata;
  return (SendWifiString(Ldata));
}

// 发送心跳指令
boolean SendLive(String CapiKey,String Cdid){
  String Ldata="mode=live&apikey="+CapiKey+"&did="+Cdid;
  return (SendWifiString(Ldata));
}

// 发送反馈指令(不带数据)
boolean SendOk(String CapiKey,String Cdid){
  String Ldata="mode=ok&apikey="+CapiKey+"&did="+Cdid;
  return (SendWifiString(Ldata));
}

// 发送反馈指令(带数据)
boolean SendOk(String CapiKey,String Cdid,String Cdata){
  String Ldata="mode=ok&apikey="+CapiKey+"&did="+Cdid+"&data="+Cdata;
  return (SendWifiString(Ldata));
}

// 置Station+单链接模式
boolean EspStation(){
  String Ldata="AT+CWMODE=1";
  if (!SendATCmd(Ldata)) return false;
  Ldata="AT+CIPMUX=0";
  return (SendATCmd(Ldata));
}

// 复位重启
boolean EspRst(int CwiteTime){
      unsigned long Lstart,Lend,Ldelay;
      Ldelay = CwiteTime * 1000;
      while (Serial.available()){Serial.read();delay(2);}
      Serial.println("AT+RST");
      char Lready[] = "ready\r\n";
      Lstart=millis();
      Lend=millis();
      while ((Lend-Lstart)<Ldelay)
      {
              if(Serial.find(Lready))return true;//成功:返回0
              delay(2);
              Lend=millis();
      }
      return false;//其他:返回-1
}

//连接wifi
boolean EspWifi(String CwifiName,String CwifiPass){
  String Ldata="AT+CWJAP='"+CwifiName+"','"+CwifiPass+"'";
  return (SendATCmd(Ldata));
}

//连接tcp
boolean EspTcp(String Cip,String Cport){
  String Ldata="AT+CIPSTART='TCP','"+Cip+"',"+Cport;
  return (SendATCmd(Ldata));
}

keywords如下:

#######################################
    Methods and Functions  方法和函数
####################################### 

SendBind    KEYWORD2
SendUp  KEYWORD2
SendLive    KEYWORD2
SendOk  KEYWORD2

GetData KEYWORD2
GetDidData  KEYWORD2

EspStation  KEYWORD2
EspRst  KEYWORD2
EspWifi KEYWORD2
EspTcp  KEYWORD2

SendATCmd   KEYWORD2
SendWifiString  KEYWORD2
### 使用ESP8266 WiFi模块上传传感器数据到服务器 为了实现通过ESP8266 Wi-Fi模块将传感器的数据发送至远程服务器,通常会采用HTTP POST请求的方式。这涉及到配置ESP8266连接Wi-Fi网络并建立与目标服务器之间的TCP/IP通信链路。 #### 配置ESP8266连接WiFi网络 首先,在程序初始化阶段设置好要连接的SSID和密码: ```cpp #include <ESP8266WiFi.h> const char* ssid = "your_SSID"; // 替换成实际的Wi-Fi名称 const char* password = "your_PASSWORD";// 替换成实际的Wi-Fi密码 void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } Serial.println("Connected!"); } ``` 这段代码实现了基本的Wi-Fi连接功能[^1]。 #### 发送POST请求传输数据给服务器 当成功接入互联网之后就可以构建HTTP客户端对象来发起针对特定URL地址的POST操作了。这里假设有一个RESTful API端点用于接收来自设备上报的信息包体格式可以是JSON字符串形式表示一组键值对儿。 下面是一个完整的例子展示了怎样读取DHT温湿度感应器数值并通过上述方式提交出去: ```cpp #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> // HTTP库支持 #include <DHT.h> // DHT库支持 #define DHTPIN 2 // 定义DHT引脚位置 #define DHTTYPE DHT11 // 设置为DHT11型号 // 初始化变量 char serverName[] = "http://example.com/api/data"; String httpMethod = "POST"; DHT dht(DHTPIN, DHTTYPE); void setup(){ pinMode(LED_BUILTIN, OUTPUT); // LED指示灯控制 digitalWrite(LED_BUILTIN, LOW); // Serial.begin(9600); dht.begin(); // 连接WiFi部分同前... } void loop(){ float h = dht.readHumidity(); // 获取当前环境相对湿度百分比(%RH) float t = dht.readTemperature(); // 获取摄氏度温度(Celsius) if (isnan(h) || isnan(t)) { Serial.println("Failed to read from DHT sensor!"); return; } String postStr = "{\"temperature\":" + String(t) + ",\"humidity\":" + String(h) + "}"; if(WiFi.status()==WL_CONNECTED){ HTTPClient http; http.begin(serverName); // 指定API URL路径 http.addHeader("Content-Type", "application/json"); int httpResponseCode = http.POST(postStr); if(httpResponseCode>0){ String response = http.getString(); Serial.printf("[HTTP RESPONSE CODE]: %d\n", httpResponseCode); Serial.print(response); digitalWrite(LED_BUILTIN,HIGH); // 成功则点亮LED提示 delay(1000); digitalWrite(LED_BUILTIN,LOW); }else{ Serial.printf("[ERROR] Failed code: %d\n", httpResponseCode); } http.end(); // 关闭连接释放资源 } else { Serial.println("WiFi Disconnected"); } delay(30000); // 每隔半分钟重复一次测量过程 } ``` 此段代码片段不仅包含了前面提到过的Wi-Fi连接逻辑还加入了利用`ESP8266HTTPClient`类来进行HTTP协议交互的部分以及调用了第三方库处理具体传感元件接口的操作[^2]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卢光庆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值