基于Arduino的智能植物养护系统设计与实现

一. 硬件设计架构

  • 土壤湿度传感器连接到模拟输入引脚A0(esp8266唯一的模拟信号输入),用于检测土壤含水量。
  • 数字引脚D1控制继电器模块,继电器负责切换水泵电源。
  • 数字引脚D2控制另一个继电器模块,用于补光灯电源切换。光照传感器连接到数字引脚D3,检测环境光照强度。

1. 控制逻辑实现

湿度控制采用双阈值设计:当检测值低于SOIL_HUMIDITY_LOW(35%)时启动水泵,高于SOIL_HUMIDITY_HIGH(70%)时停止。为防止水泵空转损坏,设置5秒的PUMP_WORK_TIME强制停止保护。光照控制采用简单的高低电平判断,当传感器输出低电平时开启补光灯。

2. 传感器数据处理

土壤湿度采用10次采样取平均值的滤波算法,通过map()函数将原始模拟值(300-800)转换为0-100%的湿度百分比。

校准参数minDry和maxWet需要根据实际测量调整,干燥土壤对应较高模拟值,湿润土壤对应较低模拟值。

3. 安全保护机制

millis()计时器记录水泵启动时间,超过设定时长会自动切断电源。

同时,继电器控制采用非锁存方式,持续检测传感器状态来维持设备运行。串口输出实时监控数据,便于调试和状态观察。

4. 扩展优化方向

未来可增加网络模块实现远程监控,添加RTC模块实现定时控制。光照控制可改为模拟量检测,设置更精细的光照阈值。

土壤湿度检测可加入温度补偿算法,提高不同环境下的测量精度。继电器控制建议增加状态指示灯,便于现场观察设备运行状态。

二. 软硬件实操

1. 硬件配置

  • 土壤湿度传感器:连接模拟引脚A0,用于实时监测土壤含水量
  • 继电器模块:控制水泵(D1)和补光灯(D2)的电源通断
  • 光照传感器:连接数字引脚D3,检测环境光强度
  • 核心控制器:采用常见的Arduino开发板(本项目使用esp8266 nodemcu开发板)

2. 土壤湿度检测优化

采用滑动平均滤波算法处理传感器数据,有效消除瞬时干扰。代码中设置10次采样取平均值,通过map函数将原始ADC值(300-800)转换为0-100%的湿度百分比。

示例代码如下:

// 引脚定义
const int SOIL_SENSOR_PIN = A0;   // 土壤湿度传感器模拟输入

pinMode(PUMP_RELAY_PIN, OUTPUT);

// 读取并转换土壤湿度(平均值滤波)
int readSoilHumidity() {
  const int sampleCount = 10; // 采样10次
  long sum = 0;
  
  for (int i = 0; i < sampleCount; i++) {
    sum += analogRead(SOIL_SENSOR_PIN);
    delay(5); // 每次采样间隔5ms,避开干扰
  }
  
  int rawValue = sum / sampleCount; // 取平均值
  
  // 校准值(根据你实际测量的干湿值修改)
  const int minDry = 800;
  const int maxWet = 300;
  
  // 映射到0-100
  int humidity = map(rawValue, minDry, maxWet, 0, 100);
  // 限制到1-100之间
  humidity = constrain(humidity, 0, 100);
  return humidity;
}

土壤传感器图片:
土壤传感器示例

!!实际使用前需进行传感器校准:

  • 完全干燥土壤时记录ADC值(minDry)
  • 充分浸湿土壤时记录ADC值(maxWet)

我在湿度控制采用双阈值设计喵:

当湿度低于35%时启动水泵
达到70%时自动停止
同时设置5秒最大运行时间防止干烧

水泵代码示例:

const int PUMP_RELAY_PIN  = 5;   // 水泵继电器

// 湿度阈值(根据实际校准)
const int SOIL_HUMIDITY_LOW  = 35;  // 下限:低于此值开始浇水
const int SOIL_HUMIDITY_HIGH = 70;  // 上限:高于此值停止浇水

// 水泵单次浇水时间(秒),防止长时间空转
const int PUMP_WORK_TIME = 5;

// 用于记录水泵状态
bool pumpIsOn = false;
unsigned long pumpStartTime = 0;

  // 初始关闭所有设备
digitalWrite(PUMP_RELAY_PIN, HIGH); // 假设继电器低电平触发,这里按高电平关闭
// 开启水泵
void startPump() {
  if (!pumpIsOn) {
    Serial.println("启动水泵");
    digitalWrite(PUMP_RELAY_PIN, LOW); // 假设低电平触发
    pumpIsOn = true;
    pumpStartTime = millis();
  }
}

// 关闭水泵
void stopPump() {
  if (pumpIsOn) {
    Serial.println("关闭水泵");
    digitalWrite(PUMP_RELAY_PIN, LOW);
    pumpIsOn = false;
  }
}


继电器示例图片喵:
继电器

3. 光照控制策略

通过数字光敏传感器检测环境光:

  • 输出低电平(0)表示光照不足,触发补光灯
  • 输出高电平(1)表示光照充足,关闭补光灯

实际应用中可替换为模拟光照传感器,实现更精确的光照强度分级控制

系统安全机制

  • 继电器初始状态设置为HIGH(断开)
  • 水泵运行时间超过预设值自动切断电源
  • 每次循环间隔1秒,避免频繁操作损坏设备
  • 串口输出所有传感器数据和控制状态,便于调试

