Dear all,
I use add_event_detect to monitor a key matrix for keys being pressed. The code works fine, but only for a while. Usually after one to two days of constant running suddenly the event does not trigger any more. Rest of GPIO works still, like relais switched via GPIO. Shutting down the program including a call of cleanup() and starting it anew does not solve the problem - the key matrix stays inoprable. Only a reboot helps.
Some side information:
The code makes use of the following modules: socket, time, pygame, signal, sys, tty, termios, select, tornado
The key matrix is attached to the Raspberry by a CAT 7 cable of about 7 meters length
* No entries occur in any log, no error message is spawned
I have no idea how to troubleshoot - thanks for help!
Kind regards
Caerandir
Dear all,
this effect might have a similar cause like ticket #85 - a limitation of OS ressources.
I met this effect in a "stress test" for a little project on my side:
"RPi.GPIO emulation on Windows" (I like it to develop on windows and then run on RPi).
Here is a simplified stand alone test loop that reproduces a "Failed to add edge detection" Runtime error after 381 cycles "reliably" on my Raspberry.
def stress_test():
import RPi.GPIO as GPIO # is already an instance
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False) # suppress wrong edge warnings
channel = 25 #
cycle = 0
print('RPi.GPIO add event stress test running ...')
try:
while True:
try:
GPIO.setup(channel, GPIO.IN)
GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.remove_event_detect(channel)
GPIO.cleanup(channel) # no fail if this commented out
cycle += 1
except RuntimeError, e:
print('Survived %s cycles, Then %s' % (cycle, e.message))
break
except KeyboardInterrupt:
print('User abort after %s cycles' % cycle)
GPIO.cleanup()
If you disable the "GPIO.cleanup(channel)" statement the loop runs infinitely.
So if you struggle with this effect it might be a workaround to check your program for dispensable intermediate cleanups, remove them and do only a final cleanup at program termination.
Hi Ali,
thanks for your hint! Actually I use GPIO.cleanup() only when the program ends. But perhaps it is an idea to use it, say, at midnight, to free some resources? I may try at some point, but as of now I wrote my own monitor and just stripped the event handler from my code. Everything else of the GPIO library works rock solid - my automation program survided uptimes of a month and more.
Cheers, Caerandir
Hi Caerandir,
it's good to hear that your application runs fine. Btw, my observations above do NOT recommend to intensify the use of cleanup(channel) calls. Things ran worse with and better without.
Nevertheless it's a somewhat annoying effect that restricts the use of the library in concurrent programming applications.
For multithreading and multiprocessing it is always a good idea to leave clean/restored states.
From this point of view I thought that
setup(channel, ...) <--> cleanup(channel)
are a "symmetrical" pair of methods and you are encouraged to use them like "braces" as
add_event_detect(channel, ...) <--> remove_event_detect(channel)
is also a symmetrical pair.
@Ben Croston
Hi Ben,
maybe you can take pleasure in this point of view and the observations can help to root cause and fix/avoid the "Failed ta add edge detection" error ocurrence..
BR
Aq
Hi Ali,
yes, I understood that GPIO.cleanup()-"flooding" is no good idea. On the other hand I understood that there may be a resource issue with add_event_detect. So I guessed that doing a cleanup once in a while might also lead to a "reorganization" of resources.
Whatever, currently I will just refrain from using event_detects in long-running programs and handle things myself until someone figured out the root cause and fixes it. I'm afraid my programming skills do not suffice to contribute myself...
Btw: I use signal.setitimer(...) and signal.signal(signal.SIGALRM, ...) to implement my own handler - works nicely.
Thanks! -Caerandir