该方案亮点:
- [X] 使用网页操作方式,访问其IP地址后实时显示温度与“自动化状态”
- [X] 可通过网页控制其开关水状态(点击后会自动退出自动化模式,请注意用水量控制),也可控制其自动化模式开关状态。
- [X] 自动化:超过30°C自动开水,低于后停水(自动化选项开启时有效)
起因:家中空调制冷效果太差,面对2024年湖北的夏天根本无效,之后我通过控制变量法得出是外机后背板的散热出了问题(被柜板挡住),最终找到解决方案:
用水泵向上喷水从而实现降温
于是我开始了探索:
- TB上购买水泵,继电器等模块,实现控制
- 直接通电,能够运行,OK!

接着,又有新问题产生了:
一直喷水太浪费了,且需要手动开关
于是我便想到了去年做火箭姿态矫正的MPU6050六轴加速度传感器,其参数中有一个NTC温度模块
其本身并非专门用于测温,而是测芯片温度,但MPU6050芯片自身的热量可忽略不计,故可看作环境温度
于是将其从火箭中拆出来,接上ESP32C3模块,具体接线方式如下:
VCC --- 3V3
GND --- GND
SDA --- P8 (SDA)
SCL --- P9 (SCL)
左侧为MPU6050,右侧为ESP32C3引脚