!!这里用的是DO引脚嗷喵,esp8266只有一个模拟信号输入,给了湿度传感器喵!!

光照部分示例代码:

const int LIGHT_RELAY_PIN = 4;   // 补光灯继电器

pinMode(LIGHT_RELAY_PIN, OUTPUT);
digitalWrite(LIGHT_RELAY_PIN, HIGH);

// 开启补光灯
void turnOnLight() {
  digitalWrite(LIGHT_RELAY_PIN, HIGH); // 高电平触发
  Serial.println("补光灯开启");
}

void turnOffLight() {
  digitalWrite(LIGHT_RELAY_PIN, LOW); // 低电平触发
  Serial.println("补光灯关闭");
}

光敏电阻模块示例:
光敏电阻模块

三. 完整代码示例

// 引脚定义
const int SOIL_SENSOR_PIN = A0;   // 土壤湿度传感器模拟输入
const int PUMP_RELAY_PIN  = 5;   // 水泵继电器
const int LIGHT_RELAY_PIN = 4;   // 补光灯继电器
// 光照传感器引脚定义
const int LIGHT_SENSOR_PIN = 0;

// 湿度阈值(根据实际校准)
const int SOIL_HUMIDITY_LOW  = 35;  // 下限:低于此值开始浇水
const int SOIL_HUMIDITY_HIGH = 70;  // 上限:高于此值停止浇水

// 水泵单次浇水时间(秒),防止长时间空转
const int PUMP_WORK_TIME = 5;

// 用于记录水泵状态
bool pumpIsOn = false;
unsigned long pumpStartTime = 0;

void setup() {
  Serial.begin(115200);

  pinMode(PUMP_RELAY_PIN, OUTPUT);
  pinMode(LIGHT_RELAY_PIN, OUTPUT);

  // 初始关闭所有设备
  digitalWrite(PUMP_RELAY_PIN, HIGH); // 假设继电器低电平触发,这里按高电平关闭
  digitalWrite(LIGHT_RELAY_PIN, HIGH);
}

// 读取并转换土壤湿度(平均值滤波)
int readSoilHumidity() {
  const int sampleCount = 10; // 采样10次
  long sum = 0;
  
  for (int i = 0; i < sampleCount; i++) {
    sum += analogRead(SOIL_SENSOR_PIN);
    delay(5); // 每次采样间隔5ms,避开干扰
  }
  
  int rawValue = sum / sampleCount; // 取平均值
  
  // 校准值(根据你实际测量的干湿值修改)
  const int minDry = 800;
  const int maxWet = 300;
  
  // 映射到0-100
  int humidity = map(rawValue, minDry, maxWet, 0, 100);
  // 限制到1-100之间
  humidity = constrain(humidity, 0, 100);
  return humidity;
}

// 开启水泵
void startPump() {
  if (!pumpIsOn) {
    Serial.println("启动水泵");
    digitalWrite(PUMP_RELAY_PIN, LOW); // 假设低电平触发
    pumpIsOn = true;
    pumpStartTime = millis();
  }
}

// 关闭水泵
void stopPump() {
  if (pumpIsOn) {
    Serial.println("关闭水泵");
    digitalWrite(PUMP_RELAY_PIN, LOW);
    pumpIsOn = false;
  }
}


// 开启补光灯
void turnOnLight() {
  digitalWrite(LIGHT_RELAY_PIN, HIGH); // 高电平触发
  Serial.println("补光灯开启");
}

void turnOffLight() {
  digitalWrite(LIGHT_RELAY_PIN, LOW); // 低电平触发
  Serial.println("补光灯关闭");
}


void loop() {
  int humidity = readSoilHumidity();
  Serial.print("当前土壤湿度: ");
  Serial.print(humidity);
  Serial.println("%");

  // 水泵控制逻辑
  if (humidity < SOIL_HUMIDITY_LOW) {
    startPump();
  } else if (humidity > SOIL_HUMIDITY_HIGH) {
    stopPump();
  }

  // 防止水泵超时运行
  if (pumpIsOn && (millis() - pumpStartTime) > PUMP_WORK_TIME * 1000) {
    stopPump();
    Serial.println("水泵超时,强制关闭");
  }

  // 光照传感器引脚读取
  int lightLevel = digitalRead(LIGHT_SENSOR_PIN);



  // 目前补光灯逻辑按照一个返回高低电平判断是否开启
  if (lightLevel == 0) {
    turnOnLight();
  } else {
    turnOffLight();
  }


  delay(1000); // 每秒检测一次
}

水泵和补光灯可以根据需求和电压等参数自行调整

四. 扩展改进建议

  • 增加水位检测传感器,防止水箱无水时水泵空转
  • 添加温湿度传感器(如DHT11)监测更多环境参数
  • 引入物联网模块(ESP8266)实现手机远程监控
  • 使用PID算法优化水泵控制,避免频繁启停
  • 添加LCD显示屏实时展示系统状态

电路连接注意事项

  • 若水泵或者补光灯为大功率设备建议与控制系统电源隔离
  • 传感器信号线远离强电线路防止干扰
  • 土壤传感器探头做防水处理延长使用寿命

总之,该设计完整实现了植物养护的自动化控制,通过模块化编程方便功能扩展,适合作为物联网入门实践项目。实际部署时需根据具体植物品种调整控制参数,并做好设备的防水防护措施。

最后,如果觉得有帮助的话,赏点小鱼干吧喵~~

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