【问题标题】:Raspberry Pi - stopping while loop with push switchRaspberry Pi - 使用按钮停止 while 循环
【发布时间】:2024-01-19 14:57:01
【问题描述】:

为了节省时间,代码在按下右侧的开关后开始循环,两个 LED 来回闪烁。我一直在尝试做的——显然没有成功——是通过按下左侧的第二个开关来关闭两个 LED 并且代码完全停止来停止 while 循环。任何帮助或提示将不胜感激。

import RPi.GPIO as GPIO
import time 

GPIO.setmode(GPIO.BOARD)

leftLED = 22
rightLED = 18
leftSWITCH = 24
rightSWITCH = 16

GPIO.setup(leftLED, GPIO.OUT)
GPIO.setup(rightLED, GPIO.OUT)
GPIO.setup(leftSWITCH, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(rightSWITCH, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.output(leftLED, False)
GPIO.output(rightLED, False)
try:
    print("press the left button to start. Press the right button to stop.")
while True:
    input_state = GPIO.input(leftSWITCH)
    if input_state == False:

        while True:
            input_state1 = GPIO.input(rightSWITCH)

            GPIO.output(rightLED, GPIO.LOW)
            time.sleep(.5)

            GPIO.output(rightLED, GPIO.HIGH)
            time.sleep(.1)

            GPIO.output(leftLED, GPIO.LOW)
            time.sleep(.5)

            GPIO.output(leftLED, GPIO.HIGH)
            time.sleep(.1)

          if input_state1 == False:
            break





 finally:
     GPIO.cleanup()

【问题讨论】:

  • 你里面的while循环是一个无限循环:条件是while True并且循环中没有break语句。您如何尝试检查左侧开关的状态?
  • 我编辑了我的代码,它不起作用,但我不知道为什么,我很抱歉我还不习惯这个网站。
  • 您是否有意将一台交换机配置为PUD_DOWN,而将另一台交换机配置为PUD_UP
  • 那是我的实验。他们俩应该都起来我接受吗?我在我的代码中修复了它。但是将两个开关都更改为 UP 仍然不会取消无限循环。
  • @larsks 我读到了PUD_UPPUD_DOWN 实际上做了什么,我可以说两个开关都连接到3.3v 所以我将两个开关都设置为PUD_UP

标签: python-3.x while-loop raspberry-pi3 gpio led


【解决方案1】:

我对树莓派和 GPIO 引脚没有经验,但我有一个想法。 我知道这不是一个有效的代码。

我的想法是运行一个while循环并检查是否按下了按钮。

如果按下左侧开关并且未启动踏板,它将启动一个线程,这将使 LED 闪烁。

如果按下右侧的开关并且指示灯已经闪烁,则线程将被终止。

import threading

def led_blink():
  # led off
  # sleep
  # led on
  # sleep

leds_are_blinking = False
while True:
  if left_switch == True and not leds_are_blinking:
    thread = threading.tread(target="led_blink")
    thread.start()
    leds_are_blinking = True
  if right_switch == True and leds_are_blinking:
    thread.stop()

【讨论】:

    【解决方案2】:

    我认为您的代码基本上可以正常工作。我已将其简化为以下内容,它可以在我的 Pi 上正常运行(请注意,我已经更改了引脚编号,因为我已经在这些引脚上连接了电线):

    import RPi.GPIO as GPIO
    import time 
    
    GPIO.setmode(GPIO.BOARD)
    
    leftSWITCH = 16
    rightSWITCH = 18
    
    GPIO.setup(leftSWITCH, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(rightSWITCH, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    try:
        print('press the left button to start. Press the right button to stop.')
    
        while True:
            input_state = GPIO.input(leftSWITCH)
            if input_state == False:
                print('left button was pressed!')
                while True:
                    input_state1 = GPIO.input(rightSWITCH)
    
                    print('.', end='', flush=True)
                    time.sleep(1)
    
                    if input_state1 == False:
                        print('right button was pressed!')
                        break
    
    finally:
        GPIO.cleanup()
    

    您的问题中的代码存在一些缩进问题,可能会导致问题;很难判断它们是否只是问题中的格式问题,或者它们是否代表代码中的实际问题。

    虽然上面的代码有效,但它们仍有很大的改进空间:特别是外循环是“忙等待”;您的代码不断循环并检查左开关。更好的解决方案是使用阻塞等待,例如使用wait_for_edge 方法:

    try:
        print('press the left button to start. Press the right button to stop.')
    
        while True:
            GPIO.wait_for_edge(leftSWITCH, GPIO.FALLING, bouncetime=100)
            print('left button was pressed!')
            while True:
                input_state1 = GPIO.input(rightSWITCH)
    
                print('.', end='', flush=True)
                time.sleep(1)
    
                if input_state1 == False:
                    print('right button was pressed!')
                    break
    
    finally:
        GPIO.cleanup()
    

    【讨论】: