【问题标题】:Two-Button Menu Iteration两键菜单迭代
【发布时间】:2021-06-26 01:56:53
【问题描述】:

我有一个脚本,我正在适应 2040 上的 micropython,我想使用两个按钮来导航菜单结构。我不知道如何使多选菜单中的迭代循环正常工作......这是我到目前为止所得到的:

""" fit: a productivity logger """
import time
import sys
import os
import uhashlib
import machine

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))
    print("> fit the",str(final_hash)," went ",str(final_survey)," lasted //",str(duration))

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)
        b1pressed = button1.value()
        time.sleep(0.01)
        if not b1pressed:
             print('Ended Manually!')
             break

def timer_up(timer_focus):
    """ counts up for indefinite period """
    now = time.time()
    while True:
         minutes = int((time.time() - now) / 60)
         print(str(timer_focus)," for ",str(minutes))
         b1pressed = button1.value()
         time.sleep(0.01)
         if not b1pressed:
             print('Ended Manually!')
             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)
    print(str(timer_focus),str(f_minutes),str(pct))

def multi_choice(options):
    done = 0
    while done == 0:
        for i in options:
            b1pressed = button1.value()
            b2pressed = button2.value()
            time.sleep(.01)
            b1released = button1.value()
            b2released = button2.value()
            if b2pressed and not b1pressed:
                print(i," b2 pressed")
                continue
            if b1pressed and not b2pressed:
                print(i," b1 pressed")
                time.sleep(2)
                return i

button1 = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
button2 = machine.Pin(3, machine.Pin.IN, machine.Pin.PULL_UP)

print("format?")
fType = multi_choice(['30-minute fit','60-minute fit','indefinite fit'])
print(fType," selected")

print("focus?")
F_FOCUS = multi_choice(['personal fit','work fit','learn fit','admin fit'])
print(F_FOCUS," selected")

fStart = time.time()

if fType == "30-minute fit":
    timer_down(1800,F_FOCUS)
elif fType == "60-minute fit":
    timer_down(3600,F_FOCUS)
elif fType == "indefinite fit":
    timer_up(F_FOCUS)
else:
    sys.exit()

fEnd = time.time()

print("sentiment?")
F_SURVEY = multi_choice(['+','=','-'])
print(F_SURVEY," selected")

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(fType)+","+str(F_FOCUS)+","+str(F_SURVEY)+","+str(fStart)+","+str(fEnd)+","+str(fDuration)+"\n")
fitdb.close()

final_print(fDuration,F_HASH_SHORT,F_SURVEY)
print(F_HASH_SHORT," ",F_HASH)

特别是,这是我正在争论的逻辑:

def multi_choice(options):
    done = 0
    while done == 0:
        for i in options:
            b1pressed = button1.value()
            b2pressed = button2.value()
            time.sleep(.01)
            b1released = button1.value()
            b2released = button2.value()
            if b2pressed and not b1pressed:
                print(i," b2 pressed")
                continue
            if b1pressed and not b2pressed:
                print(i," b1 pressed")
                time.sleep(2)
                return i

这是我想做的:

对于集合中的每个项目,

  • 显示项目,等待按钮按下
  • 如果按下按钮 1,选择该项目,返回该项目。
  • 如果按下按钮 2,则显示下一项,等待按钮按下。
  • (迭代直到按下按钮 1 以选择项目)

再说一次,这是 micropython,所以我没有你认为可用的所有模块...最好用原始代码来做。

【问题讨论】:

    标签: python micropython


    【解决方案1】:

    0.01 秒太短了。关键是,在检测到“button down”后,需要等待“button up”。你需要这样的东西:

    def wait_for_btn_up(btn):
        count = 2
        while count > 0:
            if btn.value();
                count = 2
            else:
                count -= 1
            time.sleep(0.01)
    
        
    def multi_choice(options):
        for i in options:
            print( "trying", i )
            # Wait for any button press.
            while 1:
                b1pressed = button1.value()
                b2pressed = button2.value()
                if b1pressed or b2pressed: 
                    break
            if b1pressed:
                print( i, "chosen" )
                wait_for_btn_up(button1)
                return i
            # We know B2 was pressed.
            wait_for_btn_up(button2)
    

    【讨论】:

    • 这在逻辑上确实很有帮助,但它对这个应用程序不太适用,因为 2040 上的 MicroPython 中的 GPIO 按钮需要经常读取......这就是为什么我需要疯狂的 0.01s在最后一个刷新。当然,这与选择循环混淆了,这就是我正在争论的问题。您的版本在逻辑上非常适合两个按钮部分,但现在按钮状态真的是偶尔读取。
    • 我做了很多嵌入式编码,你关于“需要经常阅读”的评论对我来说没有意义。现在,也许您需要实现一些去抖动逻辑;许多小型系统没有内置的。这只是意味着调用一个函数来等待键稳定。我可以调整答案来做到这一点。
    • 不要质疑你的技能,当然,逻辑是合理的,而且比我的烂摊子要好得多,但我不认为这是一个反跳问题。看来我用来收集按钮按下的方法需要进一步完善。使用您的功能,我只能在按钮(1、2)停止响应之前按一次,我必须按另一个...此时停止响应,我必须按另一个,交替-按钮输入。很奇怪。
    • 好吧,那么,也许我不明白你的规格。如果 B1 和 B2 是独立的、瞬时的、常开的按钮,那么代码应该可以工作。
    • 它们,只是两个Cherry MX开关,简单,独立,常开。一个在 GPIO pin2(“button1”)上,另一个在 GPIO pin3(“button2”)上。有了以上内容,我只能交替按下 button1 和 button2 来达到任何效果。第二次连续按下任一按钮两次无效(这会排除一半时间的实际选择,并且滚动选项不止一个深度)。电路打开时 button1.value() = "1",电路闭合时 button1.value() = "0",但这几乎就像逻辑在更改后不会重新检查值一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多