店舗のトイレが使用中なのか、入口まで行かないと分からない。
そんなちょっとした不便を解消するために、 人感センサーとESP32を使った「トイレ使用中ランプ」を自作してみました。
最終的には、トイレ内のセンサーが人を検知すると、 Wi-Fi経由で入口に設置したLEDが点灯する仕組みになりました。
使用中はピンク〜紫のグラデーションでLEDが点灯し、 空室になると消灯します。
完成したもの
仕組みはとてもシンプルです。
【トイレ内】
LD2410C
↓
XIAO ESP32C3
↓
Wi-Fi
↓
店舗ルーター
↓
Wi-Fi
↓
XIAO ESP32C3
↓
RGB LED
使用中 → ピンク〜紫に点灯
空室 → 消灯
センサー側と表示側、それぞれに Seeed Studio XIAO ESP32C3を使用しています。
なぜ作ろうと思ったのか
店舗では、トイレの入口まで行かないと使用中かどうか分かりません。
お客さんだけでなく、スタッフも 「いまトイレ空いてる?」 と聞かれたときに、その場では確認できません。
そこで、 トイレ内の人の有無を検知して、離れた場所から確認できないか と考えました。
最初はドアの隙間から配線してLEDを光らせることも考えましたが、 店舗の構造上、配線を通すのが難しいことが判明。
そこでESP32のWi-Fiを利用して、 センサーと表示器を完全にワイヤレスで分離することにしました。
最初は普通のESP32で試作

いきなり小型化するのではなく、 まずは一般的なESP32開発ボードとブレッドボードを使って試作しました。
人感センサーには HLK-LD2410Cを使用しています。
一般的な赤外線式の人感センサーではなく、 ミリ波レーダーを使用するセンサーです。
人が大きく動いていない状態でも検知できるため、 トイレの在室判定との相性が良さそうだと考えました。
スマホからも確認できるようにした
ESP32上に簡単なWebサーバーを作り、 同じWi-Fiに接続しているスマートフォンから状態を確認できるようにしました。
http://toilet.local/
ブラウザからアクセスすると、 「空室」「使用中」をリアルタイムで確認できます。
これによってスタッフはトイレまで確認に行かなくても、 スマートフォンから現在の状態を確認できます。
入口用ディスプレイも作ってみた
次に、トイレ入口に置く表示器を作りました。
最初の試作では、
- ESP32
- 0.96インチ OLED(SSD1306)
- RGB LED
を組み合わせました。
OLEDには「VACANT」「OCCUPIED」などを表示し、 LEDの色でも状態が分かるようにしました。
実際に使ったらディスプレイを見なかった
ところが、実際に店舗で使ってみると一つ気付きました。
意外とOLEDディスプレイを見ない。
トイレが使用中かどうかを知るだけなら、 細かな文字情報は必要ありません。
「LEDが光っていたら使用中」
これだけで十分でした。
そこで製品版ではOLEDを思い切って廃止しました。
電子工作では機能を追加したくなりますが、 実際に使ってみて不要だった機能を削るのも大切だと実感しました。
XIAO ESP32C3で小型化
試作で仕組みが問題なく動作することを確認できたので、 ESP32開発ボードから Seeed Studio XIAO ESP32C3へ移植しました。
XIAO ESP32C3は非常に小さいにもかかわらず、 Wi-FiとBluetoothを搭載しています。
今回のような小型IoT機器にはかなり使いやすいボードでした。
表示器側の構成
最終的な表示器はかなりシンプルになりました。
- Seeed Studio XIAO ESP32C3
- 抵抗内蔵RGB LED
- 外付けWi-Fiアンテナ
これだけです。
RGB LEDは共通カソードタイプを使用し、 XIAO ESP32C3のGPIOからRGBそれぞれをPWM制御しています。
RGB LED XIAO ESP32C3
RED → D1 / GPIO3
GREEN → D2 / GPIO4
BLUE → D3 / GPIO5
GND → GND
使用中はピンク〜紫のグラデーション
最初は単色のピンクLEDを使用していました。
しかしRGB LEDをPWM制御すれば、 RGBそれぞれの明るさを変えることができます。
そこで現在は、
ピンク
↓
紫
↓
青紫
↓
紫
↓
ピンク
というグラデーションをゆっくり繰り返すようにしました。
空室時は完全に消灯します。
つまり利用者が覚えるルールは、
「光っている=使用中」
だけです。
センサー側もXIAO ESP32C3へ
表示器側の小型化が成功したので、 センサー側もXIAO ESP32C3へ移植しました。
構成は、
- Seeed Studio XIAO ESP32C3
- HLK-LD2410C
だけです。
LD2410CとはUARTで通信しています。
LD2410C XIAO ESP32C3
VCC → USB
GND → GND
TX → D7 / GPIO20
RX → D6 / GPIO21
OUT → 未使用
TXとRXは交差して接続します。
Wi-Fi設定はWiFiManagerを使用
最初はArduinoのソースコードにSSIDとパスワードを直接書いていました。
しかし店舗や自宅など、設置場所が変わるたびにソースを書き換えて 再度書き込むのはかなり面倒です。
そこでWiFiManagerを導入しました。
保存済みのWi-Fiに接続できない場合は、 ESP32自身が設定用のアクセスポイントを作ります。
RESTROOM-SENSOR-SETUP
RESTROOM-INDICATOR-SETUP
iPhoneなどから接続してWi-Fiを設定すれば、 SSIDとパスワードがESP32側に保存されます。
そのため、通常は電源を抜いて再起動しても 保存済みWi-Fiへ自動接続できます。
表示器とセンサーの通信
センサー側ESP32にはWeb APIも用意しました。
http://toilet.local/api/status
アクセスすると、次のようなJSONを返します。
{
"presence": true,
"occupiedSeconds": 37
}
表示器側のXIAO ESP32C3はこのAPIを定期的に取得します。
presence が true ならRGB LEDを点灯、 false なら消灯します。
通信が一瞬切れても誤動作しないようにした
実際に店舗でテストすると、 Wi-FiやHTTP通信が一瞬失敗することがありました。
そこで1回通信に失敗しただけでは状態を変更せず、 複数回連続して取得に失敗した場合のみ通信エラーとして扱う ようにしました。
こうした部分は自宅の机上テストだけでは気付きにくく、 実際の設置環境で試してみて分かったポイントでした。
最終的な構成
【トイレ内】
LD2410C
│
XIAO ESP32C3
│
│ Wi-Fi
▼
店舗ルーター
│
│ Wi-Fi
▼
【トイレ入口】
XIAO ESP32C3
│
RGB LED
│
├─ 使用中
│ → ピンク〜紫グラデーション
│
└─ 空室
→ 消灯
作ってみた感想
最初は「トイレの使用中をLEDで知らせたい」というだけのアイデアでした。
そこから、
- ミリ波センサーによる在室判定
- Wi-Fi通信
- スマートフォンからの確認
- 入口表示器
- WiFiManagerによる設定
- XIAO ESP32C3による小型化
- RGB LEDのPWM制御
まで発展しました。
特に面白かったのは、 作る前に考えていた完成形と、実際に使ってみて必要だと感じたものが違ったことです。
OLEDディスプレイまで付けてみたものの、 最終的には「LEDが光るだけ」の方が使いやすいという結論になりました。
機能を増やすだけではなく、 実際に使いながら削っていくことで、 かなりシンプルな装置に仕上がりました。
ESP32を使った電子工作は今回のような 「身近なちょっとした不便」を解決する用途とかなり相性が良さそうです。