文章目录

    • 前言
    • 一、物联网平台配置
      • 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,点击主界面右上角的加号,再点击右上角的扫描,扫刚刚生成的二维码就能添加了,如果添加失败,就检查一下在创建产品时是否选择网关+蜂窝。​​​​​​​

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

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