You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何精准记录传感器的进入与离开触发点?现有代码重复生成记录对的问题求助

如何精准记录传感器的进入与离开触发点?现有代码重复生成记录对的问题求助

嘿,我看了你的问题和代码,立刻就明白你遇到的麻烦了——你的外层大while循环一直在高频迭代,每次循环都会重新检查传感器状态,但原逻辑没做状态跟踪,导致传感器持续触发时,每一次外层循环都会重复写入“进入”记录;紧接着内部循环可能因为传感器瞬间波动或者循环执行太快,又写入“离开”记录,结果就生成了一堆重复的记录对。

问题根源拆解

你原来的逻辑存在两个核心问题:

  1. 重复触发记录:只要传感器保持触发状态(输出0),外层循环每跑一次就会触发进入记录,退出内部循环后又立刻回到外层检测到0,重复整个流程,导致大量重复的进入/离开日志。
  2. 传感器阻塞:当代码卡在某个传感器的内部while循环时,另一个传感器的状态变化完全无法被检测到,会错过关键记录。

解决方案:添加状态跟踪标记

核心思路是只在传感器状态发生切换时记录日志,我们给每个传感器加一个状态标记,记录它当前是“已触发”还是“未触发”:

  • 当状态从「未触发」→「触发」时,写入进入日志
  • 当状态从「触发」→「未触发」时,写入离开日志

修改后的代码示例

首先在循环外初始化状态标记:

# 初始化传感器状态:False=未触发,True=正在触发中
centre_port_active = False
reward_port_active = False

然后替换原来的外层循环逻辑:

while time.time() - timeBefore < trialDuration - rewardSize: # trialDuration-rewardSize = 20-1 = 19 seconds; time.time()-timeBefore = elapsed time since reward delivery
    print('in outer loop')
    
    # 先读取当前两个传感器的状态
    centre_sensor_state = GPIO.input(sensorPins[2])
    reward_sensor_state = GPIO.input(sensorPins[0])

    # 处理中心传感器(记录2=进入,20=离开)
    if centre_sensor_state == 0:
        if not centre_port_active:
            # 状态切换为触发,记录进入
            print('detected centre')
            centrePortFlag = True
            writer.writerow([trialNum, 2, time.time() - startTime])
            centre_port_active = True
    else:
        if centre_port_active:
            # 状态切换为未触发,记录离开
            print('centre left')
            writer.writerow([trialNum, 20, time.time() - startTime])
            centre_port_active = False

    # 处理奖励端口传感器(记录0=进入,10=离开)
    if reward_sensor_state == 0:
        if not reward_port_active:
            # 状态切换为触发,记录进入
            print('detected reward')
            rewardPortFlag = True
            writer.writerow([trialNum, 0, time.time() - startTime])
            reward_port_active = True
    else:
        if reward_port_active:
            # 状态切换为未触发,记录离开
            print('reward left')
            writer.writerow([trialNum, 10, time.time() - startTime])
            reward_port_active = False

为什么这个修改有效?

  • 状态标记确保只有状态发生变化时才写入日志,不会因为循环反复检测同一状态而重复记录。
  • 去掉了阻塞式的内部while循环,现在两个传感器的状态都能被实时检测,不会出现一个传感器阻塞另一个的情况。

额外优化:传感器防抖(可选)

如果你的传感器存在抖动(比如瞬间输出1又回到0),可以加一个防抖函数,通过多次采样取稳定状态避免误触发:

import time

def get_stable_sensor_state(pin, sample_count=3, sample_delay=0.001):
    # 多次读取传感器状态,取出现次数多的结果
    states = []
    for _ in range(sample_count):
        states.append(GPIO.input(pin))
        time.sleep(sample_delay)
    return 0 if states.count(0) > states.count(1) else 1

# 使用时替换原GPIO.input调用
centre_sensor_state = get_stable_sensor_state(sensorPins[2])
reward_sensor_state = get_stable_sensor_state(sensorPins[0])

备注:内容来源于stack exchange,提问作者432111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 12:15:27