当前位置: 首页 > news >正文

基于STM32的湿度检测开关传感器设计

一、系统总体设计

1.1 系统架构

当环境湿度超过(或低于)我们设定的安全阈值时,它会像管家一样,自动拉下电闸(开启排风扇或除湿器)。

┌──────────────────────────────────────────────────────────────┐
│                    湿度检测开关系统架构                        │
├──────────────────────────────────────────────────────────────┤
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐  │
│  │  湿度传感器   │    │   STM32F103  │    │   执行机构   │  │
│  │ (DHT11/SHT30)│───▶│   主控芯片   │───▶│ (继电器/风扇) │  │
│  │ 采集环境湿度  │    │  逻辑决策中枢 │    │   执行开关动作 │  │
│  └──────────────┘    └──────┬───────┘    └──────┬───────┘  │
│                         │                    │               │
│  ┌──────────────┐    │    ┌──────────┐   │  ┌──────────┐  │
│  │   OLED显示   │◀───┘    │ 按键设定 │◀──┘  │ 蜂鸣报警 │  │
│  │ (实时数值)   │         │ (调阈值) │      │ (超限提示)│  │
│  └──────────────┘         └──────────┘      └──────────┘  │
└──────────────────────────────────────────────────────────────┘

1.2 核心指标

参数 规格 说明
湿度检测范围 20% RH ~ 90% RH 满足绝大多数室内环境
检测精度 ±5% RH (DHT11) / ±2% RH (SHT30) 精度决定控制细腻度
开关响应时间 < 200ms 发现超标立即动作
开关负载能力 AC 250V / 10A (通过继电器) 可直接驱动家用排风扇
设定方式 按键设定 / 出厂预设 灵活应对不同场景

二、核心硬件设计

2.1 核心元件选型对比

在湿度检测开关中,传感器的选型决定了系统的档次。

型号 接口方式 湿度精度 价格成本 推荐应用场景
DHT11 单总线 (1-Wire) ±5% RH 极低 ($1) 入门练手、普通家居
DHT22 (AM2302) 单总线 (1-Wire) ±2% RH 低 ($2) 对精度有一定要求的场景
SHT30 / SHT31 I2C 数字接口 ±2% RH 中等 ($4) 工业级、大棚种植、高端家电
电容式湿敏电阻 模拟电压输出 (ADC) ±3% RH 低 ($1.5) 需要自己搭建运放电路的进阶玩法

设计建议:如果是初次上手,推荐使用 DHT11,因为只需要一根数据线,时序虽然严格但极易理解;如果是做产品原型,SHT30** 是目前的行业标杆,I2C协议极其稳定,且自带温度补偿。

2.2 硬件连接表

我们以经典的 STM32F103C8T6(蓝色药丸板) 搭配 DHT11一路继电器模块 为例。

/* 硬件连接定义 */
// ---------------------------------------------------------
// 1. DHT11 湿度传感器 (单总线模式)
// ---------------------------------------------------------
#define DHT11_PORT        GPIOA
#define DHT11_PIN        GPIO_Pin_0    // PA0 连接 DHT11 DATA引脚
// 注意:DHT11 的 VCC 接 3.3V 或 5V (推荐3.3V与MCU同压),GND 接地
// 建议在 DATA 引脚与 VCC 之间并联一个 4.7kΩ 或 10kΩ 的上拉电阻,保证信号稳定// ---------------------------------------------------------
// 2. 执行机构 - 继电器模块 (控制排风扇/除湿器)
// ---------------------------------------------------------
#define RELAY_PORT        GPIOA
#define RELAY_PIN        GPIO_Pin_1    // PA1 连接 继电器 IN 引脚
// 注意:大多数继电器模块是 低电平触发(给0继电器吸合吸合,给1断开)
// 继电器模块的 VCC 接 5V,GND 接地,COM/NO/NC 接你的家用电器// ---------------------------------------------------------
// 3. 人机交互 (按键 + OLED)
// ---------------------------------------------------------
#define KEY_SET_PIN      GPIO_Pin_2    // PA2 设定键 (增减湿度阈值)
#define OLED_SDA_PIN    GPIO_Pin_7    // PB7 (I2C1_SDA)
#define OLED_SCL_PIN    GPIO_Pin_6    // PB6 (I2C1_SCL)// ---------------------------------------------------------
// 4. 报警装置 (蜂鸣器)
// ---------------------------------------------------------
#define BEEP_PIN        GPIO_Pin_3    // PA3 蜂鸣器 (达到阈值时滴滴响)

