However, on occasion (sometimes with large amounts of button presses, other times less-predictably), the script will become unresponsive. So I created a restart_program() function which kicks everything off again at the end of the 30-second limit. This way, if things freeze, all will be well 30 seconds later. That worked fine for a couple of days, but now I've been getting this error after any range of 5-75 minutes of the script running:
Code: Select all
RuntimeError: Failed to add edge detectionIs there something I can do to re-launch the script if it crashes? Or, even better, how do I keep the script from crashing?
Code: Select all
import sys
import os
import RPi.GPIO as GPIO
from Adafruit_MCP230xx import *
from time import sleep
from datetime import datetime
print 'Program running at'+str(datetime.now())
#Configuration
SWITCH1=40
SWITCH2=38
SWITCH3=36
SWITCH4=32
SWITCH5=22
SWITCH6=18
SWITCH7=16
SWITCH8=12
SWITCH9=7
SWITCH10=11
SWITCH11=13
SWITCH12=15
SWITCH13=29
SWITCH14=31
SWITCH15=33
SWITCH16=35
OnTimeInSeconds=30
mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 16) # MCP23017
#End Configuration
Counter=0
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(SWITCH1, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH2, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH3, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH4, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH6, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH7, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH8, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH9, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH10, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH11, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH12, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH13, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH14, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH15, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SWITCH16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Set MCP pins 0-15 to output (you can set pins 0..15 this way)
mcp.config(0, mcp.OUTPUT)
mcp.config(1, mcp.OUTPUT)
mcp.config(2, mcp.OUTPUT)
mcp.config(3, mcp.OUTPUT)
mcp.config(4, mcp.OUTPUT)
mcp.config(5, mcp.OUTPUT)
mcp.config(6, mcp.OUTPUT)
mcp.config(7, mcp.OUTPUT)
mcp.config(8, mcp.OUTPUT)
mcp.config(9, mcp.OUTPUT)
mcp.config(10, mcp.OUTPUT)
mcp.config(11, mcp.OUTPUT)
mcp.config(12, mcp.OUTPUT)
mcp.config(13, mcp.OUTPUT)
mcp.config(14, mcp.OUTPUT)
mcp.config(15, mcp.OUTPUT)
''' For reference, the MCP output pins are connected to the LEDs as follows:
[ 0] [ 1] [ 2] [ 3]
[ 4] [ 5] [ 6] [ 7]
[ 8] [ 9] [10] [11]
[12] [13] [14] [15]
'''
mcp.output(0, 0)
mcp.output(6, 0)
mcp.output(9, 0)
mcp.output(15, 0)
state1=0
state2=0
state3=0
state4=0
state5=0
state6=0
state7=0
state8=0
state9=0
state10=0
state11=0
state12=0
state13=0
state14=0
state15=0
state16=0
def restart_program():
python = sys.executable
os.execl(python, python, * sys.argv)
def Tick():
global Counter
if (Counter<OnTimeInSeconds-1):
Counter+=1
else:
global state1
global state2
global state3
global state4
global state5
global state6
global state7
global state8
global state9
global state10
global state11
global state12
global state13
global state14
global state15
global state16
mcp.output(0, 0)
mcp.output(1, 0)
mcp.output(2, 0)
mcp.output(3, 0)
mcp.output(4, 0)
mcp.output(5, 0)
mcp.output(6, 0)
mcp.output(7, 0)
mcp.output(8, 0)
mcp.output(9, 0)
mcp.output(10, 0)
mcp.output(11, 0)
mcp.output(12, 0)
mcp.output(13, 0)
mcp.output(14, 0)
mcp.output(15, 0)
state1=0
state2=0
state3=0
state4=0
state5=0
state6=0
state7=0
state8=0
state9=0
state10=0
state11=0
state12=0
state13=0
state14=0
state15=0
state16=0
# GPIO.cleanup()
restart_program()
def Cleanup():
GPIO.cleanup()
mcp.output(0,0)
mcp.output(0, 0)
mcp.output(1, 0)
mcp.output(2, 0)
mcp.output(3, 0)
mcp.output(4, 0)
mcp.output(5, 0)
mcp.output(6, 0)
mcp.output(7, 0)
mcp.output(8, 0)
mcp.output(9, 0)
mcp.output(10, 0)
mcp.output(11, 0)
mcp.output(12, 0)
mcp.output(13, 0)
mcp.output(14, 0)
mcp.output(15, 0)
def Mainloop():
while True:
sleep(1)
Tick()
print Counter
def Toggle1(Channel):
global state1
global Counter
Counter=0
if state1 == 0:
mcp.output(0, 1)
state1 = 1
print('LED 1 On')
else:
mcp.output(0, 0)
state1 = 0
print ('LED 1 Off')
def Toggle2(Channel):
global state2
global Counter
Counter=0
if state2 == 0:
mcp.output(1, 1)
state2 = 1
print('LED 2 On')
else:
mcp.output(1, 0)
state2 = 0
print ('LED 2 Off')
def Toggle3(Channel):
global state3
global Counter
Counter=0
if state3 == 0:
mcp.output(2, 1)
state3 = 1
print('LED 3 On')
else:
mcp.output(2, 0)
state3 = 0
print ('LED 3 Off')
def Toggle4(Channel):
global state4
global Counter
Counter=0
if state4 == 0:
mcp.output(3, 1)
state4 = 1
print('LED 4 On')
else:
mcp.output(3, 0)
state4 = 0
print ('LED 4 Off')
def Toggle5(Channel):
global state5
global Counter
Counter=0
if state5 == 0:
mcp.output(4, 1)
state5 = 1
print('LED 5 On')
else:
mcp.output(4, 0)
state5 = 0
print ('LED 5 Off')
def Toggle6(Channel):
global state6
global Counter
Counter=0
if state6 == 0:
mcp.output(5, 1)
state6 = 1
print('LED 6 On')
else:
mcp.output(5, 0)
state6 = 0
print ('LED 6 Off')
def Toggle7(Channel):
global state7
global Counter
Counter=0
if state7 == 0:
mcp.output(6, 1)
state7 = 1
print('LED 7 On')
else:
mcp.output(6, 0)
state7 = 0
print ('LED 7 Off')
def Toggle8(Channel):
global state8
global Counter
Counter=0
if state8 == 0:
mcp.output(7, 1)
state8 = 1
print('LED 8 On')
else:
mcp.output(7, 0)
state8 = 0
print ('LED 8 Off')
def Toggle9(Channel):
global state9
global Counter
Counter=0
if state9 == 0:
mcp.output(8, 1)
state9 = 1
print('LED 9 On')
else:
mcp.output(8, 0)
state9 = 0
print ('LED 9 Off')
def Toggle10(Channel):
global state10
global Counter
Counter=0
if state10 == 0:
mcp.output(9, 1)
state10 = 1
print('LED 10 On')
else:
mcp.output(9, 0)
state10 = 0
print ('LED 10 Off')
def Toggle11(Channel):
global state11
global Counter
Counter=0
if state11 == 0:
mcp.output(10, 1)
state11 = 1
print('LED 11 On')
else:
mcp.output(10, 0)
state11 = 0
print ('LED 11 Off')
def Toggle12(Channel):
global state12
global Counter
Counter=0
if state12 == 0:
mcp.output(11, 1)
state12 = 1
print('LED 12 On')
else:
mcp.output(11, 0)
state12 = 0
print ('LED 12 Off')
def Toggle13(Channel):
global state13
global Counter
Counter=0
if state13 == 0:
mcp.output(12, 1)
state13 = 1
print('LED 13 On')
else:
mcp.output(12, 0)
state13 = 0
print ('LED 13 Off')
def Toggle14(Channel):
global state14
global Counter
Counter=0
if state14 == 0:
mcp.output(13, 1)
state14 = 1
print('LED 14 On')
else:
mcp.output(13, 0)
state14 = 0
print ('LED 14 Off')
def Toggle15(Channel):
global state15
global Counter
Counter=0
if state15 == 0:
mcp.output(14, 1)
state15 = 1
print('LED 15 On')
else:
mcp.output(14, 0)
state15 = 0
print ('LED 15 Off')
def Toggle16(Channel):
global state16
global Counter
Counter=0
if state16 == 0:
mcp.output(15, 1)
state16 = 1
print('LED 16 On')
else:
mcp.output(15, 0)
state16 = 0
print ('LED 16 Off')
GPIO.add_event_detect(SWITCH1,GPIO.FALLING,callback=Toggle1,bouncetime=200)
GPIO.add_event_detect(SWITCH2,GPIO.FALLING,callback=Toggle2,bouncetime=200)
GPIO.add_event_detect(SWITCH3,GPIO.FALLING,callback=Toggle3,bouncetime=200)
GPIO.add_event_detect(SWITCH4,GPIO.FALLING,callback=Toggle4,bouncetime=200)
GPIO.add_event_detect(SWITCH5,GPIO.FALLING,callback=Toggle5,bouncetime=200)
GPIO.add_event_detect(SWITCH6,GPIO.FALLING,callback=Toggle6,bouncetime=200)
GPIO.add_event_detect(SWITCH7,GPIO.FALLING,callback=Toggle7,bouncetime=200)
GPIO.add_event_detect(SWITCH8,GPIO.FALLING,callback=Toggle8,bouncetime=200)
GPIO.add_event_detect(SWITCH9,GPIO.FALLING,callback=Toggle9,bouncetime=200)
GPIO.add_event_detect(SWITCH10,GPIO.FALLING,callback=Toggle10,bouncetime=200)
GPIO.add_event_detect(SWITCH11,GPIO.FALLING,callback=Toggle11,bouncetime=200)
GPIO.add_event_detect(SWITCH12,GPIO.FALLING,callback=Toggle12,bouncetime=200)
GPIO.add_event_detect(SWITCH13,GPIO.FALLING,callback=Toggle13,bouncetime=200)
GPIO.add_event_detect(SWITCH14,GPIO.FALLING,callback=Toggle14,bouncetime=200)
GPIO.add_event_detect(SWITCH15,GPIO.FALLING,callback=Toggle15,bouncetime=200)
GPIO.add_event_detect(SWITCH16,GPIO.FALLING,callback=Toggle16,bouncetime=200)
Counter=0
try:
Mainloop()
except KeyboardInterrupt:
Cleanup()