无法退出正在运行的python脚本

时间:2016-12-30 15:05:08

标签: python raspberry-pi pubnub keyboardinterrupt

我刚开始用python学习Raspberry Pi开发,并在我的面包板上设置了一个简单的RGB LED电路设置,然后我将它连接到Pubnub,从我构建的一个小网页界面控制它,它只发送一个方法名称和RGB值python脚本已订阅特定频道的Pubnub。

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

除了尝试关闭程序并清理GPIO引脚,取消订阅频道等外,所有这些都有效。

在过去,我使用过while True:循环,但是由于我不想在循环中执行某些操作,所以我只想打开一个连接并保持打开直到我终止它一个循环在这里没有意义

点击Ctrl + C只输出KeyboardInterrupt但它似乎没有调用except块

如何才能终止和清理GPIO引脚?

更新

重构使用signal后,我现在替换try...except(假设我已将它们导入文件顶部)

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)

但是,按ctrl + c仍然不会关闭程序并运行清理代码

2 个答案:

答案 0 :(得分:2)

使用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,但是我做同样的事情以确保在重新运行相同的应用程序或运行不同的应用程序之前重置所有引脚。

答案 1 :(得分: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()

使用 curses 模块可以使用另一种类似的方法:

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