ポータブル距離検出器:Arduino Nano自作キット(HC-SR04、18650電源、3Dプリントケース付き)
必要な部品と材料
| Arduino Nano R3 | ×1 |
| 超音波センサー HC-SR04 | ×1 |
| 18650リチウムイオン電池 | ×1 |
| TP4056リチウムイオン充電モジュール | ×1 |
| DC-DC 5V昇圧コンバーター | ×1 |
| ブザー | ×1 |
| ロータリーポテンショメーター | ×1 |
| スライドスイッチ | ×1 |
| LED(赤2、緑1、青1) | ×4 |
| 抵抗 330Ω | ×2 |
| M3キャップボルト 10mm | ×4 |
| ワイヤー(18AWG) | ×1 |
| 3Dプリントパーツ(エンクロージャ3部品) | ×1 |
| スレッドアダプター | ×1 |
必要な工具と機械
- 3Dプリンター(Anet A8使用)
- はんだごて
- ホットグルーガン
- Dremelまたはロータリーツール
使用するアプリとオンラインサービス
- Arduino IDE(NewPingライブラリ必須)
- Simplify3Dまたは任意のスライサー
プロジェクト概要
はじめに
レーマン大学運動科学部門がウェイトトレーニング研究を実施中で、反復動作の可動域にバラツキがありデータに影響が出ていました。マシンや重量を用いるエクササイズでフル可動域を検知するデバイスの製作を依頼されました。
デバイスに求められた条件:
- 検知距離が調整可能
- マシンに永久固定しない
- 三脚取り付け可能
- ワイヤレス(配線なし)
パーツ
主要パーツを以下に掲載(完全版は上部BoM参照)。最適なパーツ選定ではなく、手持ちで対応したものです。カスタムPCB、SMT部品、LiPo電池ならフットプリントを大幅縮小可能。


コード
コード(後述)のコンパイルにはNewPingライブラリが必要です。
ブザー周波数と上下限はグローバル変数で変更可能。上下限はセンサーが読み取る最小/最大距離で、ポテンショメーターのアナログ値[0,5]Vにマッピングされます。
int frequency = 700; // 周波数 Hz
int lower_bound = 60; // 最小距離 mm
int upper_bound = 200; // 最大距離 mm
起動時に3回ビープ音で正常起動を通知(setup()内)。loop()では超音波センサーから継続的にデータを取得し、ポテンショメーターで設定した閾値と比較します。
3Dプリント
全ファイルをThingiverseにアップロード、またはページ下部の統合ファイルから入手可能。CAD操作はここでは割愛。3Dプリントの制約を考慮し、オーバーハングを45度面取りで最小化(サポート材削減)、クリアランスを広めに確保(異なる校正のプリンターでも嵌合可能)。


プリント時間(参考):
- トップピース: 2時間40分
- ボトムピース: 2時間20分
- ノブ: 20分
組み立て
回路図はページ下部参照。配線前にパーツを仮組みしてフィット確認。


配線にはIDEケーブルを流用。ワイヤー群をまとめて剥けるため整理しやすいです。


大半の電子部品はプリントパーツの1つに実装するため、配線ルーティングと管理に工夫が必要です。
TP4056基板のSMDインジケーターLEDを外し、延長ワイヤーと3mmスルーホールLEDをハンダ付け(電流制限抵抗は基板内蔵)。この移植手法の動画あり。

Arduino Nanoのアクセス可能なGNDパッドが2つしかないため、ユニバーサル基板でGNDパッドを拡張。5Vラインも同様に拡張(下図参照)。


ストリップの導通をカットして5VとGNDのショートを防止(赤X印の箇所)。銅箔のみ切断で基板全体を切る必要はなし。
エンクロージャ外で配線し、随時ケースに収めてワイヤー長と干渉をチェック。

ポテンショメーターの軸を6mmカットして突出を抑制。

18650への直ハンダは悪習慣(過熱で電池劣化・故障リスク)。正しくはアルミニウムストリップをスポット溶接。
ホットボンドで電子部品を固定(恥ずかしながら)。ホットボンドは経年劣化で必ず外れるため避けるべき。正しい機械設計とファスナーが長持ちします。試作なら許容だが、量産品では不適。

