Arduino Nano 33 IoT:マルチパラメータ水質センサー(EC、pH、ORP)BLE & PWA対応
必要な部品と材料
| 部品 | 数量 |
|---|---|
| Arduino Nano 33 IoT | 1 |
| Microfire LLC アイソレートECプローブインターフェース | 1 |
| Microfire LLC アイソレートISEプローブインターフェース | 2 |
このプロジェクトについて
何を作るのか?
EC(電気伝導率)、pH、ORP(酸化還元電位)、温度を測定するデバイスを作成します。プールや水耕栽培の監視に活用できます。Bluetooth Low Energy(BLE)で通信し、Web Bluetoothを使用してウェブページ上にデータを表示します。さらに、プログレッシブウェブアプリ(PWA)としてインストール可能にします。


必要な部品は ufire.co で入手できます。
用語の解説
- EC/pH/ORP/温度:一般的な水質測定パラメータ。ECは水耕栽培の養液濃度、pHは酸性/アルカリ性、ORPは水の殺菌力を判断する指標です。
- Bluetooth Low Energy(BLE):データの送受信に適した省電力無線プロトコル。本プロジェクトで使用するArduino Nano 33 IoTにはWi-FiとBLEの両方が搭載されています。
- Web Bluetooth:Google ChromeおよびOperaで実装されているAPI群。ウェブページから直接BLEデバイスと通信できます。
- プログレッシブウェブアプリ(PWA):ネイティブアプリのように振る舞うウェブページ。Android、iOS、デスクトップで挙動が異なるため、詳細は個別に調査が必要です。
ハードウェアの組み立て
組み立て前に重要な設定があります。uFireのISEセンサーデバイスは同じI2Cアドレスを持つため、2台使用する場合は片方のアドレスを変更する必要があります。本プロジェクトでは、ISEボードの1台をORP測定用とし、アドレスを0x3eに変更します(こちらの手順を参照)。
アドレス変更後、ハードウェアの接続は簡単です。すべてのセンサーデバイスはQwiic接続システムを採用しているため、チェーン状に接続するだけです。Qwiic-メスケーブル1本で最初のセンサーをNano 33 IoTに接続します。配線は色分けされています:黒をGND、赤を3.3Vまたは5V、青をSDA(A4)、黄をSCL(A5)に接続します。

