【Arduino】測距センサ(PSD)を使って物体に反応するロボットを作る!
以前、analogWriteを用いて速さの調整をするプログラムを紹介しました。
パワーを出力することでロボットの速さが変化しましたね。
今回はanalogReadを用いたプログラムを紹介します。
Writeで出力したということは、Readで入力されるということです。
そして今回入力される値は、測距センサと言われる距離を測ることのできるセンサの値です。
センサと物体の距離をプログラムに取り込み、その読み取った値でロボットの動きを止めてみましょう!
- 測距センサの紹介
- 回路
- プログラム
→analogReadの使い方
私のブログで登場するロボットはArduinoを搭載した車輪ロボット「NR-02」です。
下記記事のArduinoを始めるならこれを買えばOKの見出しで必要なパーツを紹介しています。
解説動画
今回の記事はこちらの動画を解説したものです。
測距センサとは
PSD:Position sensitive detectorというセンサです。
メーカー:SHARP
型番 :GP2Y0A21YK
測距範囲:10cm~80cm
出力 :アナログ電圧
550円ほどで秋月電子通商で購入できます。
通販コードは I-02551 です。
このセンサの仕組みは下記のグラフの通りです。
横軸の距離が10cmから80cmになるにつれて、縦軸の電圧が下がっています。
つまり、物体までの距離の変化を電圧に変換して出力してくれるセンサです。
10cmより近い場合も電圧の変化があります。
そのため、0~10cmで使っても距離が変わっているように勘違いしてしまいますね。
必ず測定範囲内で使うようにしましょう!
回路の説明
回路の作り方はこちらです。
- 電源
- GND
- A0
を繋ぎます。
A0はセンサが測定距離を電圧に変換した信号を送るための線です。
配線図
配線図は下記のとおりです。
センサの導線の色が特殊です!
とくにVCC(電源)が黒色であるところは要注意です。
GNDと間違えないように気を付けましょう。
シリアルプロッタの使い方
シリアルプロッタを使うことで、センサの値を読み取ることができます。
まずArduinoを立ち上げます。タブから、
ファイル→スケッチ例→01.Basics→AnalogReadSerial
を開きます。
サンプルプログラムが開きましたね?
A0に繋がれたセンサの値をArduinoからパソコンに送ってくれるプログラムです。
これをこのままArduinoに書き込みます。
Arduinoの詳しい使い方はこちらです!
書き込みが終わったら、ツールタブからシリアルプロッタを開きます。
このままだと読み取りスピードが速すぎて、分かりづらいので間隔を調整します。
プログラム内のdelayを1から100に変更します。
先ほどと同様に、Arduinoに書き込み、シリアルプロッタを開きましょう。
更新速度がゆっくりになって、見やすいグラフに変わります!
センサと壁の距離を10cmにしましょう。
そしてその壁を少しずつセンサと逆方向に動かしていきます。
シリアルプロッタに表示されているグラフの縦軸の値が、壁が遠ざかるとだんだん小さくなっていきます。
80cm以上離してみると、値は小さくなっています。
しかし変化幅は小さく、分かりづらいです。
序盤に説明した通り、測定範囲内で使用しましょう!
プログラムの説明(analogReadの紹介)
今回のプログラムの肝となるanalogReadについて紹介します。
デジタルとは、
ON/OFFやHIGH/LOWのような、2つの状態で表すことのできるものです。
アナログとは、
強~中~弱~OFFのような、変化量を連続的に表すことができるものです。
analogReadは以下のようなプログラムで使うことができます!
intの後に変数を定義します。
今回はsensor_valueとします。
変数についてはこちらの記事で詳しく解説しています。
sensor_value = analogRead(A0);
と書くことで、A0で読み取ったアナログの値をsensor_valueに入れることができます。
最初は分からなくても、使うことで慣れて理解できます!
プログラムのポイント
では、実際にプログラムを作っていきましょう!
- スタートボタンを押すと1秒後に動き始める
- 物体との距離が20cm以下になると停止する
- 測距センサはA0につながっている
- スイッチは8番につながっている
- 左モータは6番(A)と9番(B)でコントロール
- 右モータは5番(A)と3番(B)でコントロール
ソースコード
ソースコード全文です。
1const int PIN_MOTOR_L_A = 6; //左モータA
2const int PIN_MOTOR_L_B = 9; //左モータB
3const int PIN_MOTOR_R_A = 5; //右モータA
4const int PIN_MOTOR_R_B = 3; //右モータB
5const int PIN_BUTTON = 8; //押しボタンスイッチ
6
7//前進
8void moveForward(int power, int duration) {
9 analogWrite(PIN_MOTOR_L_A, power); //左A
10 analogWrite(PIN_MOTOR_L_B, 0); //左B
11 analogWrite(PIN_MOTOR_R_A, power); //右A
12 analogWrite(PIN_MOTOR_R_B, 0); //右B
13 delay(duration);
14}
15
16//後退
17void moveBackward(int power, int duration) {
18 analogWrite(PIN_MOTOR_L_A, 0); //左A
19 analogWrite(PIN_MOTOR_L_B, power); //左B
20 analogWrite(PIN_MOTOR_R_A, 0); //右A
21 analogWrite(PIN_MOTOR_R_B, power); //右B
22 delay(duration);
23}
24
25//右旋回
26void turnRight(int power, int duration) {
27 analogWrite(PIN_MOTOR_L_A, power); //左A
28 analogWrite(PIN_MOTOR_L_B, 0); //左B
29 analogWrite(PIN_MOTOR_R_A, 0); //右A
30 analogWrite(PIN_MOTOR_R_B, power); //右B
31 delay(duration);
32}
33
34//左旋回
35void turnLeft(int power, int duration) {
36 analogWrite(PIN_MOTOR_L_A, 0); //左A
37 analogWrite(PIN_MOTOR_L_B, power); //左B
38 analogWrite(PIN_MOTOR_R_A, power); //右A
39 analogWrite(PIN_MOTOR_R_B, 0); //右B
40 delay(duration);
41}
42
43//ブレーキ
44void stopBreak(int duration) {
45 digitalWrite(PIN_MOTOR_L_A, LOW); //左A
46 digitalWrite(PIN_MOTOR_L_B, LOW); //左B
47 digitalWrite(PIN_MOTOR_R_A, LOW); //右A
48 digitalWrite(PIN_MOTOR_R_B, LOW); //右B
49 delay(duration);
50}
51
52//フリー
53void stopFree(int duration) {
54 digitalWrite(PIN_MOTOR_L_A, HIGH); //左A
55 digitalWrite(PIN_MOTOR_L_B, HIGH); //左B
56 digitalWrite(PIN_MOTOR_R_A, HIGH); //右A
57 digitalWrite(PIN_MOTOR_R_B, HIGH); //右B
58 delay(duration);
59}
60
61void setup() {
62 //ピンの出力(Output)or入力(Input)設定
63 pinMode(PIN_MOTOR_L_A, OUTPUT); //左モータA
64 pinMode(PIN_MOTOR_L_B, OUTPUT); //左モータB
65 pinMode(PIN_MOTOR_R_A, OUTPUT); //右モータA
66 pinMode(PIN_MOTOR_R_B, OUTPUT); //右モータB
67 pinMode(PIN_BUTTON, INPUT); //スイッチ
68
69 //スタートボタンを押されるのを待つ
70 while(digitalRead(PIN_BUTTON)==0);
71 delay(1000); //1秒待つ
72}
73
74void loop() {
75 int sensor_value; //距離センサの値
76
77 sensor_value = analogRead(A0); //センサの値を読み取る
78 if (sensor_value < 270) {
79 //270より小さい場合(遠い場合)
80 moveForward(255, 10);
81 } else {
82 stopBreak(10);
83 }
84
85}
86
プログラムの仕組み
センサと物体との距離が20cm以下になると停止する仕組みは、下記のプログラムがあるからです。
sensor_valueという定義した変数にA0の値を代入することで、センサの値を読み取ることができます。
もしその値が270より小さければ→まだ20cmでないので前進をし続ける
もしその値が270を超えてしまったら→壁が近づいてきたのでブレーキをかける
…という仕組みになっています!
動かしてみましょう!
このプログラムでロボットを動かすと、こんな感じで動きます!
(↓動作確認のところから再生されます)
まとめ
今回の記事では、測距センサを使って指定した位置でロボットが止まる仕組みを紹介しました。
analogReadやif文も使っていくうちに理解が深まっていきますよ!
- 測距センサの紹介
- 回路
- プログラム
→analogReadの使い方
測距センサは簡単にできたよ!って人には応用を。
スピーカーを使って、ロボットの気持ちを鳴き声として表現させましょう!
測距センサは、距離を測ることができるセンサです。
センサ仲間として光センサがあります。こちらは部屋の明るさ・暗さを判断できます。
測距センサと一緒に仕組みや使い方を学びましょう!
最後まで読んでいただき、ありがとうございました!
以上、CHAでした!