1. 项目概述
这个基于STM32单片机的智能自动浇花系统是我去年帮朋友做的一个小项目,当时他经常出差,家里的绿植总是因为忘记浇水而枯萎。整套系统成本不到100元,但实现了温湿度监测、阈值设置和自动灌溉功能,特别适合家庭和小型温室使用。
系统核心采用STM32F103C8T6作为主控,搭配DHT11温湿度传感器实时监测环境数据,通过LCD1602显示屏展示当前状态。当检测到土壤湿度低于设定阈值时,继电器会自动启动水泵进行灌溉。三个按键分别用于进入设置模式、增加阈值和减少阈值,每次操作都有蜂鸣器提示音反馈。
2. 硬件设计与选型
2.1 核心控制器选择
我选择STM32F103C8T6这款Cortex-M3内核单片机主要基于以下几点考虑:
- 72MHz主频完全满足实时性要求
- 64KB Flash和20KB SRAM足够存储程序和数据
- 丰富的GPIO和外设接口(3个USART、2个SPI、2个I2C)
- 价格仅10元左右,性价比极高
实际使用中发现,这款MCU的ADC精度一般,但对于DHT11这种数字传感器完全够用。如果要用模拟湿度传感器,建议选择STM32F303系列。
2.2 传感器模块
DHT11温湿度传感器虽然精度一般(湿度±5%RH,温度±2℃),但胜在价格便宜(约5元)、接口简单。它采用单总线协议,只需要一个GPIO引脚即可通信。
接线注意事项:
- VCC接3.3V-5V
- DATA引脚需要接4.7K上拉电阻
- 通信距离建议不超过20米
2.3 显示与交互设计
LCD1602是最常见的字符型液晶,价格约8元。我采用4位数据线接法节省GPIO资源:
- RS -> PB12
- RW -> GND
- EN -> PB13
- D4-D7 -> PB14-PB15
三个按键分别接PB0-PB2,采用外部中断方式检测,避免轮询消耗CPU资源。蜂鸣器接PB8,用于操作反馈。
3. 软件架构设计
3.1 主程序流程
系统采用前后台架构,主循环负责数据采集和显示,中断处理用户输入:
c复制int main(void){
// 初始化各外设
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
KEY_IO_Init();
Relay_IO_Init();
EXTIx_Init();
LCD_init();
DHT11_Init();
while(1){
// 读取温湿度
if(DHT11_ReadData()){
temp_dat = DHT11_GetTem()/256;
hum_dat = DHT11_GetHum()/256;
}
// 更新显示
sprintf(lcd_dat1,"T:%d C H:%d \n",temp_dat,hum_dat);
LCD_prints(0,0,lcd_dat1);
// 控制逻辑
if(hum_dat < set_hum_dat) Relay1=1;
else Relay1=0;
}
}
3.2 关键功能实现
3.2.1 DHT11驱动
DHT11的通信时序要求严格,必须按照以下步骤操作:
- MCU拉低DATA线至少18ms
- 拉高20-40us等待DHT11响应
- DHT11拉低80us后拉高80us
- 开始传输40位数据(湿度整数+小数+温度整数+小数+校验和)
c复制uint8_t DHT11_ReadData(void){
GPIO_ResetBits(DHT11_PORT, DHT11_PIN);
Delay_ms(20); // 拉低至少18ms
GPIO_SetBits(DHT11_PORT, DHT11_PIN);
Delay_us(30); // 主机拉高20-40us
// 等待DHT11响应
if(!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN)){
while(!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN)); // 等待低电平结束
while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN)); // 等待高电平结束
// 读取40位数据
for(i=0;i<5;i++)
for(j=0;j<8;j++){
while(!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN));
Delay_us(40);
if(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
data[i] |= (1<<(7-j));
while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN));
}
// 校验数据
if(data[4] == (data[0]+data[1]+data[2]+data[3]))
return 1;
}
return 0;
}
3.2.2 中断按键处理
三个按键分别对应不同的功能:
- KEY1(PB0):进入/退出设置模式
- KEY2(PB1):阈值+
- KEY3(PB2):阈值-
c复制void EXTI0_IRQHandler(void){ // KEY1
setnum++;
buzzer=1; delay_ms(50); buzzer=0;
if(setnum > 1) setnum=0; // 切换设置模式
EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI1_IRQHandler(void){ // KEY2
buzzer=1; delay_ms(50); buzzer=0;
if(setnum == 1 && set_hum_dat<100)
set_hum_dat++;
EXTI_ClearITPendingBit(EXTI_Line1);
}
4. 系统优化与调试
4.1 防抖处理
实际测试中发现机械按键存在抖动问题,通过以下两种方式解决:
- 硬件:在按键两端并联0.1uF电容
- 软件:在中断服务函数中增加50ms延时
4.2 电源管理
系统采用5V电源供电,但STM32需要3.3V。建议使用AMS1117-3.3稳压芯片,注意:
- 输入输出端都要加10uF电容
- 继电器和水泵电源最好与MCU分开供电
- 在继电器线圈两端反向并联二极管防止反电动势
4.3 灌溉控制策略优化
初始设计是湿度低于阈值立即浇水,这可能导致频繁启停。改进方案:
- 增加迟滞区间(如设定50%时,低于45%开启,高于55%关闭)
- 限制最小灌溉间隔(如至少间隔30分钟)
- 累计缺水时间控制灌溉量
c复制// 改进后的控制逻辑
if(hum_dat < (set_hum_dat-5)) {
if(Relay1==0 && (last_water_time==0 || (now-last_water_time)>1800000)){
Relay1=1;
last_water_time = now;
}
}
else if(hum_dat > (set_hum_dat+5)) {
Relay1=0;
}
5. 常见问题排查
5.1 DHT11读取失败
现象:显示屏显示的温度湿度值异常或不变
排查步骤:
- 检查接线是否正确,特别是上拉电阻
- 用示波器查看DATA线波形
- 调整延时参数(不同批次DHT11时序可能有差异)
- 更换传感器测试
5.2 LCD显示乱码
可能原因:
- 对比度调节不当(调整电位器)
- 初始化时序不正确
- 数据线接触不良
- 电源电压不稳(应在4.7-5.3V之间)
5.3 继电器不动作
检查流程:
- 测量继电器线圈两端电压(应≈5V)
- 检查三极管或驱动IC是否正常工作
- 确认MCU引脚输出电平正确
- 检查续流二极管方向是否正确
6. 项目扩展方向
这个基础系统还可以进一步扩展:
- 增加WiFi模块(ESP8266)实现手机远程监控
- 添加土壤PH值传感器实现更精准的养护
- 使用太阳能电池板+锂电池实现离网供电
- 加入光照传感器自动调节补光灯
- 扩展多路继电器控制不同区域的植物
我在后续版本中增加了数据记录功能,使用SPI接口的Flash芯片存储历史数据,可以通过上位机软件查看温湿度变化曲线。这对于研究植物生长环境很有帮助。