1. 项目背景与核心价值
去年帮朋友改造他的花卉大棚时,发现传统人工管理方式存在几个痛点:早上湿度高但光照不足不敢浇水,中午阳光强烈却容易忘记补水,晚上又要手动记录数据。这种粗放式管理导致他种的蝴蝶兰死亡率高达30%。于是我们决定用STM32开发一套能自主决策的智能监控系统,经过三个月的迭代,最终实现了土壤湿度、光照强度与灌溉联动的自动化控制。
这个系统的核心在于用传感器实时采集环境数据,通过STM32的ADC模块转换为数字信号,再结合阈值算法自动触发灌溉装置。相比市面上的成品控制器,我们增加了光照强度作为灌溉决策的辅助参数,解决了"阴天过度浇水"的行业常见问题。整套方案成本控制在200元以内,比商业设备便宜80%,特别适合中小型种植户DIY改造。
2. 硬件系统设计
2.1 核心器件选型
主控选用STM32F103C8T6最小系统板,这款ARM Cortex-M3内核的MCU有12位ADC和多个定时器,完全满足我们的采样需求。实测发现其运行FreeRTOS时仍能保持5ms级别的响应速度,关键参数如下:
| 器件类型 | 具体型号 | 关键参数 |
|---|---|---|
| 土壤湿度传感器 | 电容式V1.2 | 0-100%RH ±3%精度,0.5V-3V输出 |
| 光照传感器 | BH1750FVI | 0-65535 lux,I2C接口 |
| 水泵驱动 | 5V微型隔膜泵 | 最大流量1L/min,需配MOS管驱动电路 |
| 显示模块 | 0.96寸OLED SSD1306 | 128x64分辨率,I2C通信 |
特别注意:电容式湿度传感器要选环氧树脂封装版本,朋友最初用的陶瓷封装款在高温高湿环境下两周就出现了引脚腐蚀。
2.2 电路设计要点
供电部分采用双路设计:主控和传感器由AMS1117-3.3稳压供电,水泵单独使用5V 2A电源。这两个电源共地但不共用正极,避免水泵启停对ADC采样造成干扰。实际布线时要注意:
- 传感器信号线要远离电机驱动线,我们的PCB最初版本因平行走线导致ADC值跳变
- BH1750的光敏窗口要加装乳白色扩散罩,直接暴露会导致向阳面和背光面读数差异过大
- 在湿度传感器输出端并联104电容,有效滤除因长导线引入的高频噪声
3. 软件实现关键
3.1 传感器数据采集
使用STM32的DMA+ADC多通道扫描模式,配置为连续转换。以下是关键代码片段:
c复制// ADC初始化配置
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
HAL_ADC_Init(&hadc1);
// DMA配置
__HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
hdma_adc1.Instance = DMA1_Channel1;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
光照传感器通过I2C读取,特别注意BH1750在连续测量模式下需要至少120ms的积分时间。我们采用定时器触发测量,代码里要加入超时判断:
c复制if(HAL_I2C_Master_Receive(&hi2c1, BH1750_ADDR, &data, 2, 100) != HAL_OK)
{
// 重发测量指令
uint8_t cmd = BH1750_CONTINUOUS_HIGH_RES_MODE;
HAL_I2C_Master_Transmit(&hi2c1, BH1750_ADDR, &cmd, 1, 10);
}
3.2 控制算法设计
采用动态阈值算法,基本逻辑是:
- 当光照>20000lux且湿度<30%:立即浇水
- 当光照<5000lux时:即使湿度较低也禁止浇水
- 其他情况按湿度阈值控制
在FreeRTOS中创建三个任务:
- Sensor_Task:每2秒采集一次数据
- Control_Task:每5秒评估控制条件
- Display_Task:刷新OLED显示
关键判断逻辑如下:
c复制void Control_Task(void const * argument)
{
while(1) {
if(light > LIGHT_THRESHOLD_HIGH && humidity < HUMIDITY_THRESHOLD_LOW) {
HAL_GPIO_WritePin(PUMP_GPIO_Port, PUMP_Pin, GPIO_PIN_SET);
osDelay(3000); // 浇水3秒
HAL_GPIO_WritePin(PUMP_GPIO_Port, PUMP_Pin, GPIO_PIN_RESET);
}
osDelay(5000);
}
}
4. 实际部署经验
4.1 传感器安装技巧
- 土壤湿度传感器要呈45度角插入,垂直安装会导致底部积水影响读数
- 多个湿度传感器应安装在作物根系密集区,我们在大棚对角线布置了4个点
- 光照传感器安装高度建议与植物顶端平齐,最初装在棚顶导致读数比实际叶面照度高15%
4.2 系统校准方法
准备标准设备进行交叉验证:
- 土壤湿度:用烘干法测得实际含水量,记录传感器输出电压
- 光照强度:用专业照度计对比读数,发现BH1750在低照度区需要+5%补偿
校准曲线采用分段线性拟合:
code复制if(adc_value < 1500)
humidity = 0.0125 * adc_value;
else
humidity = 18.75 + 0.006*(adc_value-1500);
5. 常见问题排查
5.1 数据异常波动
现象:湿度读数偶尔突增30%后又恢复
解决方法:
- 检查传感器接地是否良好
- 在ADC输入端增加0.1μF去耦电容
- 软件上采用中值滤波,取最近5次采样中间值
5.2 水泵误触发
现象:未达阈值时水泵自启动
排查步骤:
- 用逻辑分析仪抓取GPIO信号
- 发现是长导线感应电压导致
- 在GPIO输出端增加1kΩ下拉电阻解决
5.3 I2C通信失败
现象:BH1750偶尔无响应
优化方案:
- 将I2C时钟从400kHz降到100kHz
- 在SCL/SDA线加装2.2kΩ上拉电阻
- 每次通信前发送复位指令
6. 效果验证与升级方向
经过三个月连续运行,系统将浇水次数从人工管理的每天4-6次优化为2-3次,节水35%,蝴蝶兰成活率提升至92%。后期计划增加:
- 通过ESP-01S模块上传数据到私有云
- 加入EC传感器实现肥水一体化控制
- 用PID算法优化水泵启停时长
大棚主最惊喜的功能是"阴天保护"——当系统检测到连续光照不足时,会自动减少浇水量。这个细节设计让他在梅雨季少损失了200多株苗。现在这套系统已经复制到他的三个大棚,每天节省人工巡查时间至少两小时。