Lチカをキッチリ設計できればLED以外の制御もできます。ただし、こんな設計ではダメ―――です。
whileなどのループ
LED点灯
1秒待つ
LED消灯
1秒待つ
これでLチカはできます。しかし、1秒待つを実行中は他の処理をできません。
LEDの処理だけで途中でキーボードの入力処理をするなんてことができないのです。
今回の事例ではキッチリ設計をするにはどうするか?を解説します。
1.仕様を決める
機能 点灯・消灯・点滅の3種類。
点滅は500ms点灯、500ms消灯の固定時間とする。 →これらの状態を保持する グローバル変数
g_stateを実装する。
→タイマーを毎回セットするためにg_rootを実装する。
→現在のLED出力値を保存するg_ledOutを実装する。
GUIの設計
機能に対応したボタンを実装する。
2.設計
一般的なく組込みソフトと同様にタイマーは常時起動されている。点滅のみにLED制御が実行される。
# -*- coding: utf-8 -*-
import sys
import tkinter as tk
import wiringpi as wp
#LED点滅間隔
INTERVAL = 500
#LEDのステータス
ST_OFF = 0 #消灯
ST_ON = 1 #点灯
ST_BLINK = 3 #点滅
g_state = ST_OFF
#LEDポートの出力値
g_ledOut = 0
#afterを再セットするためのグローバル変数
g_root = None
#ボタンをクリックしたときのイベントハンドラー
#消灯
def turnOff():
global g_state
g_state = ST_OFF
wp.digitalWrite(7,0)
#点灯
def turnOn():
global g_state
g_state = ST_ON
wp.digitalWrite(7,1)
#点滅
def blink():
global g_state, g_ledOut
g_state = ST_BLINK
if g_ledOut == 0:
g_ledOut = 1
else:
g_ledOut = 0
wp.digitalWrite(7,g_ledOut)
#タイマー after のイベントハンドラー
def onTimer():
global g_state, g_ledOut
if g_state == ST_BLINK:
if g_ledOut == 0:
g_ledOut = 1
else:
g_ledOut = 0
wp.digitalWrite(7,g_ledOut)
g_root.after(INTERVAL, onTimer)
def main():
global g_root, g_ledOut
g_root = tk.Tk()
g_root.title("LED control")
g_root.geometry("250x40")
#wiringpaiの初期設定
wp.wiringPiSetup()
#7番ピンをシュル力に設定
wp.pinMode(7,1)
wp.digitalWrite(7,g_ledOut)
#消灯ボタン
btnOff = tk.Button(
g_root,
text='消灯',
command=turnOff)
btnOff.grid(row=0, column=0,padx=5, pady=5)
#点灯ボタン
btnOn = tk.Button(
g_root,
text='点灯',
bg='red',
command=turnOn)
btnOn.grid(row=0, column=1, padx=5, pady=5)
#点滅ボタン
btnBlink = tk.Button(
g_root,
text='点滅',
bg='pink',
command=blink)
btnBlink.grid(row=0, column=2, padx=5, pady=5)
#タイマーにLED点滅間隔とイベントハンドラーonTimerをセット
g_root.after(INTERVAL, onTimer)
g_root.mainloop()
if __name__ == "__main__":
main()
前述した仕様を実装しました。
点滅感間隔が簡単に変えることができます。
INTERVAL = 500
3.重要な確認
「Lチカできた~~」で終わってしまっている記事がほとんどです。しかし、重要な確認が抜けています。
本当にこの時間は正確なのか? 確認しました。
時間は正確です。
WindowsでSetTimerを使うとタイマーイベントが発生しないことがある。まるで不整脈みたいな問題です。ずぼらな表示などでいいならこれでOKです。しかし、きちんとしたタイマー処理をするにはマルチメディアタイマーを使います。(ちょっと厄介です)
500ms点灯、500消灯です。もし不整脈がおきれば1秒以上の連続点灯(または消灯)となるので目視でもわかります。短時間みたかぎりでは大丈夫なようです。 |