Spectrino:Arduino Nano 33 BLE Sense & ESP8266で実現するTinyML×IoTタッチフリーソリューション集
プロジェクトの背景と目的
COVID-19パンデミックにより「非接触」「ソーシャルディスタンス」が必須となり、商業施設・公共空間での接触リスク低減が喫緊の課題となりました。本プロジェクトでは、Arduino Nano 33 BLE Sense(以下 BLE Sense)のオンボードセンサーとTinyML(TensorFlow Lite for Microcontrollers)、ESP8266/Arduino MKR WiFi 1010によるIoT連携を組み合わせ、5つのタッチフリー・ソリューションを統合プロトタイプとして実装・検証しました。
採用ハードウェア・ソフトウェアスタック
主要ハードウェア
| デバイス | 用途 | 備考 |
|---|---|---|
| Arduino Nano 33 BLE Sense | TinyML推論エッジデバイス | nRF52840、Cortex-M4 64MHz、1MB Flash/256KB RAM、マイク/IMU/温湿度/気圧/光/ジェスチャー内蔵 |
| ESP8266 ESP-01 | Wi-Fiゲートウェイ | ThingSpeakへデータ送信 |
| Arduino MKR WiFi 1010 | IoTゲートウェイ(温度測定システム) | SAMD21+NINA-W10、ECC508搭載 |
| Arducam Mini 2MP Plus (OV2640) | 画像入力 | SPI接続、96×96リサイズで推論 |
| MAX7219 4-in-1 32×8 LEDマトリクス | 表示デバイス | 「Person」「Waiting 15min」等表示 |
| SG90/MG995 サーボ ×2 | 物理アクチュエータ | ボタン押下、ゲート開閉、UVライト駆動 |
| HC-SR04 超音波センサー | 人検知トリガー | 20cm手前で検知 |
| Adafruit AMG8833 サーマルカメラ | 体表温度測定 | 8×8ピクセル、I2C接続 |
| ブザー、RGB LED、UVライト、リチウムイオン電池+充電基板 | アラート/表示/電源 | ポータブル運用想定 |
ソフトウェアツール
- Arduino Web Editor: クラウドIDE、ライブラリ管理、OTA書き込み
- Edge Impulse Studio: TinyMLデータ収集→前処理→学習→Arduinoライブラリ書き出しのエンドツーエンド環境
- ThingSpeak: IoTダッシュボード、MATLAB解析、パブリック/プライベートチャネル
- TensorFlow / TensorFlow Lite for Microcontrollers: モデル基盤
サブプロジェクト1:音声制御タッチフリー・エレベーター
課題
エレベーターのボタンは不特定多数が触れる高リスク接点。超音波/ジェスチャーセンサーは誤検知・近距離操作必須という欠点があります。
解決策:BLE Senseオンボードマイクで「上/下」音声認識
Edge Impulseでのモデル構築
- データ収集: 「up」「down」各90秒、2秒ウィンドウ、計3分
- インパルス設計: ウィンドウ300ms/増分、MFCC特徴量、Keras CNN分類器
- 前処理: ケプストラム係数で時周波特徴抽出
- 学習: 1D Conv Pool(30, kernel5) → 1D Conv Pool(10, kernel5) → Flatten → Dense、100エポック
- 結果: 訓練精度91.2%、テスト精度75%(24秒ライブテスト)
推論ロジック(抜粋)
// main.ino 抜粋
if (found_command[0] == "up") {
last_command_time = current_time;
digitalWrite(LEDG, LOW); // 緑LED点灯
servo_7.write(0); // サーボで「上」ボタン押下
delay(100);
digitalWrite(LEDG, HIGH); // LED消灯
servo_7.write(180); // サーボ復帰
}
if (found_command[0] == "down") {
last_command_time = current_time;
digitalWrite(LEDG, LOW);
servo_7.write(0); // 「下」ボタン押下
delay(100);
digitalWrite(LEDG, HIGH);
servo_7.write(180);
}
メリット比較
サブプロジェクト2:顔検知スマート・インターホン
課題
従来のインターホンはボタン押下必須。CDC指摘の通り、プラスチック/金属上でウイルス最大3日生存のリスクあり。
解決策:BLE Sense + Arducam で人物検知→ブザー鳴動 + LEDマトリクス表示
事前学習済みTensorFlow Lite「Person Detection」モデル(クラス: unused/person/notperson)を流用。ArducamからSPI転送したJPEGを96×96にリサイズ→TFLite推論。
核心コード(detection_responder.cpp)
uint8_t person_score = output->data.uint8[kPersonIndex];
uint8_t no_person_score = output->data.uint8[kNotAPersonIndex];
if (person_score > no_person_score) {
digitalWrite(LEDG, LOW); // ブザーON
digitalWrite(LEDR, HIGH);
digitalWrite(5, LOW); // LEDマトリクス表示
myDisplay.setTextAlignment(PA_CENTER);
myDisplay.print("Person");
delay(100);
// 追加: 既存インターホンの「映像確認ボタン」をサーボで押下
servo_8.write(0); delay(500); servo_8.write(180);
} else {
digitalWrite(LEDG, HIGH);
digitalWrite(LEDR, LOW);
}
画像取得(arduino_image_provider.cpp 抜粋)
ArduCAM myCAM(OV2640, CS);
// SPI初期化、CPLDリセット、レジスタ0x55通信テスト...
// JPEGデコード→96x96 RGB565→TFLite入力テンソルへコピー
サブプロジェクト3:IoT自動体温スクリーニング・ゲート
課題
手動検温は接触リスク・人手不足・データ記録不備の三重苦。
解決策:MKR WiFi 1010 + 超音波トリガー + AMG8833サーマルカメラ + ThingSpeak
- 超音波センサーで20cm以内に人検知
- サーボでゲート開放(将来はモータードライバー制御)
- AMG8833で体表温度測定
- ThingSpeakへタイムスタンプ付き送信
- 38.1℃超過ならゲート閉鎖+ブザー警報
ロジックフロー
PersonDetection
├── HC-SR04: distance <= 20cm → command
├── MKR WiFi 1010
│ ├── Servo(0) // ゲート開
│ ├── AMG8833.readThermistor()
│ ├── ThingSpeak POST (field1=temp)
│ └── if temp > 38.1°C:
│ ├── Servo(180) // ゲート閉
│ └── Buzzer ON
ThingSpeak連携コード抜粋
#include
#include
#include
#include
WiFiMulti WiFiMulti;
const char* ssid = "YourSSID";
const char* password = "YourPass";
const char* host = "api.thingspeak.com";
String api_key = "YOUR_API_KEY";
Adafruit_AMG88xx amg;
Servo servo1;
void Send_Data() {
WiFiClient client;
if (!client.connect(host, 80)) return;
String data = api_key + "&field1=" + String(amg.readThermistor()) + "\r\n";
client.print("POST /update HTTP/1.1\r\n");
client.print("Host: api.thingspeak.com\r\n");
client.print("X-THINGSPEAKAPIKEY: " + api_key + "\r\n");
client.print("Content-Type: application/x-www-form-urlencoded\r\n");
client.print("Content-Length: " + String(data.length()) + "\r\n\r\n");
client.print(data);
delay(200);
client.stop();
}
導入メリット
- 非接触・無人運用で感染リスク/人件費削減
- 来訪者が事前にダッシュボードで「今安全か」判断可能 → 来店意欲向上
- 日時別傾向分析でピーク時間帯の対策強化
- 自治体オープンデータ連携でエリア全体の安心感醸成
サブプロジェクト4:TinyML×IoT 入場制限・キューイングシステム
課題
入場者数上限(例: 50名)の手動カウントは非効率・データ不透明。待ち時間不明で来店躊躇。
解決策:入口/出口にBLE Sense+Arducamを配置、人物検知でカウント&ゲート制御、ThingSpeakで可視化
入口側ロジック
if (person_score > no_person_score) {
servo.write(0); // ゲート開
entry_count++;
ThingSpeak_send(entry_count, field1);
if (entry_count % 50 == 0) {
servo.write(180); // ゲート閉
display.print("Wait 15min"); // LEDマトリクス
delay(15*60*1000); // 15分待機
}
}
待ち時間推定アルゴリズム
X = 入場累計, Y = 退場累計, Z = 定員(50)
inside = X - Y
remaining_capacity = Z - inside
if (remaining_capacity < 0)
wait_time = (-remaining_capacity) * avg_stay_time_per_person
else
wait_time = 0
ThingSpeakダッシュボード
Field1: 入場者数 / Field2: 退場者数 / Map: 施設位置。来訪者はスマホで混雑度・待ち時間を確認可能。
既存カメラ流用の提案
防犯カメラ映像をBLE Senseへストリーミングし、中央で人物検知・カウントすれば追加ハードウェアコスト削減可能。
サブプロジェクト5:マスク着用検知 + IoT監視
モデル構築
- データセット: 3,500枚 → 厳選813枚(mask/no_mask)
- Edge Impulse: Transfer Learning (MobileNetV2 0.35)、96×96 RGB、30エポック
- 量子化後モデルサイズ: 約676KB / RAM 440KB
- 精度: テストセット 98.15%(量子化後 92.6%)
推論レスポンダー
uint8_t mask_score = output->data.uint8[kmaskIndex];
uint8_t no_mask_score = output->data.uint8[kno_maskIndex];
if (mask_score > no_mask_score) {
digitalWrite(LEDG, LOW); servo.write(0); // 入場許可
mask_count++;
} else {
digitalWrite(LEDR, LOW); servo.write(180); // 入場拒否
no_mask_count++;
}
ThingSpeak_send(mask_count, field1);
ThingSpeak_send(no_mask_count, field2);
サブプロジェクト6:通路別人数密度連動・自動UV除菌システム
課題
手動UV除菌は作業員リスク・実施記録なし・汚染度合いに応じた頻度調整不可。
解決策:通路ごとにBLE Sense+Arducam配置、人物カウントで段階的アラート→閾値超過でUV照射
通路種別ごとの閾値設計(汚染リスクに応じて調整)
| エリア | 安全(緑) | 注意(青) | 警告(赤) | UV除菌 | リセット |
|---|---|---|---|---|---|
| 衣料品 | 1〜50 | 51〜75 | 76〜100 | 101〜110 | >111 |
| 電子機器 | 1〜75 | 76〜180 | 181〜225 | 226〜240 | >241 |
| 食品/生鮮 | 1〜25 | 26〜50 | 51〜75 | 76〜90 | >91 |
レスポンダー抜粋
if (person_score > no_person_score) { count++; }
if (constrain(count, 1, 50)) digitalWrite(LED_GREEN, LOW);
if (constrain(count, 51, 75)) digitalWrite(LED_BLUE, LOW);
if (constrain(count, 76, 100)) digitalWrite(LED_RED, LOW);
if (constrain(count, 101, 110)) digitalWrite(UV_LIGHT, LOW);
if (count > 111) count = 0; // UV照射完了でリセット
ThingSpeak 4チャネル構成
- Field1: Food aisle
- Field2: Sports aisle
- Field3: Clothes aisle
- Field4: Electronics aisle
従来UVロボットとの差別化
- 通路単位の粒度で「人通過数ベース」の除菌トリガー
- 上部棚まで照射可能な固定UV照射器併用で死角なし
- IoTダッシュボードでリアルタイム密度・除菌履歴を可視化・来訪者公開
- 自律走行ロボットより大幅低コスト・スケーラブル
コードリポジトリ(GitHub)
回路図・配線図
総括と展望
本プロジェクトは、TinyML(エッジ推論)× IoT(クラウド可視化・遠隔監視)× 物理アクチュエーション(サーボ/リレー/UV) を統合し、パンデミック下の「安心・安全・非接触」を技術で支える一連のソリューションを提示しました。各サブシステムは単体でも価値があり、組み合わせることで施設全体の感染対策DXを実現します。
今後の発展として、以下が考えられます。
- エッジデバイス間のMesh通信(BLE/Thread)によるゲートウェイ集約
- 推論モデルの継続的学習(Federated Learning)
- 施設管理システム(BMS/FM)とのAPI連携
- 来訪者向けネイティブアプリ(待ち時間予測・混雑マップ・履歴通知)
- 認証取得・量産化に向けたハードウェアリファイン(産業用温度範囲、EMC対策、電源冗長化)
「技術で社会課題を解決する」というメイカー精神のもと、コードとノウハウをオープンに公開しています。ご意見・フォーク・改良版の共有を歓迎します!
製造プロセス
- Raspberry Pi 3とDHT11センサーを接続し、ThingsIo.aiクラウドへデータ送信
- Arduino UNOとOLEDディスプレイでクラシックPongゲームを自作:ステップバイステップチュートリアル
- ArduinoとMAX30100で作るリアルタイムIoT心拍数モニター
- Pixie: Arduino Pro Miniで作るNeoPixel腕時計 - アナログとデジタル融合のDIY光る時計
- Arduino MegaとNextion HMIで作る高機能ウェザーステーション
- TinyMLで植物の健康状態を診断:実践ガイド
- DIY Arduino スマートウォッチ — Apple Watch 風腕時計を自作
- Arduino Nanoと128x64 OLEDで実行するセルラーオートマトン「ライフゲーム」
- Azure IoT対応スマートプール制御システム:水温・気温監視と遠隔ポンプ制御
- IoT資産追跡ソリューションに最適な無線プロトコル選定ガイド
- IoT追跡ソリューションでオープンワゴントラック運営を強化する