1. 系统概述:让盆栽养护变得简单智能

你有没有遇到过这样的情况:出门旅游几天,回家发现心爱的盆栽已经枯萎了?或者工作太忙,总是忘记给植物浇水?我就是这样一个"植物杀手",曾经养死了好几盆多肉植物。直到我决定用自己熟悉的STM32技术来解决这个问题,才有了今天要分享的这个智能盆栽系统。

这个基于STM32的智能盆栽系统,本质上是一个24小时在线的"植物保姆"。它能够实时监测盆栽的生长环境,包括土壤湿度、环境温度、光照强度等关键参数,然后根据你设定的条件自动进行浇水、补光和温度调节。最棒的是,你可以在手机上随时查看盆栽的状态,就算出差在外也能远程照顾你的绿植朋友。

系统采用了STM32F103C8T6作为主控芯片,这款芯片性价比很高,处理能力足够强大,外设资源丰富,非常适合这种需要连接多个传感器和执行器的应用场景。整个系统包含了土壤湿度传感器、温湿度传感器、光敏电阻、OLED显示屏、WiFi模块、继电器控制的水泵和风扇等组件,构成了一个完整的环境监测和控制系统。

2. 硬件设计:选择合适的"感官"和"手脚"

2.1 核心控制器选型与配置

选择STM32F103C8T6作为主控芯片是我经过多次对比后的决定。这款芯片基于ARM Cortex-M3内核,主频可以达到72MHz,完全能够满足我们实时数据采集和处理的需求。它内置了12位ADC,可以很好地处理传感器传来的模拟信号,还有多个定时器,方便我们生成PWM信号来控制水泵和补光灯。

在实际焊接电路时,我建议先准备好最小系统板,包括8MHz晶振、复位电路和稳压电路。电源部分特别重要,因为有些传感器对电压波动很敏感。我使用了AMS1117-3.3V稳压芯片,确保系统稳定工作在3.3V电压下。记得在电源入口处加上滤波电容,我在VCC和GND之间加了100μF的电解电容和0.1μF的瓷片电容,效果很不错。

2.2 传感器模块的选择与连接

土壤湿度传感器我选择了电阻式的,价格便宜且效果不错。不过需要注意,这种传感器长期埋在土里容易氧化,所以我一般在传感器探头上涂一层清漆来保护。接线时,将传感器的模拟输出引脚连接到STM32的PA0引脚(ADC1的通道0),这样可以通过ADC读取土壤湿度值。

温湿度传感器我用了DHT11,虽然精度不是最高的,但对于盆栽监测来说完全够用。DHT11使用单总线协议,只需要一根数据线连接到STM32的PA1引脚。记得在数据线上加一个4.7kΩ的上拉电阻,否则读取数据时可能会不稳定。

光敏电阻我选择了一个模拟输出的模块,这样可以通过ADC读取具体的光照强度值,而不是简单的开关量。将输出引脚接到STM32的PA2引脚,然后在程序中通过ADC读取电压值,再根据分压电路计算出实际的光照强度。

2.3 执行器模块的设计与驱动

水泵控制是我踩过坑的地方。最初我直接用STM32的GP口驱动水泵,结果发现电流根本不够。后来改用继电器控制,选择了SRD-05VDC-SL-C这个型号,线圈电压5V,可以用STM32直接驱动。继电器的控制引脚通过一个2N3904三极管来驱动,基极串联1kΩ电阻连接到STM32的PA3引脚。

补光灯控制用了PWM调光,这样可以根据光照强度自动调节亮度。我将补光灯的控制引脚连接到STM32的PA6引脚,这个引脚支持TIM3的通道1输出PWM信号。通过调节占空比,可以实现从完全关闭到最大亮度的无级调节。

风扇控制相对简单,我也是通过继电器来控制。将控制引脚连接到STM32的PA4引脚,同样使用三极管驱动继电器。当温度超过设定阈值时,STM32会输出高电平,开启风扇降温。

2.4 通信模块的集成与配置

WiFi模块我选择了ESP8266-01S,这个小模块性价比很高,支持AT指令控制。将ESP8266的TX引脚连接到STM32的PA10(USART1的RX),RX引脚连接到PA9(USART1的TX)。供电方面,ESP8266需要3.3V电压,但峰值电流可能达到200mA,所以最好单独用一路LDO供电,不要和主芯片共用。

OLED显示屏我用了0.96寸的I2C接口屏幕,只需要四根线:VCC、GND、SCL、SDA。将SCL连接到STM32的PB6,SDA连接到PB7,这两个引脚支持I2C1。OLED屏用来显示实时的传感器数据和系统状态,非常实用。

