1 简要介绍
将按键封装为1个类,使用时只需注册各个动作函数,调用scan函数即可识别按键状态并执行相应的动作函数。优点是充分利用了Python的特性,调用非常简单方便。缺点主要是运行速度一般。适合用于对按键读取速度要求不高的场景。
2 主体代码
class Switch:
def __init__(self, Pin, active_level = 0, long_press_time_ms = 1000, press_interval_time_ms = 1000):
# 默认低电平有效
# 默认判定长按的阈值为1s
# 默认连续按下间隔最长为1s
self.pin = Pin
self.active_level = active_level
self.long_press_time_ms = long_press_time_ms
self.press_interval_time_ms = press_interval_time_ms
self.last_press_times = 1
self.no_press_func = lambda: self.pass_func() # 先将所有按下的动作函数注册为pass
self.short_press_func = lambda: self.pass_func()
self.double_press_func = lambda: self.pass_func()
self.triple_press_func = lambda: self.pass_func()
self.long_press_func = lambda: self.pass_func()
def pass_func(self):
pass
def scan(self): # 按键扫描函数
press_times = 0 # 按下次数
for i in range(0,3):
if self.pin.value() == self.active_level:
start_time_ns = time.time_ns()
time.sleep_ms(10) # 软件消抖延迟
if self.pin.value() == self.active_level:
press_times+=1
while self.pin.value() == self.active_level: # 按键按下的过程
time.sleep_ms(100)
if time.time_ns()-start_time_ns >= self.long_press_time_ms*1e6: # 按下时间超过长按阈值,判定为长按
long_press_flag = 1
self.long_press_func()
while self.pin.value() == self.active_level:
pass
press_times = 0 # 按下次数清零,防止同时触发短按(包括单击、双击、三击)功能
i = 3
break
while self.pin.value() != self.active_level: # 按键抬起后未按下的过程
time.sleep_ms(100)
if time.time_ns()-start_time_ns >= self.press_interval_time_ms*1e6:
i = 3 # 当按键抬起时间时间过长时,跳到按键次数判断部分
break
else: # 检测到未按下立刻退出,确保每次按下时i均为1,能够正常判断按下次数
break
if press_times == 0:
self.no_press_func()
elif press_times == 1:
self.short_press_func()
elif press_times == 2:
self.double_press_func()
elif press_times == 3:
self.triple_press_func()
3 测试用例
from switch import Switch
from machine import Pin
import time
switch = Switch(Pin(12, Pin.IN, Pin.PULL_UP)) # 时间参数均采用默认值,
last_num = 1
def my_print(num):
global last_num
if num != 0 or last_num != 0: # 避免连续打印0刷屏
print(num)
last_num = num
# 按键未按下、单击、双击、三击、长按分别输出0~5
switch.no_press_func = lambda: my_print(0)
switch.short_press_func = lambda: my_print(1)
switch.doble_press_func = lambda: my_print(2)
switch.triple_press_func = lambda: my_print(3)
switch.long_press_func = lambda: my_print(4)
while True:
switch.scan()
time.sleep(0.01)
测试时使用ESP32单片机,依次单双三击、长按按键,再倒序进行一次,得到的测试结果如下:
4 总结
这五种状态已经能涵盖大多数基础按键使用场景,如需拓展到四次短按以上,在原代码上简单修改即可。
笔者水平有限,如有错误望不吝指出,谢谢!