Функция обратного вызова add_event_detect запущена без повышения GPIO

Я мучился с этой проблемой в течение нескольких недель и, наконец, поддался просьбе о помощи.

ПОСТАНОВКА ЗАДАЧИ: add_event_detect запускается и вызывает свои собственные (и другие) функции обратного вызова несколько раз, даже если связанный вывод GPIO не сделан ВЫСОКИМ. Это как если бы у программного обеспечения была собственная жизнь. Когда я нажимаю кнопку LIGHT, события TIMER и MOTOR запускаются несколько раз - и я не могу понять, почему.

Я пытался:

  • Использование параметра bouncetime, но это не перехватывает лишние события
  • Использование резисторов для дебасинга

Только добавив условия таймера в обратный вызов, я могу остановить многократный запуск обратных вызовов, но это не устраняет причину проблемы, связанную с маршрутом. Мне нужно остановить выполнение обратных вызовов в первую очередь.

Схема выглядит следующим образом.

Коммутационная и светодиодная схема

Важные элементы кода показаны ниже. (Я удалил довольно много неактуального кода, и может быть трудно отследить весь поток программы, но ключевые элементы есть.

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 ответов

Другие вопросы по тегам