基于RP2040的MicroPython开关循环计数及复位开发问询
解决RP2040 Pico开关通断循环计数问题(MicroPython)
问题本质
你当前代码重复计数的核心原因是没有检测状态变化的边缘,而是持续读取开关的当前状态——只要开关保持导通,就会不断累加计数。要统计完整的通断循环,必须只在开关完成「初始状态→触发状态→初始状态」的完整周期时才计数。
核心解决思路
- 为每个开关维护上一次的状态值,通过对比当前状态与上一次状态,判断是否发生状态变化
- 针对两类开关的初始特性分别处理:
- 常闭开关(T1):默认导通,完整循环是「导通→断开→导通」
- 常开开关(T2):默认断开,完整循环是「断开→导通→断开」
- 复位按钮通过边缘触发(按下时触发)实现计数器清零
优化后代码
from machine import Pin import time # 引脚配置(根据实际接线修改引脚号) T1_PIN = 16 # 常闭开关引脚,使用上拉电阻(默认高电平=导通) T2_PIN = 17 # 常开开关引脚,使用下拉电阻(默认低电平=断开) RESET_PIN = 18 # 复位按钮引脚,使用上拉电阻(按下时为低电平) # 初始化引脚 t1 = Pin(T1_PIN, Pin.IN, Pin.PULL_UP) t2 = Pin(T2_PIN, Pin.IN, Pin.PULL_DOWN) reset_btn = Pin(RESET_PIN, Pin.IN, Pin.PULL_UP) # 计数器初始化 count_t1 = 0 count_t2 = 0 # 记录上一次状态 last_t1_state = t1.value() last_t2_state = t2.value() last_reset_state = reset_btn.value() # 状态标记:记录开关是否处于触发状态(用于判断完整循环) t1_triggered = False t2_triggered = False while True: # 读取当前状态 current_t1 = t1.value() current_t2 = t2.value() current_reset = reset_btn.value() # 处理常闭开关T1的计数:完整循环是 导通(1)→断开(0)→导通(1) if current_t1 != last_t1_state: if current_t1 == 0: # T1从导通变为断开,标记进入触发阶段 t1_triggered = True else: # T1从断开变回导通,且之前已经触发过,完成一个循环 if t1_triggered: count_t1 += 1 t1_triggered = False last_t1_state = current_t1 # 处理常开开关T2的计数:完整循环是 断开(0)→导通(1)→断开(0) if current_t2 != last_t2_state: if current_t2 == 1: # T2从断开变为导通,标记进入触发阶段 t2_triggered = True else: # T2从导通变回断开,且之前已经触发过,完成一个循环 if t2_triggered: count_t2 += 1 t2_triggered = False last_t2_state = current_t2 # 处理复位按钮:按下时(从1变为0)清零计数器 if current_reset != last_reset_state: if current_reset == 0: count_t1 = 0 count_t2 = 0 print("计数器已清零") last_reset_state = current_reset # 输出计数结果(可根据需求改为OLED显示等) print(f"T1循环计数: {count_t1} | T2循环计数: {count_t2}", end="\r") time.sleep_ms(20) # 消抖,避免机械抖动导致误判
代码关键部分说明
- 引脚电阻配置:
- 常闭开关T1用
Pin.PULL_UP,默认高电平代表导通,按下开关断开时变为低电平 - 常开开关T2用
Pin.PULL_DOWN,默认低电平代表断开,按下开关导通时变为高电平 - 复位按钮用
Pin.PULL_UP,按下时为低电平触发清零
- 常闭开关T1用
- 状态变化检测:只有当当前状态与上一次状态不同时才处理,类比C语言中的边缘检测逻辑
- 触发标记:用
t1_triggered和t2_triggered记录开关是否完成了「初始→触发」的第一步,只有当完成「触发→初始」的第二步时,才判定为一个完整循环,避免单次状态变化就计数 - 消抖处理:
time.sleep_ms(20)用于过滤机械开关的抖动,避免误触发
适配你的编程经验的类比
- 类比C语言:这里的状态检测逻辑类似你在C中用外部中断检测边缘触发,只是用轮询实现,更直观;计数器的维护和状态标记对应C中的全局变量或结构体状态
- 类比MATLAB:状态变化判断类似MATLAB中用
diff检测信号边缘,触发标记相当于一个逻辑开关,只有当完整的上升-下降沿(或下降-上升沿)出现时才累加计数 - 类比R语言:循环中的状态对比类似R中用
lag()函数对比当前值与上一个值,通过逻辑判断实现条件触发计数
内容的提问来源于stack exchange,提问作者SamB_Iamtrying
相关产品推荐
相关产品推荐

