Reputation: 2523
I just started learning Raspberry Pi development with python and have a simple RGB LED circuit setup on my breadboard, I then connected this to Pubnub to control it from a little web interface I built which just sends a method name and RGB values over Pubnub where the python script has subscribed to the particular channel.
from pubnub import Pubnub
import RPi.GPIO as G
import time
pubnub = Pubnub(publish_key="****", subscribe_key="****")
def callback(message, channel):
globals()[message['method']](message['data'])
def error(message):
print("ERROR: " + str(message))
def connect(message):
print("CONNECTED")
def reconnect(message):
print("RECONNECTED")
def disconnect(message):
print("DISCONNECTED")
G.setmode(G.BCM)
red_channel_pin = 18
green_channel_pin = 23
blue_channel_pin = 24
G.setup(red_channel_pin, G.OUT)
G.setup(green_channel_pin, G.OUT)
G.setup(blue_channel_pin, G.OUT)
pwm_red = G.PWM(red_channel_pin,500)
pwm_red.start(100)
pwm_green = G.PWM(green_channel_pin,500)
pwm_green.start(100)
pwm_blue = G.PWM(blue_channel_pin,500)
pwm_blue.start(100)
def set_rgb_values(data):
pwm_red.ChangeDutyCycle(float(data['red']))
pwm_green.ChangeDutyCycle(float(data['green']))
pwm_blue.ChangeDutyCycle(float(data['blue']))
try:
pubnub.subscribe(channels="rasprgb",callback=callback, error=error, connect=connect, reconnect=reconnect, disconnect=disconnect)
except KeyboardInterrupt:
print('Cleaning Up')
G.cleanup()
pubnub.unsubscribe(channel='rasprgb')
All of this works except for trying to close the program and clean up the GPIO pins, unsubscribe from the channel, etc.
In the past I've used a while True:
loop and that has worked, but since I don't want to do something in a loop here, I just want to open a connection and leave it open until I terminate it a loop doesn't make sense here
Hitting Ctrl + C
just outputs KeyboardInterrupt
but it doesn't seem to be calling the except block
How can I get this to be able to terminate and clean up GPIO pins?
UPDATE
After refactoring to use signal
here is what I have now replacing the try...except
(assuming I have imported them at the top of the file)
def sig_handler(signal,frame):
print('Cleaning Up')
G.cleanup()
pubnub.unsubscribe(channel='rasprgb')
sys.exit(0)
pubnub.subscribe(channels="rasprgb",callback=callback, error=error, connect=connect, reconnect=reconnect, disconnect=disconnect)
signal.signal(signal.SIGINT, sig_handler)
However, pressing ctrl + c
still does not close out the program and run the cleanup code
Upvotes: 2
Views: 2279
Reputation: 11
You can exit a script using any key press with this function. I also don't see a problem with a while loop but if I really needed an alternative method, I would use this:
import sys, os
def wait_key():
''' Wait for a key press on the console and return it. '''
result = None
import termios
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
try:
result = sys.stdin.read(1)
except IOError:
pass
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
return result
print('Press any key to quit: ')
wait_key()
Another similar method can be utilized by using the curses module like so:
import curses
stdscr = curses.initscr()
c = stdscr.getch()
print 'you entered', chr(c)
curses.endwin()
Also if you are using Windows, you can use the msvcrt module:
import msvcrt
c = msvcrt.getch()
print 'you entered', c
Upvotes: 0
Reputation: 9306
Using the signal
module, you can create a global interrupt handler:
import signal
import sys
def sig_handler(signal, frame):
print('Cleaning Up')
G.cleanup()
pubnub.unsubscribe(channel='rasprgb')
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
Now, when you CTRL-C
, your cleanup code will run, and the program will exit. I use Perl mostly on my Pis, but I do the same thing to ensure that all pins are reset before a re-run of the same application, or a run of a different app.
Upvotes: 2