我有另一个关于迭代菜单逻辑的问题,问题变成了按钮逻辑,所以我把它们分开了,因为原来的问题已经真正解决了。
我的代码如下:
""" fit: a productivity logger """
import time
import sys
import os
import uhashlib
import machine
import framebuf
from ssd1306 import SSD1306_I2C
def final_print(sec,final_hash,final_survey):
""" leaves the summary on the screen before shutting down """
mins = sec // 60
sec = sec % 60
hours = mins // 60
mins = mins % 60
short_sec = int(sec)
duration = (str(hours) + "/" + str(mins) + "/" + str(short_sec))
oled_show("> fit the"+str(final_hash),str(final_survey),"//"+str(duration))
time.sleep(30)
oled_blank()
def timer_down(f_seconds,timer_focus):
""" counts down for defined period """
now = time.time()
end = now + f_seconds
while now < end:
now = time.time()
fit_progress(now,end,timer_focus,f_seconds)
time.sleep(0.01)
# if button1.value() == 0:
# oled_show("","Ended Manually!","")
# time.sleep(2)
# break
def timer_up(timer_focus):
""" counts up for indefinite period """
now = time.time()
while True:
minutes = int((time.time() - now) / 60)
oled_show(str(timer_focus)," for ",str(minutes))
time.sleep(0.01)
# if button1.value() == 0:
# oled_show("","Ended Manually!","")
# time.sleep(2)
# break
def fit_progress(now,end,timer_focus,f_seconds):
""" tracks progress of a count-down fit and prints to screen """
remain = end - now
f_minutes = int((remain)/60)
j = 1 - (remain / f_seconds)
pct = int(100*j)
oled_show(str(timer_focus),str(f_minutes)+" min",str(pct)+"%")
def debounce(btn):
""" some debounce control """
count = 2
while count > 0:
if btn.value():
count = 2
else:
count -= 1
time.sleep(0.01)
def multi_choice(options):
""" provides multi-choice menus for two-button navigation """
for i in options:
oled_show("> fit",i,"1:yes 2:next")
# Wait for any button press.
while 1:
b1pressed = button1.value()
b2pressed = button2.value()
if b1pressed or b2pressed:
break
if b1pressed:
print( i, "chosen" )
debounce(button1)
return i
# We know B2 was pressed.
debounce(button2)
def oled_show(message1,message2,message3):
""" displays a three line message """
oled.fill(0) # clear the display
oled.text(message1,5,5)
oled.text(message2,5,15)
oled.text(message3,5,25)
oled.show()
def oled_blank():
""" blanks the oled display to avoid burn in """
oled.fill(0)
oled.show()
sda = machine.Pin(4)
scl = machine.Pin(5)
i2c = machine.I2C(0,sda=sda, scl=scl, freq=400000)
oled = SSD1306_I2C(128, 32, i2c)
button1 = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
button2 = machine.Pin(3, machine.Pin.IN, machine.Pin.PULL_UP)
F_TYPE = multi_choice(['30-minute fit','60-minute fit','indefinite fit'])
F_FOCUS = multi_choice(['personal fit','work fit','learn fit','admin fit'])
fStart = time.time()
if F_TYPE == "30-minute fit":
timer_down(1800,F_FOCUS)
elif F_TYPE == "60-minute fit":
timer_down(3600,F_FOCUS)
elif F_TYPE == "indefinite fit":
timer_up(F_FOCUS)
else:
sys.exit()
fEnd = time.time()
F_SURVEY = multi_choice(['went well','went ok','went poorly'])
fDuration = fEnd - fStart
F_HASH = uhashlib.sha256(str(fEnd).encode('utf-8')).digest()
F_HASH_SHORT = F_HASH[0:3]
fitdb = open("data.csv","a")
fitdb.write(str(F_HASH)+","+str(F_TYPE)+","+str(F_FOCUS)+","+str(F_SURVEY)+","+str(fStart)+","+str(fEnd)+","+str(fDuration)+"\n")
fitdb.close()
final_print(fDuration,F_HASH_SHORT,F_SURVEY)
特别是,您可以看到我定义了两个按钮:
button1 = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
button2 = machine.Pin(3, machine.Pin.IN, machine.Pin.PULL_UP)
它们主要用于从具有多种选择的菜单中进行选择:
def debounce(btn):
""" some debounce control """
count = 2
while count > 0:
if btn.value():
count = 2
else:
count -= 1
time.sleep(0.01)
def multi_choice(options):
""" provides multi-choice menus for two-button navigation """
for i in options:
oled_show("> fit",i,"1:yes 2:next")
# Wait for any button press.
while 1:
b1pressed = button1.value()
b2pressed = button2.value()
if b1pressed or b2pressed:
break
if b1pressed:
print( i, "chosen" )
debounce(button1)
return i
# We know B2 was pressed.
debounce(button2)
但是,我遇到了一个问题,即只能交替按下按钮。也就是说,当 multi_choice 功能开始时,我可以按 button1 选择第一个选项,或者我可以按 button2 滚动到下一个选项,但是,如果我按 button2,例如,它不会注册第二次按下 (选择第二个选项),然后我只能按下按钮 1 ...如果我这样做,我只能接下来按下按钮 2。
我确定这只是我没有看到的逻辑问题。
这些按钮是 GPIO 引脚 2 和 3 上的普通瞬时关闭 Cherry MX 开关。它们确实可靠地工作,但这种逻辑有些不稳定。
以下测试工作得很好,所以它不是按钮......
import machine
import time
button1 = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
button2 = machine.Pin(3, machine.Pin.IN, machine.Pin.PULL_UP)
while True:
b1pressed = button1.value()
b2pressed = button2.value()
time.sleep(0.01)
b1released = button1.value()
b2released = button2.value()
if b1pressed and not b1released:
print('Button1 pressed!')
if b2pressed and not b2released:
print('Button2 pressed!')
if not b2pressed and b2released:
print('Button2 released!')
elif not b1pressed and b1released:
print('Button1 released!')
我添加了一些打印语句来调试它,我可以看到按钮获取和保存值。我觉得我需要调整人工重置,也许这是我可以在去抖动中做的事情?我尝试了一些事情,但到目前为止我没有取得进展。
def debounce(btn):
""" some debounce control """
count = 2
while count > 0:
if btn.value():
count = 2
else:
count -= 1
time.sleep(0.01)
def multi_choice(options):
""" provides multi-choice menus for two-button navigation """
for i in options:
print("below for")
print("button 1 below for",button1.value())
print("button 2 below for",button2.value())
oled_show(" fit",i,"1:sel 2:next")
while 1:
print("below while")
print("button 1 below while",button1.value())
print("button 2 below while",button2.value())
b1pressed = button1.value()
b2pressed = button2.value()
if b1pressed or b2pressed:
print("below first if")
print("button 1 first if",button1.value())
print("button 2 first if",button2.value())
break
if b1pressed:
print("below second if")
print("button 1 second if",button1.value())
print("button 2 second if",button2.value())
debounce(button1)
return i
debounce(button2)
以及上述调试打印的输出:
>>> %Run -c $EDITOR_CONTENT
below for
button 1 below for 0
button 2 below for 1
below while
button 1 below while 0
button 2 below while 1
below first if
button 1 first if 0
button 2 first if 1
below for
button 1 below for 1
button 2 below for 0
below while
button 1 below while 1
button 2 below while 0
below first if
button 1 first if 1
button 2 first if 0
below second if
button 1 second if 1
button 2 second if 0
below for
button 1 below for 0
button 2 below for 1
below while
button 1 below while 0
button 2 below while 1
below first if
button 1 first if 0
button 2 first if 1
below for
button 1 below for 1
button 2 below for 0
below while
button 1 below while 1
button 2 below while 0
below first if
button 1 first if 1
button 2 first if 0
below second if
button 1 second if 1
button 2 second if 0