You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下Python脚本触发Ctrl+C键盘中断时无法稳定清空LCD显示屏问题

故障根因
  • 你当前依赖KeyboardInterrupt异常捕获的处理逻辑,会在代码任意执行位置触发中断,若中断刚好发生在lcd_driver内部和LCD硬件通信的过程中,会导致驱动对象状态异常,后续finally块调用的清屏、关背光操作就会失效,这就是你遇到的概率性失败的核心原因。
  • 大部分LCD驱动的操作是异步发指令到硬件,若Python进程在指令未完全发送到硬件前就退出,也会导致操作不生效。
  • 原代码中多个循环没有添加短延迟,CPU占用过高也会增加指令发送被打断的概率。
解决方案
  1. 显式注册SIGINT(Ctrl+C触发的信号)处理函数,设置退出标记,所有循环逻辑检测到退出标记后主动退出,避免异步中断打断LCD驱动的正常操作,保证驱动状态一致。
  2. 在清屏、关背光操作前后增加短延迟,确保硬件指令完全下发完成后进程再退出。
  3. 修复Python3环境下getaddr函数的字节编码报错问题,降低功能异常概率。
修改后的完整代码
#!/usr/bin/env python

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

PIN = 23
COUNT = 0
# 新增全局退出标记
exit_flag = False

# 新增SIGINT信号处理函数
def sigint_handler(signum, frame):
    global exit_flag
    exit_flag = True

# 注册信号处理逻辑
signal.signal(signal.SIGINT, sigint_handler)

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:
        if exit_flag:
            break
        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
        sleep(0.5)

def curtime():
    while True:
        if exit_flag:
            break
        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
        sleep(0.2)

def getaddr(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,
        # 修复Python3下字符串需转字节的问题
        struct.pack('256s', ifname[:15].encode())
    )[20:24])

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

try:
    while True:
        if exit_flag:
            break
        button = GPIO.input(PIN)
        if button == True:
                if COUNT == 0:
                    disp.lcdstring("Press the Button",1,0)
                    disp.lcdstring("To Start Demo!",2,1)
                    sleep(0.2)
                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)

finally:
    # 等待当前未完成的驱动操作执行结束
    sleep(0.2)
    disp.clear()
    # 等待清屏指令完全下发到硬件
    sleep(0.3)
    disp.backlight(0)
    sleep(0.2)
    GPIO.cleanup()

内容的提问来源于stack exchange,提问作者Kristal Luna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 07:06:03