英文:
Toggling a value during a loop without time.sleep()
问题
我正在尝试在我的程序中创建一个可切换的值,而且要在循环期间进行。我不能在程序中使用 time.sleep()
,因为我不能完全停止程序(这样你就不能在此期间按按钮)。
我可以简单地这样做:
while True:
if button.is_pressed():
# 执行任务
但是,这样的话,值将在每一帧之间切换。这太快了。
我还尝试过这样:
while True:
if button.value:
cur_state_right = button.value
if cur_state_right != prev_state_right:
# 执行任务
prev_state_right = cur_state_right
这使你需要在执行任务之前按下然后释放按钮。然而,在实际操作中,只有在按下按钮时任务才会执行,就好像必须在特定时间按下按钮一样。出于某种原因,当你按住按钮时,代码也会停止运行。这是不好的,因为这段代码运行数字时钟,不应该随机停止。
以防万一是其余的代码导致了这个问题,以下是代码的其余部分:
import board
import busio
from adafruit_ht16k33 import segments
import adafruit_gps
from adafruit_datetime import timedelta, datetime
import time
import digitalio
import microcontroller
# ... (其余的代码)
希望这对你有帮助。如果你有任何其他问题,请随时提问。
英文:
I'm trying to make a toggleable value in my program, during a loop. I can't use time.sleep()
in the program, as I can't have the program stopping completely (so that you can't press buttons during this time).
I could just do this:
while True:
if button.is_pressed():
# do task
But then, the value will be toggled every frame. This is too fast.
I also tried this:
while True:
if button.value:
cur_state_right = button.value
if cur_state_right != prev_state_right:
# do task
prev_state_right = cur_state_right
This makes you press then release the button before the task can be done again. However in practice, the task is only done sometimes when you press the button, like it must be pressed at a specific time. For some reason, the code also stops when you hold the button down. This is bad, as this code runs a digital clock, which shouldn't stop randomly.
Just in case it's the rest of the code that's causing this, here it is:
import board
import busio
from adafruit_ht16k33 import segments
import adafruit_gps
from adafruit_datetime import timedelta, datetime
import time
import digitalio
import microcontroller
btn_right = digitalio.DigitalInOut(board.GP5)
btn_right.switch_to_input(pull=digitalio.Pull.UP)
btn_confirm = digitalio.DigitalInOut(board.GP9)
btn_confirm.switch_to_input(pull=digitalio.Pull.UP)
btn_left = digitalio.DigitalInOut(board.GP13)
btn_left.switch_to_input(pull=digitalio.Pull.UP)
i2c = busio.I2C(board.GP27, board.GP26)
display = segments.Seg7x4(i2c)
gps = adafruit_gps.GPS_GtopI2C(i2c)
display.fill(1)
time.sleep(1)
display.fill(0)
gps.send_command(
b"PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
) # start gps data grab
gps.send_command(b"PMTK220,1000") # set ur to 1hz
gps.send_command(b"PMTK285,2,100") # activate pps if not already on
def load(filename):
f = open(filename + ".txt", "r")
output = f.read()
f.close()
return output
def save(filename, data):
f = open(filename + ".txt", "w")
f.write(data)
f.close()
def button_input():
prev_state_left = btn_left.value
prev_state_centre = btn_confirm.value
prev_state_right = btn_right.value
while True:
cur_state_left = btn_left.value
if cur_state_left != prev_state_left:
if not cur_state_left:
return "<"
prev_state_left = cur_state_left
cur_state_centre = btn_confirm.value
if cur_state_centre != prev_state_centre:
if not cur_state_centre:
return "!"
prev_state_centre = cur_state_centre
cur_state_right = btn_right.value
if cur_state_right != prev_state_right:
if not cur_state_right:
return ">"
prev_state_right = cur_state_right
def savings_check():
dst = 0
while True:
display.fill(0)
display.print(dst)
option = button_input()
if option == "!":
break
while True:
if option == ">":
dst += 1
break
if option == "<":
dst -= 1
break
else:
break
return dst
dst = savings_check()
gps.update()
while True:
try:
time.sleep(1)
gps.update()
timeset = datetime(
gps.timestamp_utc.tm_year,
gps.timestamp_utc.tm_mon,
gps.timestamp_utc.tm_mday,
gps.timestamp_utc.tm_hour,
gps.timestamp_utc.tm_min,
gps.timestamp_utc.tm_sec,
)
break
except Exception as e:
display.print("LOAD")
print(e)
print("Time load fail. Retrying. Satellites:", gps.satellites)
print("Load success!")
if dst != 0:
timeset = timeset + timedelta(hours=dst)
timeset = timeset + timedelta(seconds=15)
last_print = time.monotonic()
last_update = time.monotonic()
pps_state = True
prev_state_right = not btn_right.value
while True:
current = time.monotonic()
if btn_left.value and btn_confirm.value and btn_right.value:
if current - last_print >= 1.0:
last_print = current
timeset = timeset + timedelta(seconds=1)
display.print(
"{:02d}".format(timeset.hour) + "{:02d}".format(timeset.minute)
)
print(timeset, "With", gps.satellites, "Satellites")
if timeset.second % 2 == 0:
display.colon = True
else:
display.colon = False
elif not btn_left.value:
display.colon = False
display.print(
"{:02d}".format(timeset.day) + "{:02d}".format(timeset.month)
)
elif not btn_confirm.value:
display.colon = False
display.print(timeset.year)
elif not btn_right.value:
cur_state_right = not btn_right.value
if cur_state_right != prev_state_right:
if pps_state:
gps.send_command(b"PMTK285,0,100")
print("PPS off")
if not pps_state:
gps.send_command(b"PMTK285,2,100")
print("PPS on")
pps_state = not pps_state
prev_state_right = cur_state_right
elif not btn_left.value and not btn_confirm.value and not btn_right.value:
microcontroller.reset()
答案1
得分: 1
由于你的设置,你的数值将会相反。你把按钮拉高,因此在静止状态下,它的值将为1。你将按钮连接到了地线,所以当你按下它时,值将为0。
话虽如此。这里是捕捉按钮事件的逻辑:
rbtn = btn_right.value
while True:
# value = 1, last_value = 0
# 在你的设置中,这表示按钮释放
if btn_right.value and not rbtn:
# 做一些操作
...
# last_value = 1, value = 0
# 在你的设置中,这表示按钮按下
if rbtn and not btn_right.value:
# 做一些操作
...
# 更新
rbtn = btn_right.value
英文:
Due to your setup, your values will be backwards. You are pulling the button up so, at rest, it's value will be 1. You have your button wired to ground so, when you press it, the value will be 0
All that being said. Here is the logic to capture button events
rbtn = btn_right.value
while True:
#value = 1, last_value = 0
#in your setup, this means released
if btn_right.value and not rbtn:
#do something
...
#last_value = 1, value = 0
#in your setup, this means pressed
if rbtn and not btn_right.value:
#do something
...
#update
rbtn = btn_right.value
答案2
得分: 0
问题在于我在if语句中放错了代码或者放在了外面。
原始代码如下:
while True:
if button.value:
cur_state_right = button.value
if cur_state_right != prev_state_right:
# 进行任务
prev_state_right = cur_state_right
然而应该是这样的:
prev_state_right = btn_right.value
while True:
cur_state_right = btn_right.value
if cur_state_right != prev_state_right:
if cur_state_right:
# 进行任务
prev_state_right = cur_state_right
英文:
The problem was that I had put the wrong code in or out of the if statement.
It looked like this:
while True:
if button.value:
cur_state_right = button.value
if cur_state_right != prev_state_right:
# do task
prev_state_right = cur_state_right
However it should have been like this:
prev_state_right = btn_right.value
while True:
cur_state_right = btn_right.value
if cur_state_right != prev_state_right:
if cur_state_right:
# do task
prev_state_right = cur_state_right
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论