Back to Blog
App Dev DIY

物理スイッチをスマート化する
AutoON

賃貸の壁スイッチをスマート化したい。でも壁に穴は開けられないし、電気配線を直接いじる資格もない。 それなら、サーボモーターを使って物理的にスイッチを押す仕組みを作ればいい。

そうして開発したのが、ESP32とWebアプリを連携させたスマートホームスイッチ AutoON。 しかし、いざ作り始めると、物理デバイスならではの「泥臭い試行錯誤」の連続だった。

AutoON 実機設置イメージ — 壁のスイッチにサーボモーターが取り付けられている様子

試行錯誤1:押す力と角度の葛藤

壁スイッチを押し込む最適な角度は、設置位置によって微妙に異なる。 サーボモーターの回転角度をプログラムに固定値で書き込んでテストしたところ、 押し込みが強すぎてアクリル板の固定ブラケットが悲鳴を上げたり、逆に弱すぎてスイッチが切り替わらなかったりした。

実機を見ながら何十回もArduino IDEでコードを書き換えるのは現実的ではない。 そこで、Webアプリの設定画面から「1度単位」でON角度・OFF角度・待機位置を微調整できる機能を実装した。 調整すると即座にサーボがその角度まで動き、その場で物理的なフィット感を確認できる。このWeb UI化が最大のブレイクスルーだった。

Webアプリのダッシュボード画面 操作ダッシュボード
Webアプリの設定画面 リアルタイム角度微調整

試行錯誤2:3路スイッチの迷宮

次の課題は、廊下や階段にある「3路スイッチ」だった。 2箇所で同じ電灯を操作できる回路のため、スイッチの物理的な向き(上/下)と、実際の照明のON/OFFが一致しない。 その結果、アプリ側で「ONボタン」を押したのに、物理スイッチがすでにONの向きにあったため、サーボが空振りするという問題が発生した。

そこで設定画面に「3路スイッチモード」を急遽実装。 このモードでは、アプリの表示を絶対値の「ON/OFF」から「SWITCH(切り替え)」に変え、 サーボを現在の向きとは逆側に常に動かすトグル制御を行うことでこの問題をクリアした。

試行錯誤3:曜日タイマーと常時稼働サーバー

朝決まった曜日に自動で電気を点ける「目覚まし機能」も欲しかった。 しかし、ESP32単体では複雑なスケジュール管理や高精度なタイマー動作、Web UIの処理を同時に行うには荷が重い。

解決策として、余っていたラズベリーパイを常時稼働サーバーに設定し、バックエンド(Node.js)をホストさせた。 node-scheduleを使って特定の曜日だけトリガーするタイマーシステムを構築し、 サーバーの常時起動管理には pm2 を導入。実用的で安定した「スマート目覚まし」が完成した。

🔗 3路スイッチモード

階段や廊下のように物理状態と電灯状態がズレる3路回路に対応。ON/OFFの区別なくトグル動作を行う。

🔘 プッシュボタンモード

シーソースイッチではなく、押した時だけ一時的にONになり、離すと戻るタイプのスイッチに対応。

🔌 手動ボタン割り込み

壁側に設置した物理タクトスイッチを押すことで、スマホがない状態でも即座にサーボが作動するハードウェア割り込み。

シンプルな配線と設置

ESP32開発ボードを中心に、サーボモーター(SG90)と、手動操作用の物理タクトスイッチを接続。 ESP32の内部プルアップ抵抗(INPUT_PULLUP)を活用し、外付け抵抗を使わないシンプルな配線をブレッドボード上に構築した。

配線写真 — ブレッドボード上のESP32、SG90サーボ、ボタンの接続
壁スイッチへの設置詳細写真 — 3Dプリントパーツやアクリル板での固定方法

技術スタック

React Vite Express Node.js ESP32 (Arduino C++) ESP32Servo mDNS Responder

ESP32側でmDNS(autoon.local)をホストし、バックエンドのExpressが中継してESP32のAPI(/api/status/api/toggle)へアクセスする。 実機なしでもアプリの動作開発を行えるよう、バックエンドには DUMMY_MODE(シミュレーション用)も用意して開発をスムーズに進めた。

Back to Blog