2025/4/13
大风
目前还是名大二的学生,这是第二篇博客,对于刚学完C语言有对物联网感兴趣的同学可以尝试,我使用的是Vscode中的platformio的环境开发,也可以使用arduino ide,成本低,在家里可以复现,但是细节仍需要打磨完善,同时如果觉得我做的传感器比较多,可以进行删减,如果有感兴趣的可以关注一下,非常欢迎私信交流学习,我也会在周末更新博客。
一、摘要:
本项目“基于ESP32的小型互联网系统”正是在这样的背景下应运而生。我们的目标是开发一个集成的环境监测和自动化控制系统,该系统不仅能够监测家庭环境的关键参数,还能够根据监测数据自动调节设备,实现家庭绿植的自动化生长培养和小型鱼类家庭水箱的环境监测。通过这一系统,我们希望能够实现一个无人化的居住环境,使得居住者无需亲自操作,系统便能根据环境变化自动调节,以达到最适宜居住的条件。
二、整体流程图:
三、项目实施
蜂鸣器 土壤湿度传感器 空气温湿度 OLED
水温传感器 红外传感器 光强传感器 3.3V水泵
OLED显示
蓝牙的话可以下载Bluetooth appliance.
四、项目组成部分(硬件和代码部分)
1. 微控制器
• ESP32:主控芯片,负责处理传感器数据、控制外设和通信。
2. 传感器
• 温湿度传感器(DHT22):用于测量环境温度和湿度。
• 光强传感器(BH1750):用于测量环境光强。
• 土壤湿度传感器:用于测量土壤湿度。
• 水温传感器(DS18B20):用于测量水温。
3. 控制模块
• 继电器:用于控制水泵的开关。
• 蜂鸣器:用于发出警报声。
4. 通信模块
• 蓝牙模块(BluetoothSerial):用于通过蓝牙接收控制命令。
• 红外遥控模块(IRremote):用于通过红外遥控器接收控制命令。
5. 显示模块
• OLED显示屏(U8G2_SSD1306_128X64_NONAME_F_HW_I2C):用于显示传感器数据。
6. 接口
- OLED 显示屏:SCL (GPIO 22), SDA (GPIO 21)
- DS18B20 温度传感器:DATA (GPIO 4)
- DHT22 温湿度传感器:DATA (GPIO 32)
- BH1750 光强传感器:SCL (GPIO 22), SDA (GPIO 21)
- 土壤湿度传感器:ANALOG (GPIO 34)
- 继电器:CONTROL (GPIO 2)
- 蜂鸣器:CONTROL (GPIO 19)
- 红外接收器:RECEIVE (GPIO 13)
- 继电器:
- VCC -- 5V (电源正极)
- GND-- GND (电源负极)
- IN -- GPIO 2 (ESP32)
- COM -- 5V (电源正极)
- NO -- 水泵正极
7.库文件
- Wire.h:用于I2C通信。
- U8g2lib.h:用于OLED显示屏的驱动。
- DHT.h:用于温湿度传感器的驱动。
- BH1750.h:用于光强传感器的驱动。
- BluetoothSerial.h:用于蓝牙通信。
- IRremote.h:用于红外遥控的驱动。
- OneWire.h:用于DS18B20传感器的驱动。
- DallasTemperature.h:用于DS18B20传感器的驱动。
8.开发环境
1. 开发环境:VSCODE PlatformIO
2.串口:同时按住window和X 点击设备管理器,寻找串口即可
3.手机端:下载Bluetooth,连接蓝牙。
4.通信:可以下载打印助手,注意设置确保了开发板和计算机之间的数据传输速率一致,我使用的是115200波特率。
五、核心代码
1.传感器数据读取
void readSensors()
{
static unsigned long lastReadTime = 0;
const unsigned long readInterval = 2000; // 每2秒读取一次
if (millis() - lastReadTime < readInterval)
{
return; // 未到读取时间
}
lastReadTime = millis();
// 读取温湿度传感器数据
float temp = dht.readTemperature();
float hum = dht.readHumidity();
if (isnan(temp) || isnan(hum))
{
temperature = -1; // 表示未连接或读取失败
humidity = -1;
dhtConnected = false;
Serial.println("DHT sensor read failed");
}
else
{
temperature = temp;
humidity = hum;
dhtConnected = true;
Serial.println("DHT sensor read success");
}
// 读取光强传感器数据
if (lightMeter.begin())
{
lightLevel = lightMeter.readLightLevel();
lightMeterConnected = true;
Serial.println("BH1750 sensor read success");
}
else
{
lightLevel = -1; // 表示未连接或读取失败
lightMeterConnected = false;
Serial.println("BH1750 sensor read failed");
}
// 读取土壤湿度传感器数据
if (soilMoistureConnected)
{
soilMoisture = analogRead(soilMoisturePin);
if (soilMoisture == 0 || soilMoisture == 1023) // 检查是否连接
{
soilMoisture = -1; // 表示未连接或读取失败
soilMoistureConnected = false;
Serial.println("Soil moisture sensor read failed");
}
else
{
Serial.println("Soil moisture sensor read success");
}
}
else
{
soilMoisture = -1; // 表示未连接或读取失败
Serial.println("Soil moisture sensor not connected");
}
// 读取水温传感器数据
bool waterTempReadSuccess = false;
for (int i = 0; i < 3; i++) // 尝试读取 3 次
{
sensors.requestTemperatures(); // 请求温度读取
waterTemperature = sensors.getTempCByIndex(0); // 获取第一个设备的温度
if (!isnan(waterTemperature))
{
waterTempReadSuccess = true;
break;
}
delay(100); // 等待 100ms 后再次尝试
}
if (waterTempReadSuccess)
{
waterTemperatureConnected = true;
Serial.println("Water temperature sensor read success");
}
else
{
waterTemperature = -1; // 表示未连接或读取失败
waterTemperatureConnected = false;
Serial.println("Water temperature sensor read failed");
}
// 检查蜂鸣器的连接状态
buzzerConnected = digitalRead(buzzerPin) != -1;
// 检查继电器的连接状态
relayConnected = digitalRead(relayPin) != -1;
}
2.蓝牙通信
void handleBluetooth()
{
if (SerialBT.available())
{
int command = SerialBT.parseInt();
Serial.print("Received Bluetooth command: ");
Serial.println(command);
switch (command)
{
case 1: // 打开继电器(水泵)
relayState = true;
digitalWrite(relayPin, HIGH);
manualControl = true; // 标记为手动控制
SerialBT.println("Relay ON");
Serial.println("Relay ON");
break;
case 2: // 关闭继电器(水泵)
relayState = false;
digitalWrite(relayPin, LOW);
manualControl = true; // 标记为手动控制
SerialBT.println("Relay OFF");
Serial.println("Relay OFF");
break;
case 3: // 打开蜂鸣器
buzzerState = true;
controlBuzzer();
SerialBT.println("Buzzer ON");
Serial.println("Buzzer ON");
break;
case 4: // 关闭蜂鸣器
buzzerState = false;
controlBuzzer();
SerialBT.println("Buzzer OFF");
Serial.println("Buzzer OFF");
break;
case 5: // 播放两只老虎
playSong(song, noteDurations, sizeof(song) / sizeof(int), buzzerPin);
SerialBT.println("Playing 'Two Tigers'");
Serial.println("Playing 'Two Tigers'");
break;
case 0: // 翻页
currentPage = (currentPage == 1) ? 2 : 1;
Serial.println("Page changed to " + String(currentPage)); // 添加调试信息
displaySensors(); // 更新 OLED 显示
SerialBT.println("Page changed");
Serial.println("Page changed");
break;
default:
SerialBT.println("Unknown command");
Serial.println("Unknown command");
break; // ... 其他命令 ...
}
}
}
3.继电器控制
void controlRelay()
{
if (manualControl)
return; // 如果是手动控制,不进行自动控制
if (soilMoisture < soilMoistureThresholdLow)
{
if (!relayState)
{
relayState = true;
digitalWrite(relayPin, relayState);
SerialBT.println("Soil moisture is low. Relay ON");
}
}
else if (soilMoisture >= soilMoistureThresholdHigh)
{
if (relayState)
{
relayState = false;
digitalWrite(relayPin, relayState);
SerialBT.println("Soil moisture is high. Relay OFF");
}
}
}
4.红外控制
void handleIRCommands()
{
if (IrReceiver.decode()) // 使用默认实例 IrReceiver
{
Serial.print("Received IR code: ");
Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // 打印接收到的红外信号编码值
switch (IrReceiver.decodedIRData.decodedRawData) // 使用 decodedRawData
{
case 0xFFC23D: // 按键 0
currentPage = (currentPage == 1) ? 2 : 1; // 翻页
Serial.println("Page changed to " + String(currentPage)); // 添加调试信息
displaySensors(); // 更新 OLED 显示
break;
case 0xFF02FD: // 新增处理 0 的按键
currentPage = (currentPage == 1) ? 2 : 1; // 翻页
Serial.println("Page changed to " + String(currentPage)); // 添加调试信息
displaySensors(); // 更新 OLED 显示
Serial.println("Page changed by IR");
break;
default:
break;
}
IrReceiver.resume(); // 接收下一个值
}
}
六、作品程序调试
1. 开发环境:VSCODE PlatformIO
2.串口:同时按住window和X 点击设备管理器,寻找串口即可
3.手机端:下载Bluetooth,连接蓝牙。
4.通信:可以下载打印助手,注意设置确保了开发板和计算机之间的数据传输速率一致,我使用的是115200波特率。
什么是波特率?
波特率是指串口通信的速率,即每秒钟传输的二进制位数。常见波特率为9600和115200。通信双方需设定相同波特率以确保有效通信。
七、结语
大道五十 天衍四十九 人遁其一
选自《周易.系辞上传》
在学习的路上我也是个小白,但是我相信只要努力,就会有收获,即使效果渺茫,但是天道酬勤,海纳百川,正所谓“宁欺白头翁 莫欺少年穷”。
非常感谢您的阅读。