まとめ
振り返るとIRセンサーの方が良かったかもしれませんが、超音波センサーで実験するまで気づけませんでした。IRセンサーは視野角が狭い(約±15°、全角30°)ため、物体がセンサー真上に来る前にブザーが鳴り、誤検知・不正確な読み取りの原因になります。また、物体の面が送信音波に対して垂直(または許容角度内)でないと反射波を受信できず距離算出不能です。
当初の計画はユニットを床置きし、ウェイトバーのプレートが閾値を超えて降下したらブザーを鳴らすというもの(固定センサー、移動トリガー)。エンジニア仲間が逆転の発想を提案:センサーを動くバーに取り付け、地面を向ける。地面がトリガーになり、広い視野角による不正確さも解消。
この提案は問題解決に優れ、実装も容易。注文した1/4インチ三脚ナットアダプターに1/4→3/8アダプターと3/8→1/4アダプターが付属しており、後者が活用できます。
最初Dremelが手元になく、三脚アダプター全体を考慮して3Dモデリングしたため、18650電池と合わせて重量増に。これ以上重くしたくないので、第2アダプターをカットしてからマウントをモデリングし直します。1週間後にこの代替マウント解法を完成させます。それまで現バージョンでも動作します!
今後の展望
超音波センサー実験で限界を理解。視野角±15°(全角30°)のため、物体が真上に来る前にトリガーされ不正確。また、物体面が音波に垂直でないと反射波を受信できず距離測定不能。
仲間の提案(センサーを移動側に、地面をターゲットに)はこの問題を解決し実装も容易。1/4インチ三脚ナットアダプターの付属品(3/8→1/4変換)が活用可能。重量増対策として第2アダプターをカットしてからマウント再設計予定。1週間後に取り組みます。
コード
- RangeDetectionDevice.ino
RangeDetectionDevice.ino Arduino
/** Viktor Silivanov 3/22/2018 Portable distance detection device using the HC-SR04 Ultrasonic sensor with distance adjustment for triggering the buzzer. **/
//******************** Libraries ****************************************************************************************************************************************************************************************************************
#include <NewPing.h>
//******************** Pins *********************************************************************************************************************************************************************************************************************
//Analog Pins
#define wiper A5
//Digital Pins
#define echo 2
#define trig 3
#define ON_LED 7
#define buzzer 8
#define buzzer_LED 9
//******************** Global Variables **********************************************************************************************************************************************************************************************************
//User Modification Allowed
int frequency = 700; // Frequency in Hz
int lower_bound = 60; // Distance in mm
int upper_bound = 200; // Distance in mm
//Do Not Modify
int buzz_time = 250; // Startup buzzer duration ms
int buzz_delay = 280; // Startup buzzer delay ms
int max_distance = 400; // NewPing library argument
int i = 0;
int distance;
int threshold;
NewPing sonar(trig, echo, max_distance);
//******************** Setup *********************************************************************************************************************************************************************************************************************
void setup() {
Serial.begin(9600);
pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
pinMode(buzzer, OUTPUT);
pinMode(buzzer_LED, OUTPUT);
pinMode(ON_LED, OUTPUT);
digitalWrite(ON_LED, HIGH); // Green LED on while powered
// 3 beeps on startup
while(i < 3){
digitalWrite(buzzer_LED, HIGH);
tone(buzzer, frequency, buzz_time);
delay(buzz_delay);
i++;
}
digitalWrite(buzzer_LED, LOW);
}
//******************** Main Loop *************************************************************************************************************************************************************************************************************
void loop() {
distance = sonar.ping_cm(); // Get distance in cm
threshold = analogRead(wiper); // Read potentiometer
threshold = map(threshold, 0, 1023, lower_bound, upper_bound); // Map to trigger range
if(distance != 0 && distance < threshold){
tone(buzzer, frequency);
digitalWrite(buzzer_LED, HIGH);
} else{
noTone(buzzer);
digitalWrite(buzzer_LED, LOW);
}
// serial_test(); // Uncomment for serial monitor debugging
}
//******************** Test Function ************************************************************************************************************************************************************************************************************
void serial_test(){
Serial.print("Ping: ");
Serial.print(distance);
Serial.println("cm");
Serial.print("Range: [");
Serial.print(lower_bound);
Serial.print(", ");
Serial.print(upper_bound);
Serial.println("] cm");
Serial.print("Threshold: ");
Serial.print(threshold);
Serial.println("cm");
delay(100);
}
カスタムパーツとエンクロージャ
全3パーツを1ファイルに統合
回路図

製造プロセス
- TinyML言語検出器:Edge ImpulseとArduino Nano 33 BLE Senseで「はい」を多言語判別
- Arduino NanoとMPU-6050で作るリアルタイムジャイロスコープゲーム
- Arduinoデジタルダイス: LCD表示の乱数ジェネレーター自作
- Arduino Nanoで37LEDルーレットゲームを自作:ヨーロピアンスタイル完全再現
- ATtiny85ミニアーケード:スネークゲーム - 手のひらサイズOLEDゲーム機の製作
- Arduino Nanoで作る音声反応デスクライト:音楽に合わせて光るイルミネーション
- Arduino Nano と OpenCV で実現する自律顔追跡ロボットカー
- 銅メッキプロジェクト:Arduino UNOで作るスマート電気メッキシステム
- Arduino Nanoで作るNeoPixelマトリックス版Pongゲーム
- ポータブル温度監視ステーション: TMP36とLCDで高精度表示
- Arduinoシフトレジスタで美しい光のシーケンスを作成