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()
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