【实战】ESP32s3 + 阿里云IOT + MQTT协议,实现温湿度上报与远程控制简易Demo
目录
前言
在物联网开发中,将设备数据上传至云端并通过 App 远程控制,是极为常见的应用场景。本文以 ESP32-S3 为核心硬件,基于 VS Code + PlatformIO 开发环境(Arduino 框架),从零开始手把手带你连接阿里云物联网平台,实现温湿度数据上报和灯光远程开关控制。全文贯穿实战,附完整代码与避坑指南,助你快速上手。

一、阿里云平台配置
1.1 创建产品
首先,登录阿里云物联网平台,申请一个免费的公共实例,进入实例管理页面。

创建产品

填写产品名称,选择自定义品类

创建完成后,在产品列表中即可看到刚刚建立的产品。

1.2 添加设备
在产品页,点击“管理设备”。

添加设备,添加的设备就是我们ESP32要连接的设备。

起个设备名

点击确认,可以看到设备已创建。

1.3 定义物模型
物模型定义了设备与云端的交互数据规范。这里我们添加温度、湿度、灯的属性。
在产品页,进入“查看” → “功能定义” → “前往编辑草稿” 。


添加自定义功能

添加温度属性。
-
温度(Temperature):数据类型
float,读写类型“读写”。

添加湿度属性。
-
湿度(Humidity):数据类型
int,读写类型“读写”。

添加灯属性。
-
灯光开关(light):数据类型
bool(取值范围 0/1),读写类型“读写”。

