2016-12-30 10 views
0

私はちょうどPythonでRaspberry Piの開発を学び始めました。ブレッドボードに簡単なRGB LED回路を設定しました。これをPubnubに接続して、 Pythonスクリプトが特定のチャンネルを購読しているPubnubにメソッド名とRGB値を送信します。実行中のPythonスクリプトを終了できません

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

このすべては、私がwhile True:ループを使ってきたし、それが働いている過去になど

、チャネルからの退会、プログラムを閉じて、GPIOピンをクリーンアップしようとしている以外の作品私はここでループで何かしたくないので、私は接続を開いて、ループを終了するまで開こうとします。ループは意味がありません。

Ctrl + CはちょうどKeyboardInterruptを出力しますが、除外ブロックを呼び出すようではない

GPIOピンを終端してクリーンアップするにはどうしたらいいですか?

UPDATE

ここsignalを使用するようにリファクタリングした後、私は今まだctrl + cを押すと、しかし、(私は、ファイルの先頭にそれらをインポートしていると仮定)

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) 

try...exceptを交換したものですプログラムを終了せずにクリーンアップコードを実行しないでください

+0

をあなたがCを試してみましたtrl-D? –

+0

いいえ、 'ctrl + d'はシェルを閉じるだけですが、スクリプトを再実行すると、すでに使用中のピンについて警告されますので、実際にそのクリーンアップを行う必要があります。 – Jordan

答えて

1

signalモジュールを使用すると、グローバル割り込みハンドラ:

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) 

、あなたがCTRL-C、あなたのクリーンアップコードを実行すると、プログラムが終了します。主に私のPisでPerlを使用していますが、同じアプリケーションを再実行する前にすべてのピンをリ​​セットしたり、別のアプリを実行したりするために同じことをします。

+0

これはまだ動作していないようです – Jordan

+0

あなたは例外的なブロックに入れているわけではありませんか? – stevieb

+0

いいえ、 'signal.signal'は例外ブロックに入りますか? – Jordan

0

この機能で任意のキーを押すと、スクリプトを終了できます。私はまた、whileループに問題が表示されていないが、私は本当に別の方法を必要に応じて、私はこれを使用します。

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

別の同様の方法は非常に似呪いモジュールを使用することにより利用することができます。

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

Windowsを使用している場合、あなたはMSVCRTモジュールを使用することができます

import msvcrt 
c = msvcrt.getch() 
print 'you entered', c 
関連する問題