我一直在從事一個(gè)項(xiàng)目,通過該項(xiàng)目我可以整理來自 MQ-135 空氣質(zhì)量傳感器的空氣質(zhì)量信息,以檢測(cè)我工作場(chǎng)所空氣質(zhì)量惡化的情況。然而,MQ-135 空氣質(zhì)量傳感器的位置在從傳感器收集原始信息時(shí)具有巨大的重要性。因此,我決定通過開發(fā)一個(gè)用戶友好的界面,通過選定的角度制作一個(gè)可移動(dòng)的傳感器底座。為了實(shí)現(xiàn)這一目標(biāo)并添加一些確鑿的功能(例如可調(diào)節(jié)背景光),我使用 Python 中的 guizero 模塊為我的 Raspberry Pi 開發(fā)了一個(gè) GUI,名為 Air Quality Module。
通過空氣質(zhì)量模塊,您可以通過選擇給定角度之一 - 0、30、45、90、135、180 - 來控制連接到迷你云臺(tái)套件的兩個(gè)伺服電機(jī),并以 RGB 格式調(diào)整背景光 - 255, 255, 255. 而且,最重要的是,您可以監(jiān)控 MQ-135 傳感器生成的當(dāng)前空氣質(zhì)量范圍:如果空氣質(zhì)量惡化,GUI 會(huì)通過警告消息通知您。
本項(xiàng)目中提到的一些產(chǎn)品和組件:
樹莓派 3 板殼 3B
樹莓派 4B/3B+ SD 卡 32GB
樹莓派 3B Micro-HDMI VGA 轉(zhuǎn)換器電纜
補(bǔ)給品:
樹莓派 3 型號(hào) B+× 1
DigitSpace Raspberry Pi 3 板殼× 1
SD 卡 32 GB× 1
DigitSpace Raspberry Pi 3B Micro-HDMI VGA 轉(zhuǎn)換線× 1
Adafruit MCP3008× 1
MQ-135 空氣質(zhì)量傳感器× 1
Pimoroni Pan-Tilt 帽子× 1
SG90微型伺服電機(jī) × 2
RGB擴(kuò)散共陽(yáng)極× 1
SparkFun 可焊接面包板 - 迷你× 2
電阻 220 歐姆 × 3
跳線(通用) × 1
在這個(gè)項(xiàng)目中,你將學(xué)到:
如何使用 Raspberry Pi 的角度控制伺服電機(jī)
如何使用 Raspberry Pi 調(diào)整 RGB LED 的顏色
如何使用 MCP3008 和 Raspberry Pi 讀取模擬傳感器
如何使用 guizero 模塊開發(fā) GUI
如何編寫范圍函數(shù)來排列值,如 Arduino 中的 map 函數(shù)
第 1 步:使用 MCP3008 讀取模擬傳感器
與 Arduino 相比,Raspberry Pi 沒有內(nèi)置的 ADC(模數(shù)轉(zhuǎn)換器),我們可以通過它輕松地從模擬傳感器收集信息。因此,我們需要在我們的電路中實(shí)現(xiàn)一個(gè)外部 ADC,以整理來自模擬傳感器(如 MQ-135 空氣質(zhì)量傳感器)的數(shù)據(jù)。我使用了 MCP3008 8 通道 ADC,因?yàn)樗矢咔沂褂煤?jiǎn)單。
我使用 Raspberry Pi 上的 Adafruit CircuitPython MCP3xxx 庫(kù)來讀取帶有 MCP3008 的模擬傳感器。
但是,您需要安裝在 Python 中提供 CircuitPython 支持的 Adafruit_Blinka 庫(kù)才能使用上述庫(kù)。
sudo pip3 install adafruit-blinka
如果需要,您必須在執(zhí)行命令之前在 Raspberry Pi Configuration Settings 上啟用 SPI。
完成后,從命令行運(yùn)行以下命令來安裝 Adafruit CircuitPython MCP3xxx 庫(kù)。
sudo pip3 install adafruit-circuitpython-mcp3xxx
然后,按如下方式進(jìn)行引腳連接。盡管在項(xiàng)目原理圖和代碼中對(duì)引腳連接進(jìn)行了很好的解釋,但除此之外,我將保留 MCP3008 的以下引腳連接原理圖。
MCP3008 CLK 轉(zhuǎn) Pi SCLK
MCP3008 DOUT 轉(zhuǎn) Pi MISO
MCP3008 DIN 轉(zhuǎn) Pi MOSI
MCP3008 CS 轉(zhuǎn) Pi D5
MCP3008 VDD 至 Pi 3.3V
MCP3008 VREF 至 Pi 3.3V
MCP3008 AGND 到 Pi GND
MCP3008 DGND 到 Pi GND
MCP3008 CH0 到模擬傳感器的信號(hào)引腳
CH0 指的是 MCP3008 上的第一個(gè)輸入引腳 - 從 0 到 7。
第 2 步:開發(fā) GUI(空氣質(zhì)量模塊)和編程 Raspberry Pi
為了能夠在 Python 中創(chuàng)建 GUI,您需要在 Raspberry Pi 上安裝 guizero 模塊。然后,您可以使用模塊提供的所有小部件和事件。
從您的命令行運(yùn)行以下命令來安裝 guizero 模塊。
sudo pip3 install guizero
導(dǎo)入所需的庫(kù)和模塊。
不要忘記包含所有 GUI 小部件 - App、Box、Text、TextBox、PushButton、ButtonGroup、MenuBar、info、yesno、warn。
創(chuàng)建 SPI 總線、cs(片選)和 mcp 對(duì)象。
創(chuàng)建連接到 MCP3008 輸入引腳的模擬輸入通道——我只使用了通道 0。
定義 GPIO 引腳設(shè)置 - GPIO.setmode(GPIO.BCM) 。
定義 RGB 引腳并設(shè)置 PWM 頻率 - 100。
在 100 - OFF 處啟動(dòng) RGB PWM 引腳。
定義伺服電機(jī)引腳并設(shè)置 PWM 頻率 - 50。
在 0 - OFF 處啟動(dòng)伺服底座和臂銷。
定義菜單欄選項(xiàng)命令(功能):
在Tutorial()函數(shù)中,如果需要,打開一個(gè) yesno 消息以轉(zhuǎn)到項(xiàng)目教程頁(yè)面。
在Components()函數(shù)中,打開一條信息消息以顯示組件。
在About()函數(shù)中,打開一條信息消息以顯示電梯間距。
定義小部件命令和功能:
在_range()函數(shù)中,復(fù)制 Arduino 映射函數(shù)以在 Python 中排列給定范圍內(nèi)的值。
在evaluateSensorValue()函數(shù)中,從測(cè)試范圍內(nèi)的 MQ-135 空氣質(zhì)量中獲取空氣質(zhì)量值 - 從 0-60000 到 0-1023。
測(cè)試您的模塊,然后在本例中定義 0 到 60000 之間的值范圍。
如果超過閾值 (300),則通過警告消息通知 - 空氣質(zhì)量惡化 - 并將狀態(tài)更改為危險(xiǎn)。
在adjust_color()函數(shù)中,通過使用ChangeDutyCycle()更改 PWM 頻率(在 0 到 100 之間)來調(diào)整 RGB LED 的顏色。將輸入的顏色值從 0-255 排列到 0-100。
在base_tilt_move()和arm_tilt_move()函數(shù)中,通過選擇的角度控制伺服電機(jī) - 0, 30, 45, 90, 135, 180 - 運(yùn)行ChangeDutyCycle(selected_angle) 。2 到 12 之間的循環(huán)值精確地適用于 0 到 180 之間的角度。
調(diào)整伺服電機(jī)位置后不要忘記執(zhí)行以下行以關(guān)閉伺服 PWM 引腳。
改變工作周期(0)
創(chuàng)建名為 Air Quality Module 的 GUI 應(yīng)用程序。
定義菜單欄選項(xiàng) - 教程、組件、關(guān)于。
使用 box 小部件設(shè)計(jì)界面
RGB 顏色接口
使用布局網(wǎng)格對(duì)齊部件。
將相關(guān)命令(功能)分配給調(diào)整按鈕 - adjust_color。
空氣質(zhì)量界面
定義傳感器和狀態(tài)文本變量。
使用repeat()函數(shù)每秒更新 MQ-135 空氣質(zhì)量傳感器生成的傳感器值。
注意:在執(zhí)行app.display()函數(shù)時(shí),While 循環(huán)不起作用。
迷你云臺(tái)底座接口
在按鈕組小部件中定義角度 - 0、30、45、90、135、180。
分配相關(guān)命令(函數(shù)) - base_tilt_move。
迷你云臺(tái)臂接口
在按鈕組小部件中定義角度 - 0、30、45、90、135、180。
分配相關(guān)的命令(函數(shù))——arm_tilt_move。
啟動(dòng)循環(huán) app.display() 。
特征
1) 改變儀器的背景顏色(RGB)。
2) 通過選擇中間角度 - 0、30、45、90、135、180 來調(diào)整迷你云臺(tái)套件上伺服電機(jī)的位置。
3) 當(dāng)傳感器 (MQ-135) 檢測(cè)到空氣質(zhì)量惡化時(shí)收到通知 - 狀態(tài):危險(xiǎn)。
在菜單欄上:
4) 進(jìn)入教程頁(yè)面。
5) 檢查組件。
6) 顯示電梯間距。
連接
引腳連接在代碼和下面的項(xiàng)目示意圖中得到了很好的解釋。
將樹莓派連接到屏幕。
將 MCP3008 和 RGB LED 連接到迷你面包板上。在將 MCP3008 連接到 Raspberry Pi 之前,我使用了一個(gè)電位器來測(cè)試值范圍。
組裝迷你云臺(tái)套件并將 MQ-135 空氣質(zhì)量傳感器粘在迷你云臺(tái)套件(臂)上。
總結(jié)
完成所有步驟后,我將所有部件固定在一個(gè)舊塑料盒上,并將設(shè)備放在我的桌子上,以收集空氣質(zhì)量數(shù)據(jù)并使用樹莓派上的空氣質(zhì)量模塊 (GUI) 調(diào)整其背景顏色
示意圖
代碼
# Raspberry Pi Adjustable Air Quality Detector Controlled via GUI
#
# Raspberry Pi 3B+
#
# By Kutluhan Aktar
#
# Learn how to develop a GUI, named Air Quality Module, to control a mini pan-tilt kit and get information from an MQ-135 Air Quality Sensor.
# Also, you can change the background light (RGB) via the GUI.
#
# Get more information on the project page:
# https://theamplituhedron.com/projects/Raspberry-Pi-Adjustable-Air-Quality-Detector-Controlled-via-GUI/
from guizero import App, Box, Text, TextBox, PushButton, ButtonGroup, MenuBar, info, yesno, warn
from time import sleep
from subprocess import call
import RPi.GPIO as GPIO
import busio
import digitalio
import board
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn
# Create the SPI bus
spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
# Create the cs (chip select)
cs = digitalio.DigitalInOut(board.D5)
# Create the mcp object
mcp = MCP.MCP3008(spi, cs)
# Create analog inputs connected to the input pins on the MCP3008.
channel_0 = AnalogIn(mcp, MCP.P0)
# Define RGB pins settings and PWM frequencies
GPIO.setmode(GPIO.BCM)
red_pin = 2
green_pin = 3
blue_pin = 4
GPIO.setup(red_pin, GPIO.OUT)
GPIO.setup(green_pin, GPIO.OUT)
GPIO.setup(blue_pin, GPIO.OUT)
red_value = GPIO.PWM(red_pin, 100)
blue_value = GPIO.PWM(blue_pin, 100)
green_value = GPIO.PWM(green_pin, 100)
red_value.start(100)
blue_value.start(100)
green_value.start(100)
# Define servo motor pin settings and PWM frequencies
servo_base_pin = 20
servo_arm_pin = 21
GPIO.setup(servo_base_pin, GPIO.OUT)
GPIO.setup(servo_arm_pin, GPIO.OUT)
servo_base_value = GPIO.PWM(servo_base_pin, 50)
servo_arm_value = GPIO.PWM(servo_arm_pin, 50)
servo_base_value.start(0)
servo_arm_value.start(0)
# Define menu bar options' commands (functions).
def Tutorial():
# Open the project page if requested.
go_to_tutorial = yesno("Open Tutorial", "Get more information about the project!")
if go_to_tutorial == True:
command = "chromium-browser https://theamplituhedron.com/projects/"
call([command], shell=True)
print("Project Tutorial!")
else:
warn("Close", "Return to the application!")
def Components():
info("Components", "Raspberry Pi 3B+\nMQ-135 Sensor\nMini Pan-Tilt Kit\n2 x Servo Motor\nRGB LED\n2 x Mini Breadboard\nMCP3008")
def About():
info("About", "Develop a GUI, named Air Quality Module, to control a mini pan-tilt kit and get information from an MQ-135 Air Quality Sensor. Also, you can change the background light (RGB) on the GUI.")
# Define application commands and features:
def _range(x, in_min, in_max, out_min, out_max):
return int((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
def evaluateSensorValue():
# Test your module, then define the value range - in this case between 0 and 60000.
sensorValue = _range(channel_0.value, 0, 60000, 0, 1023)
sensor_value.value = sensorValue
# Threshold
if(sensorValue > 300):
status_text.value = "Status: DANGER"
status_text.text_color = "yellow"
warn("!!!DANGER!!!", "Air Quality Deteriorating!")
else:
status_text.value = "Status: OK"
status_text.text_color = "green"
def adjust_color():
red = _range(int(r_input.value), 0, 255, 1, 100)
green = _range(int(g_input.value), 0, 255, 1, 100)
blue = _range(int(b_input.value), 0, 255, 1, 100)
red_value.ChangeDutyCycle(101 - red)
blue_value.ChangeDutyCycle(101 - blue)
green_value.ChangeDutyCycle(101 - green)
def base_tilt_move():
# Cycle values between 2 and 12 are working precisely:
selected_angle = 2 + (int(base_angle.value) / 18)
servo_base_value.ChangeDutyCycle(selected_angle)
sleep(0.5)
servo_base_value.ChangeDutyCycle(0)
def arm_tilt_move():
selected_angle = 2 + (int(arm_angle.value) / 18)
servo_arm_value.ChangeDutyCycle(selected_angle)
sleep(0.5)
servo_arm_value.ChangeDutyCycle(0)
# Create the GUI application.
appWidth = 1200
appHeight = 500
app = App(title="Air Quality Module", bg="#eb2e00", width=appWidth, height=appHeight)
# Define menu bar options.
menubar = MenuBar(app, toplevel=["Tutorial", "Components", "About"],
options=[
[ ["View", Tutorial] ],
[ ["Inspect", Components ] ],
[ ["About", About] ]
])
# Design the interface using the box widget.
top = Box(app, width="fill", height=appHeight / 2, align="top")
bottom = Box(app, width="fill", height=appHeight / 2, align="bottom")
color_interface = Box(top, width=appWidth / 2, align="left", layout="grid", border=True)
quality_interface = Box(top, width=appWidth / 2, align="right")
base_interface = Box(bottom, width=appWidth / 2, align="left")
arm_interface = Box(bottom, width=appWidth / 2, align="right")
# RGB Color Interface
color_header = Text(color_interface, text="Adjust RGB Background Color", color="#002699", size=20, grid=[0,0])
r_label = Text(color_interface, text="R :", color="#1a53ff", size=15, grid=[0,1])
r_input = TextBox(color_interface, grid=[1,1])
r_input.bg = "#ff5c33"
r_input.text_color = "#1a53ff"
g_label = Text(color_interface, text="G :", color="#1a53ff", size=15, grid=[0,2])
g_input = TextBox(color_interface, grid=[1,2])
g_input.bg = "#ff5c33"
g_input.text_color = "#1a53ff"
b_label = Text(color_interface, text="B :", color="#1a53ff", size=15, grid=[0,3])
b_input = TextBox(color_interface, grid=[1,3])
b_input.bg = "#ff5c33"
b_input.text_color = "#1a53ff"
adjust_button = PushButton(color_interface, grid=[2,4], width="20", text="Adjust", command=adjust_color)
adjust_button.bg = "#002699"
adjust_button.text_color = "white"
# Air Quality Interface
quality_header = Text(quality_interface, text="Air Quality Sensor", color="#002699", size=20, align="top")
sensor_value = Text(quality_interface, text="TEST", color="#002699", size=120)
status_text = Text(quality_interface, text="Status: OK", color="green", size=15, align="bottom")
# Update the sensor value.
sensor_value.repeat(1000, evaluateSensorValue)
# Mini Pan-Tilt Base Interface
base_header = Text(base_interface, text="Pan-Tilt Base", color="#002699", size=20)
base_angle = ButtonGroup(base_interface, options=["0", "30", "45", "90", "135", "180"], selected="0", width=20, command=base_tilt_move)
base_angle.text_size = 15
base_angle.text_color = "white"
# Mini Pan-Tilt Arm Interface
arm_header = Text(arm_interface, text="Pan-Tilt Arm", color="#002699", size=20)
arm_angle = ButtonGroup(arm_interface, options=["0", "30", "45", "90", "135", "180"], selected="0", width=20, command=arm_tilt_move)
arm_angle.text_size = 15
arm_angle.text_color = "white"
# Start the loop.
app.display()
-
檢測(cè)器
+關(guān)注
關(guān)注
1文章
865瀏覽量
47714 -
GUI
+關(guān)注
關(guān)注
3文章
662瀏覽量
39741
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論