もみあげあしめ

組み込みとかIoTとか、いろいろ

Philips Hue に物理スイッチをつける

Philips Hue には、スマホなしでの操作を可能にする(Philips Hue Tapスイッチ)がある。
そのお値段、なんと樋口一葉野口英世

f:id:shima_nigoro:20160919204751p:plain:w300
うん、自分で作ろう。

この記事の目標

3つの物理スイッチで Philips Hue の電源をON/OFFとシーンの切り替えを行う。

用意するもの

どのご家庭にもある、次の素材を使ってサクッと作ります。

Raspberry Pi 3 Model B (Element14)

  • ブレッドボード

サンハヤト SAD-101 ニューブレッドボード

  • ジャンパワイヤ
    • オス - オス( * 5 )+ オス - メス( * 3 )

ジャンパワイヤ(オス?オス) 10本セットジャンパワイヤ(オス?メス) 10本セット

  • タクトスイッチ( * 3 )

uxcell タクトスイッチ PCBモーメンタリ触覚タクトプッシュボタンスイッチ   4ピンDIP 6x6x4.5mm 10個入り

お好みでタクトスイッチをON/OFFスイッチに変更していただいても問題ありません。
#消費電力も上がるし、この記事で紹介するコードでは動作しませんが…。

スイッチを組み立てる

Raspberry PiにはGPIO(General Purpose Input / Output = 汎用入出力)が結構用意されている。
GPIOを使うと自由に電気信号を出力したり、入力を受けたりできる。

今回はこのGPIOポートを使って物理スイッチを実現する。
#今回はといいつつ、大抵の物理スイッチはほぼ同じ仕組みで動いていると思うが…。

Raspberry Pi に入力するためのピンを決める

11, 13, 15番のピンがちょうど 3.3V 電源と GND に挟まれているのでそこを使う。
f:id:shima_nigoro:20160925153709j:plain:h200

配線する

3.3V 電源と GND から伸ばしたジャンパワイヤをブレッドボードの + と - の部分に挿す。
11, 13, 15番のピンから伸ばしたジャンパワイヤはスイッチに繋がるように挿す。
最後に、スイッチと GND を繋ぐようにジャンパワイヤを挿す。
f:id:shima_nigoro:20160925154501j:plain:h200

これで、タクトスイッチを押したときに通電して GPIO に電流が流れる。
#とりあえず、空中配線で作っておく。

ソフトの仕様を決める

仕様を決めてから、コード(Pythonスクリプト)を作る。できる限りシンプルに。
#実際は実現性を確認するために、いろいろ試しに作ってみてからだけどね…。

スイッチ押下の検出案1:ポーリング

0.1秒に 1回 GPIO の状態を監視してLowからHighの変化で押下と判断する。
CPU資源を無駄使いするので却下

スイッチ押下の検出案2:割り込み

GPIOの立ち上がりエッジをトリガに押下と判定する。
常時動作させるつもりなので、CPU資源の利用が少ないこちらの案を採用する。

スイッチ押下時の動作

・スイッチが押されたときはランプの状態遷移は下記とおり

イベント→
↓ランプの状態
スイッチ1押下 スイッチ2押下 スイッチ3押下
点灯 ランプを消灯する ランプを消灯する ランプを消灯する
消灯 50%の明るさで
ランプを点灯する
75%の明るさで
ランプを点灯する
「くつろぐ」シーンの
ランプを点灯する

#点灯パターンはとりあえずで決めた

コード(Pythonスクリプト)を作る

Hue 操作用と全体制御用の2つのスクリプトを使う。

Philips Hue の操作用

以前の記事作ったスクリプトに電源状態を確認する関数を追加して利用する。
Raspberry Pi で Philips Hue を操作する #2 - もみあげあしめ

スイッチ押下の検出+状態遷移用

Raspberry Pi 用の GPIO ライブラリが使いやすかったのでそのまま利用する。

常時起動するよう設定する

自動起動スクリプト「/etc/rc.local」に下記を追記する。
これで再起動してもバックグラウンドプロセスとして動作させられる。

sudo python /home/pi/hue_switch.py &

#当たり前だけれど、「exit 0」の前に

動作を確認する

折角なので動作しているところを撮影してみた。

#明るさを固定するにはどうすればいいのだ…

嵌ったところ

GPIO に何も入力していないのに 1 と 0 を繰り返し不安定になる

理由 :「GPIO ポートが入力 = 0V で待ち受けている」ではなく不定値らしい。
解決策:GPIO をプルダウンに設定する ※デフォルトでプルダウンなのでソフトで設定するだけ

GPIO.setup(gpio_list, GPIO.IN)
↓
GPIO.setup(gpio_list, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)


「TypeError: onSwitchPush() takes no arguments (1 given)」が表示される

理由 :GPIO のコールバック関数の引数が足りていなかった。
解決策:引数に channel を追加する。 ※コールバックを設定したポート番号が通知されるようになる。

def onSwitchPush():
↓
def onSwitchPush(channel):


物理スイッチ押下(立ち上がりエッジ)を複数回検出してしまう

理由 :チャタリング除去していないため。
解決策:立ち上がりを判定するまでの時間を適切に設定する。

GPIO.add_event_detect(gpio_channel, GPIO.RISING, callback=onSwitchPush)
↓
GPIO.add_event_detect(gpio_channel, GPIO.RISING, callback=onSwitchPush, bouncetime=250)

※連打しても1秒で4回くらいなので250msくらいにしておく。

おわりに

v2 が発売されているが、v1 は私が購入したときから比べて今はだいぶ安くなっているみたい。

Philips hue(ヒュー) スターターセット 929000259907 リテールパッケージ

Philips hue(ヒュー) スターターセット 929000259907 リテールパッケージ

作るのにかかった時間と材料費を含めると買ったほうが安いのでは…?という質問は厳禁である。

Philips hue Tap (ヒュー タップ) 929001115205

Philips hue Tap (ヒュー タップ) 929001115205

ちなみに、ランプ1つとブリッジを単体で購入すると約¥15,000くらい(16/9/25現在)。

Philips Hue(ヒュー) シングルランプ 800 lm   929001156102

Philips Hue(ヒュー) シングルランプ 800 lm 929001156102

Philips Hue(ヒュー) ブリッジ   929001180614

Philips Hue(ヒュー) ブリッジ 929001180614