2016-12-30 3 views
0

Ich habe gerade begonnen, Himbeer-Pi-Entwicklung mit Python zu lernen und habe eine einfache RGB-LED-Schaltung auf meinem Steckbrett installiert, dann habe ich dies mit Pubnub verbunden, um es von einem kleinen Web-Interface zu steuern, das ich gerade gebaut sendet einen Methodennamen und RGB-Werte über Pubnub, wo das Python-Skript den bestimmten Kanal abonniert hat.Ich kann kein laufendes Python-Skript beenden

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 dies funktioniert, außer für den Versuch, das Programm zu schließen und den GPIO-Pins aufzuzuräumen, abmelden aus dem Kanal usw.

In der Vergangenheit habe ich verwendet, um eine while True: Schleife und das hat funktioniert , aber da will ich nicht etwas in einer Schleife, hier zu tun, möchte ich nur eine Verbindung öffnen und offen lassen, bis ich kündigen sie eine Schleife Sinn hier

Schlagen Ctrl + C nur ausgibt KeyboardInterrupt aber es nicht machen scheint nicht den Ausnahmeblock

aufzurufen

Wie kann ich dies erreichen, um GPIO-Pins zu terminieren und zu bereinigen?

UPDATE

Nach Refactoring signal hier zu verwenden ist, was ich jetzt habe ersetzt die try...except (vorausgesetzt ich sie am Anfang der Datei importiert haben)

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) 

jedoch Drücken ctrl + c noch schließt das Programm nicht und führt den Bereinigungscode aus

+0

Haben Sie versucht, C trl-D? –

+0

nein, aber es scheint 'ctrl + d' schließt nur die Shell, wenn ich das Skript erneut ausführen warnt es über die Pins wird bereits verwendet, also muss ich wirklich tun, dass Reinigung – Jordan

Antwort

1

Mit dem Modul signal können Sie ein erstellen globale 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) 

Wenn Sie jetzt CTRL-C, Ihr Bereinigungscode ausgeführt werden sollen, und das Programm wird beendet. Ich benutze Perl hauptsächlich auf meiner Pis, aber ich mache dasselbe, um sicherzustellen, dass alle Pins zurückgesetzt werden, bevor die gleiche Anwendung erneut ausgeführt wird oder eine andere App ausgeführt wird.

+0

dies scheint immer noch nicht zu funktionieren – Jordan

+0

Du bringst das nicht in den Ausnahmeblock, oder? – stevieb

+0

Nein, geht das 'Signal.signal' in den Ausnahmeblock? – Jordan

0

Sie können ein Skript mit jedem Tastendruck mit dieser Funktion beenden. Ich habe kein Problem mit einer while-Schleife auch, aber wenn ich wirklich eine alternative Methode benötigt, würde ich diese verwenden:

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() 

Ein weiteres ähnliches Verfahren kann unter Verwendung der Flüche Modul wie so genutzt werden:

import curses 
stdscr = curses.initscr() 
c = stdscr.getch() 
print 'you entered', chr(c) 
curses.endwin() 

auch wenn Sie Windows verwenden, können Sie das msvcrt Modul verwenden:

import msvcrt 
c = msvcrt.getch() 
print 'you entered', c