Amazonブラックフライデー、皆さんは何か買いましたか?
私はアドベントカレンダーのネタのために、買ったことのないものを買いました。
購入品紹介
ESP32-WROOM
1,680円 → 1,428円
Wi-Fi機能が内蔵されているマイコンです。ClaudeにもChatGPTにも相談してどちらも候補に挙げてきたのでこちらにしました。
HC-SR501
650円(安くならなかった)
人体感知センサーです。
ノーブランド品でレビューもなくて不安でしたが、チャッピーに相談したら、「HC-SR501と記載があれば大丈夫!」などいろいろアドバイスをくれたのでこちらにしました。購入して3週間経ちましたがまだ届きません。
使用例
個室の空き状況をリアルタイムでWebページに表示するシステムを作ることにしました。
人感センサー → ESP32 → Webサーバー → ブラウザ
購入品が届くまでの間にWebサイトを作ることにしました。
仕様を決めるのにCursorのplanモードを試してみました。
「個室の空き状況をリアルタイムで表示するWebサイトを作りたい」と雑に投げても、いくつか質問してきて、それに答えたらいい感じの仕様書を作ってくれました。
技術スタック:
- Next.js(App Router)
- Socket.IO(リアルタイム通信)
- Tailwind CSS(スタイリング)
- Docker(開発環境)
マイコンからはHTTPでセンサーの状態を送って、ブラウザへはWebSocketでリアルタイムに配信する構成です。
できあがったサイトがこちら↓

お気に入りポイントは、空きと使用中の部屋数を表示しているところです。指示していないのに実装してくれました。
しかもレスポンシブ!

続いてマイコン開発
IoTの知識は皆無なので、AIに全部聞きながら進めました。
まず環境構築。
Arduino IDEをインストールし、マイコンがESP32なので、ESP32のボードとドライバーをインストールしました。この辺は全部チャッピーに教えてもらいました。
次に実装。
人感センサーがまだ届かないので、Wi-Fiに接続し、2秒おきにセンサーのオンオフを送る処理を実装してもらいました。
#include <WiFi.h>
#include <HTTPClient.h>
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* SERVER_URL = "API_ENDPOINT";
const int INTERVAL_MS = 2000; // 送信間隔(ミリ秒)
bool occupied = true; // 最初は true
// ========================================
// Wi-Fi接続
// ========================================
void connectWiFi() {
Serial.print("Wi-Fi接続中...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int retryCount = 0;
while (WiFi.status() != WL_CONNECTED && retryCount < 30) {
delay(500);
Serial.print(".");
retryCount++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWi-Fi接続完了!");
Serial.print("IPアドレス: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nWi-Fi接続失敗。再起動します...");
ESP.restart();
}
}
// ========================================
// サーバーに状態を送信
// ========================================
void sendStatus(bool isOccupied) {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Wi-Fi未接続");
return;
}
HTTPClient http;
http.begin(SERVER_URL);
http.addHeader("Content-Type", "application/json");
String json = isOccupied ? "{\"occupied\":true}" : "{\"occupied\":false}";
Serial.print("送信: ");
Serial.println(json);
int httpCode = http.POST(json);
if (httpCode > 0) {
String response = http.getString();
Serial.print("レスポンス: ");
Serial.println(response);
} else {
Serial.print("エラー: ");
Serial.println(http.errorToString(httpCode));
}
http.end();
}
// セットアップ
void setup() {
Serial.begin(115200);
Serial.println("\n==========================================");
Serial.println("マイコン動作確認テスト開始");
Serial.println("==========================================");
connectWiFi();
Serial.print("対象: ");
Serial.println(SERVER_URL);
Serial.println("==========================================\n");
}
// メインループ
void loop() {
sendStatus(occupied);
// true/false を切り替え
occupied = !occupied;
// 次のリクエストまで待機
delay(INTERVAL_MS);
}
マイコン起動中のWebサイトの様子がこちら↓
IoT初心者でしたが、ほぼ躓かずに開発できました。躓いたところといえば、Wi-Fiの接続情報をタイポして繋がらなかったことくらいです。
人感センサーが届いたら更新しようと思います。更新されなかったら察してください。
最後に
AIのおかげで未経験の分野にも手を出しやすくなったと感じます。
弊社でも非エンジニアがAIを使ってツールを作ったりしています。
この記事のデモ動画をGIFにするのに、非エンジニアの方が作成したツールを使わせてもらいました。
このシステムを作ろうと思ったきっかけは、自社オフィスの個室の空き状況を可視化できればなぁと思ったからです。
弊社にはWeb会議用の個室が数十個あります。
予約なしで自由に使えるのですが、たまに混み合って個室難民になることがあります。
こういうシステムがあれば個室を探す時間を減らせると思うんです。
自社導入を手伝ってくれる人を探しています。
🌺 沖縄から「21世紀を代表する会社」を創る仲間を募集
シーエー・アドバンスは、「沖縄のインターネット産業の未来を創る」をビジョンに掲げ、サイバーエージェントグループの一員として、ABEMAやAmebaを支える社内システムを開発しています。 勤務地は沖縄・那覇市 おもろまち。 Next.js 、React、Ruby on Rails、AWS などモダンな技術で、東京・ベトナムのエンジニアと協業。若手が裁量権を持って挑戦できる環境です。
失敗を恐れず挑戦できる文化。一緒にアドバンス(進歩)しませんか?
