G.Freeman
Posts: 2
Joined: Thu Oct 15, 2015 1:25 am

GPIO callback not firing outside of idle

Thu Oct 15, 2015 1:39 am

Thanks for taking the time to read my question!

I'm using GPIO callbacks to record some information into a text file, as well as print a line to the console. The code works fine in idle, but silently does nothing if running it from a a terminal window. It doesn't throw an error, it just doesn't trigger the callback.

Diligent Googling hasn't turned up anything that matches the symptoms. It's probably something simple, but python/pi/linux aren't my forte.

I'm running the current version of Raspbian and Python 2.7.9

Here's my code in it's entirety. Any help is appreciated.

Code: Select all

import gps, time, os, sys
import RPi.GPIO as GPIO

print "Starting GPS recorder"


#Setup our configuration variables
dataOutputFile = "gps_recorder.txt"
timeSetIntervalInSeconds = 1800
maxAllowedLines = 200


#Setup our various global counters
iterationCounter = 0
cleanOutCounter = 0
timeSetCounter = 99999 #Set the timeSetCounter high enough that it will run immediately on the first pass


#Setup our GPS global variable
session = gps.gps("localhost", "2947") # Listen on port 2947 (gpsd) of localhost
session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)
gpstime = ""


#Define our entry and exit GPIO input pin numbers using broadcom numbering
GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme
entryPin = 25
exitPin = 24
#Define our pins as inputs on the selected channels/pins, and pull them to 0 volts.
GPIO.setup(int(entryPin), GPIO.IN)
GPIO.setup(int(exitPin), GPIO.IN) 


#Setup the event handler for the input pin voltage change for the entry signal
def entry_callback(channel):
    print"Entry detected at " + gpstime
    with open(dataOutputFile,"a") as output_file:
        output_file.write("I " + gpstime + "\n")    

while True:
    try:
        GPIO.add_event_detect(int(entryPin), GPIO.RISING, callback=entry_callback, bouncetime=200)  # add rising edge detection on a channel
        break
    except RuntimeError:
        print "Failed to initialize GPIO event handler for entry pin"
        print "Trying again in five seconds"
        time.sleep (5)


#Setup the event handler for the input pin voltage change for the exit signal
def exit_callback(channel):
    print"Exit detected at " + gpstime
    with open(dataOutputFile,"a") as output_file:
        output_file.write("O " + gpstime + "\n")

while True:
    try:
        GPIO.add_event_detect(int(exitPin), GPIO.RISING, callback=exit_callback, bouncetime=200)  # add rising edge detection on a channel
        break
    except RuntimeError:
        print "Failed to initialize GPIO event handler for exit pin"
        print "Trying again in five seconds"
        time.sleep(5)


#This is the loop that updates the GPS position and timestamps into the location file
print "Initial setup complete, beginning main loop"
while True:
    try:
        #print "Stepping into the next gps entry"
        report = session.next()

        gpstime = session.utc[0:4] + session.utc[5:7] + session.utc[8:10] + ' ' + session.utc[11:19]
                
        #print "Current GPS time assigned locally: " + gpstime

        if cleanOutCounter >= maxAllowedLines:
            print "clearing stuff"
            cleanOutCounter = 0
            lines = open(dataOutputFile).readlines()
            open(dataOutputFile,"w").writelines(lines[-100:])
            print "cleared stuff"
        
        if report['class'] == 'TPV' and iterationCounter >= 30:
            if hasattr(report, 'time'):
                with open(dataOutputFile,"a") as output_file:
                    output_file.write("{0},{1},{2}\n".format(gpstime, report.lat, report.lon))    

                iterationCounter = 0
                cleanOutCounter += 1

        if timeSetCounter >= timeSetIntervalInSeconds and session.utc != None and session.utc != "":
                print 'Setting system time to GPS time... ' + gpstime
                os.system('sudo date --set="%s"' % gpstime)
                print 'System time set.'
                timeSetCounter = 0
                
        iterationCounter += 1
        timeSetCounter += 1
        
    except KeyError:
        pass
    except KeyboardInterrupt:
        GPIO.cleanup() 
        quit()
    except StopIteration:
        session = None
        GPIO.cleanup() 
        print "GPSD has terminated"

GPIO.cleanup()

G.Freeman
Posts: 2
Joined: Thu Oct 15, 2015 1:25 am

Re: GPIO callback not firing outside of idle

Thu Oct 15, 2015 9:08 pm

Figured it out. Interestingly enough, the problem is that setting the system date using the

Code: Select all

os.system('sudo date --set="%s"' % gpstime)
bit of code causes callback threads to choke and die. Amusingly, it only causes it to choke and when it's run from within the script; Running the same command outside the script otherwise doesn't impact the running script. It also doesn't raise an error, just quietly murders the GPIO callback threads.

Also, it works perfectly in Idle. Because... Reasons, I guess.

User avatar
croston
Posts: 723
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool

Re: GPIO callback not firing outside of idle

Thu Oct 15, 2015 10:30 pm

Hmmm interesting. It could be the same issue as reported here: https://sourceforge.net/p/raspberry-gpi ... ickets/81/

Return to “Python”