3. 软件设计:让系统"聪明"起来

3.1 系统初始化与主循环设计

系统上电后,首先进行一系列的初始化操作。我在main函数中按照这样的顺序初始化:先初始化系统时钟和GPIO,然后初始化ADC用于读取传感器数据,接着初始化I2C用于OLED显示,最后初始化USART用于和ESP8266通信。

初始化完成后,系统进入主循环。在主循环中,我设置了几个主要的任务:读取传感器数据、更新OLED显示、检查阈值并控制执行器、处理网络通信。每个任务都有独立的时间戳,避免某个任务占用太多时间影响系统实时性。

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    
    OLED_Init();
    ESP8266_Init();
    
    while (1)
    {
        Read_Sensors();
        Update_Display();
        Check_Threshold();
        Handle_Network();
        HAL_Delay(1000);
    }
}

3.2 传感器数据采集与处理

读取传感器数据时需要注意抗干扰处理。我采用了多次采样取平均值的办法,比如读取土壤湿度时,连续采样10次然后去掉最大最小值,取中间8次的平均值。这样可以有效消除偶然的干扰。

对于DHT11温湿度传感器,读取时需要严格按照时序要求。我写了一个专门的读取函数,先发送开始信号,然后等待传感器响应,最后读取40位数据。记得要检查校验和,确保数据正确性。

光照强度的计算需要一些校准。我先用手机的光照度测量APP作为参考,记录不同光照条件下光敏电阻的输出电压,然后建立电压和照度的对应关系。在实际程序中,我用查表法加线性插值来计算实际的光照强度。

3.3 自动控制逻辑的实现

自动控制逻辑是整个系统最核心的部分。我设置了上下限阈值来判断是否需要执行相应的操作。比如当土壤湿度低于下限阈值时启动水泵浇水,当温度高于上限阈值时开启风扇降温。

为了避免执行器频繁启停,我加入了迟滞控制。比如土壤湿度的下限阈值是30%,但我会在湿度达到35%时才停止浇水,这样避免在临界点附近反复开关水泵。

void Check_Threshold(void)
{
    // 土壤湿度控制
    if (soil_moisture < moisture_low_threshold && !is_watering) {
        Start_Watering();
    } else if (soil_moisture > moisture_high_threshold && is_watering) {
        Stop_Watering();
    }
    
    // 温度控制
    if (temperature > temp_high_threshold && !is_cooling) {
        Start_Cooling();
    } else if (temperature < temp_low_threshold && is_cooling) {
        Stop_Cooling();
    }
    
    // 光照控制
    if (light_intensity < light_low_threshold && !is_lighting) {
        Start_Lighting();
    } else if (light_intensity > light_high_threshold && is_lighting) {
        Stop_Lighting();
    }
}

3.4 网络通信与云端交互

ESP8266模块通过AT指令与STM32通信。我先发送"AT"指令测试模块是否正常,然后设置WiFi模式为STA模式,连接指定的WiFi热点。连接成功后,配置模块为单连接模式,准备与云平台通信。

我选择了OneNet作为云平台,因为它对个人开发者很友好,免费额度也足够用。通过MQTT协议将传感器数据上传到平台,数据格式采用JSON包装,包含时间戳和各项传感器读数。

void Send_To_Cloud(void)
{
    char json_data[128];
    sprintf(json_data, "{\"temp\":%.1f,\"humi\":%.1f,\"soil\":%d,\"light\":%d}",
            temperature, humidity, soil_moisture, light_intensity);
    
    ESP8266_Send_Cmd("AT+CIPSEND=0,%d", strlen(json_data));
    ESP8266_Send_Data(json_data);
}

云端数据接收也很重要。我设置了MQTT订阅功能,当手机APP发送控制指令时,云平台会通过MQTT消息下发给设备。STM32收到消息后解析JSON数据,执行相应的操作,比如切换工作模式或修改阈值参数。

4. 手机APP与数据可视化

4.1 实时数据监控界面设计

手机APP我用了MIT App Inventor来开发,这个工具对初学者很友好,不需要深厚的编程基础就能做出可用的APP。主界面显示四个关键的传感器数据:温度、湿度、土壤湿度和光照强度,每个数据都用数字和进度条两种方式显示,非常直观。

数据刷新频率设置为每5秒一次,这个频率既不会给设备带来太大负担,又能保证数据的实时性。在网络状况不好时,APP会自动降低刷新频率,避免因重试机制导致的数据延迟。

