#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <DHT.h>
// OLED显示屏设置
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// DHT22设置
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// 引脚定义
const int pumpPin = 5; // 水泵控制
// 系统参数
const int DRY_THRESHOLD = 50; // 干燥阈值百分比
const int WET_THRESHOLD = 70; // 湿润阈值百分比
const int MIN_TEMP_FOR_WATERING = 9; // 最低浇水温度
const int MAX_TEMP_FOR_WATERING = 23; // 最高浇水温度
// 灌溉系统参数
const float AREA = 100.0; // 种植面积(平方米)
const float DEPTH = 0.4; // 土壤深度(米)
const float PUMP_FLOW_RATE = 2.0; // 水泵流量(升/分钟)
const float WATER_ABSORPTION_RATE = 0.2; // 土壤吸水率(%/升水/平方米)
// 系统状态
bool watering = false;
unsigned long lastWateringTime = 0;
const unsigned long WATERING_COOLDOWN = 60000; // 1分钟浇水冷却时间
unsigned long wateringStartTime = 0;
float soilMoisture = 50.0; // 初始土壤湿度(%)
void setup() {
Serial.begin(115200);
// 初始化OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306分配失败"));
for(;;);
}
display.display();
delay(2000);
display.clearDisplay();
// 初始化DHT传感器
dht.begin();
// 设置引脚模式
pinMode(pumpPin, OUTPUT);
digitalWrite(pumpPin, LOW);
// 显示初始信息
displayWelcomeMessage();
}
void loop() {
// 读取空气温湿度数据
float airHumidity = dht.readHumidity();
float airTemperature = dht.readTemperature();
// 检查传感器读数是否有效
if (isnan(airHumidity) || isnan(airTemperature)) {
Serial.println("无法从DHT传感器读取数据!");
displaySensorError();
delay(2000);
return;
}
// 更新土壤湿度(模拟吸水/蒸发过程)
updateSoilMoisture();
// 控制逻辑
bool shouldWater = shouldStartWatering(soilMoisture, airTemperature) &&
!watering &&
(millis() - lastWateringTime > WATERING_COOLDOWN);
bool shouldStop = shouldStopWatering(soilMoisture, airTemperature) && watering;
if (shouldWater) {
startWatering();
} else if (shouldStop) {
stopWatering();
}
// 在OLED上显示数据
displaySensorData(airTemperature, airHumidity, soilMoisture);
// 串口输出调试信息
logSensorData(airTemperature, airHumidity, soilMoisture);
delay(2000); // 2秒更新一次
}
// 更新土壤湿度(模拟吸水/蒸发过程)
void updateSoilMoisture() {
unsigned long currentTime = millis();
if (watering) {
// 计算浇水时间(分钟)
float wateringDuration = (currentTime - wateringStartTime) / 60000.0;
// 计算总浇水量(升)
float waterAmount = PUMP_FLOW_RATE * wateringDuration;
// 计算湿度增加量
float moistureIncrease = (waterAmount * WATER_ABSORPTION_RATE) / (AREA * DEPTH);
soilMoisture += moistureIncrease;
// 限制最大湿度
if (soilMoisture > 100.0) {
soilMoisture = 100.0;
}
} else {
// 模拟自然蒸发过程(每小时降低0.5%)
float evaporationRate = 0.5 / 3600.0 * (currentTime - lastWateringTime) / 1000.0;
soilMoisture -= evaporationRate;
// 限制最小湿度
if (soilMoisture < 0.0) {
soilMoisture = 0.0;
}
}
}
// 辅助函数
void displayWelcomeMessage() {
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.println("智能灌溉系统");
display.println("空气土壤温湿度控制");
display.display();
delay(2000);
}
// 条件判断
bool shouldStartWatering(float soilMoisture, float temp) {
return soilMoisture < DRY_THRESHOLD &&
temp >= MIN_TEMP_FOR_WATERING &&
temp <= MAX_TEMP_FOR_WATERING;
}
bool shouldStopWatering(float soilMoisture, float temp) {
return soilMoisture >= WET_THRESHOLD ||
temp < MIN_TEMP_FOR_WATERING ||
temp > MAX_TEMP_FOR_WATERING;
}
void startWatering() {
digitalWrite(pumpPin, HIGH);
watering = true;
wateringStartTime = millis();
lastWateringTime = millis();
Serial.println("开始浇水");
}
void stopWatering() {
digitalWrite(pumpPin, LOW);
watering = false;
lastWateringTime = millis();
Serial.println("停止浇水");
}
void displaySensorData(float airTemp, float airHum, float soilHum) {
display.clearDisplay();
display.setCursor(0,0);
// 显示空气数据
display.print("WENDU: ");
display.print(airTemp, 1);
display.println("C");
display.print("KONGSHI: ");
display.print(airHum, 0);
display.println("%");
// 显示土壤数据
display.print("TURANSHI: ");
display.print(soilHum, 1);
display.println("%");
// 显示系统状态
if (watering) {
display.println("ZT: ZHENGZAIJIAOSHUI");
// 显示已浇水时间
display.print("TIME: ");
display.print((millis() - wateringStartTime)/1000);
display.println("s");
} else if (soilHum < DRY_THRESHOLD) {
display.println("ZT: YUYAOJIAOSHUI");
} else if (soilHum > WET_THRESHOLD) {
display.println("ZT: SHUIFENCHONGZU");
} else {
display.println("ZT: ZHENGZHANG");
}
display.display();
}
void displaySensorError() {
display.clearDisplay();
display.setCursor(0,0);
display.println("传感器错误!");
display.println("请检查连接");
display.display();
}
void logSensorData(float airTemp, float airHum, float soilHum) {
Serial.print("空气温度: ");
Serial.print(airTemp);
Serial.print("C, 空气湿度: ");
Serial.print(airHum);
Serial.print("%, 土壤湿度: ");
Serial.print(soilHum);
Serial.println("%");
if(watering) {
Serial.print("当前状态: 正在浇水 (已浇水");
Serial.print((millis() - wateringStartTime)/1000);
Serial.println("秒)");
} else if(soilHum < DRY_THRESHOLD) {
Serial.println("当前状态: 需要浇水");
}
}