add_event_detect回调函数在GPIO不高的情况下触发

时间:2016-09-26 15:50:51

标签: python gpio meta-raspberrypi

我已经为这个问题痛苦了好几个星期,并且终于屈服于寻求帮助。

问题陈述:“add_event_detect”被触发并多次调用其自己的(AND其他)回调函数,即使绑定的GPIO引脚未变为高电平。就好像软件有自己的生命。当我按下LIGHT按钮时,TIMER和MOTOR事件被多次触发 - 我无法理解为什么。

我试过了:

  • 使用bouncetime参数,但这不会捕获额外事件
  • 使用电阻去抖动

只有在回调中添加计时器条件才能阻止回调多次运行,但这并不能解决问题的路由原因。我需要在第一时间停止执行回调。

电路看起来像这样。

Switching and LED circuit

重要的代码元素如下所示。 (我删除了相当多的不相关代码,可能很难追踪程序的全部流程,但关键元素就在那里。

aPins = [24]        
pinLightOut     = 23

pinMotorToggle  = 20
pinLight        = 16
pinTimer    = 21

GPIO.setmode(GPIO.BCM)

# Set the relay pins to high (220v circuits are off)
GPIO.setup (aPins, GPIO.OUT, initial=GPIO.HIGH)
GPIO.setup (pinLightOut         , GPIO.OUT, initial = GPIO.HIGH)

GPIO.setup (pinLight        , GPIO.IN, pull_up_down = GPIO.PUD_OFF)
GPIO.setup (pinMotorToggle  , GPIO.IN, pull_up_down = GPIO.PUD_OFF)
GPIO.setup (pinTimer        , GPIO.IN, pull_up_down = GPIO.PUD_OFF)

outLEDPower     = 26
outLEDSchedule  = 19
outLEDBypass    = 13
outLEDMotorOn   = 6
outLEDLight     = 5

aLED    = [outLEDSchedule, outLEDMotorOn, outLEDBypass, outLEDLight, outLEDPower]

GPIO.setup  (aLED,      GPIO.OUT)
GPIO.output (aLED,      GPIO.LOW)

GPIO.output(outLEDPower, GPIO.HIGH)     # The power light is on by default
GPIO.output(outLEDSchedule, gTimerActive)   # The timer is active at start up by default


# Setup the GPIO callbacks for an event detected.

GPIO.add_event_detect (pinTimer, GPIO.FALLING, callback=Timer_Switch, bouncetime= 1000)
GPIO.add_event_detect (pinMotorToggle, GPIO.FALLING, callback=Start_Switch, bouncetime = 1000)
GPIO.add_event_detect (pinLight, GPIO.FALLING, callback=Light_Switch, bouncetime = 1000)

def Start_Switch (c1):

global gStartSwitch, gTimerActive, gStartSwitchLED, LastThreadTime


# This condition is to make up for the bouncetime that does not appear to work.
if time.time() - LastThreadTime > 2: 

    # NB to reset this time variable otherwise more callbacks are initiated
    LastThreadTime = time.time()

    if not gTimerActive:


        gStartSwitch = True
        gStartSwitchLED = not gStartSwitchLED

        GPIO.output (outLEDBypass, gStartSwitchLED)

    else:

        print "Cannot start motor while timer is running"

def Timer_Switch (c4):

global gTimerActive, gStopBecauseTimerToggle, LastThreadTime

if time.time() - LastThreadTime > 2:

    LastThreadTime = time.time()

    print "Timer Switch Pressed on channel : " + str(c4)

    if gTimerActive == True:
        GPIO.output (outLEDSchedule, GPIO.LOW)
        gTimerActive = False
    else:
        GPIO.output (outLEDSchedule, GPIO.HIGH)
        gTimerActive = True

    gStopBecauseTimerToggle = True


def Light_Switch (c4):

global LastThreadTime, gLightActive

if time.time() - LastThreadTime > 2:

    LastThreadTime = time.time()

    print "Light Switch pressed on channel : " + str(c4)

    if not gLightActive:

        GPIO.output(pinLightOut, GPIO.LOW)
        GPIO.output (outLEDLight, GPIO.HIGH)

        gLightActive = True

    else :

        GPIO.output(pinLightOut, GPIO.HIGH) 
        GPIO.output (outLEDLight, GPIO.LOW)
        gLightActive = False


def MotorActivate (vZone, vDuration):

global gTimerActive,  gStartSwitch, gMotorActive, gZone, gTimeLeft, gStopMotor, gStopBecauseTimerToggle, gStartSwitchLED

if vZone <= len(aPins):

    timeCount = 0
    MotorTimeEnd  = time.time() + vDuration
    TimeNow = time.time()
    vTimeLast = 0
    gTimeLeft = str(vDuration)
    gZone = str(vZone)

    GPIO.output (aPins [vZone-1], GPIO.LOW)
    GPIO.output (outLEDMotorOn, GPIO.HIGH)

    gMotorActive = True

    while time.time() <= MotorTimeEnd and not gStartSwitch and not gStopBecauseTimerToggle:

        if time.time() - vTimeLast >= 1:

            gTimeLeft = str(round(MotorTimeEnd - time.time(),0))
            vTimeLast = time.time()

    GPIO.output (aPins [vZone-1], GPIO.HIGH)
    GPIO.output (outLEDMotorOn, GPIO.LOW)
    GPIO.output (outLEDBypass, GPIO.LOW)
    gStartSwitchLED = False

gMotorActive = False


#########################################################################################
# Main Body of program below
#########################################################################################


try:

while 1>0:

    if gTimerActive and time.time() - vTimeStampTimer >= 3 : # Check timer every 3 seconds

        MotorActivator = "Timer"             
        MotorZones = CheckPoolSchedule (aFloat)      # Check to see if the current time is inside the timer window

        if len(MotorZones) > 0 and not gStopMotor:       

            RunSchedule (MotorZones)                 # The RunSchedule is the function that calls the MotorActivate function

    if gStartSwitch:

        RunSchedule (aPoolList)             # Run the schedule with a default time frame


    if time.time() - vLI >= 5:              # Check light timer every 5 seconds

        if not gLightActive:

            aLightZone = CheckPoolSchedule (aLight) # Check to see if time is in the timer schedule

            if len(aLightZone) > 0:

                Light_Switch (99)

        if gLightActive and vLightOffTime <> -1:

            if time.time() >= vLightOffTime:

                Light_Switch (98)


finally:

print "Leaving programme"
GPIO.cleanup()  

您所看到的任何其他内容或有关使我的代码更好的建议都将不胜感激。

提前谢谢

0 个答案:

没有答案