LoginSignup
3
6

More than 3 years have passed since last update.

【RaspberryPi】部屋の照明を消すと自動的に LCD も消灯するエコ設計 DIY

Last updated at Posted at 2020-02-04

前回は液晶ディスプレイを消灯できるものに交換しました。
次はロマンを追い求めてみたいと思います。

仕様

  1. 部屋の照明が消える
  2. Arduino に接続された照度センサーにより部屋の照度を検知(50 以下になる)
  3. Python がシリアル通信から部屋の照度を取得(50 以下を取得)
  4. 部屋が暗い状態に(照度 50 以下に)変化したら液晶ディスプレイの消灯コマンドを実行
  5. 部屋の照明を点ける
  6. 部屋が明るい状態に(照度 50 以上に)変化したら点灯コマンドを実行

背景

  • コマンドをいちいち打つのが面倒
  • かといって部屋に人がいない(照明を消した)状態で LCD 点きっぱなしはもったいない
  • ロマン重視

ハードウェア設計

マイコン:Arduino Micro
照度センサー:NJL7302L-F3 1個
抵抗:10kΩ 1個

回路はそれほど難しいものではないです。
入力は 5V で、出力が A3 と抵抗 10kΩ -> GND になっているだけです。
(回路図では抵抗が 220Ω になってますが、それしか絵が見つけられなかったので読み替えてください)
Screenshot_20200201[1].png

IMG_20200201_1728.jpg

参考:ちびでぃ〜の2で遊んでみた

ソフトウェア設計

まずは Arduino で実行するプログラムのソースコードです。
A3(アナログ3番ポート)を読み取って、1秒おきにシリアル通信へ書き出すだけのシンプルなものです。

mySketch.ino
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)を取ったところがグレーになってます。
Screenshot_20200201[2].png
※数値などの表示はダミーです。

ちなみにソースコードの一部はこんな感じ。

main.py
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)にしてはどうか。
結果はこちら。
Screenshot_20200201[3].png
いやいや、そうじゃないんだ。
空間というか、白背景で余白を持たせたいだけなんだ。

なんとかならないものかと調べていると、
白背景のフレームを親に置き、子としてラベルを所属させたら良いとの情報。

main.py
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)

Screenshot_20200201[4].png
今度はうまく行きました。
ネット民達は天才だらけですな。
しかし、これだけのために半日潰してますからね。報われないっす。

仕上げ

センサーデバイス(Arduino)を探して、接続できれば接続して「接続先」と「通信速度」を表示します。
例外時は何もしません。1秒後に再処理して接続できたらそれで良いと判断できるからです。

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秒後にリトライします。

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)

ウィンドウを閉じる前に、バックライトを点灯します。
バックライト制御が中断するので、点灯しておいた方が何かあったときは便利かなと思いました。

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 ができるようになりました。
消費電力は「ちりつも」ですから。地球に優しいシステムになりました。

次は温度・湿度・気圧を取得してデータベースに記録し続けるという
仕組みができたらいいなと思っています。

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6