
1. 项目概述这个基于STM32的智能空气加湿器项目是我去年为一个智能家居客户开发的完整解决方案。相比市面上大多数只能简单开关的加湿器这个设计实现了真正的智能化控制——不仅能自动调节湿度还能远程监控最关键的是解决了传统加湿器容易干烧的安全隐患。在实际开发过程中我发现很多现成的加湿器方案要么功能单一要么稳定性差。这个项目通过STM32F103RCT6主控配合多个传感器模块实现了从环境监测到智能控制的完整闭环。特别值得一提的是水位检测功能这个看似简单的设计在实际应用中能避免90%以上的加湿器故障。2. 硬件系统设计2.1 核心控制器选型选择STM32F103RCT6作为主控主要基于三点考虑丰富的外设接口需要同时处理I2C(温湿度传感器)、SPI(OLED)、ADC(水位检测)、GPIO(按键和继电器)等多种接口实时性要求需要快速响应传感器数据变化及时控制加湿器状态成本控制相比更高端的STM32系列这款芯片在满足需求的同时更具性价比注意实际开发中发现STM32F103的ADC参考电压需要特别处理建议在VDDA和VSSA引脚加上0.1μF滤波电容否则水位检测会出现波动。2.2 传感器模块配置温湿度检测使用SHT30传感器相比常见的DHT22有以下优势精度更高(±2%RH vs ±5%RH)响应速度更快(8秒 vs 15秒)I2C接口节省GPIO资源水位检测采用模拟量输出的传感器通过STM32的ADC1通道5采集。实际测试中发现需要做以下处理// 均值滤波算法示例 #define SAMPLE_TIMES 10 uint16_t GetWaterLevel(void) { uint32_t sum 0; for(int i0; iSAMPLE_TIMES; i){ sum ADC_GetValue(ADC_CHANNEL_5); HAL_Delay(5); } return sum/SAMPLE_TIMES; }2.3 通信模块实现WiFi通信选用ESP8266模块通过AT指令与STM32交互。在连接华为云IoT平台时需要注意MQTT心跳包需要每90秒发送一次订阅/发布主题需要严格按照华为云格式$oc/devices/{device_id}/sys/messages/down $oc/devices/{device_id}/sys/properties/report数据格式采用JSON示例{ services: [{ service_id: Humidifier, properties: { temperature: 25.6, humidity: 45.2, water_level: 80, power_status: 1 } }] }3. 软件架构设计3.1 主程序流程系统采用前后台架构主循环处理逻辑如下传感器数据采集(每2秒一次)状态检测(水位、按键)逻辑判断(自动/手动模式)设备控制(继电器、蜂鸣器)数据显示更新云端通信(每10秒一次)实测发现这种设计在STM32F103上运行稳定CPU占用率约65%3.2 关键状态机实现加湿器工作模式切换是核心功能状态机设计如下typedef enum { MODE_AUTO, MODE_MANUAL } WorkMode; typedef enum { STATE_OFF, STATE_ON, STATE_ALARM } DeviceState; void Humidifier_StateMachine(void) { static WorkMode mode MODE_AUTO; static DeviceState state STATE_OFF; // 模式切换处理 if(Key2_Pressed()) { mode (mode MODE_AUTO) ? MODE_MANUAL : MODE_AUTO; OLED_ShowMode(mode); } // 状态转移逻辑 switch(state) { case STATE_OFF: if(mode MODE_AUTO humidity threshold) { state STATE_ON; Relay_On(); } else if(Key3_Pressed()) { state STATE_ON; Relay_On(); } break; case STATE_ON: if(water_level 20) { state STATE_ALARM; Relay_Off(); Buzzer_On(); } else if(mode MODE_AUTO humidity threshold) { state STATE_OFF; Relay_Off(); } else if(Key3_Pressed()) { state STATE_OFF; Relay_Off(); } break; case STATE_ALARM: if(water_level 50) { state STATE_OFF; Buzzer_Off(); } break; } }3.3 OLED显示优化0.96寸OLED显示内容需要精心设计第一页温湿度实时数据Temp: 25.6°C Humi: 45.2%RH Mode: Auto第二页设备状态信息Water: 80% Power: ON Threshold: 50%第三页网络连接状态WiFi: Connected MQTT: Active IP: 192.168.1.100通过按键1实现页面切换使用u8g2图形库驱动注意需要开启双缓冲避免闪烁u8g2_Setup_ssd1306_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8x8_gpio_and_delay_stm32); u8g2_InitDisplay(u8g2); u8g2_SetPowerSave(u8g2, 0); u8g2_ClearBuffer(u8g2);4. 云端对接实现4.1 华为云IoT平台配置创建产品定义以下服务属性temperature (float)humidity (float)water_level (int)power_status (bool)设置命令POWER_ONPOWER_OFFSET_THRESHOLD配置数据转发规则将设备数据存储到华为云表格存储服务4.2 MQTT通信实现ESP8266连接华为云的核心AT指令序列ATCWMODE1 ATCWJAPSSID,password ATMQTTUSERCFG0,1,NULL,设备ID,设备密钥 ATMQTTCONN0,华为云地址,1883,1 ATMQTTSUB0,订阅主题,1消息发布示例ATMQTTPUB0,发布主题,{\services\:[{\service_id\:\Humidifier\,\properties\:{\temperature\:25.6}}]},0,04.3 手机APP开发要点Android端使用MQTT Android库实现控制功能关键代码// 初始化MQTT客户端 MqttAndroidClient client new MqttAndroidClient(context, ssl://华为云地址:8883, clientId_ System.currentTimeMillis()); // 连接选项 MqttConnectOptions options new MqttConnectOptions(); options.setUserName(设备ID); options.setPassword(设备密钥.toCharArray()); options.setAutomaticReconnect(true); options.setCleanSession(false); // 订阅主题 client.subscribe($oc/devices/{device_id}/sys/messages/down, 1, (topic, message) - { String payload new String(message.getPayload()); // 处理下发命令 }); // 发布控制命令 public void sendCommand(String cmd) { String topic $oc/devices/{device_id}/sys/commands/request_idUUID.randomUUID(); String payload {\command_name\:\cmd\,\paras\:{}}; client.publish(topic, payload.getBytes(), 1, false); }5. 常见问题与解决方案5.1 水位检测不稳定现象ADC采集值波动大导致误报警解决方案硬件上在传感器输出端加104电容滤波软件采用滑动平均滤波算法设置合理的阈值回差如低于20%报警高于50%恢复5.2 WiFi频繁断开现象ESP8266每隔几分钟就断开重连排查步骤检查电源稳定性建议单独3.3V供电调整AT指令发送间隔最少200ms添加看门狗机制自动恢复连接// WiFi看门狗实现 void WiFi_Watchdog(void) { static uint32_t lastACK 0; if(HAL_GetTick() - lastACK 10000) { // 10秒无响应 ESP8266_Reset(); lastACK HAL_GetTick(); } } void ESP8266_Callback(char* response) { lastACK HAL_GetTick(); // 收到任何响应都刷新计时 }5.3 OLED显示残影现象切换页面时出现上一页内容残留解决方法切换页面时先执行全屏清空使用u8g2的整页刷新模式降低SPI时钟频率实测8MHz最稳定5.4 云端命令延迟现象手机APP下发命令后设备响应慢优化方案缩短MQTT心跳间隔从默认120秒改为60秒使用QoS1保证消息可达性在设备端添加命令缓存队列#define CMD_QUEUE_SIZE 5 typedef struct { char cmd[20]; uint32_t timestamp; } MQTT_Command; MQTT_Command cmdQueue[CMD_QUEUE_SIZE]; uint8_t cmdIndex 0; void MQTT_PushCommand(const char* cmd) { strncpy(cmdQueue[cmdIndex].cmd, cmd, 19); cmdQueue[cmdIndex].timestamp HAL_GetTick(); cmdIndex (cmdIndex 1) % CMD_QUEUE_SIZE; } void Process_Commands(void) { for(int i0; iCMD_QUEUE_SIZE; i) { if(cmdQueue[i].timestamp ! 0) { ExecuteCommand(cmdQueue[i].cmd); cmdQueue[i].timestamp 0; } } }6. 项目优化建议经过三个月的实际运行测试我总结了以下优化方向低功耗优化在非加湿时段切换STM32到Stop模式使用ESP8266的深度睡眠功能需硬件修改动态调整传感器采样频率多设备联动通过华为云规则引擎实现与空调联动当温度28°C且湿度40%时同时开启加湿器和空调固件OTA升级利用华为云的固件升级服务添加Bootloader支持分段更新本地日志存储添加SPI Flash存储历史数据异常事件本地记录网络恢复后同步这个项目最让我满意的部分是水位检测与自动保护的实现在实际使用中成功避免了多次干烧事故。有个客户反馈说这个功能让他们的设备维护成本降低了70%。