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

关于关闭PIR运动传感器检测功能的技术咨询

解决PIR传感器撤防后仍触发检测的问题

看起来你现在的核心困扰是撤防后PIR传感器还在持续检测并触发报警,代码里有几个关键逻辑错误导致功能失效,咱们一步步来修复:

先理清核心问题

  1. 你写了两个完全重复的disarmAlarm函数,后面的会直接覆盖前面的,导致撤防逻辑混乱;
  2. pir_off函数里的GPIO.input(11) == False只是做了一次状态比较,根本没有改变传感器的工作状态——GPIO输入是传感器的输出信号,你没法强行把它设为False,只能停止检测它的状态;
  3. 你用Clock.schedule_interval定时调用callback来检测PIR,但撤防时没有取消这个定时任务,所以它会一直后台运行,持续读取传感器状态,自然会触发报警。

具体修复步骤

1. 保存定时任务引用,方便启停

首先在类的初始化方法里添加一个变量,用来保存PIR检测定时任务的引用,后续取消任务时会用到:

def __init__(self, **kwargs):
    super().__init__(**kwargs)
    self.pir_detect_task = None  # 存储PIR检测的定时任务

2. 修正armAlarm函数的定时任务逻辑

你原来的布防逻辑里,启动检测的条件搞反了(应该是布防时启动检测,撤防时停止),同时要把定时任务的引用保存下来:

def armAlarm(self):
    global Activated, Armed
    if self.txt_display.text == str(pincode):
        Clock.schedule_once(lambda dt: self.indicated(), 3)
        Armed = True
        Activated = False
        GPIO.output(22, 0)
        GPIO.output(18, 1)
        GPIO.output(16,1)
        time.sleep(0.5)
        GPIO.output(16,0)
        # 如果之前有未取消的任务,先清理
        if self.pir_detect_task:
            Clock.unschedule(self.pir_detect_task)
        # 布防成功,启动PIR检测
        self.pir_detect_task = Clock.schedule_interval(lambda dt: self.callback(), 0.5)
    elif self.txt_display.text != str(pincode):
        Armed = False
        Activated = False
        self.txt_display.text = ''
        self.info.text = '**Incorrect Pin**'
        self.info.background_color = [1, 1, 1, 1]
        Clock.schedule_once(lambda dt: self.reset_notice(), 3)
        self.info.background_color = [0, 1, 0, 1]
        # PIN错误,停止检测
        if self.pir_detect_task:
            Clock.unschedule(self.pir_detect_task)
            self.pir_detect_task = None

3. 合并并修复disarmAlarm函数

把两个重复的disarmAlarm合并成一个,覆盖所有撤防场景:

def disarmAlarm(self):
    global Activated, Armed
    # 先验证PIN码是否正确
    if self.txt_display.text != str(pincode):
        self.info.text = '**Incorrect Pin**'
        self.info.background_color = [1, 1, 1, 1]
        Clock.schedule_once(lambda dt: self.reset_notice(), 3)
        self.txt_display.text = ''
        return
    
    # PIN正确,执行撤防操作
    Armed = False
    Activated = False
    self.info.text = 'Alarm disarmed'
    self.info.background_color = [0, 1, 0, 1]
    self.txt_display.text = ''
    # 关闭所有GPIO输出设备
    GPIO.output(16,0)
    GPIO.output(22, 0)
    GPIO.output(18, 0)
    # 取消PIR检测的定时任务,彻底停止检测逻辑
    if self.pir_detect_task:
        Clock.unschedule(self.pir_detect_task)
        self.pir_detect_task = None
    print('Alarm deactivated')

4. 移除无效函数

你的pir_off和reset_alarm函数逻辑完全无效,直接删掉即可——停止PIR检测的核心是取消定时任务,而不是试图修改GPIO输入状态。

关键逻辑说明

  • 定时任务的启停:用Clock.schedule_interval启动检测后,必须用Clock.unschedule传入任务引用来停止,否则它会每隔0.5秒自动调用callback读取PIR状态;
  • 全局变量一致性:确保Armed和Activated的状态在布防/撤防时同步更新,避免逻辑冲突;
  • GPIO输入本质:PIR的GPIO输入是传感器的输出信号,你没法强行设置它的状态,只能停止读取这个信号的逻辑。

这样修改后,当你输入正确PIN码执行撤防时,定时任务会被彻底取消,callback不再被调用,自然就不会检测到PIR的状态变化,报警也就不会触发了。

内容的提问来源于stack exchange,提问作者user12358221

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:42:33