编写程序(使用ArduinoIDE),编译并上传,灯亮了,输出了实时温度
接下来继续完善用户体验,界面,操作,统统安排! 最终代码如下:
#include <Adafruit_MPU6050.h> //include library
#include <Adafruit_Sensor.h> //include library
#include <WiFi.h>
#include <ESPAsyncWebServer.h> // 包含异步Web服务器库文件
AsyncWebServer server(80); // 创建WebServer对象, 端口号80
// 使用端口号80可以直接输入IP访问,使用其它端口需要输入IP:端口号访问
// 一个储存网页的数组
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h2>空调浇水控制</h2>
<!-- 创建一个ID位dht的盒子用于显示获取到的数据 -->
<div id="dht">
</div>
<button onclick="set()"> 开启/关闭浇水 </button>
<button onclick="autoset()"> 开启/关闭自动 </button>
</body>
<script>
// 按下按钮会运行这个JS函数
function set() {
var payload = "ESP32"; // 需要发送的内容
// 通过get请求给 /set
var xhr = new XMLHttpRequest();
xhr.open("GET", "/set?value=" + payload, true);
xhr.send();
}
function autoset() {
var payload = "ESP32"; // 需要发送的内容
// 通过get请求给 /set
var xhr = new XMLHttpRequest();
xhr.open("GET", "/auto?value=" + payload, true);
xhr.send();
}
// 设置一个定时任务, 1000ms执行一次
setInterval(function () {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
// 此代码会搜索ID为dht的组件,然后使用返回内容替换组件内容
document.getElementById("dht").innerHTML = this.responseText;
}
};
// 使用GET的方式请求 /dht
xhttp.open("GET", "/dht", true);
xhttp.send();
}, 200)
</script>)rawliteral";
Adafruit_MPU6050 mpu; //Instantiate object
#define mpu6050TimeInterval 100 //Detect the time interval of a trip
unsigned long mpu6050Times = 0; //Record the device running time
float mpu6050Temp = 0; //Define a variable
float xAcceleration , yAcceleration , zAcceleration ; //Define three variables
float xAccele , yAccele , zAccele ; //Define three variables
float xGyro = 0, yGyro = 0, zGyro = 0; //Define three variables
float gravity = 9.8; //Define a variable
int isdone=0;
bool iswater=0,isauto=1;
String Merge_Data(void)
{
int Humidity = 50;// 此处应为获取温度代码
int Temperature = 26;// 此处应为获取湿度代码
// 将温湿度打包为一个HTML显示代码
String dataBuffer = "<p>";
dataBuffer += "<h1>传感器数据 </h1>";
dataBuffer += "<b>温度: </b>";
dataBuffer += String(mpu6050Temp);
dataBuffer += "<br />";
dataBuffer += "<b>当前浇水状态: </b>";
dataBuffer += String(iswater);
dataBuffer += "<br />";
dataBuffer += "<b>当前自动状态: </b>";
dataBuffer += String(isauto);
dataBuffer += "<br /></p>";
// 最后要将数组返回出去
return dataBuffer;
}
// 下发处理回调函数
void Config_Callback(AsyncWebServerRequest *request)
{
iswater=!iswater;
isauto=0;
request->send(200, "text/plain", "OK"); // 发送接收成功标志符
}
// 下发处理回调函数
void Auto_Callback(AsyncWebServerRequest *request)
{
isauto=!isauto;
request->send(200, "text/plain", "OK"); // 发送接收成功标志符
}
void setup()
{
WiFi.begin("SSID","PASSWD");
while(WiFi.status()!=WL_CONNECTED){ //未连接上
delay(500);
Serial.println("正在连接...");
}
Serial.println("连接成功!"); //连接上
pinMode(1,OUTPUT);
// 添加HTTP主页,当访问的时候会把网页推送给访问者
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/html", index_html); });
// 设置反馈的信息,在HTML请求这个Ip/dht这个链接时,返回打包好的传感器数据
server.on("/dht", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/plain", Merge_Data().c_str()); });
server.on("/set", HTTP_GET, Config_Callback); // 绑定配置下发的处理函数
server.on("/auto", HTTP_GET, Auto_Callback); // 绑定配置下发的处理函数
server.begin(); // 初始化HTTP服务器
Serial.begin(115200); //Example Set the baud rate of the serial port to 9600
if (!mpu.begin()) { // Try to initialize!
while (millis() - 1000) { //Wait for the device to come online
Serial.println("Failed to find MPU6050 chip");
}
}
mpu.setAccelerometerRange(MPU6050_RANGE_16_G); //Set the accelerometer range
mpu.setGyroRange(MPU6050_RANGE_250_DEG); //Set the gyroscope range
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ); //Set filtering bandwidth
Serial.println("Go online!");
}
void loop() {
getMpu6050Data(); //Obtain data about the mpu6050
if(isauto==1){
if(mpu6050Temp>=30){
digitalWrite(1,HIGH);
iswater=1;
}else if(mpu6050Temp<30){
digitalWrite(1,LOW);
iswater=0;
}
}else if(isauto==0){
digitalWrite(1,iswater);
}
}
void getMpu6050Data() {
if (millis() - mpu6050Times >= mpu6050TimeInterval) { //This command is executed once in a while
mpu6050Times = millis();
sensors_event_t a, g, temp; //Set three variables
mpu.getEvent(&a, &g, &temp); //Read the corresponding three values
mpu6050Temp = temp.temperature; //Acquired temperature
xAcceleration = a.acceleration.x ; //Acquired acceleration
yAcceleration = a.acceleration.y ; //Acquired acceleration
zAcceleration = a.acceleration.z ; //Acquired acceleration
xAccele = xAcceleration / gravity; //Convert the units of acceleration into g
yAccele = yAcceleration / gravity; //Convert the units of acceleration into g
zAccele = zAcceleration / gravity; //Convert the units of acceleration into g
xGyro = g.gyro.x; //Acquired angular velocity
yGyro = g.gyro.y; //Acquired angular velocity
zGyro = g.gyro.z; //Acquired angular velocity
Serial.print("Temp: ");
Serial.print(mpu6050Temp); //Serial print temperature
Serial.print(" , x-accele: ");
Serial.print(xAccele); //Serial print acceleration
Serial.print(" , y-accele: ");
Serial.print(yAccele); //Serial print acceleration
Serial.print(" , z-accele: ");
Serial.print(zAccele); //Serial print acceleration
Serial.print(" , x-gyro:");
Serial.print(xGyro); //Serial port print angular speed
Serial.print(" , y-gyro:");
Serial.print(yGyro); //Serial port print angular speed
Serial.print(" , z-gyro:");
Serial.println(zGyro); //Serial port print angular speed
}
}
代码中依然保留了对MPU6050其他数据的读取,如果需要增加功能可直接使用;
亮点:
- [X] 使用网页操作方式,访问其IP地址后实时显示温度与“自动化状态”
- [X] 可通过网页控制其开关水状态(点击后会自动退出自动化模式,请注意用水量控制),也可控制其自动化模式开关状态。
- [X] 自动化:超过30°C自动开水,低于后停水(自动化选项开启时有效)
- [ ] 网页尚未添加CSS美化,仅做功能实现演示,如有需要可自行添加CSS美化

