零知IDE——基于STM32F407VET6的HC-SR505安防监控系统
✔零知IDE 是一个真正属于国人自己的开源软件平台,在开发效率上超越了Arduino平台并且更加容易上手,大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码,让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品,测试产品。快来动手试试吧!
✔访问零知实验室,获取更多实战项目和教程资源吧!
www.lingzhilab.com
目录
一、硬件接线部分
1.1 硬件清单
1.2 接线方案
1.3 具体接线图
1.4 连接实物图
二、代码讲解部分
2.1 引脚定义与库引入
2.2 初始化设置
2.3 HC-SR505处理函数
2.4 非阻塞式设计
2.5 系统完整代码
三、项目结果演示
3.1 操作流程
3.2 视频演示
四、HC-SR505热释电传感器工作原理
五、常见问题解答 (FAQ)
Q1: HC-SR505检测距离太近或角度不够?
Q2: HC-SR505一直输出高电平是怎么回事?
Q3: 为什么人静止不动时传感器不触发?
(1)项目概述
本项目基于功能强大的STM32F407VET6微控制器(零知增强板主控芯片)和HC-SR501人体热释电红外传感器,构建了一个多功能、可视化的智能安防监控系统。系统不仅能够检测人体活动并触发声光报警,还能实时监测环境的温湿度和光照强度,通过一块240x240分辨率的彩色TFT显示屏直观地展示所有信息。
(2)项目难点及解决方案
问题描述:多任务处理与实时性,确保同时处理传感器数据读取
(3)项目效果预览
HC-SR505项目效果预览
一、硬件接线部分
1.1 硬件清单
元件名称 | 型号/规格 | 数量 | 备注 |
---|---|---|---|
主控板 | STM32F407VET6核心 | 1 | 零知增强板主控板 |
人体红外传感器 | HC-SR501 | 1 | 核心检测器件 |
温湿度传感器 | DHT11 | 1 | 温湿度监测 |
光敏电阻模块 | 模拟输出 | 1 | 光线监测 |
TFT显示屏 | 1.3英寸 ST7789 | 1 | 240x240分辨率 |
有源蜂鸣器 | BUZZER | 1 | 声音报警 |
LED | 5mm | 1 | 报警指示灯 |
电阻 | 220Ω | 1 | 用于LED限流(如果LED无内置电阻) |
连接线 | Dupont线 | 若干 | 连接到各个模块 |
1.2 接线方案
零知增强板引脚 | 连接的元件与引脚 | 说明 |
---|---|---|
5 | DHT11 DATA | 温湿度数据线 |
6 | HC-SR501 OUT | 人体感应信号输出 |
A0 | 光敏电阻模块 AO | 模拟光线强度信号 |
12 | 蜂鸣器 + / S | 控制蜂鸣器发声 |
13 | LED阳极(长脚) | 报警指示灯(通过220Ω电阻接地) |
53 | TFT TFT_CS | SPI片选 |
8 | TFT TFT_DC | 数据/命令选择 |
9 | TFT TFT_RST | 复位 |
7 | TFT TFT_BL | 背光控制 |
3.3V | TFT VCC | 显示屏电源(注意:很多1.54寸屏是3.3V) |
GND | TFT GND | 显示屏电源地 |
52 | TFT SCK | SPI时钟 |
51 | TFT MOSI | SPI主出从入 |
注意:TFT屏的通信连接到硬件SPI,请参照零知增强板的引脚说明图连接。HC-SR505连接使用+5V电源供电,其他组件使用3.3V供电。
1.3 具体接线图
1.4 连接实物图
二、代码讲解部分
2.1 引脚定义与库引入
#include <Adafruit_GFX.h> // 核心图形库
#include <Adafruit_ST7789.h> // ST7789显示屏驱动库
#include <SPI.h> // SPI通信库
#include <DHT.h> // DHT温湿度传感器库// 引脚定义
#define TFT_CS 53
#define TFT_DC 8
// ... 其他引脚定义
#define PIR_PIN 6 // HC-SR501输出信号引脚
PIR_PIN 6 定义了HC-SR501传感器的信号线连接在数字引脚6上。所有设备的工作都基于这些引脚定义。
2.2 初始化设置
void setup() {// ... 串口初始化tft.init(240, 240); // 初始化显示屏pinMode(TFT_BL, OUTPUT);digitalWrite(TFT_BL, HIGH); // 开启背光pinMode(PIR_PIN, INPUT_PULLUP); // 设置HC-SR505引脚为输入上拉模式// ... 其他引脚模式设置dht.begin(); // 启动DHT传感器drawMainScreen(); // 绘制主界面
}
HC-SR505传感器输出为高阻态,引脚电平能被稳定地拉高,防止误触发。
drawMainScreen()
函数绘制了项目的静态UI框架
2.3 HC-SR505处理函数
void handlePIRSensor() {static bool lastPirState = false;bool pirState = digitalRead(PIR_PIN); // 读取传感器当前状态if (pirState != lastPirState) { // 状态发生变化lastPirState = pirState;if (pirState) { // 状态变为HIGH,检测到人体!tft.fillCircle(60, 75, 15, ST77XX_GREEN); // 更新UI图标为绿色digitalWrite(LED_PIN, HIGH); // LED亮tone(BUZZER_PIN, 1000, 200); // 蜂鸣器短响一声// 在屏幕底部显示警告文字tft.fillRect(0, 220, 240, 20, ST77XX_RED);tft.setCursor(30, 222);tft.print("Human activity detected!");// 触发蜂鸣器间断鸣响逻辑lastBuzzerTime = millis();buzzerState = true;analogWrite(BUZZER_PIN, 10); // PWM驱动蜂鸣器,音量较小} else {// 状态变为LOW,无人tft.fillCircle(60, 75, 15, ST77XX_RED); // 图标恢复红色digitalWrite(LED_PIN, LOW); // LED灭tft.fillRect(0, 220, 240, 20, ST77XX_BLACK); // 清除警告文字}}
}
lastPirState:比较当前状态和上一次状态来判断是否发生变化。只有在变化时才执行后续动作,避免持续触发。
2.4 非阻塞式设计
void loop() {static unsigned long lastUpdate = 0;// 每500ms更新一次显示if (millis() - lastUpdate > 500) {lastUpdate = millis();updateSensorData(); // 更新温湿度和光照数据显示handlePIRSensor(); // 检查HC-SR501状态}handleEncoder(); // (预留)处理编码器checkButtonPress(); // (预留)处理按钮handleBuzzer(); // 处理蜂鸣器报警声音
}
使用
millis()
计时,每500毫秒执行一次数据更新和传感器检查
2.5 系统完整代码
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <SPI.h>
#include <DHT.h>// 引脚定义
#define TFT_CS 53
#define TFT_DC 8
#define TFT_RST 9
#define TFT_BL 7
#define PIR_PIN 6
#define DHT_PIN 5
#define LIGHT_SENSOR A0
#define ENC_CLK 2
#define ENC_DT 3
#define ENC_SW 4
#define BUZZER_PIN 12
#define LED_PIN 13// 初始化显示屏
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
DHT dht(DHT_PIN, DHT11);// 全局变量
int menuIndex = 0;
int lastEncoded = 0;
long lastButtonPress = 0;
unsigned long lastBuzzerTime = 0;
bool buzzerState = false;
bool screenOn = true;void setup() {Serial.begin(9600);// 初始化显示屏tft.init(240, 240);tft.setRotation(1);tft.fillScreen(ST77XX_BLACK);tft.setTextSize(3);tft.setCursor(60, 110);tft.print("Ready");delay(500);pinMode(TFT_BL, OUTPUT);digitalWrite(TFT_BL, HIGH);// 初始化传感器pinMode(PIR_PIN, INPUT_PULLUP);pinMode(BUZZER_PIN, OUTPUT);pinMode(LED_PIN, OUTPUT);pinMode(ENC_CLK, INPUT_PULLUP);pinMode(ENC_DT, INPUT_PULLUP);pinMode(ENC_SW, INPUT_PULLUP);dht.begin();// 绘制初始界面drawMainScreen();Serial.println("智能安防系统升级版启动完成!");
}void loop() {static unsigned long lastUpdate = 0;// 每500ms更新一次显示if (millis() - lastUpdate > 500) {lastUpdate = millis();updateSensorData();handlePIRSensor();}handleEncoder();checkButtonPress();handleBuzzer();
}void drawMainScreen() {tft.fillScreen(ST77XX_BLACK);// 绘制标题栏tft.fillRect(0, 0, 240, 30, ST77XX_BLUE);tft.setCursor(30, 10);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(2);tft.print("Security system");// 绘制数据区域tft.setTextColor(ST77XX_WHITE);tft.setTextSize(1);// 人体检测区域tft.fillRoundRect(10, 40, 100, 60, 5, ST77XX_MAGENTA);tft.setCursor(25, 50);tft.print("Detection");tft.fillCircle(60, 75, 15, ST77XX_RED);// 温湿度区域tft.fillRoundRect(130, 40, 100, 60, 5, ST77XX_MAGENTA);tft.setCursor(145, 50);tft.print("Temp & humi");// 光线感应区域tft.fillRoundRect(10, 110, 100, 60, 5, ST77XX_MAGENTA);tft.setCursor(25, 120);tft.print("Light sensing");// 状态区域tft.fillRoundRect(130, 110, 100, 60, 5, ST77XX_MAGENTA);tft.setCursor(150, 120);tft.print("System status");tft.setCursor(135, 150);tft.print("Running");// 底部菜单tft.fillRect(0, 180, 240, 60, ST77XX_CYAN);tft.setCursor(15, 195);tft.setTextColor(ST77XX_BLACK);tft.print("Status Settings Data About");
}void updateSensorData() {// 更新温湿度显示float temp = dht.readTemperature();float humidity = dht.readHumidity();tft.fillRect(135, 65, 90, 30, ST77XX_MAGENTA);tft.setTextColor(ST77XX_WHITE);tft.setCursor(135, 65);tft.print("T:");tft.setCursor(150, 65);tft.print(temp);tft.setTextColor(ST77XX_WHITE);tft.setCursor(135, 80);tft.print("H:");tft.setCursor(150, 80);tft.print(humidity);// 更新光线感应显示int lightValue = analogRead(LIGHT_SENSOR);int lightLevel = map(lightValue, 0, 1023, 0, 100);tft.fillRect(15, 135, 90, 30, ST77XX_MAGENTA);tft.setCursor(35, 135);tft.setTextColor(ST77XX_WHITE);tft.print(lightLevel);// 绘制光线指示条tft.fillRect(20, 150, 20, 5, ST77XX_BLACK);tft.fillRect(20, 150, lightLevel * 0.2, 5, ST77XX_YELLOW);
}void handlePIRSensor() {static bool lastPirState = false;bool pirState = digitalRead(PIR_PIN);if (pirState != lastPirState) {lastPirState = pirState;if (pirState) {// 检测到人体tft.fillCircle(60, 75, 15, ST77XX_GREEN);digitalWrite(LED_PIN, HIGH);tone(BUZZER_PIN, 1000, 200);// 显示警告信息tft.fillRect(0, 220, 240, 20, ST77XX_RED);tft.setCursor(30, 222);tft.setTextColor(ST77XX_WHITE);tft.print("Human activity detected!");// 触发蜂鸣器lastBuzzerTime = millis();buzzerState = true;analogWrite(BUZZER_PIN, 10); // 最小音量} else {// 无人体活动tft.fillCircle(60, 75, 15, ST77XX_RED);digitalWrite(LED_PIN, LOW);// 清除警告信息tft.fillRect(0, 220, 240, 20, ST77XX_BLACK);}}
}void handleBuzzer() {// 处理蜂鸣器间断播报if (buzzerState && millis() - lastBuzzerTime > 1000) {buzzerState = !buzzerState;lastBuzzerTime = millis();if (buzzerState) {analogWrite(BUZZER_PIN, 10); // 最小音量} else {analogWrite(BUZZER_PIN, 0); // 关闭}}
}void handleEncoder() {// 处理旋转编码器输入// 实现菜单导航功能
}void checkButtonPress() {// 处理按钮按下事件// 实现功能选择
}
pirState参数说明: 存储HC-SR501当前输出电平的变量。HIGH表示检测到人体,LOW表示未检测到。
程序流程图:
三、项目结果演示
3.1 操作流程
(1)上电启动
系统初始化,屏幕显示“Ready”后进入主界面。主界面分为四个区域:人体检测(红色)、温湿度、光线感应、系统状态(Running)
(2)正常监控状态
无人经过时,人体检测图标为红色,温湿度和光照数据正常刷新,底部无报警信息。
(3)触发报警状态
当有人进入HC-SR505探测范围时:
人体检测图标立即变为绿色,LED指示灯亮起,屏幕底部出现红色报警条并显示警告信息,蜂鸣器开始报警。
(4)报警解除
人离开探测范围后,所有报警指示(屏幕、LED、蜂鸣器)自动解除,系统恢复常态监控
3.2 视频演示
HC-SR505安防监控系统
从启动、正常监控、HC-SR505快速触发报警到自动解除报警的全过程
四、HC-SR505热释电传感器工作原理
HC-SR505是一款基于热释电红外(Pyroelectric Infrared, PIR)技术的迷你型人体自动感应模块。与HC-SR501相比,它具有体积小、触发灵敏、自动延时的特点。
工作原理
人体有恒定的体温,一般在37℃左右,因此会发射出特定波长约为10uM的红外线。被动红外探测器的工作原理是检测人体发射的约10uM的红外线。
HC-SR505采用重复触发模式,即在前一次输出结束后,如果再次检测到人体移动,会立即重新输出高电平。
五、常见问题解答 (FAQ)
Q1: HC-SR505检测距离太近或角度不够?
A: HC-SR505的探测距离和角度是固定的,无法像HC-SR501那样调节:
如需更大范围检测,需要考虑使用多个传感器或选择HC-SR501等可调节型号。
Q2: HC-SR505一直输出高电平是怎么回事?
A: 可能是传感器故障或安装环境有问题:
检查是否安装在有强烈热源或气流变化大的地方。确保电源稳定,模块未损坏。
Q3: 为什么人静止不动时传感器不触发?
A: 这是所有PIR传感器的共同特性:
它们检测的是红外辐射的变化,而不是静态热源。人静止时红外辐射无变化,传感器无法检测。
项目资源整合
DHT11温湿度传感器库: DHT-sensor-library