kuroの覚え書き

96の個人的覚え書き

ラズパイにキャラクタディスプレイとシャットダウンスイッチ

ラズパイには電源ボタンがない。電源を入れるときはケーブルを刺すだけなので、別に困りはしないが、切るときはネットワーク越しにアクセスするか、キーボードとモニタを繋いでシャットダウンするしかない。もしくはブチっとケーブルを抜くか。ハードディスクを繋いでいなければ、いきなり切っても物理的に破壊される可能性は低いが、データが壊れる可能性は否定できない。そこでシャットダウンスイッチを付けて、OSのシャットダウンができるようにしてみた。
基本的にはpythonのプログラムをバックグラウンドで待機させておき、ボタンの押下を検出したらシャットダウンシークエンスを開始させるようにするわけだ。
以前に作成したキャラクタディスプレイにボタンを追加する形である程度の利便性を出してみた。
ボタンを軽く押すとIPアドレスWiFiのIDを表示させる。
ボタンを3秒押し続けるとシャットダウンに移行する、という感じだ。

#!/usr/bin/python3
# coding: utf-8
import subprocess
import Adafruit_CharLCD as LCD
import os, time
import RPi.GPIO as GPIO

# GPIO
lcd_rs        = 17
lcd_en        = 27
lcd_d4        = 11
lcd_d5        = 22
lcd_d6        = 9
lcd_d7        = 10

sw            = 4

GPIO.setmode(GPIO.BCM)
GPIO.setup(sw, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# LCD size
lcd_columns = 8
lcd_rows    = 2

# Adafruit_CharLCD
lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7,
                       lcd_columns, lcd_rows)
# reset lcd
def main():
    lcd.clear()
    cmd='date "+%Y/%m/%d %H:%M:%S" > date.txt'
    subprocess.call(cmd, shell=True)
    with open('date.txt') as f:
       dt=f.read()
    cmd='ip a show eth0 | grep "inet " |cut -f6,13 -d " " > eth0.txt'
    subprocess.call(cmd, shell=True)
    with open('eth0.txt') as f:
        ip1=f.read()
    cmd='ip a show wlan0 | grep "inet " |cut -f6,12 -d " " > wlan0.txt'
    subprocess.call(cmd, shell=True)
    with open('wlan0.txt') as f:
        ip2=f.read()
    cmd='iwconfig wlan0 | grep "ESSID" |cut -f9 -d " " > essid.txt'
    subprocess.call(cmd, shell=True)
    with open('essid.txt') as f:
        ip3=f.read()

    # Demo scrolling message right/left.
    lcd.clear()
    lcd.set_cursor(7,0)
    lcd.message(dt)
    for i in range(lcd_columns+len(dt)):
        time.sleep(0.2)
        lcd.move_left()
    time.sleep(1.0)
    lcd.clear()
    lcd.set_cursor(7,0)
    lcd.message(ip1)
    for i in range(lcd_columns+len(ip1)):
        time.sleep(0.2)
        lcd.move_left()
    time.sleep(1.0)
    lcd.clear()
    lcd.set_cursor(7,0)
    lcd.message(ip3)
    for i in range(lcd_columns+len(ip3)):
        time.sleep(0.2)
        lcd.move_left()
    time.sleep(1.0)
    lcd.clear()
    lcd.set_cursor(7,0)
    lcd.message(ip2)
    for i in range(lcd_columns+len(ip2)):
        time.sleep(0.2)
        lcd.move_left()
    lcd.clear()

def sd_proc():
    time.sleep(0.5)
    lcd.clear()
    lcd.set_cursor(0,0)
    lcd.message("Shutdown")
    time.sleep(0.5)
    lcd.set_cursor(0,1)
    lcd.message("process")
    time.sleep(1.0)
    lcd.clear()
    lcd.set_cursor(0,0)
    lcd.message("selected")
    time.sleep(1.0)
    lcd.clear()
    lcd.set_cursor(0,0)
    lcd.message("Goodbye!")
    time.sleep(2.0)
    lcd.clear()
    os.system( "sudo shutdown -h now" )

if __name__ == '__main__':

    try:
        while True:
            if GPIO.input(sw) == GPIO.LOW:
                time.sleep(3)
                if GPIO.input(sw) == GPIO.LOW:
                    sd_proc()
                else:
                    main()
            else:
                pass
            time.sleep(0.01)
    except KeyboardInterrupt:
        GPIO.cleanup()

ただ、ラズパイの仕様でOSをシャットダウンしてもボードの電源回路は落ちないので、ヘッダピンの電源が切れることはないため、LCDのバックライトが点きっぱなしなのがイマイチなのだが。