On my Pi I am using cron to run a shell script, which in turn runs a python script on startup using the @reboot flag. This python script sets up a GPIO pin to listen for a button push, and for some reason about 2/3 of the time (but not all the time) I get a RuntimeError: Failed to add edge detection. This has never happened to me when running the script in the terminal, only on reboot.

Here's my crontab entry:

@reboot sh /home/pi/Desktop/startup.sh

The startup.sh script:


python3 /home/pi/Desktop/hdrShooter.py

Within hdrShooter.py there is a lot going on, but here is the line that crashes:

GPIO.add_event_detect(17, GPIO.RISING, callback=self.on_button_press)
  • It is futile trying to run a GUI script on startup because it runs before the GUI exists. There are hundreds of similar questions on this site.
    – Milliways
    Nov 18 '21 at 21:00
  • @Milliways Doesn't need to be a GUI script. I also tried not running it via lxterminal, same result.
    – Spencer
    Nov 18 '21 at 21:46
  • You have changed the Question - which ORIGINALLY used lxterminal
    – Milliways
    Nov 18 '21 at 22:35
  • @Milliways I removed that to prevent potential confusion. My question is not how to run a terminal at startup, but rather how to fix the GPIO RuntimeError, which I don't think is related. As mentioned it failed both ways.
    – Spencer
    Nov 18 '21 at 22:46

This is a brief answer; I won't try to address potential issues in Python, but I will make one suggestion wrt your cron job running @reboot.

Many of the cron issues reported here have to do with the fact that cron does not monitor availability of resources prior to running an @reboot job. In other words, the system (or specifically systemd in most modern Linux distros) starts cron before it starts a service/daemon that may be needed. When this happens, cron simply cannot deal with it, and throws an error that can be misleading.

A solution that often helps (but not always) is to run the sleep command before starting the job you want to run. In your case, the crontab entry would be this:

@reboot sleep 15; sh /home/pi/Desktop/startup.sh  

15 means 15 seconds; you may want to try a few different values...

Finally, it's sometimes useful to redirect the stderr output from a script to a file to aid in trouble shooting:

@reboot sleep 15; sh /home/pi/Desktop/startup.sh 2> /home/pi/Desktop/stderr.txt 
  • Thanks Seamus, this is helpful. I was manually writing the traceback to a txt file in python, but didn't realize you can do that from the shell script. I hate the idea of sleeping for a somewhat arbitrary number of seconds, is there a way to know what service is handling the GPIOs and waiting for that to start? Or is there a better option than cron? I tried rc.local, but that seemed like a generally worse idea...
    – Spencer
    Nov 18 '21 at 23:11
  • If nothing else I guess I could try/except python to just keep trying to setup the GPIO callback for a few seconds...
    – Spencer
    Nov 18 '21 at 23:15
  • @Spencer: You may not want to use it as a permanent solution, but you should try it to verify that it resolves the issue - that is to say, is the issue created by resource availability/timing? Why don't you resolve your initial question first, and then we can move on to discuss alternatives?
    – Seamus
    Nov 18 '21 at 23:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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