本项目参加2025贸泽电子M-Design创意设计竞赛,选择方向一:边缘智能、智能设备。本项目无PCB设计。
完整功能:本项目在网页展示监控视频流、当前温湿度数据、监测区域检测到物体的时间。当监测区域出现物体时,系统自动保存前6.66秒的视频,随后在网页可直接下载。
一、项目介绍
本项目是基于树莓派4B的智能环境监测解决方案,整合了视频采集、传感器数据处理及Web服务三大核心模块。系统采用树莓派4B作为主控制器,通过USB摄像头实现视频采集,结合Flask框架构建局域网视频服务器,支持通过Web浏览器实时观看监控画面。STC8G微控制器负责采集DHT11温湿度传感器及HC-SR04超声波传感器数据,通过UART串口通信协议将数据实时传输至树莓派。当检测到超声波距离值突变(物体进入监测区域)时,系统自动触发GPIO控制的报警指示灯,同时保存触发前6.66秒的视频。Web服务端采用Flask框架搭建,除实时视频流外,还提供温湿度数值显示、事件时间记录以及历史视频下载功能。
本系统实现了环境感知、事件响应与数据可视化的完整闭环,可广泛应用于智能家居、仓库安防等物联网场景。
二、硬件系统组成
2.1 树莓派4B
本项目采用1GB RAM的树莓派4B运行Ubuntu 20.04 LTS操作系统,负责视频数据采集与录制,以及在线观看与下载等工作。树莓派4B通过USB接口连接分辨率为640x480,帧率为15fps的的摄像头;通过USB-UART模块连接STC8G单片机,读取环境数据与运动监测结果。最终,将当前视频监控数据、环境信息、拍摄的视频等信息在网页上实时展示,局域网内可自由访问。
2.2 STC8G1K08A处理器
本项目使用一个基于8051内核的STC8G1K08A处理器,读取DHT11传感器的温湿度信息,读取HC-SR04超声测距传感器的数据。该处理器对数据进行分析后,控制一个指示灯,同时以UART协议上传有关信息至树莓派。上述器件于面包板上搭建。
STC8G1K08A引脚 | 连接元件/模块 | 信号类型 |
P3.2 | HC-SR04 (超声波传感器) | Trig (触发信号) |
P3.3 | HC-SR04 | Echo (回波信号) |
P5.5 | DHT-11 (温湿度传感器) | Data (数据线) |
P5.4 | 9018晶体管(驱动指示灯) | Base (基极) |
P3.1 | CH340 | Rx (接收端) |
P3.0 | CH340 | Tx (发送端) |
2.3 从Mouser采购的器件
本项目使用Wurth Elektronik生产的WCAP-ATG8 33uF 35V 20%径向引线铝电解电容和KEMET生产的50V 0.1uF X7R 10%含引线多层陶瓷电容器作为STC8G单片机、HC-SR04、DHT-11和指示灯的电源滤波电容。
此外,本项目使用Raspberry Pi生产的SC1628型32GB存储卡,作为树莓派4B的系统盘。
三、系统架构设计
· 树莓派4B:视频采集模块、Web服务模块、数据处理模块、物体检测事件响应模块。
· STC8G:传感器采集模块、通信模块、物体检测事件触发模块。
· 系统协作机制:树莓派与STC8G通过USB-TTL转换器建立串行通信链路,树莓派轮询接收传感器数据包并更新Web界面。当超声波事件触发时,STC8G将事件信号传输至树莓派,后者随即启动视频保存线程,实现硬件层与软件层的事件响应闭环。
四、软件实现细节
4.1 视频采集模块
1. 用途
实现摄像头视频流的实时采集、时间戳叠加与环形缓冲区管理,为网页流媒体和事件触发录像提供原始数据源。
2. 功能
- 初始化USB摄像头设备,设置分辨率(640×480)
- 通过多线程锁保证视频帧读取的线程安全
- 在每帧画面叠加实时时间戳(精确到秒)
- 维护容量为100帧的环形缓冲区(约6.6秒时长的视频缓存)
- 将视频帧实时编码为JPEG格式,通过生成器持续输出流媒体数据
3. 输出
- 实时视频流:MJPEG格式流数据,通过/video_feed路由传输
- 环形缓冲区:存储最近100帧原始视频数据(OpenCV Mat格式)
class VideoRecorder:
def __init__(self):
self.cap = cv2.VideoCapture(0)
self.cap.set(3, 640)
self.cap.set(4, 480)
self.lock = threading.Lock()
self.buffer = []
self.recording = False
self.event_time = None
self.frames_queue = []
self.buffer_size = 100 # 10秒缓冲(假设15FPS)
def gen_frames(self):
while True:
with self.lock:
ret, frame = self.cap.read()
# 添加时间戳
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cv2.putText(frame, timestamp, (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
if not ret:
break
# 维护环形缓冲区
if len(self.frames_queue) >= self.buffer_size:
self.frames_queue.pop(0)
self.frames_queue.append(frame.copy())
ret, buffer = cv2.imencode('.jpg', frame)
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n')
def start_recording(self):
if self.recording:
return
self.recording = True
self.event_time = datetime.now()
timestamp = self.event_time.strftime("%Y%m%d_%H%M%S")
filename = os.path.join(VIDEO_DIR, f"event_{timestamp}.avi")
# 创建视频写入器
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter(filename, fourcc, 15.0, (640, 480))
# 写入缓冲帧和后续帧
for frame in self.frames_queue:
out.write(frame)
out.release()
self.recording = False
4.2 Web服务模块
1. 用途
构建基于Flask的Web服务系统,提供用户交互界面与数据接口,实现监控系统的可视化交互。
2. 功能
- 主页面路由(/):
- 动态渲染HTML模板,展示实时视频、传感器数据、事件记录
- 自动刷新机制(30秒间隔)
- 视频文件列表按时间倒序排列,附带下载链接
- 视频流路由(/video_feed):
- 推送MJPEG格式视频流,支持跨平台浏览器访问
- 文件下载路由(/download/<filename>):
- 提供安全验证的视频文件下载服务
- 时间同步接口(/get_time):
- 返回服务器当前标准时间
3. 输出
- 动态网页:包含实时视频流、温湿度数据、事件记录的HTML页面
- HTTP响应:视频流数据包(multipart/x-mixed-replace类型)
- 文件传输:AVI格式视频文件下载服务
@app.route('/')
def index():
# 获取已保存的视频文件列表
videos = []
for f in sorted(os.listdir(VIDEO_DIR), reverse=True):
if f.endswith('.avi'):
timestamp = datetime.strptime(f[6:-4], "%Y%m%d_%H%M%S")
videos.append({
'filename': f,
'time': timestamp.strftime("%Y-%m-%d %H:%M:%S"),
'url': url_for('download_video', filename=f) # 生成下载URL
})
server_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_tem, current_hum = sensor_vals.tem, sensor_vals.hum
return render_template_string('''
<html>
<head>
<title>视频监控</title>
<meta http-equiv="refresh" content="30"> <!-- 每5秒自动刷新 -->
</head>
<body>
<h1>实时视频流</h1>
<img src="/video_feed" style="width:640px; height:480px;">
<h2>传感器数据刷新时间 {{server_time}} </h2> <!-- 用这种方式加入传感器数据 -->
<h3>当前温度{{ current_tem }}℃, 当前湿度{{ current_hum }}%</h3>
<h2>事件记录(共{{ videos|length }}条)</h2>
<h3>点击事件名称,下载该视频</p>
<ul>
{% for video in videos %}
<a href="{{ video.url }}" download
style="margin-left: 20px; text-decoration: none;">
<button style="padding: 3px 8px; background: white; color: black; border: none; border-radius: 3px;">
{{ video.time }}
</button>
<br>
</a>
{% endfor %}
</ul>
<h3>其他</h3>
</body>
</html>
''', videos=videos, server_time=server_time, current_tem=current_tem, current_hum=current_hum) #在这里登记要加入的变量
@app.route('/video_feed')
def video_feed():
return Response(video_stream.gen_frames(),
mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/get_time')
def get_time():
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@app.route('/download/<filename>')
def download_video(filename):
# 安全验证
if '..' in filename or filename not in os.listdir(VIDEO_DIR):
abort(404)
return send_from_directory(VIDEO_DIR, filename,
as_attachment=True)
4.3 数据处理模块
1. 用途
解析处理来自STC8G微控制器的串口数据,管理传感器状态与事件触发逻辑。
2. 功能
- 通过命名管道(camera_pipe)接收原始数据(细节请看代码附件)
- 数据解析处理:
- 拆分逗号分隔的字符串(格式示例:"TRIGGER,temp=25.6,hum=58%")
- 提取温度、湿度数值并更新状态
- 处理触发信号时进行30秒间隔过滤(防误触发机制)
- 状态维护:
- 记录最后一次有效触发时间戳
- 计算当前与上次触发的时间间隔
class SensorMonitorData():
def __init__(self):
self.tem = ""
self.hum = ""
self.trig = False
self.debug = 0
self.last_trig = 0
self.min_interval = 30.0
def process(self,line):
line_vals=line.split(',')
if len(line_vals)>=3:
t1 = float(line_vals[-1])
if(line_vals[0] == "TRIGGER"):
self.trig = ((t1-self.last_trig)>self.min_interval)
self.debug = t1-self.last_trig
if(self.trig):
self.last_trig=t1
self.tem = line_vals[3]
self.tem = self.tem.split('=')[-1]
self.hum = line_vals[2]
4.4 物体检测事件响应模块
1. 用途
响应超声波传感器的触发信号,执行视频保存操作,实现事件驱动的视频存档。
2. 功能
- 事件检测:
- 监听数据处理模块的trig状态变化
- 满足最小触发间隔(30秒)时激活响应
- 视频保存:
- 创建独立线程执行录像任务
- 从环形缓冲区提取前100帧(约6.6秒)视频
- 生成标准AVI文件(XVID编码,15FPS,640×480分辨率)
- 文件名包含事件时间(格式:event_20240516_142643.avi)
- 文件管理:
- 视频存储至/home/asus/test345/ip_camera/videos目录
- 自动维护可下载文件列表
3. 输出
- 事件视频文件:标准AVI格式录像文件(含事件前6秒视频)
- 网页事件记录:带时间戳的可下载链接列表
def monitor_pipe(pipe_path, recorder):
print(f'pipe_path={pipe_path}')
if not os.path.exists(pipe_path):
os.mkfifo(pipe_path)
while True:
with open(pipe_path, 'r') as pipe:
while True:
line = pipe.readline().strip()
sensor_vals.process(line)
if sensor_vals.trig: # 检测到触发标记
threading.Thread(target=recorder.start_recording).start()
time.sleep(0.1)
4.5 物体检测事件触发模块(STC8G)
1. 用途
实现超声波检测事件判定与响应,协调传感器采集与通信模块的联动。
2. 功能
- 事件判定逻辑
- 当echo_cnt<3000时标记为触发状态(is_triggered=triggered)
- 触发持续判定:需连续10次检测有效(trig_cnt>10时重置)
- 硬件响应控制
- 触发时点亮P5.4指示灯(P54=1)
- 常态下关闭指示灯(P54=0)
- 事件关联处理
- 触发时立即通过串口发送事件标识
- 抑制非触发数据发送频率(通过send_cnt计数器实现)
3. 输出
- 硬件信号
while(1){
delay_ms(1);
echo_cnt=0;
startHC();
Echo = 1;
while(Echo == 0);
Echo = 1;
while(Echo == 1) echo_cnt++;
if (echo_cnt<3000){
is_triggered=triggered;
trig_cnt++;
P54=1;
}
else{
is_triggered=not_triggered;
trig_cnt=0;
P54=0;
}
echos=echo_cnt;
DHT11_ReceiveData(&get_humidity,&get_temperature);
if(send_cnt <10 && is_triggered==not_triggered){
send_cnt ++;
}
else if(trig_cnt<2){
printf("%s,HUM,%4.1f,TEM=%4.1f\r\n",is_triggered,get_humidity,get_temperature);
send_cnt = 0;
}
if(trig_cnt>10) trig_cnt=0;
delay_ms(5);
}
}
五、功能演示
Web浏览器页面截图中,除实时监控视频外,其余信息(温湿度、物体进入监测区域的时间)每30秒更新一次。点击事件的时间,可下载发生该事件前6.66秒的录像。附件event_20250319_122919.avi为拍摄的视频。
硬件设备和实时视频流同框的图片。桌上展示本项目硬件系统(黑色外壳的摄像头、树莓派、面包板)。显示器左侧网页展示视频流,摄像头在拍摄本项目硬件系统,右侧网页展示当前时间,与视频流时间戳一致。
监控视频可下载的图片。附件event_20250328_121432.avi为完整视频,记录物体进入监测区域(面包板处指示灯亮起)前约6秒的数据。
六、遇到的难题及解决方法
本项目使用小型钨丝灯珠作为指示灯,其工作电流至少为20mA,不宜用STC8G直接驱动。经过考虑,我用一个9018三极管驱动钨丝灯珠,解决了单片机输出电流不足的问题。
七、项目总结
本项目设计并实现了一套基于嵌入式系统的智能环境监测解决方案,集成了视频采集、传感器数据处理和Web服务三大核心模块,构建了一个完整的物联网应用系统。系统以树莓派4B为主控制器,负责视频采集、数据处理和Web服务,通过USB摄像头实现实时视频监控,并利用Flask框架搭建局域网视频流服务器,支持通过浏览器实时观看监控画面。STC8G微控制器作为辅助处理器,负责采集DHT11温湿度传感器和HC-SR04超声波传感器的数据,并通过UART串口将数据传输至树莓派。当超声波传感器检测到物体进入监测区域时,系统会触发GPIO控制的LED报警指示灯,并保存触发前6秒的视频数据,实现事件驱动的视频存档功能。
本系统具有较高的实用性和扩展性,可广泛应用于智能家居、仓库安防、环境监测等物联网场景。通过整合视频监控、环境感知和事件响应功能,系统实现了对环境的全方位监测与智能化管理,为物联网应用提供了一个可靠的技术解决方案。
最后,感谢贸泽电子、硬禾学堂对本项目的赞助!期待下一次M-Design活动!
附:运行说明
1. 代码test_serail2pipe.py
- 用途:接收STC8G通过串口回传的传感器数据
- 输出:管道文件
2. 代码test_webserver2.py
- 用途:视频采集模块、Web服务模块、数据处理模块、物体检测事件响应模块
- 输入:管道文件
- 输出:浏览器网页,默认地址为树莓派的IP,端口5000
3. 代码start.sh
- 用途:执行前两份树莓派Python程序
- 用法:赋予该脚本执行权限后,在crontab设置其开机自启动
- 若发现温湿度数据更新异常,请重新运行test_serail2pipe.py
4. 工程test_stc8g.zip
- 用途:STC8G程序,包含可下载的hex文件
- 用法:使用STC-ISP串口下载至单片机