三、软件系统设计

3.1 基础数据结构

/* 湿度开关数据结构 */
#include "stm32f10x.h"
#include <stdio.h>// 系统开关的工作模式
typedef enum {MODE_AUTO = 0,      // 自动模式(超过阈值自动开启继电器)MODE_MANUAL = 1,    // 手动模式(强制开启/关闭)MODE_SETTING = 2     // 设定模式(正在调节湿度阈值)
} WorkMode;// 全局核心变量
WorkMode sys_mode = MODE_AUTO;float current_humidity = 0.0f;    // 当前检测到的湿度 (百分比)
float current_temp = 0.0f;       // 当前温度 (摄氏度)
float humi_threshold = 70.0f;     // 湿度开关阈值 (默认70%,超过则开启)uint8_t relay_status = 0;          // 继电器状态:0关,1开
uint32_t system_tick = 0;         // 系统滴答节拍

3.2 DHT11 单总线驱动(核心难点)

DHT11不需要复杂的I2C协议,它走的是自定义的“单总线时序”。读数的关键在于微秒级的延时控制和严密的高低电平判断

/* DHT11 驱动程序 */// 配置PA0为输出模式
void DHT11_IO_OUT(void) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DHT11_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}// 配置PA0为输入模式
void DHT11_IO_IN(void) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DHT11_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}// 微妙延时 (针对72MHz主频的粗略校准)
void DHT11_DelayUs(uint16_t us) {uint32_t temp = us * 8; // 经验系数,不同编译器需微调while(temp--);
}// 发送起始信号并读取一次数据
// 返回值:0成功,1失败
uint8_t DHT11_Read_Data(float *temperature, float *humidity) {uint8_t buf[5] = {0};uint8_t i, j;// 1. 主机发送起始信号(拉低至少18ms)DHT11_IO_OUT();GPIO_ResetBits(DHT11_PORT, DHT11_PIN);DHT11_DelayUs(20000); // 拉低20ms// 2. 主机释放总线,等待DHT11响应GPIO_SetBits(DHT11_PORT, DHT11_PIN);DHT11_DelayUs(30);DHT11_IO_IN();// 3. 检测DHT11的响应信号(拉低约80us,再拉高80us)if(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 0) {while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 0); // 等待低电平过去while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 1); // 等待高电平过去// 4. 正式接收40位数据 (8位湿度整数 + 8位湿度小数 + 8位温度整数 + 8位温度小数 + 8位校验和)for(i = 0; i < 5; i++) {for(j = 0; j < 8; j++) {while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 0); // 等待50us的低电平起始位过去DHT11_DelayUs(40); // 延时40us,如果是高电平,说明数据位是1;如果是低电平,说明是0if(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 1) {buf[i] |= (1 << (7-j));}while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 1); // 等待剩余的高电平过去}}// 5. 校验数据正确性if(buf[0] + buf[1] + buf[2] + buf[3] == buf[4]) {*humidity = (float)buf[0];*temperature = (float)buf[2];return 0; // 成功}}return 1; // 读取失败
}

3.3 执行器与逻辑控制

