温湿度监测与控制系统设计:基于ESP32与阿里云物联网的实现

文章目录

  • 前言
  • 一、物联网平台配置
  • 1.1功能定义
  • 1.2人机互动设置
  • 1.3创建测试设备
  • 二、环境配置
  • 三、代码实现
  • 3.1参数查询
  • 3.2物联网连接、温湿度数据读取并发送与消息接收
  • 四、APP连接
  • 前言

            这篇文章主要介绍了如何在Arduino环境下,使用ESP32接入阿里云物联网平台(http://www.aliyun.com),实现温湿度数据的实时更新和手机APP的远程控制。以下是我在开发过程中总结的具体步骤。主要参考这篇文章:链接:基于Arduino环境下ESP32接入阿里云

               注:这里默认你们对MQTT协议和阿里云物联网平台有一定的了解,不了解的可以观看这个视频合集里面的前五个视频。https://www.bilibili.com/video/BV1oJ411176Q?spm_id_from=333.788.videopod.episodes&vd_source=44f96ba7e07ae350233601fdcdd9bcce

    一、物联网平台配置

            本章节主要讲述阿里云物联网平台的相关操作,具体流程及关系图如下图所示:

           1.1功能定义

             首先登录阿里云平台,没有账号的注册一个账号并实名认证;在产品目录下找到物联网,再找到生活物联网平台(飞燕平台)。

           然后点击管理控制台→项目→创建新项目→前往开发→创建新产品,产品名称自定义,所属品类可以选择环境电器(温湿度传感器),节点类型选择网关,通讯方式选择蜂窝,芯片模组选择其他,其余设置默认。          

             创建完之后点击前往开发,在功能定义那一块可以选择用系统自带的,也可以选择自定义(个人建议使用自定义),使用自定义之前记得把系统自带的删除(避免标识符冲突,这个标识符在数据传输的过程中很重要,在后文会提及);在自定义栏目的那里点击“添加自定义功能”,根据自己实际需求填写,可参考下图,功能名称可以自定义,不用选择系统提示的,标识符也是自己定义,但要确保在同一产品下不能重复。

            如果要创建诸如空调、加湿器等只有开、关两种状态的功能,建议数据类型选择bool。

           1.2人机互动设置

            功能定义完成之后,进入人机互动设置,选择云智能APP,点击保存。

            产品展示界面的品牌随便选一个就行,产品型号自己起名字。

            这里设备面板是指手机app的显示面板,可以选择模板,也可以点击创建模板,空白模板自己编辑。

           在编辑过程中,诸如空调等可以控制的模块要选择“功能”栏下面的,只需要显示信息的模块在“信息”栏下面选择。例如下面的界面,如果在“功能”栏下面的温度拖到面板上,到时候在手机APP就会出现你可以自己手动调节显示温度的情况,所以一定要注意,编辑完之后保存,退出之后再次点击选择模板,选择自己编辑的模板 。

            最后一步产品说明,随便上传一个PDF文档就可以。

       1.3创建测试设备

            人机交互设置完之后,点击设备调试,创建测试设备​​​​​​​,自定义测试设备名之后便能得到平台颁布的设备参数信息​​​​​​​。

    二、环境配置

            首先在platformIO创建一个新项目,并安装一下库Adafruit Unified Sensor库、DHT sensor library库、PubSubClient库和ArduinoJson库,ArduinoJson建议使用6.21.4版本。除此之外还需修改PubSubClient.h文件参数,将参数修改至如图所示,可以通过在mian.cpp文件下引入PubSubClient.h,右击“转到定义”找到文件。

    一定要修改!

    一定要修改!

    一定要修改!

    不然会连接失败。

     三、代码实现

            3.1参数查询

            代码部分包含物联网连接与温湿度读取两块,在开始之前,需要知道设备三元组信息MQTT连接参数和发布与订阅消息的topic;相关概念这里就不在赘述,接下来讲一下如何获取这些参数;首先打开阿里云的官网,在产品目录下找到物联网平台。​​​​​​​

           点击管理控制台,公共实例,设备管理,在设备目录下找到刚刚新增的设备。 

            上面的箭头指向的就是三元组信息,下面的箭头指向的就是MQTT连接参数。​​​​​​​

            订阅和发布消息的topic可以在产品→点击产品→Topic类列表→物模型通信Topic里查看,这里我直接给出代码。

    发布消息的topic,Produckey和deviceName改成自己设备的Produckey和deviceName。

    sys/ProductKey/${deviceName}/thing/event/property/post

    订阅消息的topic,同上。

    /sys/ProductKey/${deviceName}/thing/service/property/set

            3.2物联网连接、温湿度数据读取、发送与消息接收

             根据实际修改以下所有“*”部分的代码,代码中空调等设备可以根据自己的情况进行修改。

    //引入头文件
    #include <Arduino.h>
    #include <WiFi.h>
    #include <ArduinoJson.h>
    #include <PubSubClient.h>
    #include <DHT.h>
    #include <Adafruit_Sensor.h>
    
    //设备三元组信息
    #define Product_Key   "****************"
    #define Device_Name   "****************"
    #define DeviceS_ecret "****************"
    
    //MQTT连接参数
    #define MQTT_SERVER       Product_Key ".iot-as-mqtt." Region_ID ".aliyuncs.com"
    #define MQTT_PORT         1883 
    #define MQTT_USERNAME     "************************"
    #define CLIENT_ID         "************************"
    #define MQTT_PASSWORD     "************************"
    
    //发布和订阅消息用的topic
    #define PubTopic "/sys/***********/*****/thing/event/property/post"
    #define SubTopic "/sys/***********/*****/thing/service/property/set"
    
    //温度监测
    #define DHTPIN **      // DHT11 数据引脚连接的 GPIO 
    #define DHTTYPE DHT11 // 定义传感器型号,我这的是DHT11,需改为自己的传感器型号
    
    //wifi信息
    const char *ssid = "*****";               //wifi名称
    const char *password = "*****";           //wifi密码
    
    //设备控制引脚
    #define air_pin *     //空调GPIO引脚
    #define humier_pin *  //加湿器GPIO引脚
    #define dehumi_pin *  //除湿器GPIO引脚
    
    WiFiClient espClient;
    PubSubClient client(espClient);
    DHT dht(DHTPIN, DHTTYPE);
    

            以下的是发布消息的函数,这段代码中params[]里面的temp、humi就是前文提到的标识符,这里根据自己设置的标识符进行修改。

    //发布消息
    void pubMsg() {
      // 创建一个足够大的StaticJsonDocument对象来存储预期的JSON数据
      StaticJsonDocument<512> doc;
    
      // 设置JSON数据
      JsonObject params = doc.createNestedObject("params");
      params["temp"] = dht.readTemperature();;  // 温度
      params["humi"] = dht.readHumidity();  // 湿度
      params["air"] = digitalRead(air_pin);      //空调状态
      params["dehumi"] = digitalRead(dehumi_pin);   //除湿器状态
      params["humier"] = digitalRead(humier_pin);   //加湿器状态
      doc["method"] = "thing.event.property.post";
    
      // 序列化JSON数据为字符串
      char jsonOutput[512];
      serializeJson(doc, jsonOutput);
    
      // 使用修改后的pubMsg函数发送JSON字符串
      if (client.publish(PubTopic, jsonOutput)) {
        Serial.println("Publish success");
        // 连接成功后订阅主题
        client.subscribe(SubTopic);
      } else {
        Serial.println("Publish fail");
      }
    }

           以下是接收消息的函数, 跟上文提及的一样,修改自己的标识符。

    //接收消息
    void processJsonMessage(char* message) {
      StaticJsonDocument<512> doc; // 调整大小以适应您的需要
      DeserializationError error = deserializeJson(doc, message);
      bool airState = digitalRead(air_pin);  // 空调的当前状态
      bool humierState = digitalRead(humier_pin);  // 加湿器的当前状态
      bool dehumiState = digitalRead(dehumi_pin);  // 除湿器的当前状态
    
      if (error) {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.f_str());
        return;
      }
    
      // 从JSON中提取信息
      const char* method = doc["method"];   // "thing.service.property.set"
      JsonObject params = doc["params"];
      float temp = params["temp"];  // 温度
      float humi = params["humi"];  // 湿度
      bool air = params.containsKey("air") ? params["air"] : airState;    // 空调状态
      bool humier = params.containsKey("humier") ? params["humier"] : humierState;// 加湿器状态
      bool dehumi = params.containsKey("dehumi") ? params["dehumi"] : dehumiState;// 除湿器状态
    
    
      Serial.print("Method:");
      Serial.println(method);
      Serial.print("temp:");
      Serial.println(temp);
      Serial.print("humi:");
      Serial.println(humi);
      Serial.print("air:");
      Serial.println(air);
      Serial.print("humier:");
      Serial.println(humier);
      Serial.print("dehumi:");
      Serial.println(dehumi);
    
      // 根据接收到的设备控制信息更新设备状态
      if (air != airState) {
        airState = air;
        digitalWrite(air_pin, air);
      }
    
      if (humier != humierState) {
        humierState = humier;
        digitalWrite(humier_pin, humier);
      }
    
      if (dehumi != dehumiState) {
        dehumiState = dehumi;
        digitalWrite(dehumi_pin, dehumi);
      }
    }

            这是个回调函数,Esp32接收到信息就会调用这个函数来处理消息。

    //回调函数
    void callback(char* topic, byte* payload, unsigned int length) {
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");
    
      // 将payload转换为字符串
      char message[length + 1];
      memcpy(message, payload, length);
      message[length] = '\0';
    
      // 打印原始消息
      Serial.println(message);
    
      // 调用processJsonMessage函数处理消息
      processJsonMessage(message);
    }
    

            下面的是wifi初始化和MQTT服务器连接函数。

    //wifi初始化
    void wifiInit()
    {
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(1000);
        Serial.println("WiFi not Connect");
      }
     
      Serial.println("Connected to AP");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
     
      Serial.print("espClient [");
     
      client.setServer(MQTT_SERVER, MQTT_PORT);   /* 连接WiFi之后,连接MQTT服务器 */
      client.setCallback(callback);
    }
    
    //连接服务器
    void mqttCheckConnect()
    {
      while (!client.connected())
      {
        Serial.println("Connecting to MQTT Server ...");
        if (client.connect(CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD))
        {
     
          Serial.println("MQTT Connected!");
     
        }
        else
        {
          Serial.print("MQTT Connect err:");
          Serial.println(client.state());
          delay(5000);
        }
      }
    }

            实现每两秒发送一次数据,可以通过修改UPDATE_INTERVAL的数值来修改发送数据的间隔。

    void setup() {
      Serial.begin(115200);         //开启串口
      Serial.println("Demo Start");
      dht.begin();                  //初始化传感器
      pinMode(air_pin,OUTPUT);      //配置空调引脚
      pinMode(humier_pin,OUTPUT);   //配置加湿器引脚
      pinMode(dehumi_pin,OUTPUT);   //配置除湿器引脚
      wifiInit();                   //连接wifi
      mqttCheckConnect();           //连接MQTT服务器
      pubMsg();                     //发布初始化消息
    }
    
    void loop() {
      client.loop(); //保持客户端的连接
      // 定时发布消息(每2秒)
      unsigned long UPDATE_INTERVAL = 2000
      unsigned long lastUpdateTime = 0;  
      unsigned long currentMillis = millis();
      if (currentMillis - lastUpdateTime >= UPDATE_INTERVAL) 
      {
        lastUpdateTime = currentMillis;
        pubMsg(); 
      }
    }

            在物联网平台点击日志服务可以看到,数据已经发送成功,再点击设备的物模型就可以看到数据了,至此代码部分讲解完成。​​​​​​​​​​​​​​

    四、APP连接

            首先在手机下载名为“云智能”的APP,打生活物联网平台,找到自己的项目,打开人机互动界面,点击下载配网二维码,输入自己的设备名称就可以生成二维码了。        ​​​​​​​

            在手机端打开APP,点击主界面右上角的加号,再点击右上角的扫描,扫刚刚生成的二维码就能添加了,如果添加失败,就检查一下在创建产品时是否选择网关+蜂窝。​​​​​​​

            点击“完成”之后就能进入控制面板界面了,这里的控制面板就是在设置人机交互时自己设计的面板。​​​​​​​

    作者:Σ踏支浪の书➹

    物联沃分享整理
    物联沃-IOTWORD物联网 » 温湿度监测与控制系统设计:基于ESP32与阿里云物联网的实现

    发表回复