Python Raspberry Pi长按钮按住与短点击控制LED

Python Raspberry Pi长按钮按住与短点击控制LED,python,raspberry-pi,Python,Raspberry Pi,首先是免责声明,我对Raspberry Pi和Python完全陌生,所以我可能在这里做了一些完全胡说八道的事情,我道歉 作为第一个练习,我试着制作一个二进制计数器,通过按下一个物理GPIO按钮,一个接一个地点亮多达4个LED,每次都会增加一个,我成功地做到了这一点,我想添加更多的功能,如果我长时间按住按钮(在本例中为2秒),例如,计数器将重置为0,所有LED将熄灭 这是我现在所做的代码,但行为并不完全是我想要的 import RPi.GPIO as GPIO from time import s

首先是免责声明,我对Raspberry Pi和Python完全陌生,所以我可能在这里做了一些完全胡说八道的事情,我道歉

作为第一个练习,我试着制作一个二进制计数器,通过按下一个物理GPIO按钮,一个接一个地点亮多达4个LED,每次都会增加一个,我成功地做到了这一点,我想添加更多的功能,如果我长时间按住按钮(在本例中为2秒),例如,计数器将重置为0,所有LED将熄灭

这是我现在所做的代码,但行为并不完全是我想要的

import RPi.GPIO as GPIO
from time import sleep, time

led0 = 40
led1 = 35
led2 = 33
led3 = 31
btn = 7

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

GPIO.setup(led0,GPIO.OUT)
GPIO.setup(led1,GPIO.OUT)
GPIO.setup(led2,GPIO.OUT)
GPIO.setup(led3,GPIO.OUT)
GPIO.setup(btn,GPIO.IN,pull_up_down=GPIO.PUD_UP)

start_time = 0
counter = 0
time_counter = 0

time_flag = False
button_flag = True


try:
    while True:
        if GPIO.input(btn) == 0: # Button is pressed
            if time_flag == True:
                time_counter = time() - start_time
                #print (f"time_counter = {round(time_counter,2)}s")            
                
            if button_flag == True:
                time_flag = True
                start_time = time()

                counter += 1
                #print (time_counter)
                
                if time_counter > 2:
                    counter = 0
                if counter == 16:
                    counter = 0
                    
                print (format(counter, '02d'), format(counter, '04b')) # bin(counter)[2:].zfill(4)
                button_flag = False
                sleep(0.05)
                
                GPIO.output(led0, counter & 0x01)
                GPIO.output(led1, counter & 0x02)
                GPIO.output(led2, counter & 0x04)
                GPIO.output(led3, counter & 0x08)
        else:
            button_flag = True
            time_counter = 0


except KeyboardInterrupt:
    GPIO.cleanup()
问题是,当我长时间按住按钮时,我希望执行特定的代码,但反过来发生的情况是,如果我长时间按住按钮,一开始什么也不会发生,我需要再次按下按钮,让它执行我想要的操作,并重置计数器以关闭所有LED

这里有一个GIF演示了这个问题,在第一部分中,我只是使用快速单击来增加,然后我按住按钮很长时间(2秒),但它没有按预期工作,我必须再次单击才能使其生效


如果您有任何建议,我将不胜感激

我认为问题在于当您按住按钮时,
button\u flag
将在1次循环后设置为
False
。当按钮仍然按下时,
if button_flag==True
块下的代码将不再运行。松开按钮后,
else
块将运行并将
时间计数器设置为0。然后你的
如果时间计数器>2
条件从未满足,因此从未将
计数器
设置为0。

我认为问题是当你按住按钮时,
按钮标志
将在1次循环后设置为
。当按钮仍然按下时,
if button_flag==True
块下的代码将不再运行。松开按钮后,
else
块将运行并将
时间计数器设置为0。然后,您的
如果时间\u计数器>2
条件从未满足,因此从未将
计数器
设置为0。

您应该将时间检查移动到时间标志检查块内。而且,如果时间计数器达到其极限,则在超时发生后立即反映LED的变化

import RPi.GPIO as GPIO
from time import sleep, time

led0 = 40
led1 = 35
led2 = 33
led3 = 31
btn = 7

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

GPIO.setup(led0,GPIO.OUT)
GPIO.setup(led1,GPIO.OUT)
GPIO.setup(led2,GPIO.OUT)
GPIO.setup(led3,GPIO.OUT)
GPIO.setup(btn,GPIO.IN,pull_up_down=GPIO.PUD_UP)

start_time = 0
counter = 0
time_counter = 0

time_flag = False
button_flag = True


try:
    while True:
    if GPIO.input(btn) == 0: # Button is pressed
        if time_flag == True:
            time_counter = time() - start_time
            #print (f"time_counter = {round(time_counter,2)}s")            
            
            if time_counter > 2:
                counter = 0
                GPIO.output(led0, counter & 0x01)
                GPIO.output(led1, counter & 0x02)
                GPIO.output(led2, counter & 0x04)
                GPIO.output(led3, counter & 0x08)


        if button_flag == True:
            time_flag = True
            start_time = time()

            counter += 1
            #print (time_counter)
            
            if counter == 16:
                counter = 0
                
            print (format(counter, '02d'), format(counter, '04b')) # bin(counter)[2:].zfill(4)
            button_flag = False
            sleep(0.05)
            
            GPIO.output(led0, counter & 0x01)
            GPIO.output(led1, counter & 0x02)
            GPIO.output(led2, counter & 0x04)
            GPIO.output(led3, counter & 0x08)
    else:
        button_flag = True
        time_counter = 0


except KeyboardInterrupt:
    GPIO.cleanup()

您应该将时间检查移动到时间标志检查块内。而且,如果时间计数器达到其极限,则在超时发生后立即反映LED的变化

import RPi.GPIO as GPIO
from time import sleep, time

led0 = 40
led1 = 35
led2 = 33
led3 = 31
btn = 7

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

GPIO.setup(led0,GPIO.OUT)
GPIO.setup(led1,GPIO.OUT)
GPIO.setup(led2,GPIO.OUT)
GPIO.setup(led3,GPIO.OUT)
GPIO.setup(btn,GPIO.IN,pull_up_down=GPIO.PUD_UP)

start_time = 0
counter = 0
time_counter = 0

time_flag = False
button_flag = True


try:
    while True:
    if GPIO.input(btn) == 0: # Button is pressed
        if time_flag == True:
            time_counter = time() - start_time
            #print (f"time_counter = {round(time_counter,2)}s")            
            
            if time_counter > 2:
                counter = 0
                GPIO.output(led0, counter & 0x01)
                GPIO.output(led1, counter & 0x02)
                GPIO.output(led2, counter & 0x04)
                GPIO.output(led3, counter & 0x08)


        if button_flag == True:
            time_flag = True
            start_time = time()

            counter += 1
            #print (time_counter)
            
            if counter == 16:
                counter = 0
                
            print (format(counter, '02d'), format(counter, '04b')) # bin(counter)[2:].zfill(4)
            button_flag = False
            sleep(0.05)
            
            GPIO.output(led0, counter & 0x01)
            GPIO.output(led1, counter & 0x02)
            GPIO.output(led2, counter & 0x04)
            GPIO.output(led3, counter & 0x08)
    else:
        button_flag = True
        time_counter = 0


except KeyboardInterrupt:
    GPIO.cleanup()