本プロジェクトでは温度情報をECセンサーから取得するため、ECボードに温度センサーを接続してください(すべてのボードに温度測定機能があります)。EC、pH、ORPプローブをそれぞれ対応するセンサーのBNCコネクタに接続します。防水ケースに収めると、水回りでの使用に安心です。
ソフトウェア構成
ソフトウェアはファームウェア(Nano 33 IoT側)とウェブページの2部構成です。
基本フロー
- ウェブページがBLEでNanoに接続
- ウェブページがテキストコマンドを送信して情報取得やアクションを指示
- Nanoがコマンドを受信・実行し、結果を返信
- ウェブページが応答を受け取り、UIを更新
この構成により、測定実行やセンサーキャリブレーションなど、必要な機能をすべてウェブページから操作できます。
BLEサービスとキャラクタリスティック
BLEの基本概念を理解しましょう。サービスを「本」、キャラクタリスティックを「ページ」に例えると分かりやすいです。ページには「内容を書き換え可能」「変更時に通知を受信可能」といった特殊な性質があります。
本ファームウェアでは以下の1サービス・2キャラクタリスティックを定義します:
BLEService uFire_Service("4805d2d0-af9f-42c1-b950-eae78304c408");
BLEStringCharacteristic tx_Characteristic("50fa7d80-440a-44d2-967a-ec7731ec736a", BLENotify, 20);
BLEStringCharacteristic rx_Characteristic("50fa7d80-440b-44d2-967b-ec7731ec736b", BLEWrite, 20);
tx_Characteristic:デバイスからウェブページへ測定値などを送信(BLENotifyで変更通知)rx_Characteristic:ウェブページからコマンドを受信(BLEWriteで書き込み許可)
初期化コード:
BLE.setLocalName("uFire BLE");
BLE.setAdvertisedService(uFire_Service);
uFire_Service.addCharacteristic(tx_Characteristic);
uFire_Service.addCharacteristic(rx_Characteristic);
BLE.addService(uFire_Service);
rx_Characteristic.setEventHandler(BLEWritten, rxCallback);
BLE.advertise();
rx_Characteristic.setEventHandler(BLEWritten, rxCallback)で、値変更時にrxCallback関数を実行するよう設定。BLE.advertise()でアドバタイズを開始し、デバイスを検出可能にします。
テキストコマンド
デバイスとウェブページはシンプルなテキストコマンドでやり取りします。uFireセンサーにはJSON/MsgPackベースのライブラリが付属しており、コマンド仕様は公式ドキュメントで確認できます。本プロジェクトでは可読性の高いJSONを採用します。
動作例
- ウェブページが
ecコマンドをrx_Characteristicに書き込み - デバイスが実行し、
{"ec":1.24}をtx_Characteristicに書き込んで返信 - ウェブページが受信して表示
ウェブページの実装
フロントエンドにVue.jsを使用し、バックエンドは不要です。ビルドシステムも使わず、js、css、assetsフォルダに分けて管理します。スタイリングにはBulma.ioを採用。
HTMLの<head>に以下を記述し、PWA化の要となるmanifest.jsonを読み込みます:
<link rel="manifest" href="manifest.json">
JavaScriptはapp.js(Vueの基本設定・UI変数)、ble.js(Bluetooth処理)、ec.js/ph.js/orp.js(各センサーのコマンド送信)に分割。
JavaScriptとWeb Bluetooth
対応ブラウザ:Chrome、Operaのみ(他ブラウザは未対応)。
app.jsにはファームウェアと同じUUIDを定義。ble.jsのconnect()関数で接続処理を行います:
this.device = await navigator.bluetooth.requestDevice({
filters: [{ namePrefix: "uFire" }],
optionalServices: [this.serviceUuid]
});
接続にはユーザーの物理的操作(ボタンタップ等)が必須です。セキュリティ上、プログラムからの自動接続はできません。接続ダイアログはChromeのネイティブUIで変更不可。
サービス・キャラクタリスティックの取得と通知設定:
service = await server.getPrimaryService(this.serviceUuid);
characteristic = await service.getCharacteristic(this.txUuid);
await characteristic.startNotifications();
characteristic.addEventListener("characteristicvaluechanged", this.value_update);
value_updateコールバックで受信JSONをパースしUIを更新。5秒ごとの定期更新タイマーも設定しています。
ローカルでHTTPS配信が必要です(serve-https等を利用)。
PWA化の手順
ウェブページをアプリとしてインストール可能にする手順:
- manifest.json生成:App Manifest Generator等を利用。アプリケーションスコープ、開始URL、表示モード(
standalone推奨)を設定し、index.htmlと同階層に配置。 - Service Worker作成:オフラインアクセス用のキャッシュ機能を実装。Googleのサンプルをベースにキャッシュ対象ファイルを調整。
- アイコン生成:Favicon Generatorで必要なサイズを作成。
- Service Worker登録:Vueの
mounted()フックで登録:
mounted: function () {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js');
}
},
LighthouseでPWA要件を検証可能。要件を満たすとChromeがインストールバナーを表示します。

コードリポジトリ
回路図
すべてQwiicケーブルで接続します。

製造プロセス
- Raspberry Pi & HDC2010:I2C温湿度センサー完全セットアップガイド
- Windows IoTとRaspberry Piで作るセキュアな顔認証ドアロック
- Raspberry Pi、PIRセンサー、MQTTで作るモーション制御AWS IoTボタン
- Windows 10 IoT CoreとSHT15センサーで高精度な温湿度モニタリング
- Raspberry Pi 3 Model B+へのWindows 10 IoT Coreインストール:ステップバイステップガイド
- Raspberry Pi 4 を Web サーバーに変えて自分のサイトを構築する方法
- GoPiGo v2をWindows 10 IoT Coreで拡張 - Raspberry Pi 3対応
- Azure IoT対応スマートプール制御システム:水温・気温監視と遠隔ポンプ制御
- Infineon、Amazon Web ServicesからAdvanced Technology Partnerに認定
- Web対応DDS:IoT、クラウド、リアルタイム接続を橋渡し
- IoTがWebアプリ設計・開発に革命をもたらす理由