Arduino开发之如何连接WIFI模块?

文章目录

  • 0.引言
  • 1.WIFI模块说明
  • 2.安装ESP8266开发板库
  • 3.设置ESP8266连接WIFI
  • 4.Arduino通过ESP8266收发消息
  • 5.功能演示
  • 0.引言

      在硬件开发过程中,会将许多传感器组合,产生许多数据,这些数据需要传输到上位机进行数据融合处理才能实现硬件系统的功能,或许这些数据不急着处理,可以将数据存储到SD卡中,隔一段时间后再导出统一整理,但有时需要无线通信,远控硬件作出行动。对于无线传输控制硬件,蓝牙和WIFI都可以实现,但蓝牙更多的应用于连接设备,在传输速度上比WIFI慢,若需信息传输,可以选择WIFI。本文采用ESP8266-12E的WFI模块,在【Arduino如何进行开发?】基础上,阐述Arduino如何连接WIFI模块。

    1.WIFI模块说明

      
      WIF模块情况
      ESP8266(CP2102),NodeMCU板载ESP-12E ( 4MB Flash) WIFI模组和USB转TTL串口(CP2102/ CH340)芯片,不用外接下载器,直接通过USB线与电脑相连,方便下载固件和调试。
      引脚说明:
      

    2.安装ESP8266开发板库

      (1)将ESP8266模块通过USB连接电脑,在工具→端口选择端口,若端口不可选中,需要安装usb转串口通用驱动.EXE
      (2)在文件→首选项→其他开发板管理器地址,网址添加:
      http://arduino.esp8266.com/stable/package_esp8266com_index.json
      
      (3)在工具→开发板→开发板管理器,添加ESP8266库;
      
      注:若因网络问题无法安装,下载ESP8266安装包,安装完成后重启Arduino,即可添加ESP8266库。
      (4)在工具→管理库,添加pubsubclient库和ArduinoJson库。
      

    3.设置ESP8266连接WIFI

      (1)设置热点名称、热点密码;
      热点名称和密码为方便测试是否连接网络,可使用手机热点或者无线路由器。
      若使用无线路由器,可在笔记本浏览器输入:tplogin.cn访问路由器管理网页。
      (2)获取Sub、Pub的代码;
      Sub、Pub的代码来自于易联智能物联网平台,获取步骤如下:
      
      (3)编写设置代码;
      ESP8266_SetWifi.ino

    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    #define BUILTIN_LED 2
    char P_NAME[] = "F305";           //设置热点名称
    char P_PSWD[] = "f305f305";       //设置热点密码
    char sub[] = "Sub/100326";    //设置设备Sub代码
    char pub[] = "Pub/100326";    //设置设备Pub代码
    const char *ssid = P_NAME;
    const char *password = P_PSWD;
    const char *mqtt_server = "easyiothings.com";
    String reStr;
    WiFiClient espClient;
    PubSubClient client(espClient);
    unsigned long lastMsg = 0;
    #define MSG_BUFFER_SIZE (50)
    char msg[MSG_BUFFER_SIZE];
    int value = 0;
    void setup_wifi()
    {
      delay(10);
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
      }
      randomSeed(micros());
    }
    void callback(char *topic, byte *payload, unsigned int length)
    {
      for (int i = 0; i < length; i++)
      {
        Serial.print((char)payload[i]);
      }
      Serial.println();
    }
    void reconnect()
    {
      while (!client.connected())
      {
        String clientId = "ESP8266Client";
        clientId += String(random(0xffff), HEX);
        if (client.connect(clientId.c_str()))
        {
          client.publish(pub, "{\"State\":\"OnLine\"}");
          client.subscribe(sub);
        }
        else
        {
          Serial.print(client.state());
          delay(5000);
        }
      }
    }
    void setup()
    {
      pinMode(BUILTIN_LED, OUTPUT);
      Serial.begin(9600);
      setup_wifi();
      client.setServer(mqtt_server, 1883);
      client.setCallback(callback);
      digitalWrite(BUILTIN_LED, HIGH);
    }
    void loop()
    {
      if (!client.connected())
      {
        reconnect();
      }
      client.loop();
      if (Serial.available() > 0)
      {
        reStr = Serial.readStringUntil('\n');
        //检测json数据是否完整
        int jsonBeginAt = reStr.indexOf("{");
        int jsonEndAt = reStr.lastIndexOf("}");
        if (jsonBeginAt != -1 && jsonEndAt != -1)
        {
          reStr = reStr.substring(jsonBeginAt, jsonEndAt + 1);
          int str_len = reStr.length() + 1;
          char char_array[str_len];
          reStr.toCharArray(char_array, str_len);
          client.publish(pub, char_array);
        }
      }
    }
    

      (4)ArduinoIDE中开发板选择NodeMCU 1.0(ESP-12E Module),上传代码,查看ESP8266连接网络情况。
      

    4.Arduino通过ESP8266收发消息

      (1)将WIFI模块去掉USB线,连接到Arduino上,为测试数据收发,将时钟模块也连接到Arduino上;
      WIFI模块引脚说明:

        “GND”:接Arduino的GND
        “3v3”:接Arduino的3v3
        “EN”:接Arduino的3v3
        “TX”:接Arduino的RXD
        “RX”:接Arduino的TXD
      时钟模块引脚说明:
        “GND”:接Arduino的GND
        “VCC”:接Arduino的5V
        “SDA”:接Arduino的A4
        “SCL”:接Arduino的A5

      (2)编写运行代码
      Communiate_ThroughESP8266.ino

    /*
    可实现功能:
      时钟模块的秒数上传到云平台,且云平台能发送指令被arduino接收。
    接线:
      将ESP8266的Rx引脚接在Arduino的Tx上,Tx引脚接在Rx上。但下载代码时需将Rx与Tx的接线移除,否则程序会报错;
    */
    #include <ArduinoJson.h>//导入JSON库,用来封装发送数据的格式
    #include <Wire.h>
    #include <DS3231.h>
    StaticJsonDocument<500> sendJson;          // 创建JSON对象,用来存放发送数据
    StaticJsonDocument<500> readJson;          // 创建JSON对象,用来存放接收到的数据
    unsigned long lastUpdateTime = 0;          //记录上次上传数据时间
    const unsigned long updateInterval = 10000; // 在这里设置数据发送至云平台的时间间隔,单位为毫秒
    byte year;
    byte month;
    byte date;
    byte dOW;
    byte hour;
    byte minute;
    byte second;
    DS3231 dsTime;
    bool century = false;
    bool h12Flag = false;
    bool pmFlag = false;
    
    //定义相关的变量
    long ID = 100326;// 定义设备ID号,替换成云平台生成的ID号
    String DS3231TIME="";      
    // Arduino的初始化函数,仅在通电时运行一次
    void setup()
    {
      Serial.begin(9600);//初始化串口,用于和esp8266进行通信,完成数据的接收与上传
      Wire.begin();
      delay(500);
    }
    // Arduino的loop函数,当setup函数执行完毕后进入该函数并一直循环运行
    void loop()
    {
      // 该函数段可完成数据定时上报的功能,并且不会阻塞loop函数的运行
      if (millis() - lastUpdateTime > updateInterval) 
      {
        sendJsonData();
        lastUpdateTime = millis();
      }
      // 当用户使用手机或者网站控制当前设备时ESP8266会通过串口向Arduino发送指令,该函数段可判断串口有没有接收到消息,并完成对用户消息的解析
      while (Serial.available() > 0) { // 判断串口缓冲区是否有消息
        String inputString = Serial.readStringUntil('\n');  //从串口缓冲区读入数据,并赋值给inputString变量(String变量为Arduino独有变量类型,可以简化字符串操作)
        //检测json数据是否完整,若通过则进行下一步的处理
        /*
          云平台向硬件下发JSON的格式为 {TIME:1} 类型的字符串,通常叫键值对,C语言中叫做哈希表。经测试,在易联智能发送指令时,【接口名称】无法设置,指令只能从【控制指令】窗口发出,发出的指令为 {TIME:1} ,正常情况【接口名称】处选择TIME,然后再【控制指令】输入1,发送即可
        */
        int jsonBeginAt = inputString.indexOf("{",1);
        int jsonEndAt = inputString.lastIndexOf("}",inputString.lastIndexOf("}")-1);
        if (jsonBeginAt != -1 && jsonEndAt != -1)
        {
          inputString = inputString.substring(jsonBeginAt, jsonEndAt + 1);    //净化json数据
          deserializeJson(readJson, inputString);                             //通过ArduinoJSON库将JSON字符串转换为方便操作的对象
          // 判断接收的指令
          if (readJson.containsKey("TIME"))   //判断云平台下发的消息是否包含TIME标识符,如果是则进行下一步处理
          {
            delay(100);
            DS3231TIME = (int)readJson["TIME"];
            Serial.print(DS3231TIME);
            Serial.println();
          }
          delay(500);
          sendJsonData(); //向云平台发送最新的信息
        }
      }
      DS3231TIME=dsTime.getSecond();
    }
    //上传数值
    void sendJsonData()
    {
      // 将数据添加到JSON对象中,左边为在云平台中定义的标识符,右边为变量
      sendJson["ID"] = ID;
      sendJson["TIME"] = DS3231TIME;
      //将对象转换成字符串,并向ese8266发送消息
      serializeJson(sendJson, Serial);  
      Serial.print("\n");
    }
    

      (3)上传代码
      上传代码时,RX、TX先不要与Arduino上的TXD、RXD连接,不然会报错。
      (4)在云平台查看消息
      

    5.功能演示

      (1)Arduino发送消息
      
      (2)Arduino接收消息
      在云平台的【控制指令】处输入:{TIME:123},点击发送。
      

    参考资料:
    [1] cacrle. Arduino如何进行开发?; 2023-03-15 [accessed 2023-03-28].
    [2] Cacra. Arduino 与 ESP8266 WIFI模块的连接; 2018-05-27 [accessed 2023-03-28].
    [3] Schdust. Arduino连接ESP8266实现联网功能; 2023-02-12 [accessed 2023-03-28].
    [4] 凉西西工作室. 解决Arduino开发板管理器下载esp8266开发包失败和速度慢的方法; 2021-03-21 [accessed 2023-03-28].
    [5] 闪烁shimmer. A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header; 2022-01-19 [accessed 2023-03-28].
    [6] 奈何col. Arduino IDE安装esp8266 SDK; 2018-3-28 [accessed 2023-03-28].

    物联沃分享整理
    物联沃-IOTWORD物联网 » Arduino开发之如何连接WIFI模块?

    发表评论