前回は液晶ディスプレイを消灯できるものに交換しました。
次はロマンを追い求めてみたいと思います。
仕様
- 部屋の照明が消える
- Arduino に接続された照度センサーにより部屋の照度を検知(50 以下になる)
- Python がシリアル通信から部屋の照度を取得(50 以下を取得)
- 部屋が暗い状態に(照度 50 以下に)変化したら液晶ディスプレイの消灯コマンドを実行
- 部屋の照明を点ける
- 部屋が明るい状態に(照度 50 以上に)変化したら点灯コマンドを実行
背景
- コマンドをいちいち打つのが面倒
- かといって部屋に人がいない(照明を消した)状態で LCD 点きっぱなしはもったいない
- ロマン重視
ハードウェア設計
マイコン:Arduino Micro
照度センサー:NJL7302L-F3 1個
抵抗:10kΩ 1個
回路はそれほど難しいものではないです。
入力は 5V で、出力が A3 と抵抗 10kΩ -> GND になっているだけです。
(回路図では抵抗が 220Ω になってますが、それしか絵が見つけられなかったので読み替えてください)
ソフトウェア設計
まずは Arduino で実行するプログラムのソースコードです。
A3(アナログ3番ポート)を読み取って、1秒おきにシリアル通信へ書き出すだけのシンプルなものです。
void setup() {
//start serial connection
Serial.begin(9600);
//configure pin A3 as an input and enable the internal resistor
pinMode(A3, INPUT);
}
void loop() {
//read the photocell value into a variable
int sensorVal = analogRead(A3);
//print out the value of the photocell
Serial.println(sensorVal);
//delay 1000 ms
delay(1000);
}
インターフェース設計
UI 画面表示とバックライト制御は Python が行います。
まずは Tkinter で画面を作りますが、パディング(padx, pady)を取ったところがグレーになってます。
※数値などの表示はダミーです。
ちなみにソースコードの一部はこんな感じ。
self.label1=Label(self, text="接続先", bg="white", font=("Sans", 16, "normal"))
self.label1.grid(row=0, column=0, sticky="news", padx=5, pady=2)
self.label2=Label(self, text="/dev/ttyACM0", bg="#E4E4FF", font=("Sans", 16, "normal"))
self.label2.grid(row=0, column=1, sticky="news", padx=5, pady=2)
内部パディング(ipadx, ipady)にしてはどうか。
結果はこちら。
いやいや、そうじゃないんだ。
空間というか、白背景で余白を持たせたいだけなんだ。
なんとかならないものかと調べていると、
白背景のフレームを親に置き、子としてラベルを所属させたら良いとの情報。
self.label1=Label(self, text="接続先", bg="white", font=("Sans", 16, "normal"))
self.label1.grid(row=0, column=0, sticky="news", ipadx=5, ipady=2)
self.frame2=Frame(self, bg="white")
self.frame2.grid(row=0, column=1, sticky="news")
self.frame2.columnconfigure(0, weight=1)
self.label2=Label(self.frame2, text="", bg="#E4E4FF", font=("Sans", 16, "normal"))
self.label2.grid(row=0, column=0, sticky="news", padx=5, pady=2)
```
<img width="286" alt="Screenshot_20200201[4].png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362854/be5f96fb-d4a7-0612-1d22-d02b3280a450.png">
今度はうまく行きました。
ネット民達は天才だらけですな。
しかし、これだけのために半日潰してますからね。報われないっす。
## 仕上げ
センサーデバイス(Arduino)を探して、接続できれば接続して「接続先」と「通信速度」を表示します。
例外時は何もしません。1秒後に再処理して接続できたらそれで良いと判断できるからです。
```Python:main.py
# 表示を更新
def update(self):
# センサーデバイスを探す
self.ser_name=sensor_setting.dev_search()
try:
# 通信準備中かつ、センサーデバイスが OS に認識されている場合
if not self.ser_init and self.ser_name != "":
# シリアル通信の初期化
self.ser=serial.Serial(self.ser_name, sensor_setting.bps, timeout=sensor_setting.timeout)
# 通信準備完了
self.ser_init=True
# 接続先を表示
self.label2.configure(text=self.ser_name)
# 接続速度を表示
self.label4.configure(text="{0}bps".format(sensor_setting.bps))
# 例外時は何もしない
except:
pass
```
接続できたらシリアル通信を開始して、照度を取得します。
部屋が暗くなったらバックライト消灯、明るくなったら点灯するように連動します。
例外発生時は次の1秒後にリトライします。
```Python:main.py
try:
# シリアル通信を開始
if self.ser.is_open == False:
self.ser.open()
# 1行受信(b'照度¥r¥n' の形式で受信)
serval=self.ser.readline()
if len(serval) >= 0:
# 改行コードを削除(b'照度')
serval=serval.strip()
# バイナリ形式から文字列に変換(照度)
serval=serval.decode("utf-8")
# 照度を更新
self.label12.configure(text=serval)
# バックライト点灯中に部屋が暗くなったら
if int(serval) < 50 and self.backlight_state == 1:
# バックライト消灯
os.system('sudo sh -c "echo 0 > /sys/class/backlight/soc\:backlight/brightness"')
self.backlight_state=0
# バックライト消灯中に部屋が明るくなったら
elif int(serval) >= 50 and self.backlight_state == 0:
# バックライト点灯
os.system('sudo sh -c "echo 1 > /sys/class/backlight/soc\:backlight/brightness"')
self.backlight_state=1
# 例外時
except:
# センサー表示をクリア
self.label6.configure(text="")
self.label8.configure(text="")
self.label10.configure(text="")
self.label12.configure(text="")
# 1秒後に再表示
self.master.after(1000, self.update)
```
ウィンドウを閉じる前に、バックライトを点灯します。
バックライト制御が中断するので、点灯しておいた方が何かあったときは便利かなと思いました。
```Python:main.py
# 閉じるボタンイベント
def on_closing():
if messagebox.askyesno("Quit", "終了しますか?"):
# バックライト点灯
os.system('sudo sh -c "echo 1 > /sys/class/backlight/soc\:backlight/brightness"')
# アプリケーション終了
root.destroy()
```
## まとめ
Python ソースコードは長めなので、
ご興味ありましたら GitHub をご参照ください。
https://github.com/km7902/mySensor
なんとか、部屋の照明と連動してバックライト ON/OFF ができるようになりました。
消費電力は「ちりつも」ですから。地球に優しいシステムになりました。
次は温度・湿度・気圧を取得してデータベースに記録し続けるという
仕組みができたらいいなと思っています。