How to get Python to run display clear on keyboard interrupt

Viewed 115

My Question is for the very end, I am trying to get the script to clear the display and disable the backlight when Control + C is pressed in linux, half of the time the lcd display will not clear

I have tried to get the python to close properly and clear the display but it only works a portion of time, even with sleep(1) added

#!/usr/bin/env python

import RPi.GPIO as GPIO
import lcd_driver
import socket
import struct
import fcntl
import time
import os
import re
from time import sleep

PIN = 23
COUNT = 0

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(PIN,GPIO.IN,pull_up_down=GPIO.PUD_UP)

print('Writing to Display!')
disp = lcd_driver.lcd()

def cputemp():
    while True:
        cputemp = os.popen("vcgencmd measure_temp").readline()
        celsius = re.sub("[^0123456789/.]", "", cputemp)
        fahrenheit = int(9.0/5.0*int(float(celsius)+32))
        disp.lcdstring("Cpu : {} C".format(celsius), 1)
        disp.lcdstring("Temp: {}  F".format(fahrenheit), 2)
        button = GPIO.input(PIN)
        if button == False:
            break

def curtime():
    while True:
        disp.lcdstring("Time: {}".format(time.strftime("%H:%M:%S")), 1)
        disp.lcdstring("Date: {}".format(time.strftime("%m/%d/%Y")), 2)
        button = GPIO.input(PIN)
        if button == False:
            break

def getaddr(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,
        struct.pack('256s', ifname[:15])
    )[20:24])

def getip():
    ip = getaddr('wlan0')
    while True:
        disp.lcdstring("IP Address: WiFi", 1)
        disp.lcdstring(ip, 2)
        button = GPIO.input(PIN)
        if button == False:
            break

try:
    while True:
            button = GPIO.input(PIN)
            if button == True:
                    if COUNT == 0:
                        disp.lcdstring("Press the Button",1,0)
                        disp.lcdstring("To Start Demo!",2,1)
                    if COUNT == 1:
                        disp.clear()
                        cputemp()
                    if COUNT == 2:
                        disp.clear()
                        curtime()
                    if COUNT == 3:
                        disp.clear()
                        getip()
                    if COUNT == 4:
                        disp.clear()
                        COUNT = 1
                    if COUNT > 4:
                        disp.clear()
                        COUNT = 0

        if button == False:
                COUNT = COUNT +1
                sleep(0.5)

except KeyboardInterrupt:
    pass

finally:
    disp.clear()
    disp.backlight(0)
    GPIO.cleanup()

3 Answers

You can add a shutdown hook using the atexit module

example code:

import RPi.GPIO as GPIO
import lcd_driver
import socket
import struct
import atexit
import fcntl
import time
import os
import re
from time import sleep

def exit_handler():
   print(' Cleaning Up!')
   disp.clear()
   disp.backlight(0)
   GPIO.cleanup()
   exit(1)
atexit.register(exit_handler)
try:
    while True:
            button = GPIO.input(PIN)
            if button == True:
                    if COUNT == 0:
                        disp.lcdstring("Press the Button",1,0)
                        disp.lcdstring("To Start Demo!",2,1)
                    if COUNT == 1:
                        disp.clear()
                        cputemp()
                    if COUNT == 2:
                        disp.clear()
                        curtime()
                    if COUNT == 3:
                        disp.clear()
                        getip()
                    if COUNT == 4:
                        disp.clear()
                        COUNT = 1
                    if COUNT > 4:
                        disp.clear()
                        COUNT = 0

        if button == False:
                COUNT = COUNT +1
                sleep(0.5)

except KeyboardInterrupt:
   pass 

I use it on OrangePI to close a value when my code crash/exit and it works every time

import RPi.GPIO as GPIO
import lcd_driver
import socket
import struct
import atexit
import fcntl
import time
import os
import re
from time import sleep

def exit_handler():
   print(' Cleaning Up!')
   disp.clear()
   disp.backlight(0)
   GPIO.cleanup()
   exit(1)

try:
    while True:
            button = GPIO.input(PIN)
            if button == True:
                    if COUNT == 0:
                        disp.lcdstring("Press the Button",1,0)
                        disp.lcdstring("To Start Demo!",2,1)
                    if COUNT == 1:
                        disp.clear()
                        cputemp()
                    if COUNT == 2:
                        disp.clear()
                        curtime()
                    if COUNT == 3:
                        disp.clear()
                        getip()
                    if COUNT == 4:
                        disp.clear()
                        COUNT = 1
                    if COUNT > 4:
                        disp.clear()
                        COUNT = 0

        if button == False:
                COUNT = COUNT +1
                sleep(0.5)


except KeyboardInterrupt:
   pass

finally:    
   atexit.register(exit_handler)

Working code!!!

For Simplicity, being I can't vote yet

The difference is importing the atexit library Adding in the event handler at top of code and replacing lcd.clear with lcd_driver.lcd()

And omitting the keyboard interrupt and following code to reflect how it is currently

#!/usr/bin/env python

import RPi.GPIO as GPIO
import lcd_driver
import socket
import struct
import atexit
import fcntl
import time
import os
import re
from time import sleep

PIN = 23
COUNT = 0

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(PIN,GPIO.IN,pull_up_down=GPIO.PUD_UP)

print('Writing to Display!')
disp = lcd_driver.lcd()

def exit_handler():
   disp = lcd_driver.lcd()
   disp.backlight(0)
   GPIO.cleanup()

atexit.register(exit_handler) 

def cputemp():
    while True:
        cputemp = os.popen("vcgencmd measure_temp").readline()
        celsius = re.sub("[^0123456789/.]", "", cputemp)
        fahrenheit = int(9.0/5.0*int(float(celsius)+32))
        disp.lcdstring("Cpu : {} C".format(celsius), 1)
        disp.lcdstring("Temp: {}  F".format(fahrenheit), 2)
        button = GPIO.input(PIN)
        if button == False:
            break

def curtime():
    while True:
        disp.lcdstring("Time: {}".format(time.strftime("%H:%M:%S")), 1)
        disp.lcdstring("Date: {}".format(time.strftime("%m/%d/%Y")), 2)
        button = GPIO.input(PIN)
        if button == False:
            break

def getaddr(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,
        struct.pack('256s', ifname[:15])
    )[20:24])

def getip():
    ip = getaddr('wlan0')
    while True:
        disp.lcdstring("IP Address: WiFi", 1)
        disp.lcdstring(ip, 2)
        button = GPIO.input(PIN)
        if button == False:
            break

try:
    while True:
        button = GPIO.input(PIN)
        if button == True:
                if COUNT == 0:
                    disp.lcdstring("Press the Button",1,0)
                    disp.lcdstring("To Start Demo!",2,1)
                if COUNT == 1:
                    disp.clear()
                    cputemp()
                if COUNT == 2:
                    disp.clear()
                    curtime()
                if COUNT == 3:
                    disp.clear()
                    getip()
                if COUNT == 4:
                    disp.clear()
                    COUNT = 1
                if COUNT > 4:
                    disp.clear()
                    COUNT = 0

        if button == False:
            COUNT = COUNT +1
            sleep(0.5)

except KeyboardInterrupt:
   pass 
Related