0

Intro

It seems to me that when one adds and event detection, then removes it and the adds it again, something strange happen: 1) an event is removed to the "detection list"; 2) the event happens; 3) The event is added to the detection list; Result) The callback function is called immediately after 3) even if the event occurred while it was not detected

In Details

My setup is the following:

  • Raspberry Pi 2011.12 with archlinuxarm
  • GPIO17: green led
  • GPIO18: yellow led
  • GPIO23: push button (pull up)
  • GPIO24: door contact (closed when door is closed, pull up)

I want my RPI to be a door guard, in particular

  • With the push button toggle between STATUS = 0 (non-armed) and STATUS = 1 (armed
  • When in STATUS = 0 green led is on and yellow is off and the PI does not do anything
  • When in STATUS = 1 green led is off and yellow is on and the PI print when the door is being opened or closed

My code is the following

        import RPi.GPIO as GPIO
        from threading import Event
        import signal
        import sys

        GPIO.setmode(GPIO.BCM)
        GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(18, GPIO.OUT, initial=0)
        GPIO.setup(17, GPIO.OUT, initial=1)

        STATUS = False

        #When a door event occour:
        def door(channel):
                if GPIO.input(23):
                        print("The door has been opened!")
                else:
                        print("The door has been closed!")


        #When one pushes the button to toggle the sysyem
        def toggle(channel):
                global STATUS
                if STATUS:
                        GPIO.output(17,1)
                        GPIO.output(18,0)
                        GPIO.remove_event_detect(23)
                        STATUS = False
                else:
                        GPIO.output(18,1)
                        GPIO.output(17,0)
                        GPIO.add_event_detect(23, GPIO.BOTH, callback=door, bouncetime=300)
                        STATUS = True


        GPIO.add_event_detect(24, GPIO.FALLING, callback=toggle, bouncetime=300)

        #Cleanup function to gently close the system
        def cleanup(signum, frame):
                GPIO.cleanup()
                sys.exit(0)

        #to handle signals
        signal.signal(signal.SIGTERM, cleanup)
        signal.signal(signal.SIGINT, cleanup)

        #Wait forever
        Event().wait()

In particular, when one activate the system, an event detection is added both if the door is opened or closed. When one deactivate the system the detection of the event is removed

The Problem

I have the following situation that I cannot understand:

  • The system is armed
  • The door is opened and closed several times; at the end the door is closed
  • The system is un-armed
  • The door is opened
  • The system is armed again

Immediately after that I get an event "The door has been opened!". What I do not understand is my door has been opened before I armed the system. It seems that when I add the detection of the event again the RPi.GPIO remembers what happened when the detection was removed. The funny is that the problem is not symmetric: if I exchanged opening and closing events in the previous list, I do not get the message "The door has been closed!"

QUESTION

Where am I wrong? Is there a way to "flush" the events while they are not added to the interrupt list?

1 Answer 1

1

This is likely to be a feature of RPi.GPIO. I would not try to fight it.

Perhaps change to something like the following.

...

STATUS = False

#When a door event occour:
def door(channel):
   global STATUS
   if STATUS:
      if GPIO.input(23):
         print("The door has been opened!")
      else:
         print("The door has been closed!")

#When one pushes the button to toggle the sysyem
def toggle(channel):
   global STATUS
   if STATUS:
      GPIO.output(17,1)
      GPIO.output(18,0)
      STATUS = False
   else:
      GPIO.output(18,1)
      GPIO.output(17,0)
      STATUS = True

GPIO.add_event_detect(23, GPIO.BOTH, callback=door, bouncetime=300)
GPIO.add_event_detect(24, GPIO.FALLING, callback=toggle, bouncetime=300)

...
1
  • Thanks for your solution. However, as a good practice I think that it is better to keep the interrupt calls as low as possible.
    – MaPo
    Commented Sep 11, 2019 at 9:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.