

距離を測るだけのセンサーが、収納の「片付け忘れ」を年間で約3万円分の時間コスト削減につながることが分かっています。
超音波センサーは、音波を使って距離を測定するデバイスです。最もよく使われる「HC-SR04」は、40kHzの超音波パルスを発射し、物体に反射して戻ってくるまでの時間を計測することで距離を算出します。音速が約340m/秒であることを利用しているため、計算式は非常にシンプルです。
距離の計算式は以下の通りです。
$$\text{距離(cm)} = \frac{\text{エコー時間(μs)} \times 0.034}{2}$$
2で割るのは、音波が「行き」と「帰り」の両方を移動するためです。つまり往復分を考慮する必要があります。
HC-SR04とArduinoの配線は4ピンのみで完結します。
| HC-SR04ピン | Arduinoピン | 役割 |
|---|---|---|
| VCC | 5V | 電源供給 |
| GND | GND | グラウンド |
| TRIG | デジタルピン9(任意) | 超音波の発射トリガー |
| ECHO | デジタルピン8(任意) | 反射波の受信 |
配線はこれだけです。ArduinoとHC-SR04は3V3での動作には対応していないため、必ず5V端子に接続してください。3.3Vで駆動するマイコン(Raspberry PiのGPIOなど)に直結すると、ECHOピンの5V出力で入力ピンを破損させるリスクがあるので注意が必要です。
収納棚への設置を検討するなら、センサー単品はAmazonやAkizuki(秋月電子通商)で1個あたり約150〜300円で入手できます。5個セットであれば1,000円以下で購入できるため、複数箇所の収納を同時に管理したい場合でも初期投資を抑えられます。
秋月電子通商:HC-SR04超音波距離センサーモジュール商品ページ
これは使えそうです。配線が4本で済むことは、収納棚への後付け設置でも大きなメリットになります。
Arduinoで超音波センサーを動かす基本プログラムを見ていきましょう。以下のスケッチは、HC-SR04を使って距離をシリアルモニターに表示する最小構成のコードです。
```cpp
// HC-SR04 基本スケッチ(距離測定・シリアル出力)
const int trigPin = 9;
const int echoPin = 8;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
// TRIGピンに10μsのパルスを送信
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// ECHOピンでパルス幅を計測
long duration = pulseIn(echoPin, HIGH);
// 距離をcmに変換
float distance = duration * 0.034 / 2;
Serial.print("距離: ");
Serial.print(distance);
Serial.println(" cm");
delay(500); // 500ms待機
}
```
このコードのポイントは`pulseIn()`関数です。この関数はECHOピンがHIGHになっている時間(マイクロ秒)を返します。その値に0.034を掛けて2で割ると、センサーから物体までの距離(cm)が得られます。
コードが書けたら動作確認が基本です。
ArduinoIDE上部の「シリアルモニター」ボタンをクリックし、ボーレートを9600に設定してください。センサーの前に手を置くと距離の数値が変化するはずです。センサーの有効計測範囲は約2cmから400cmで、これはA4用紙の長辺(約29.7cm)が13枚分並んだ距離に相当します。収納棚の奥行きを測るには十分な範囲です。
`pulseIn()`関数にはタイムアウト引数を設定することが推奨されます。デフォルトのタイムアウトは1秒ですが、収納棚のように距離変化が少ない環境では`pulseIn(echoPin, HIGH, 30000)`のように30msに制限することで、プログラム全体の応答速度が大幅に改善されます。
距離の数値をそのまま表示するだけでは、収納管理の現場では使いにくいです。距離に応じてLEDの色を変えることで、「棚が空いているか・物が入っているか」を一目で判断できる仕組みが実現できます。
これは収納の「見える化」です。
以下は、3色のLEDを使って棚の状態を3段階で表示するプログラム例です。
```cpp
// HC-SR04 + 3色LED で収納状態を可視化
const int trigPin = 9;
const int echoPin = 8;
const int ledGreen = 5; // 空き(20cm以上)
const int ledYellow = 6; // 半分(10〜20cm)
const int ledRed = 7; // 満杯(10cm未満)
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(ledGreen, OUTPUT);
pinMode(ledYellow, OUTPUT);
pinMode(ledRed, OUTPUT);
}
float getDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000);
return duration * 0.034 / 2;
}
void loop() {
float distance = getDistance();
// すべてのLEDを消灯
digitalWrite(ledGreen, LOW);
digitalWrite(ledYellow, LOW);
digitalWrite(ledRed, LOW);
if (distance >= 20.0) {
digitalWrite(ledGreen, HIGH); // 空き
} else if (distance >= 10.0) {
digitalWrite(ledYellow, HIGH); // 半分
} else {
digitalWrite(ledRed, HIGH); // 満杯
}
delay(300);
}
```
距離の閾値(20cm・10cm)は収納棚の奥行きに合わせて変更してください。例えば奥行き40cmのクローゼットなら、「30cm以上で空き」「15〜30cmで半分」「15cm未満で満杯」といった設定が実態に近くなります。
LEDは単色品であれば1個あたり10〜20円です。3色セット(赤・黄・緑)はAmazonで100個入りが500円前後で販売されているため、複数の棚に設置してもコストはほぼゼロに近い水準です。
LEDを直接Arduinoのデジタルピンに接続する場合は、必ず電流制限抵抗(220Ω〜330Ω)を直列に挿入してください。抵抗なしで接続するとArduinoの出力ピンに定格(40mA)を超える電流が流れ、ピンが破損する可能性があります。これだけは例外なく守る必要があります。
シリアルモニターはPCがないと確認できません。収納棚のそばにPCを置くのは現実的ではないため、小型液晶ディスプレイ(LCD)をArduinoに追加することで、スタンドアロン動作する収納管理ボードが完成します。
LCDは「I2C接続の16×2型」が最も扱いやすいです。4ビット接続の従来型LCDは配線が6〜8本必要でしたが、I2CモジュールはSDA・SCLの2本追加するだけで済みます。つまり配線の複雑さが大幅に減ります。
必要なライブラリは`LiquidCrystal_I2C`です。ArduinoIDEのライブラリマネージャーから検索・インストールできます。
```cpp
// HC-SR04 + I2C LCD 収納距離表示
#include
#include
LiquidCrystal_I2C lcd(0x27, 16, 2); // アドレスは0x27または0x3F
const int trigPin = 9;
const int echoPin = 8;
void setup() {
lcd.init();
lcd.backlight();
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
float getDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000);
return duration * 0.034 / 2;
}
void loop() {
float distance = getDistance();
lcd.setCursor(0, 0);
lcd.print("Dist: ");
lcd.print(distance, 1);
lcd.print(" cm ");
lcd.setCursor(0, 1);
if (distance >= 20.0) {
lcd.print("Status: EMPTY ");
} else if (distance >= 10.0) {
lcd.print("Status: HALF ");
} else {
lcd.print("Status: FULL ");
}
delay(500);
}
```
I2CのアドレスはLCDモジュールによって`0x27`または`0x3F`のどちらかです。アドレスが分からない場合は、I2Cスキャンスケッチ(ArduinoIDEのサンプルスケッチに含まれる)を先に実行して確認するのが確実です。
I2C LCD(16×2)はAmazonや秋月電子通商で600〜1,000円程度で入手可能です。Arduinoのデジタルピンを消費せずに情報表示ができるため、後からLEDや他のセンサーを追加する拡張性も保たれます。これは使えそうです。
Arduino公式リファレンス:Wire(I2C)ライブラリの使い方(英語)
多くの解説記事が触れない盲点があります。それは「設置角度による誤検知」です。HC-SR04の検出ビーム角は約15〜30度の広がりを持っています。これはA4用紙1枚(21cm幅)が1m先で横幅約53cmの扇状に広がる範囲に相当します。
収納棚の仕切り板やハンガーなど「斜めに置かれた物体」に超音波が反射して別の角度に散乱すると、センサーが正しく反射波を受信できず、距離が実際より長く表示される「見かけ上の空き」が発生します。厳しいところですね。
この問題に対処するには以下の3点を意識した設置が有効です。
- センサーを棚の天板中央に垂直下向きに設置する:棚の側面に横向きで取り付けると、衣類や小物の角に当たった超音波が側壁で多重反射しやすくなります。
- 測定値の平均化処理をプログラムに加える:1回の計測値ではなく、10回計測した中央値または平均値を使うことで、突発的な誤値の影響を90%以上排除できます。
- センサー前面に直径3〜5cmの筒(ガイド管)を付ける:厚紙や塩ビ管を切断して超音波の指向性を絞ることで、棚板の両端に反射波が届きにくくなります。
平均化処理のコード例を示します。
```cpp
float getAverageDistance(int samples) {
float total = 0;
for (int i = 0; i < samples; i++) {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000);
total += duration * 0.034 / 2;
delay(50); // 計測間隔
}
return total / samples;
}
```
`getAverageDistance(10)`のように呼び出せば、10回計測の平均距離が返されます。10回分の計測に要する時間は約500ms(0.5秒)で、収納の開閉検知には十分なレスポンス速度です。
また、収納扉を開閉した直後の1〜2秒間は気流でセンサーの測定値がぶれることがあります。扉の開閉を検知するリードスイッチ(200〜400円)を併用し、「扉が開いた直後3秒間は計測を停止する」制御を加えると、誤表示をほぼゼロにできます。
設置工事不要・後付けで済む点が、賃貸住宅での収納管理に超音波センサー+Arduinoが選ばれる理由の一つです。粘着テープとマジックテープを使えば、棚への固定も原状回復できる形で完結します。
Arduino公式リファレンス:pulseIn()関数の詳細仕様(タイムアウト引数を含む)