一、 前言
近年來,隨著汽車保有量的持續(xù)增長,車內(nèi)環(huán)境安全問題逐漸引起公眾關(guān)注。尤其是此前曝光的汽車內(nèi)飾材料,如皮墊、膠水等,可能釋放甲醛等有害氣體,嚴重威脅駕乘人員的健康。甲醛作為一種常見的室內(nèi)空氣污染物,長期接觸可能導(dǎo)致呼吸道疾病、皮膚過敏,甚至增加致癌風(fēng)險。因此,開發(fā)一款實時監(jiān)測車內(nèi)環(huán)境的設(shè)備顯得尤為重要。該設(shè)備能夠間接檢測甲醛、有機物、溫濕度等關(guān)鍵指標(biāo),幫助用戶了解車內(nèi)空氣質(zhì)量,并采取相應(yīng)措施,確保駕乘環(huán)境的健康與安全。
二、項目概述
本項目基于高性能的樹莓派5開發(fā)平臺,結(jié)合先進的BME680和SHT30傳感器,構(gòu)建了一套高精度車內(nèi)空氣質(zhì)量實時監(jiān)測系統(tǒng)。BME680傳感器具備多參數(shù)檢測能力,可精準(zhǔn)測量揮發(fā)性有機化合物(VOC)、溫度、濕度和氣壓等關(guān)鍵環(huán)境指標(biāo),尤其適用于車內(nèi)復(fù)雜空氣成分的分析;SHT30傳感器則提供了工業(yè)級的高精度溫濕度數(shù)據(jù),進一步增強了系統(tǒng)的環(huán)境感知能力。樹莓派5通過硬件I2C接口與傳感器高效通信,利用其強大的數(shù)據(jù)處理能力和多任務(wù)處理優(yōu)勢,實現(xiàn)了對車內(nèi)環(huán)境數(shù)據(jù)的實時采集。系統(tǒng)通過直觀的可視化界直接展示空氣質(zhì)量具體數(shù)據(jù)、溫濕度數(shù)據(jù)值,幫助用戶及時了解車內(nèi)環(huán)境狀況并采取相應(yīng)措施。本項目的設(shè)計不僅提升了駕乘環(huán)境的舒適性與健康安全性,還為智能車載系統(tǒng)的開發(fā)提供了可擴展的硬件平臺和軟件框架,具有廣泛的應(yīng)用前景。
三、傳感器及主控概況
主控:樹莓派5
傳感器
1、 BME680
2、 SHT30
樹莓派io接口
三、系統(tǒng)架構(gòu)
四、系統(tǒng)界面
五、實物圖
六、核心代碼
import tkinter as tk
import subprocess
import re
# 執(zhí)行 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
# 執(zhí)行 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 的數(shù)據(jù)顯示
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 的數(shù)據(jù)顯示
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)
# 創(chuàng)建主窗口
root = tk.Tk()
root.title("Sensor Data Monitor")
# 獲取屏幕的寬高,設(shè)置 16:9 的比例
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# 設(shè)置為 16:9 比例
window_width = screen_width
window_height = int(window_width * 9 / 16)
# 調(diào)整窗口大小并設(shè)置全屏
root.geometry(f"{window_width}x{window_height}")
root.attributes("-fullscreen", True) # 啟用全屏
# --- 抬頭部分 ---
header_label = tk.Label(root, text="車內(nèi)環(huán)境監(jiān)控展示系統(tǒng)", font=("Arial", 36, "bold"), fg="white", bg="#4CAF50")
header_label.pack(fill="x", pady=20)
# --- a.out 數(shù)據(jù)部分(卡片樣式) ---
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 數(shù)據(jù)部分(卡片樣式) ---
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 主循環(huán)
root.mainloop()
七、視頻鏈接
八、項目文檔
參考附件