スマートガレージ駐車アシスト:RGB LEDフィードバックで駐車位置をガイド
必要な部品と材料
| 部品 | 数量 |
|---|---|
| Arduino Nano R3 | 1 |
| 超音波センサー HC-SR04(汎用) | 1 |
| コンデンサ 1000µF | 1 |
| 1N4148 高速スイッチングダイオード | 1 |
| スルーホール抵抗 470Ω | 1 |
| WS2812B LEDストリップ 1m IP30 5V | 1 |
必要な工具と機器
- 3Dプリンター(汎用)
- はんだごて(汎用)
プロジェクト概要
車が近づき、最終的に停止(駐車)位置に達するまで、アドレサブルRGB LEDでドライバーにフィードバックを提供するガレージ駐車センサーです。動画で動作を確認できます。
手元にあったアクリル製直径1/2インチの半円材(長さ20-7/16インチにカット)をレンズとして、かつダブテール継ぎ手セクションを保持する部材として設計しました。これはネットで約$0.66/フィートで購入可能ですが、クリアフィラメントでセグメント印刷可能なレンズモデルも同梱しています。
STEP 1: LEDストリップ準備
WS2812B LEDストリップ(個別アドレサブルRGBスマートピクセル、30LED、1m)を2つの15LEDセグメントにカットし、各セグメントの先頭にリード線をはんだ付け。ストリップの矢印はリード線が必要な側とは「反対方向」を向くように。
STEP 2: レールセクション組み立て
アウトサイドレール1本、インサイドレール2セグメント(片側分)、中央にケースを配置して組み立て。
STEP 3: LEDストリップ設置
両側からLEDストリップのリード線をケースに通し、裏面テープで固定。LEDストリップは各アウトサイドレール端から約1/2インチ手前で終了。
STEP 4: レンズ挿入
レンズを両端からケース奥までスライドさせ、すべてのダブテールをロック。印刷レンズ使用時は片側4個必要で、ダブテール部分を橋渡しする設計。
STEP 5: バッカーボードへ取り付け
エンドキャップ付きアセンブリをバッカーボード(私は1/2インチMDF、幅2インチ、長さ45-1/8インチにカット)に取り付け。小型ナベ頭または皿頭ネジを使用(丸頭ネジは不可:後でUSBケーブルをスロットに通して再プログラミングする際に干渉するため)。
STEP 6: 電子部品配線
コンデンサの位置に注意。電源からの電圧スパイク防止用。LED信号線(ピン7)には抵抗、Arduino(V+)にはダイオードを使用し、電源オフ時にUSBを挿してもArduinoがLEDに電圧を供給しようとしてオンボードレギュレーターに過電流が流れるのを防止。ダイオードと抵抗は配線途中ではんだ付けし、熱収縮チューブで絶縁。ケース底部近くを外側からドリルで穴を開け、電源配線を通す(ワイヤー種類によりサイズが異なるためモデルには未設計)。18/2ワイヤー推奨。私はドアベル用ワイヤーを使い、ケース外側にコネクタを設けた。
STEP 7: Arduino固定と配線完了
2.5mmネジでArduinoを固定し、配線接続を完了。ホールドダウンの端部がケースの四角穴に突き刺さる形。Arduinoの最外側未使用ピンを取り外して設置を容易にした。
STEP 8: 超音波センサー取り付け
2.5mmネジで超音波センサー(HC-SR04)をカバーにホールドダウンで固定。センサーへのはんだ付け完了。注意:配線がセンサー中央側を向くようにし、組み立て時に側壁と干渉しないようにする。
STEP 9: カバー取り付け
3mmネジでカバーをケースに固定。
STEP 10: Arduinoプログラミング
以下のコードでArduinoをプログラミング。事前にIDEライブラリ「FastLED」と「QuickStats」を更新してからコンパイル。パラメータ『startdistance』(車両接近検知開始距離)と『stopdistance』(車両最終駐車位置)を調整。センサー範囲は3cm〜400cmなので、両パラメータはこの範囲内で設定。
STEP 11: ガレージドアオープナー連動
ガレージドアオープナーにコンセント内蔵ランプソケットアダプタを取り付け、5VDC電源をここに接続してライトバーへ配線。ドアが開いてからドアライトが消えるまでの間のみライトバーが点灯するため、常時点灯を防止。
コード
- Arduino Code
Arduino Code Arduino
/* Garage Parking Sensor - Published By Bob Torrence */
#include <FastLED.h>
#include <QuickStats.h>
QuickStats stats;
#define LED_PIN 7
#define NUM_LEDS 15
const int trigPin = 9;
const int echoPin = 10;
CRGB leds[NUM_LEDS];
float duration;
float durationarray[15];
int distance;
int stopdistance = 115; // 駐車位置(cm)
int startdistance = 400; // 検知開始距離(cm)
int increment = ((startdistance - stopdistance) / 15);
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
Serial.begin(9600);
}
void loop() {
for (int i = 0; i <= 14; i++) {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
durationarray[i] = pulseIn(echoPin, HIGH);
distance = durationarray[i] * 0.034 / 2;
Serial.print(distance); Serial.print(" ");
}
duration = stats.median(durationarray, 15);
distance = duration * 0.034 / 2;
Serial.print("Distance: "); Serial.println(distance);
if (distance < stopdistance) {
// 赤:停止位置到達
for (int i = 0; i <= 14; i++) leds[i] = CRGB(255, 0, 0);
FastLED.show();
}
else if (distance < stopdistance + increment) {
// 黄:残り1段階
for (int i = 1; i <= 14; i++) leds[i] = CRGB(0, 0, 0);
leds[0] = CRGB(255, 255, 0); FastLED.show(); delay(50);
}
else if (distance < stopdistance + increment * 2) { /* 黄2LED */ }
else if (distance < stopdistance + increment * 3) { /* 黄3LED */ }
else if (distance < stopdistance + increment * 4) { /* 緑4LED */ }
else if (distance < stopdistance + increment * 5) { /* 緑5LED */ }
else if (distance < stopdistance + increment * 6) { /* 緑6LED */ }
else if (distance < stopdistance + increment * 7) { /* 緑7LED */ }
else if (distance < stopdistance + increment * 8) { /* 緑8LED */ }
else if (distance < stopdistance + increment * 9) { /* 緑9LED */ }
else if (distance < stopdistance + increment * 10) { /* 緑10LED */ }
else if (distance < stopdistance + increment * 11) { /* 緑11LED */ }
else if (distance < stopdistance + increment * 12) { /* 緑12LED */ }
else if (distance < stopdistance + increment * 13) { /* 緑13LED */ }
else if (distance < stopdistance + increment * 14) { /* 緑14LED */ }
else {
// 緑全点灯:駐車位置より手前
for (int i = 0; i <= 14; i++) leds[i] = CRGB(0, 255, 0);
FastLED.show(); delay(50);
}
}
カスタムパーツとエンクロージャ
3Dプリント用ファイルは別途参照。
回路図
2019-04-21更新:ダイオード方向を修正
製造プロセス
- TinyML言語検出器:Edge ImpulseとArduino Nano 33 BLE Senseで「はい」を多言語判別
- Arduino NanoとMPU-6050で作るリアルタイムジャイロスコープゲーム
- Arduinoデジタルダイス: LCD表示の乱数ジェネレーター自作
- Arduino Nanoで37LEDルーレットゲームを自作:ヨーロピアンスタイル完全再現
- ATtiny85ミニアーケード:スネークゲーム - 手のひらサイズOLEDゲーム機の製作
- ポータブル距離検出器:Arduino Nano自作キット(HC-SR04、18650電源、3Dプリントケース付き)
- Arduino Nanoで作る音声反応デスクライト:音楽に合わせて光るイルミネーション
- パーソナル・ヘルスケア・アシスタント(PHA):コミュニティ健康見守りIoTソリューション
- 銅メッキプロジェクト:Arduino UNOで作るスマート電気メッキシステム
- Arduino Nanoで作るNeoPixelマトリックス版Pongゲーム
- Arduinoシフトレジスタで美しい光のシーケンスを作成