IoT水質センサーシステム - Arduinoベースのリアルタイム監視
必要な部品と材料
| Arduino Uno | ×1 |
| ジャンパーワイヤー (オス/メス) | ×1 |
| HC-05 Bluetoothモジュール | ×1 |
| RGB LED (ディフューズド、共通カソード) | ×1 |
| 抵抗 330Ω | ×3 |
| 可変抵抗 (汎用) | ×1 |
| RGB LCDシールドキット (16x2キャラクターディスプレイ) | ×1 |
| 抵抗 1kΩ | ×1 |
必要な工具と機器
- ワイヤーストリッパー & カッター (26-14 AWG)
アプリとオンラインサービス
- Arduino IDE
- Ardutooth (Androidアプリ) - Bluetooth経由でデータ表示
プロジェクト概要
水は私たちの生活に不可欠な資源です。その品質を常に把握しておくことは重要です。
TDS (総溶解固形物) とは
TDS (Total Dissolved Solids) は、水中に溶解している固形物の総量を ppm (parts per million) で表したものです。電気伝導率 [S/m] から算出され、伝導率が高いほどTDS値も高くなります。主な水のTDS目安:
- 純水: 80-150 ppm
- 水道水: 250-350 ppm
- 地下水: 500-1000 ppm
- 海水: 約30,000 ppm
WHO (世界保健機関) は飲料水のTDSを300ppm以下と推奨しています。一方、100ppm未満は必須ミネラルが不足し、300ppm以上は「硬水」でミネラル過多とされます。
通常はTDSペンで測定しますが、Arduinoと連携させるには専用のTDSメーターが必要です。このプロジェクトでは、専用メーターを使わずに自作センサーで測定します。

回路構成
Arduino側
- 5Vをブレッドボードの一方の電源レールに接続
- GNDをもう一方の電源レールに接続
- 1kΩ抵抗の一端をGND、もう一端をブレッドボードに接続。ArduinoのアナログピンA0をこの抵抗に接続。さらに、抵抗から伸びたワイヤーと5Vから伸びたワイヤーの先端をワニ口クリップに接続 (これが水に浸す電極になります)

LCDディスプレイ
- VSS → GNDレール
- VDD → 5Vレール
- V0 → 可変抵抗の中央端子 (両端は5VとGND)
- RS → Arduino D7
- R/W → GNDレール
- E → Arduino D8
- D4-D7 → Arduino D10-D13

HC-05 Bluetoothモジュール
- VCC → 5Vレール
- GND → GND
- TX → Arduino D3 (ソフトウェアシリアルのRXとして使用)
- RX → Arduino D2 (ソフトウェアシリアルのTXとして使用)

RGB LED
- 共通カソード (最長ピン) → GND
- 赤 (カソード右隣) → 330Ω抵抗経由でArduino D9 (PWM)
- 緑 (カソード左隣) → 330Ω抵抗経由でArduino D6 (PWM)
- 青 (最左) → 330Ω抵抗経由でArduino D5 (PWM)

自由端子間抵抗の算出原理 (オームの法則)
既知抵抗 R₁=1kΩ と、水に浸した2本のワイヤー間の未知抵抗 R₂ が直列につながっています。Arduino A0ピンにはほぼ電流が流れないため、直列回路とみなせます。
オームの法則 V = IR より、V₁ = IR₁, V₂ = IR₂。直列なので V₁ + V₂ = 5V。したがって V₂ = 5 - V₁。
V₂/V₁ = R₂/R₁ より、R₂ = R₁ × (5-V₁)/V₁。Arduinoのアナログ読み取り値 (0-1023) から V₁ を求め、R₂ を算出します。

動作原理: 抵抗率 → 伝導率 → TDS
抵抗 R = ρ × L / A → 抵抗率 ρ = R × A / L
伝導率 c = 1/ρ
TDS = c × 7000 (経験的係数)
ここで L は電極間距離 (0.06m)、A は電極断面積 (0.000154 m²) です。
使用ライブラリ
Arduino IDEのライブラリマネージャーからもインストール可能です。

スケッチ (水質監視コード)
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
// Bluetooth用: RX=D3, TX=D2
SoftwareSerial BTserial(3, 2);
float reads;
int pin = A0;
float vOut = 0;
float vIn = 5;
float R1 = 1000;
float R2 = 0;
float buffer = 0;
float TDS;
float R = 0;
float r = 0;
float L = 0.06;
double A = 0.000154;
float C = 0;
float Cm = 0;
int rPin = 9, bPin = 5, gPin = 6;
int rVal = 255, bVal = 255, gVal = 255;
LiquidCrystal lcd(7, 8, 10, 11, 12, 13);
void setup() {
Serial.begin(9600);
BTserial.begin(9600);
lcd.begin(16, 2);
pinMode(rPin, OUTPUT);
pinMode(bPin, OUTPUT);
pinMode(gPin, OUTPUT);
pinMode(pin, INPUT);
lcd.print("Conductivity: ");
}
void loop() {
reads = analogRead(A0);
vOut = reads * 5.0 / 1023.0;
Serial.println(reads);
buffer = (vIn / vOut) - 1;
R2 = R1 * buffer;
Serial.println(R2);
delay(500);
// 抵抗率 → 伝導率 → TDS
r = R2 * A / L;
C = 1 / r;
Cm = C * 10; // mS/cm
TDS = Cm * 700;
// LCD表示
lcd.setCursor(0, 1);
lcd.print(C);
// RGB LEDで水質を色表示
if (reads < 600) {
if (reads <= 300) setColor(255, 0, 255); // 紫: 純水に近い
else if (reads > 200) setColor(200, 0, 255);
} else {
if (reads <= 900) setColor(0, 0, 255); // 青: 水道水レベル
else if (reads > 700) setColor(0, 255, 255); // シアン: やや高い
}
// Bluetoothでスマホアプリ (Ardutooth) に送信
BTserial.print(C);
BTserial.print(",");
BTserial.print(TDS);
BTserial.print(";");
delay(500);
}
void setColor(int red, int green, int blue) {
analogWrite(rPin, 255 - red);
analogWrite(gPin, 255 - green);
analogWrite(bPin, 255 - blue);
}
自作センサープローブ
古い試験管を利用しました。両端に穴を開けてワイヤーを通し、パテで固定しています。

回路図

製造プロセス
- Raspberry Pi & HDC2010:I2C温湿度センサー完全セットアップガイド
- Raspberry Pi 3とDHT11センサーを接続し、ThingsIo.aiクラウドへデータ送信
- スマートゴミ箱:自動廃棄物管理のためのセルラーIoTソリューション
- Heliumベースのソーラー駆動空気質センサー:設計と導入ガイド
- Phantom YoYo高感度水センサーをMCP3008 ADC経由でRaspberry Piに接続
- Windows 10 IoT CoreとSHT15センサーで高精度な温湿度モニタリング
- スマートホーム連携向けマルチポジション温度センサーシステム
- スマートArduino水筒:リアルタイム監視とアラート機能付き
- Arduino Nanoで作るスマートな動体検知水鉄砲
- Arduino Nano製ウェザーステーション:気圧・温湿度・UV・時計表示付き
- 先進カーボンベースNO₂センサーが室内空気質モニタリングを強化