一、 前言
近年来,随着汽车保有量的持续增长,车内环境安全问题逐渐引起公众关注。尤其是此前曝光的汽车内饰材料,如皮垫、胶水等,可能释放甲醛等有害气体,严重威胁驾乘人员的健康。甲醛作为一种常见的室内空气污染物,长期接触可能导致呼吸道疾病、皮肤过敏,甚至增加致癌风险。
因此,开发一款实时监测车内环境的设备显得尤为重要。该设备能够间接检测甲醛、有机物、温湿度等关键指标,帮助用户了解车内空气质量,并采取相应措施,确保驾乘环境的健康与安全。
二、项目概述
本项目基于高性能的树莓派5开发平台,结合先进的BME680和SHT30传感器,构建了一套高精度车内空气质量实时监测系统。BME680传感器具备多参数检测能力,可精准测量挥发性有机化合物(VOC)、温度、湿度和气压等关键环境指标,尤其适用于车内复杂空气成分的分析;SHT30传感器则提供了工业级的高精度温湿度数据,进一步增强了系统的环境感知能力。
树莓派5通过硬件I2C接口与传感器高效通信,利用其强大的数据处理能力和多任务处理优势,实现了对车内环境数据的实时采集。系统通过直观的可视化界直接展示空气质量具体数据、温湿度数据值,帮助用户及时了解车内环境状况并采取相应措施。
本项目的设计不仅提升了驾乘环境的舒适性与健康安全性,还为智能车载系统的开发提供了可扩展的硬件平台和软件框架,具有广泛的应用前景。
三、传感器及主控概况
主控:树莓派5
传感器
1、 BME680
2、 SHT30
树莓派io接口
三、系统架构
四、系统界面
五、实物图
六、核心代码
import tkinter as tk
import subprocess
import re
# 执行 a.out 并获取输出
def run_aout():
try:
result = subprocess.run(["./a.out"], capture_output=True, text=True, check=True)
temperature = None
humidity = None
lines = result.stdout.splitlines()
for line in lines:
if "Temperature" in line:
temperature = float(line.split()[1].replace("c", ""))
elif "Humidity" in line:
humidity = float(line.split()[1].replace("%", ""))
return temperature, humidity
except subprocess.CalledProcessError as e:
print(f"Error occurred: {e}")
return None, None
# 执行 bme68x 并获取输出
def run_bme68x():
try:
result = subprocess.run(["./bme68x"], capture_output=True, text=True, check=True)
temperature = None
pressure = None
humidity = None
gas_resistance = None
temp_match = re.search(r"temperature:s*([-d.]+)*C", result.stdout)
pressure_match = re.search(r"pressure:s*([-d.]+)hPa", result.stdout)
humidity_match = re.search(r"humidity:s*([-d.]+)%", result.stdout)
gas_resistance_match = re.search(r"Gas resistance:s*([-d.]+) ohm", result.stdout)
if temp_match:
temperature = float(temp_match.group(1))
if pressure_match:
pressure = float(pressure_match.group(1))
if humidity_match:
humidity = float(humidity_match.group(1))
if gas_resistance_match:
gas_resistance = float(gas_resistance_match.group(1))
return temperature, pressure, humidity, gas_resistance
except subprocess.CalledProcessError as e:
print(f"Error occurred: {e}")
return None, None, None, None
# 更新界面上的显示
def update_display():
# 获取 a.out 的温度和湿度
temperature_aout, humidity_aout = run_aout()
# 获取 bme68x 的温度、气压、湿度和气体阻抗
temperature_bme, pressure, humidity_bme, gas_resistance = run_bme68x()
# 更新 a.out 的数据显示
if temperature_aout is not None and humidity_aout is not None:
label_temp_aout.config(text=f"{temperature_aout:.2f} °C")
label_humidity_aout.config(text=f"{humidity_aout:.2f} %")
else:
label_temp_aout.config(text="Error")
label_humidity_aout.config(text="Error")
# 更新 bme68x 的数据显示
if temperature_bme is not None and humidity_bme is not None and pressure is not None and gas_resistance is not None:
label_temp_bme.config(text=f"{temperature_bme:.2f} °C")
label_pressure.config(text=f"{pressure:.2f} hPa")
label_humidity_bme.config(text=f"{humidity_bme:.2f} %")
label_gas_resistance.config(text=f"{gas_resistance:.2f} ohm")
else:
label_temp_bme.config(text="Error")
label_humidity_bme.config(text="Error")
label_pressure.config(text="Error")
label_gas_resistance.config(text="Error")
# 每隔 1 秒更新一次
root.after(1000, update_display)
# 创建主窗口
root = tk.Tk()
root.title("Sensor Data Monitor")
# 获取屏幕的宽高,设置 16:9 的比例
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# 设置为 16:9 比例
window_width = screen_width
window_height = int(window_width * 9 / 16)
# 调整窗口大小并设置全屏
root.geometry(f"{window_width}x{window_height}")
root.attributes("-fullscreen", True) # 启用全屏
# --- 抬头部分 ---
header_label = tk.Label(root, text="车内环境监控展示系统", font=("Arial", 36, "bold"), fg="white", bg="#4CAF50")
header_label.pack(fill="x", pady=20)
# --- a.out 数据部分(卡片样式) ---
frame_aout = tk.Frame(root, bg="#f0f0f0", bd=10, relief="groove", padx=20, pady=20)
frame_aout.pack(fill="x", padx=10, pady=10)
label_aout_title = tk.Label(frame_aout, text="SHT30 Sensor Data", font=("Arial", 18, "bold"), bg="#f0f0f0")
label_aout_title.pack()
label_temp_aout = tk.Label(frame_aout, text="Temperature: -- °C", font=("Arial", 16), bg="#f0f0f0")
label_temp_aout.pack(pady=10)
label_humidity_aout = tk.Label(frame_aout, text="Humidity: -- %", font=("Arial", 16), bg="#f0f0f0")
label_humidity_aout.pack(pady=10)
# --- bme68x 数据部分(卡片样式) ---
frame_bme = tk.Frame(root, bg="#e0f7fa", bd=10, relief="groove", padx=20, pady=20)
frame_bme.pack(fill="x", padx=10, pady=10)
label_bme_title = tk.Label(frame_bme, text="BME680 Sensor Data", font=("Arial", 18, "bold"), bg="#e0f7fa")
label_bme_title.pack()
label_temp_bme = tk.Label(frame_bme, text="Temperature: -- °C", font=("Arial", 16), bg="#e0f7fa")
label_temp_bme.pack(pady=10)
label_pressure = tk.Label(frame_bme, text="Pressure: -- hPa", font=("Arial", 16), bg="#e0f7fa")
label_pressure.pack(pady=10)
label_humidity_bme = tk.Label(frame_bme, text="Humidity: -- %", font=("Arial", 16), bg="#e0f7fa")
label_humidity_bme.pack(pady=10)
label_gas_resistance = tk.Label(frame_bme, text="Gas Resistance: -- ohm", font=("Arial", 16), bg="#e0f7fa")
label_gas_resistance.pack(pady=10)
# 启动更新显示
update_display()
# 启动 GUI 主循环
root.mainloop()
七、视频链接
八、项目文档
参考附件