我在我的 PI 4B 上运行一些需要多线程的代码。我正在使用事件来管理线程并在出现键盘中断或按下 mainBUtton 时运行的函数时停止它们。
from threading import Thread, Event
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
import time
import os
def setup():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(relayPin, GPIO.OUT)
GPIO.setup(ledPinRed, GPIO.OUT)
GPIO.setup(ledPinGreen, GPIO.OUT)
GPIO.setup(buzzerPin, GPIO.OUT)
global Buzz
Buzz = GPIO.PWM(buzzerPin, 440)
GPIO.setup(mainButtonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # set buttonPin to PULL UP INPUT mode
GPIO.setup(faceRecPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # set buttonPin to PULL UP INPUT mode
discordPing.getTokenID("token.txt")
def action():
GPIO.output(ledPinRed,GPIO.LOW)
GPIO.output(ledPinGreen, GPIO.HIGH)
GPIO.output(relayPin, GPIO.HIGH)
time.sleep(5)
GPIO.output(ledPinGreen, GPIO.LOW)
GPIO.output(relayPin, GPIO.LOW)
def destroy():
GPIO.output(relayPin, GPIO.LOW)
GPIO.cleanup()
def onPress():
GPIO.output(relayPin, GPIO.LOW)
buzzerThread = Thread(target=buzzerLoop)
buzzerThread.start()
buzzerThread.join()
def buzzerLoop():
print("Starting Buzzer")
Buzz.start(50)
ringEvent = Event()
ledThread = Thread(target=ledLoop,args=(ringEvent,))
rfidThread = Thread(target=rfidReader, args=(ringEvent,))
rfidThread.start()
ledThread.start()
for i in range(1, len(song)):
Buzz.ChangeFrequency(song[i])
time.sleep(beat[i]*0.13)
Buzz.stop()
ringEvent.set()
ledThread.join()
#rfidThread.join()
def ledLoop(ringEvent):
print("Starting LED")
while True:
if ringEvent.is_set():
break
else:
GPIO.output(ledPinRed, GPIO.LOW)
time.sleep(.75)
GPIO.output(ledPinRed, GPIO.HIGH)
time.sleep(.75)
def loop(event):
while True:
if event.is_set():
print("Button Functionality Shutting Down")
break
else:
if GPIO.input(mainButtonPin)==GPIO.LOW:
print("Main BUtton Pressed")
onPress()
elif GPIO.input(faceRecPin)==GPIO.LOW:
print("starting face-rec")
fullFaceRecognition(event)
else :
pass
#GPIO.output(ledPinRed,GPIO.HIGH)
def openFile(filename):
with open(filename, "r") as file:
lines = len(file.readlines())
file.seek(0)
for x in range(lines):
code = (file.readline()).strip('\n')
listOfCodes.append(code)
def rfidReader(event):
reader = SimpleMFRC522()
code = ''
count = 0
while True:
if event.is_set():
print("RFID Shutting Down")
break
print(f"Starting RFID - ID#{count}")
code = reader.read_id()
print(f"Read {count}")
count += 1
if code != '':
read = False
for x in listOfCodes:
if x == str(code):
print("Valid Code - Unlocking")
'''action()'''
code = ''
read = True
#time.sleep(3)
break
else:
pass
if read == False:
code = ''
print("Invalid User")
relayPin = 36
ledPinRed = 11
ledPinGreen = 13
mainButtonPin = 31
faceRecPin = 32
buzzerPin = 37
mainEvent = Event()
#Main Code
if __name__ == '__main__':
try:
setup()
mainLoopThread = Thread(target=loop, args=(mainEvent,))
mainLoopThread.start()
mainLoopThread.join()
except KeyboardInterrupt:
print("Program Ended")
mainEvent.set()
destroy()
虽然这可能很明显,但我认为它仍然很重要,但主按钮和 RFID 标签需要多次使用,所以目标是在读取一个 RFID 标签后不要让 mainLoop 停止,而是要有能力保持循环 if 语句。
代码输出
Main BUtton Pressed
Starting Buzzer
Starting LED
Starting RFID - ID#0
Read 0
Valid Code - Unlocking
RFID Shutting Down
Button Functionality Shutting Down
在此之后,由于循环被破坏,按钮不起作用。