我还添加了数据异常提醒功能,当某个传感器数据超过合理范围时,对应的数据显示会变成红色闪烁,同时手机振动提醒。这样即使你不盯着APP看,也能及时发现问题。

4.2 历史数据图表展示

历史数据用折线图来展示,可以选择查看过去1小时、6小时、24小时或7天的数据趋势。图表用了ZoomCharts库,支持手势缩放和滑动,查看细节很方便。

每个传感器数据都可以单独显示或隐藏,方便分析不同参数之间的关联性。比如你可以同时查看温度和土壤湿度的变化,分析温度对水分蒸发的影响。

数据存储方面,我用了SQLite数据库本地存储最近7天的数据,更早的数据会上传到云端归档。这样既保证了APP的响应速度,又不会丢失历史数据。

4.3 远程控制功能实现

远程控制功能包括模式切换和手动控制。模式切换可以在自动和手动之间选择,在自动模式下,系统根据预设的阈值自动控制执行器;在手动模式下,用户可以通过APP直接控制水泵、风扇和补光灯。

手动控制界面做了防止误操作的设计,比如点击水泵开关后,需要再次确认才会真正执行操作。同时还有安全定时功能,比如手动开启水泵后,如果5分钟内没有自动关闭,系统会强制关闭并发送提醒。

阈值设置界面提供了直观的滑块调节,拖动滑块时可以看到实时的阈值数值。设置完成后需要点击保存按钮,新的阈值会立即生效并保存到设备的EEPROM中,即使断电也不会丢失。

5. 系统优化与实用技巧

5.1 功耗优化策略

虽然这个系统主要是有线供电,但功耗优化仍然很重要,特别是在使用电池作为备用电源的情况下。我采取了多种措施来降低功耗:首先是在软件中加入空闲时休眠的功能,当没有操作时,STM32进入低功耗模式,只有中断才能唤醒。

传感器读数也做了优化,不是所有传感器都需要高频度读取。比如温度变化比较缓慢,我可以每10秒读一次;而土壤湿度变化更慢,每分钟读一次就足够了。这样大大减少了不必要的功耗。

ESP8266模块的功耗相当可观,所以我只在需要传输数据时才开启WiFi连接,数据传输完成后立即断开。平均下来,WiFi模块的功耗降低了70%左右。

5.2 网络稳定性提升

无线网络连接最怕的就是不稳定,我用了多种机制来保证连接可靠性。首先是心跳包机制,设备每分钟向云平台发送一个心跳包,如果连续3次没有收到响应,就判断为网络断开,自动尝试重连。

重连逻辑也做了优化,不是简单立即重连,而是采用指数退避算法:第一次断开后等待1秒重连,如果又断开则等待2秒,然后是4秒、8秒,直到最大等待时间32秒。这样避免在网络状况不好时频繁重连造成额外负担。

数据上传也加入了重试机制,如果上传失败,数据会暂时保存在本地的环形缓冲区中,等待网络恢复后重新上传。缓冲区大小设置为100条数据,足够存储24小时的数据量。

5.3 传感器校准与维护

传感器校准是保证数据准确的关键。我建议每个月进行一次传感器校准,方法很简单:土壤湿度传感器校准需要准备完全干燥的土壤和水分饱和的土壤,分别记录读数作为0%和100%的参考点。

温度传感器校准可以用一个准确的水银温度计作为参考,在不同温度环境下对比读数。光照传感器校准稍微麻烦些,需要用到专业的光照度计,或者用手机上的光照度测量APP作为参考(虽然精度不高,但对于盆栽应用足够了)。

传感器维护也很重要,特别是土壤湿度传感器,长期埋在土里容易氧化。我建议每三个月取出清洁一次,用细砂纸轻轻打磨探头表面,然后涂上新的保护漆。

5.4 成本控制与替代方案

整个系统的成本我控制在100元以内,大部分元件都能在淘宝上买到。如果想进一步降低成本,有几个替代方案:可以用DS18B20代替DHT11来测温度,虽然少了湿度测量,但温度精度更高且价格更便宜。

OLED显示屏也可以省略,完全通过手机APP来查看数据,这样能节省20元左右。水泵可以选择更小流量的型号,因为盆栽浇水不需要很大流量,小流量水泵价格更便宜且更省电。

PCB设计方面,如果量大的话可以考虑打样PCB,但如果只是自己做一两个,用洞洞板焊接就足够了。我就是在洞洞板上完成的原型,虽然不如PCB美观,但完全不影响功能。

更多推荐