/* 继电器与开关逻辑 */// 初始化继电器和蜂鸣器引脚
void Actuator_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = RELAY_PIN | BEEP_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA, RELAY_PIN); // 默认关闭继电器GPIO_SetBits(GPIOA, BEEP_PIN);  // 默认关闭蜂鸣器
}// 核心开关决策逻辑:这就是湿度开关的大脑!
void Humidity_Switch_Logic(void) {switch(sys_mode) {case MODE_AUTO:// 核心逻辑:如果湿度 > 设定阈值,开启排风;否则关闭if(current_humidity > humi_threshold) {if(relay_status == 0) {relay_status = 1;GPIO_ResetBits(RELAY_PORT, RELAY_PIN); // 吸合继电器GPIO_ResetBits(GPIOA, BEEP_PIN);       // 滴滴两声报警DHT11_DelayUs(100000);GPIO_SetBits(GPIOA, BEEP_PIN);DHT11_DelayUs(100000);GPIO_ResetBits(GPIOA, BEEP_PIN);DHT11_DelayUs(100000);GPIO_SetBits(GPIOA, BEEP_PIN);printf("[Switch] 湿度超标! 开启排风扇...\n");}} else {if(relay_status == 1) {relay_status = 0;GPIO_SetBits(RELAY_PORT, RELAY_PIN); // 断开继电器printf("[Switch] 湿度恢复正常,关闭排风扇。\n");}}break;case MODE_MANUAL:// 不做任何自动判断,完全由人为按键控制继电器的开和关break;}
}// 按键扫描:调整湿度阈值(例如每次按键增加/减少5%)
void Key_Scan_Setting(void) {static uint8_t key_lock = 0; // 按键自锁,防止长按连续触发if(GPIO_ReadInputDataBit(GPIOA, KEY_SET_PIN) == 0) {if(key_lock == 0) {key_lock = 1;humi_threshold += 5.0f;if(humi_threshold > 95.0f) humi_threshold = 30.0f; // 循环调整printf("[Setting] 湿度阈值调整为: %.0f%% \n", humi_threshold);}} else {key_lock = 0;}
}

四、主程序与系统集成

4.1 完整主程序

/* 湿度检测开关主程序 */
#include "stm32f10x.h"
#include "system_stm32f10x.h"// 模拟系统滴答时钟
void SysTick_Init(void) {SysTick_Config(SystemCoreClock / 1000); // 1ms触发一次
}void SysTick_Handler(void) {system_tick++;
}// 毫秒延时函数
void delay_ms(uint32_t ms) {uint32_t start = system_tick;while((system_tick - start) < ms);
}int main(void) {// 1. 底层初始化SystemInit();SysTick_Init();USART1_Init(115200); // 初始化串口用于电脑监控Actuator_Init();    // 初始化继电器和蜂鸣器OLED_Init();         // 初始化显示屏(此处省略具体初始化代码)printf("\r\n==== 湿度检测开关系统启动 ====\r\n");printf("默认阈值: %.0f%% \r\n", humi_threshold);uint32_t last_dht_read_time = 0;// 2. 系统主循环while(1) {// --- 任务1:每隔2秒读取一次湿度传感器(DHT11读取不能太频繁)---if(system_tick - last_dht_read_time >= 2000) {if(DHT11_Read_Data(&current_temp, &current_humidity) == 0) {printf("[Sensor] 温度: %.1f°C, 湿度: %.1f%% \n", current_temp, current_humidity);// 在OLED屏幕上显示数值char disp_buff[30];sprintf(disp_buff, "Humidity: %.1f %% ", current_humidity);OLED_ShowString(0, 0, disp_buff);sprintf(disp_buff, "Threshld: %.0f %% ", humi_threshold);OLED_ShowString(0, 2, disp_buff);} else {OLED_ShowString(0, 0, "Sensor Error!");printf("[Error] DHT11 Read Failed!\n");}last_dht_read_time = system_tick;}// --- 任务2:扫描按键,调整阈值 ---Key_Scan_Setting();// --- 任务3:执行核心开关逻辑 ---Humidity_Switch_Logic();// 主循环延时,降低CPU空转发热delay_ms(10);}
}

参考代码 湿敏传感器(设计方案+原理图+程序+芯片资料) www.youwenfan.com/contentcnt/124170.html

五、应用场景与总结

核心应用场景:

  1. 浴室/卫生间:安装在吊顶里,当洗澡导致湿度飙升超过80%时,自动开启排气扇,洗完澡自动关停,防止发霉。
  2. 地下室/储藏室:梅雨季节自动开启工业除湿机,保护存放的字画或器材。
  3. 农业大棚:土壤湿度或者空气湿度超标时,自动开启排风机或喷淋系统。
  4. 智能家居联动:作为一个独立的WiFi/蓝牙边缘节点,上报湿度数据给手机App。

总结:

这个基于STM32的湿度检测开关系统,抓住了“感知(DHT11/SHT30)+ 决策(STM32的逻辑判断)+ 执行(继电器强电控制) 这一物联网设备的本质骨架。

http://www.jsqmd.com/news/705135/

相关文章:

  • 基于CAP-X集成Allegro灵巧手与ReKep关键点约束的机器人操作项目
  • MCP 2026证书链校验绕过漏洞(CVE-2026-0947):如何用3行OpenSSL命令快速定位受影响节点?
  • 别再为Unity WebGL播放本地视频发愁了!VideoPlayer + StreamingAssets保姆级避坑指南
  • 035、嵌入式与边缘场景:轻量化Agent的挑战与设计
  • Phi-3.5-mini-instruct效果展示:同一问题在不同top_p值下的回答多样性对比
  • 2026执助考试用书红黑榜,看完再买不踩坑! - 品牌测评鉴赏家
  • 工业部署实战:用YOLOv6-S在T4 GPU上跑出869 FPS的保姆级量化教程
  • MCP 2026动态权限分配失效事故复盘(某央企数据泄露溯源报告·内部首曝)
  • .NET Preview 架构演进、技术深度解析
  • Windows Cleaner深度指南:彻底解决C盘爆红和系统卡顿的终极方案
  • 惊艳翻译效果:Hunyuan-MT-7B在WMT25比赛中30语种第一的实战展示
  • 揭秘Fairseq-Dense-13B-Janeway:其训练数据与创意能力的来源分析
  • VS Code MCP插件安全审计清单(含OWASP VS Code Top 10风险项+自动化检测脚本)
  • 电-气-热综合能源系统优化调度模型详解
  • AI驱动的错误监控代理:从告警到自愈的智能运维实践
  • 脂蛋白(a)升高相关疾病核心靶点的多组学筛选、活性成分匹配与机制验证的全链条研究
  • BililiveRecorder:基于.NET的模块化直播录制架构深度解析
  • LangGraph智能体聊天界面开发:Agent Chat UI部署与定制指南
  • 电池销售系统|基于java + vue电池销售系统(源码+数据库+文档)
  • 商业分析 AI Agent Harness Engineering:市场调研、数据可视化与决策支持
  • 深入解析 OpenJDK 17 在 Linux 上的线程创建机制
  • 用STM32的TIM3编码器模式给JGB37-520电机测速,我踩过的那些坑
  • MCP 2026推理优化黄金窗口期仅剩90天!:2026 Q1前必须掌握的4类MoE稀疏激活调度技术与3种内存带宽规避模式
  • Qwen3-VL-WEBUI真实案例分享:用AI自动生成网页代码和流程图
  • ComfyUI-Florence2终极指南:15种视觉任务的完整解决方案
  • 华硕笔记本性能控制终极指南:3步快速上手GHelper轻量级工具
  • 模拟IC设计避坑:用Cadence Virtuoso仿真五管OTA时,我的gm/id参数为啥对不上?
  • 面试必备,查漏补缺;多线程 +spring+JVM 调优 + 分布式 +redis+ 算法
  • 别再只用单一邻接矩阵了!用MAGCN(多视图图注意力网络)搞定节点分类,实测抗干扰能力提升明显
  • 科学探究实验