DIY智能家居:用ESP8266实现温湿度联动风扇自动控制(接入EMQX平台)

本项目基于ESP8266实现智能风扇控制系统,集成DHT11温湿度传感器,支持自动与手动双模式。通过MQTT协议接入EMQX云平台,用户可远程设置开关或切换为自动模式(温度≥28°C开启,≤26°C关闭)。系统实时上报环境数据与设备状态,具备低功耗、响应快、稳定性高特点,适用于智能家居场景。
准备工作:
材料:
材料名称
数量
备注
esp8266
1
用于和MQTT通信
马达
1
模拟风扇降温
继电器
1
控制风扇开关
DHT11
1
温度检测
杜邦线
若干
2
安装串口驱动

首先需要安装CK341SER驱动程序,以支持后续的硬件连接与调试。
3
设置ESP8266下载地址




12
在Arduino IDE的开发板管理器中,添加ESP8266的下载源地址:http://arduino.esp8266.com/stable/package_esp8266com_index.json。
4
下载必要依赖





123
在Arduino IDE中的“开发板管理器”来查找并下载ESP8266核心库及PubSubClient库并进行下载,之后切换到"库管理"中下载DHT sernor library依赖,点击安装之后会有弹窗,选中“全部安装”即可。
5
接线图




12
- 电源与共地
- 所有模块的 GND(继电器、DHT11、马达驱动部分)都连接到 ESP8266 的 GND,形成共地。
- DHT11 连接
- DHT11 的 VCC 接 ESP8266 的 3.3V。
- DHT11 的 GND 接 GND。
- DHT11 的 数据引脚(DATA) 接 ESP8266 的某个 GPIO(常见为 D2 )。
- 继电器连接
- 继电器模块的 VCC 接 3.3V 或 5V(视模块而定,多数可兼容 3.3V 控制)。
- 继电器的 GND 接 GND。
- 继电器的 IN(控制信号) 接 ESP8266 的一个 GPIO(例如 D1 )。
- 继电器的常闭(NC)接ESP8266的GND。
- 马达(模拟风扇)连接
- 马达一端接 外部电源正极(如 3V电源)。
- 马达负极接继电器的COM(公共端)。
Untitled Sketch_bb.pdf
603.66KB
6
代码

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// === 配置区 ===
// 修改为自己的WiFi名称
#define WIFI_SSID "vivoX200"
// 修改密码
#define WIFI_PASSWORD "12345678"
#define MQTT_SERVER "broker.emqx.io"
#define MQTT_PORT 1883
#define MQTT_USER ""
#define MQTT_PASSWORD ""
#define DEVICE_PREFIX "home/yj"
// 温度
#define TOPIC_TEMP DEVICE_PREFIX "/sensor/temperature"
// 湿度
#define TOPIC_HUM DEVICE_PREFIX "/sensor/humidity"
// 设置开关
#define TOPIC_FAN_SET DEVICE_PREFIX "/fan/set"
// 当前风扇开关状态
#define TOPIC_FAN_STATE DEVICE_PREFIX "/fan/state"
// 手动/自动
#define TOPIC_FAN_MODE DEVICE_PREFIX "/fan/mode" // 新增:模式状态
// 引脚定义
#define DHT_PIN 4 // D2 (GPIO4)
#define RELAY_PIN 5 // D1 (GPIO5)
#define DHTTYPE DHT11
const long SENSOR_INTERVAL = 5000; // 5秒读一次传感器
// 自动控制阈值(带迟滞)
const float TEMP_THRESHOLD_ON = 28.0; // ≥28°C 开风扇
const float TEMP_THRESHOLD_OFF = 26.0; // ≤26°C 关风扇
// === 全局变量 ===
DHT dht(DHT_PIN, DHTTYPE);
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastSensorRead = 0;
bool fanState = false;
bool fanStateChanged = false;
bool autoMode = true; // 默认启动自动模式
void mqttCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("MQTT Message received on [");
Serial.print(topic);
Serial.print("]: ");
String msg = "";
for (int i = 0; i < length; i++) {
msg += (char)payload[i];
}
Serial.println(msg);
if (String(topic) == TOPIC_FAN_SET) {
if (msg == "ON") {
setFanState(true);
autoMode = false;
client.publish(TOPIC_FAN_MODE, "MANUAL", true);
Serial.println("🔄 Switched to MANUAL mode (ON)");
} else if (msg == "OFF") {
setFanState(false);
autoMode = false;
client.publish(TOPIC_FAN_MODE, "MANUAL", true);
Serial.println("🔄 Switched to MANUAL mode (OFF)");
} else if (msg == "AUTO") {
autoMode = true;
client.publish(TOPIC_FAN_MODE, "AUTO", true);
Serial.println("🔄 Switched to AUTO mode");
// 触发立即评估温度
fanStateChanged = true; // 实际会在 loop 中通过温度判断
} else {
Serial.println("⚠️ Unknown command! Use 'ON', 'OFF' or 'AUTO'");
}
}
}
void setFanState(bool on) {
Serial.print("🔧 Setting fan to ");
Serial.println(on ? "ON" : "OFF");
digitalWrite(RELAY_PIN, on ? HIGH : LOW); // 继电器:HIGH=开(根据你的模块调整)
fanState = on;
fanStateChanged = true;
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to WiFi: ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("✅ WiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println();
Serial.println("❌ Failed to connect to WiFi!");
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientId = "ESP8266_DHT_Fan_";
clientId += String(ESP.getChipId(), HEX);
if (clientId.length() > 23) clientId = clientId.substring(0, 23);
if (client.connect(clientId.c_str(), MQTT_USER, MQTT_PASSWORD)) {
Serial.println(" ✅ Connected!");
client.subscribe(TOPIC_FAN_SET);
Serial.print("Subscribed to: ");
Serial.println(TOPIC_FAN_SET);
} else {
Serial.print(" ❌ Failed, rc=");
Serial.print(client.state());
Serial.println(" - retrying in 5 seconds");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println(">>> SMART FAN CONTROLLER v2.1 (Auto + Manual) <<<");
Serial.println("===================================");
Serial.println("🚀 Starting Smart Fan Controller");
Serial.println("===================================");
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW); // 默认关闭风扇
Serial.println("🔌 Relay initialized to OFF");
dht.begin();
Serial.println("🌡 DHT11 sensor initialized");
setup_wifi();
client.setServer(MQTT_SERVER, MQTT_PORT);
client.setCallback(mqttCallback);
if (!client.connected()) {
reconnect();
}
// 初始上报模式和状态
client.publish(TOPIC_FAN_MODE, "AUTO", true);
client.publish(TOPIC_FAN_STATE, "OFF", true);
}
void loop() {
if (!client.connected()) {
Serial.println("⚠️ MQTT disconnected, reconnecting...");
reconnect();
}
client.loop();
// 上报风扇状态变化(仅当变化时)
if (fanStateChanged) {
client.publish(TOPIC_FAN_STATE, fanState ? "ON" : "OFF", true);
Serial.print("📡 Published fan state: ");
Serial.println(fanState ? "ON" : "OFF");
fanStateChanged = false;
}
// 定期读取传感器并执行自动控制
if (millis() - lastSensorRead > SENSOR_INTERVAL) {
lastSensorRead = millis();
float h = dht.readHumidity();
float t = dht.readTemperature();
if (!isnan(t) && !isnan(h)) {
client.publish(TOPIC_TEMP, String(t).c_str());
client.publish(TOPIC_HUM, String(h).c_str());
Serial.print("📊 Temp: ");
Serial.print(t);
Serial.print("°C, Humidity: ");
Serial.print(h);
Serial.println("%");
// ========== 自动控制逻辑 ==========
if (autoMode) {
bool targetState = fanState; // 默认保持当前状态
if (t >= TEMP_THRESHOLD_ON) {
targetState = true; // 太热,开风扇
} else if (t <= TEMP_THRESHOLD_OFF) {
targetState = false; // 足够凉,关风扇
}
// 在 (26°C, 28°C) 区间保持原状态(防抖)
if (targetState != fanState) {
setFanState(targetState);
}
}
} else {
Serial.println("❌ Failed to read from DHT11!");
}
}
}
7
MQTTX连接




12
打开MQTTX客户端新建连接,输入名称以及服务器ip地址,完成之后点击右上角的连接。
8
添加订阅





123
点击添加订阅按钮,订阅主题。
9
运行效果
0
0
0
qq空间
微博
复制链接
分享 更多相关项目
猜你喜欢
评论/提问(已发布 0 条)
0