在循环中切换数值而不使用time.sleep()。

huangapple go评论66阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年7月18日 00:32:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76706466.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定