部屋がどうしようもなく暑い。
という訳でこの夏、2階の部屋に屋根裏換気扇を付けました。
三菱電機 換気排熱ファン V-20MEX2
主に天井に取り付け、熱せられた屋根裏の熱を室内の空気ごと建屋外に排熱する換気扇。
裏側のファン部分が丸ごと上下し、OFF時には完全に通気口を塞ぐ気密を落とさない構造になっています。
天井に穴を開ける勇気がなくて点検口のフタを繰り抜いてとりつけ。また電気工事士の資格もないため、ながーいAC100Vコードをくっつけてそれの抜き差しでOFF/ONする仕組み。
取り付けて早速回してみましたが、今ひとつ換気の効果が出ていません。
これは恐れていたというかむしろなんとなくそんな気はしていた屋根裏密閉構造なのかもしれない・・・。そうなるともう工事屋さんの世界ではあるけれどどのみち屋根裏換気は必要だから良しとしよう。
OFF/ONはラズパイで
換気扇の改善はおいおい考えるとして、換気扇のOFF/ONはRaspberry Piでやろうと決めてました。
余っていたRaspberry Pi 1 Model B+(タブン)に同じく余っていたRaspberryHabuと(略)Corega CG-WLUSB300GNMと(略)DHT11でこんな感じに組みました。
今回タクトスイッチでの入力を行うためTC4050BPを追加しています。
GPIOと物理デバイスの配線は以下のとおり。
GPIO No.(MODE) | Device |
0(Input) | タクトスイッチ |
3(Output) | LED |
5(Input) | DHT11 |
7(Output) | リレー |
換気扇から伸びる100Vケーブルの片側をカットし、リレーを間にはさみます。。
プログラム
何を実現するコードかといいますと
- テキストにONって書いてあったらリレーをONにする
- タクトスイッチを押すとOFF←→ONをトグルできる
だけです。
require 'wiringpi' require 'fileutils' #init flag_file = "/dev/shm/flag_file.dat" io = WiringPi::GPIO.new do |gpio| gpio.pin_mode(3, WiringPi::OUTPUT) gpio.pin_mode(7, WiringPi::OUTPUT) gpio.pin_mode(0, WiringPi::INPUT) end io.digital_write(3, WiringPi::LOW) io.digital_write(7, WiringPi::LOW) f_chk_code = "ON" # FLAG READ def flag_read flag_file = "/dev/shm/flag_file.dat" File.open(flag_file, "r:UTF-8") do |f| f_chk = f.gets return f_chk.chomp! end end # FLAG WRITE def flag_write(fw) flag_file = "/dev/shm/flag_file.dat" File.open(flag_file, "w:UTF-8") do |f| if f.flock(File::LOCK_EX|File::LOCK_NB) if fw >= 1 then f.puts("ON") puts "push botton ON" else f.puts("OFF") puts "push botton OFF" end return 0 else return 1 end end end # Main loop loop do now = flag_read #button check buttom_state = io.digital_read(0) if buttom_state == 1 then sleep(0.4) buttom_state = io.digital_read(0) if buttom_state == 1 then if now == f_chk_code res = flag_write(0) else res = flag_write(1) end end end #Relay Switch if now == f_chk_code then io.digital_write(3, WiringPi::HIGH) io.digital_write(7, WiringPi::HIGH) puts "flag is HIGH" else io.digital_write(3, WiringPi::LOW) io.digital_write(7, WiringPi::LOW) puts "flag is LOW" end sleep(0.5) end
解説というより自分メモ
4-17行目
初期化。8-12行目はGPIO各ピンの動作モードを指定。書式はWiringPiの公式(?)より。
20-27行目
flag_readというメソッドを定義しています。
フラグを書いたテキストファイル(/dev/shm/flag_file.dat)=フラグファイルを読み込んで変数に入れます。その後.chomp!メソッドを使って改行コードを取り除いています。これをやらないとただ単にif f_chk == ONとやっても必ずfalseになります。解るまで正直かなりかかりました。
flag_file =は各所に書いてありますが、メソッドの中で書かないとエラーになった為。何か手があるんでしょう。きっと・・・
29-46行目
flag_writeというメソッドを定義しています。
フラグファイルを作成するのですが、このファイルは他プログラムが書く可能性もあるので.flockメソッドを使ってロックファイルによる排他制御を行っています。その競合により書き込めなかった場合は1を戻り値に返しますが、特にノーアクション。ループしてるのでまた押せばいいかという運用。
今後は初期のフラグファイル作成もここでやる予定
49-80行目
メインのループ
55-66行目はタクトスイッチが押されているかを読み取り、押されている場合0.4秒まってもう一度読み込みます。それでも押されている場合は現在のフラグファイルと比較し今がONならOFFへ、今がOFFならONへリレーをトグルします。
メソッドを呼び出すときの引数は数字だそうですよ。最初ONとか書いて止まってました。
68-77行目でフラグファイルの読み出し結果とチェックコードを比較して、一致すればリレーとステータスLEDをONへ、不一致であれば両方をOFFのにします。
これはメソッドで書けたら良さそうなものですが、io.digital_writeはメソッド内では使えないようで。
実行結果と今後
putsで0.5秒おきにメッセージを出しつつ、ボタンが押されるのを待ちます。チャタリング防止に0.4秒ほど押し続けた時のみフラグファイルの中身が変わるようにしました。その後ポーリングでフラグファイルをチェックし、ONと書いてあればGPIOをONにします。
flag is LOW flag is LOW flag is LOW flag is LOW push botton ON flag is LOW flag is HIGH flag is HIGH flag is HIGH flag is HIGH flag is HIGH push botton OFF flag is HIGH flag is LOW flag is LOW flag is LOW flag is LOW
テキストファイルに希望のステータスを書いてから読み取って変更する手間を組んだため長くなりました。その代わり今後Ruby以外(ex.コマンドの実行結果によってシェルスクリプトから)でも変更指示をかけられます。
CでかかれたDHT11温度読み取りの結果をテキストに吐いて、Wgetで取得したWeb上の気温との差分を出して換気扇を動作。そんな事がやりたいなと思っています。もしテキスト公開している外気温データがなければ、別の涼しい場所においているもう一つのラズパイから温度データを取得して温度差を動作条件としてもいいかもしれません。
2016/08/17 追記
続編はこちら