注意:属性标识符严格区分大小写,后续代码中需完全一致。
二、ESP32代码实现
2.1 核心代码
本项目使用 VS Code + PlatformIO 开发,基于 Arduino 框架编写。
main.cpp
#include <Arduino.h>
#include "mywifi.h"
#include "mqtt.h"
extern PubSubClient client;
float temp = 24.4;
int humi = 60;
uint8_t light_state = 0;
void setup()
{
pinMode(led_pin, OUTPUT);
Serial.begin(9600);
mqtt_paramsinit();
wifi_connect();
mqtt_init();
mqtt_connect();
}
void loop()
{
// 保持 MQTT 连接
if (!client.connected())
{
mqtt_connect();
}
// 处理 MQTT 消息
client.loop();
// 定期上报(每 5 秒一次)
static unsigned long lastReport = 0;
if (millis() - lastReport > 5000)
{
mqtt_send_telemetry();
lastReport = millis();
}
delay(10);
}
mywifi.cpp
#include "mywifi.h"
const char* ssid = "你的WiFi名";
const char* password = "你的WiFi密码";
void wifi_connect()
{
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED);
Serial.println("WiFi Connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
mywifi.h
#ifndef __MYWIFI_H__
#define __MYWIFI_H__
#include <Arduino.h>
#include <WiFi.h>
void wifi_connect();
#endif
mqtt.cpp
#include "mqtt.h"
WiFiClient espClient; // 创建WiFi客户端对象
PubSubClient client(espClient); // 创建MQTT客户端对象
extern float temp;
extern int humi;
extern uint8_t light_state;
// 阿里云配置
// 阿里云三元组
const char* PRODUCT_KEY = "你的ProductKey"; // 你的ProductKey
const char* DEVICE_NAME = "你的DeviceName"; // 你的DeviceName
const char* DEVICE_SECRET = "你的DeviceSecret"; // 你的DeviceSecret
// 阿里云 MQTT 服务器地址
const char* MQTT_SERVER = "你的ProductKey.iot-as-mqtt.cn-shanghai.aliyuncs.com"; // 你的ProductKey.iot-as-mqtt.cn-shanghai.aliyuncs.com
const int MQTT_PORT = 1883;
// Topic
String pubTopic; // 上报,属性上报
String subTopic; // 订阅,属性设置
// MQTT 连接参数(由三元组计算得出)
String mqttClientId;
String mqttUsername;
String mqttPassword;
// HMAC-SHA1 工具函数
String mqtt_hmacSha1(const String& data, const String& key)
{
byte hmacResult[20];
mbedtls_md_context_t ctx;
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
mbedtls_md_init(&ctx);
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1);
mbedtls_md_hmac_starts(&ctx, (const unsigned char*)key.c_str(), key.length());
mbedtls_md_hmac_update(&ctx, (const unsigned char*)data.c_str(), data.length());
mbedtls_md_hmac_finish(&ctx, hmacResult);
mbedtls_md_free(&ctx);
String hex = "";
for (int i = 0; i < 20; i++)
{
char buf[3];
sprintf(buf, "%02x", hmacResult[i]);
hex += buf;
}
return hex;
}
// 设置初始化参数
void mqtt_paramsinit()
{
mqttClientId = String(DEVICE_NAME) + "|securemode=3,signmethod=hmacsha1|";
mqttUsername = String(DEVICE_NAME) + "&" + String(PRODUCT_KEY);
String signData = "clientId" + String(DEVICE_NAME) +
"deviceName" + String(DEVICE_NAME) +
"productKey" + String(PRODUCT_KEY);
mqttPassword = mqtt_hmacSha1(signData, String(DEVICE_SECRET));
pubTopic = "/sys/" + String(PRODUCT_KEY) + "/" + String(DEVICE_NAME) + "/thing/event/property/post";
subTopic = "/sys/" + String(PRODUCT_KEY) + "/" + String(DEVICE_NAME) + "/thing/service/property/set";
}
void mqtt_init()
{
// 设置MQTT服务器和回调函数
client.setServer(MQTT_SERVER, MQTT_PORT);
client.setCallback(mqtt_callback);
client.setKeepAlive(60);
}
// MQTT连接函数,负责与阿里云IoT平台建立连接,并在连接成功后订阅指定主题
void mqtt_connect()
{
while (!client.connected())
{
Serial.println("尝试连接阿里云MQTT...");
// 使用客户端ID、用户名和密码尝试连接MQTT服务器
if (client.connect(mqttClientId.c_str(), mqttUsername.c_str(), mqttPassword.c_str()))
{
Serial.println("已连接到阿里云MQTT服务器");
// 订阅主题
client.subscribe(subTopic.c_str());
Serial.print("已订阅: ");
Serial.println(subTopic);
}
else
{
Serial.print("连接失败, 状态码=");
Serial.print(client.state());
Serial.println(",5秒后重试");
delay(5000);
}
}
}
// MQTT消息回调函数
void mqtt_callback(char* topic, byte* payload, unsigned int length)
{
String message = "";
for (int i = 0; i < length; i++)
{
message += (char)payload[i];
}
Serial.print("回调message: ");
Serial.println(message);
JsonDocument doc;
DeserializationError error = deserializeJson(doc, message);
if (error)
{
Serial.print("JSON解析失败: ");
Serial.println(error.f_str());
return;
}
// 解析 params 中的 light
JsonObject params = doc["params"].as<JsonObject>();
if (!params["light"].isNull())
{
bool light_status = params["light"];
if (light_status)
{
digitalWrite(led_pin, HIGH);
Serial.println("light_on");
}
else
{
digitalWrite(led_pin, LOW);
Serial.println("light_off");
}
}
}
// 上报设备遥测数据(温度和湿度)到阿里云IoT平台
void mqtt_send_telemetry()
{
JsonDocument doc;
doc["method"] = "thing.event.property.post";
JsonObject params = doc["params"].to<JsonObject>();
params["Temperature"] = temp;
params["Humidity"] = humi;
String jsonStr;
serializeJson(doc, jsonStr);
if (client.publish(pubTopic.c_str(), jsonStr.c_str()))
{
Serial.print("上报数据: ");
Serial.println(jsonStr);
}
else
{
Serial.println("上报失败");
}
}
mqtt.h
#ifndef MQTT_H__
#define MQTT_H__
#include <Arduino.h>
#include <PubSubClient.h>
#include "WiFi.h"
#include <ArduinoJson.h>
#include <mbedtls/md.h>
#define led_pin 2
String mqtt_hmacSha1(const String& data, const String& key);
void mqtt_paramsinit();
void mqtt_init();
void mqtt_connect();
void mqtt_callback(char* topic, byte* payload, unsigned int length);
void mqtt_send_telemetry();
void mqtt_send_attributes(String attribute);
#endif
2.2 代码中需修改部分
在 mywifi.cpp 中,将 ssid 和 password 替换为你的实际 WiFi 名称和密码。

在 mqtt.cpp 中,将 PRODUCT_KEY , DEVICE_NAME , DEVICE_SECRET 替换为你的ProductKey,DeviceName,DeviceSecret。

ProductKey,DeviceName,DeviceSecret可在阿里云控制台的“设备”页中查看。



三、测试结果
烧录程序后,ESP32 会自动连接 WiFi 和阿里云 MQTT 服务器,并开始周期性上报温湿度数据。在控制台的“设备 → 物模型数据 → 运行状态”中,可以看到实时更新的温度、湿度数值。

在“监控运维 → 在线调试”中选择该设备,进入“属性调试”页,对 light 属性进行设置(输入 1 或 0),点击“设置”下发指令。

看看结果
结语
本文通过一个完整的Demo,展示了ESP32如何快速接入阿里云物联网平台,实现温湿度数据上报和远程灯光控制。核心步骤包括:
-
阿里云端产品和物模型配置
-
ESP32端使用MQTT+HMAC-SHA1认证连接
-
上报数据遵循Alink标准格式
-
接收并解析云端下发的属性设置指令
整个过程无需编写复杂的服务器代码,完全依赖阿里云托管服务,非常适合个人开发者和小型项目快速落地。
由于水平有限,文中难免存在疏漏或不当之处,欢迎大家批评指正。如果你在尝试的过程中遇到问题,欢迎留言交流、共同探讨。
程序源码
更多推荐


所有评论(0)