SSブログ
電子工作・プログラミング(Arduino系) ブログトップ

HC-SR04で距離を測定~ArduinoとM5stack~ [電子工作・プログラミング(Arduino系)]

この記事は、まだ、書いている途中なので写真は、後で付けます。


[NEW]今回は、HC-SR04という距離センサーを使って、距離を測定したいと思います。使うのは、M5stackGray、プログラムはArduinoです。

1.HC-SR04とM5stackGrayの取り付け

まずは、HC-SR04とM5stackについてです。

HC-SR04。超音波での測定ができる。

img_20200223_184100.287.jpg

裏面

img_20200223_184113.087.jpg


まずは、HC-SR04とM5stackGlay、この2つを取り付けます。ピン配列についてですが、M5stackGrayには、オス用のピンと、メス用のピンがあります。どちらでもいいと思うので、使うほうを見てピン配置をしてください。

※メスのバージョンはやってないので間違っているかもしれません。間違っていたらコメントで教えてください[あせあせ(飛び散る汗)]

VCC・・・どこかの5V(オスメス同様)
GND・・・どこかのGND(オスメス同様)
Echoピン・・・青い5番ピン(メスの場合は青いG5)
Trigピン・・・青い2番ピン(メスの場合は青いG2)
青いところは、デジタルピンなんだそうです。

接続
VCC 赤
GND 緑
Echo オレンジ
Trig 黄色

M5stackのピン配置

img_20200223_184146.390.jpg

これで接続は完了です。

2.M5stackGrayのプログラム

まずは、簡単に、1列分データを表示して、出し切ったら画面をリセットして、またやり直すというプログラムにします。

プログラム
※メス用ピンでやった時には、ピン定義を変えてね(違っていたらコメントお願いします[ふらふら])


#include <M5Stack.h>
#include <Arduino.h>

#define echoPin 5 //エコーピンを5番ピンに指定
#define trigPin 2 //トリガーピンを2番ピンに指定

  long duration; //往復時間を測る変数
  int distance; //計算結果(距離)を入れる変数

void setup()
{

  Serial.begin(115200);

  M5.begin();
  delay(500);
  M5.Lcd.setTextFont(4);//テキストサイズを4にする
  M5.Lcd.setCursor(0, 0);//M5プリント用カーソルを0,0に移動
 
  pinMode(trigPin, OUTPUT); //トリガーピンをOUTPUTにする
  pinMode(echoPin, INPUT); //エコーピンをINPUTにする

  Serial.begin(9600); 
}


void loop()
{
  for (int i=1; i <= 9; i++){//データは1列に8つ書けるので、8回で1まとめにする
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH);
  
  distance = duration * 0.034 / 2; //距離を計算する
  
    M5.Lcd.print(distance);//この2行で、M5stackGrayに
    M5.Lcd.println("cm");  //距離データを表示して、改行(printlnのlnのところ)
   Serial.print(distance);//この2行で、シリアルモニタに
   Serial.println("cm");//距離データを表示して、改行(printlnのlnのところ)
  
  delay(1000);//1秒間隔
  }
M5.Lcd.fillScreen(BLACK);//1番下まで距離データを入力したら、画面を黒にしてデータを消す。
M5.Lcd.setCursor(0, 0);//カーソルを0,0にする

}



このプログラムを実行すると、以下のように動きます。

・シリアルモニタに表示(X㎝)

・M5stackGrayに上からデータが表示      }
 表示させるデータは、1列8個         }  繰り返し
・一番下に行ったら全消しして、上から表示   }

ポイントは、distance = duration * 0.034 / 2 という距離測定計算のところです。
訳すと、
距離=時間×光の速さ÷2
ということです。時間はナノ秒、それに合わせて光の速さ340m/秒を、0.034㎝/ナノ秒にしています。÷2は、HC-SR04が、往復の時間を計測しているからです。0.034㎝/ナノ秒というところにご注意
また、データを消す作業は、M5.Lcd.fillScreen(BLACK)で、すべてのスクリーンを黒にして行っています。

たくさんデータが入っていっぱいになると
img_20200224_142607.734.jpg
リセットされる
img_20200224_142612.366.jpg

いいとおもう。・・・



思った人もいると思いますが、これだと、一番下のデータが出てきても、すぐに消えてしまったり、長くデータを見ていられません。なので、これを改良します。

・データ表示を3行にして、できるだけ長くデータを表示させる。

そうしたプログラムがこちら


#include <M5Stack.h>
#include <Arduino.h>

#define echoPin 5 //エコーピンを5番ピンに指定
#define trigPin 2 //トリガーピンを2番ピンに指定

  long duration; //往復時間を測る変数
  int distance; //計算結果(距離)を入れる変数

void setup(){

  Serial.begin(115200);

  M5.begin();
  delay(500);
  M5.Lcd.setTextFont(4);//テキストサイズを4にする
  M5.Lcd.setCursor(0, 0);//M5プリント用カーソルを0,0に移動
 
  pinMode(trigPin, OUTPUT); //トリガーピンをOUTPUTにする
  pinMode(echoPin, INPUT); //エコーピンをINPUTにする

  Serial.begin(9600);
}


void loop(){
  for (int i=0; i <= 210; i = i+30){ //書くX座標を変えていくfor文
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.034 / 2; //距離を計算する
    M5.Lcd.setCursor(0, i);//カーソルを移動
    M5.Lcd.print(distance);//この2行で、M5stackGrayに
    M5.Lcd.print("cm");//距離データを表示して、改行(printlnのlnのところで)
    Serial.print(distance);//この2行で、シリアルモニタに
    Serial.println("cm");//距離データを表示して、改行(printlnのlnのところで)  
    delay(1000);  //1秒間隔
  }
  M5.Lcd.fillRect(100,0,100,240,BLACK);//2行目を黒四角で埋めて、データリセット

  for (int i=0; i <= 210; i = i+30){ 
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
 
    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.034 / 2; //距離を計算する
    M5.Lcd.setCursor(100, i);//カーソルを移動
    M5.Lcd.print(distance);//この2行で、M5stackGrayに
    M5.Lcd.print("cm");//距離データを表示して、改行(printlnのlnのところ)
    Serial.print(distance);//この2行で、シリアルモニタに
    Serial.println("cm");//距離データを表示して、改行(printlnのlnのところ)  
    delay(1000);  //1秒間隔
  }

  M5.Lcd.fillRect(200,0,100,240,BLACK);//3行目を黒四角で埋めて、データリセット

  for (int i=0; i <= 210; i = i+30){ 
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
 
    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.034 / 2; //距離を計算する
    M5.Lcd.setCursor(200, i);//カーソルを移動
    M5.Lcd.print(distance);//この2行で、M5stackGrayに
    M5.Lcd.print("cm");//距離データを表示して、改行(printlnのlnのところ)
    Serial.print(distance);//この2行で、シリアルモニタに
    Serial.println("cm");//距離データを表示して、改行(printlnのlnのところ)  
    delay(1000);  
  }

  M5.Lcd.fillRect(0,0,100,240,BLACK);//1行目を黒四角で埋めて、データリセット

}



こうすると、以下のようになります。
・シリアルモニタ表示

・1列目を消して、1列目に新たなデータを表示 }
・2列目を消して、2列目に新たなデータを表示 }繰り返し
・3列目を消して、3列目に新たなデータを表示 }

ポイントは、指定した間隔のデータを消す作業です。この作業は、先ほどのM5.Lcd.fillScreen(BLACK)と違って、M5.Lcd.fillRect(0,0,100,240,BLACK)を使います。長方形を描くツールで、書式は、M5.Lcd.fillRect(始点X,始点Y,終点X,終点Y,色)です。これを使って、指定した間隔を黒く塗りつぶして、データを消しています。また、データを書くカーソル移動のためのM5.Lcd.setCursorや、塗りつぶしの黒長方形を描くM5.Lcd.fillRectの値は、変わってきている。

こんな感じ(データを入れる行がリセットされて、新しいデータが入ってくる)
img_20200224_141630.469.jpg

img_20200224_141640.064.jpg

img_20200224_141624.160.jpg

この繰り返し

いい感じーーー・・・

ですが

さらに思ったことはありませんか?「データ量は問わないけど、スクロール化したい」と。
先ほどのプログラムでは、書き加えるだけで、スクロールしません。なので、スクロール化してみました。そのプログラムがこちら


#include <M5Stack.h>
#include <Arduino.h>

#define echoPin 5 //エコーピンを5番ピンに指定
#define trigPin 2 //トリガーピンを2番ピンに指定

  long duration; //往復時間を測る変数
  int distance; //計算結果(距離)を入れる変数
  int deta[8];//スクロールのデータが入る配列(9つデータが入る)
  int detaX;//配列番号用変数
  
void setup(){

  Serial.begin(115200);

  M5.begin();
  delay(500);
  M5.Lcd.setTextFont(4);//テキストサイズを4にする
  M5.Lcd.setCursor(0, 0);//カーソルを指定
 
  pinMode(trigPin, OUTPUT); //トリガーピンをOUTPUTにする
  pinMode(echoPin, INPUT); //エコーピンをINPUTにする

  Serial.begin(9600); 
}


void loop(){
  deta[1] = 0;//1番の配列(1番古い値)を削除
  deta[1] = deta[2];//}
  deta[2] = deta[3];//}
  deta[3] = deta[4];//}
  deta[4] = deta[5];//}配列を移動(古いほうへ)
  deta[5] = deta[6];//}
  deta[6] = deta[7];//}
  deta[7] = deta[8];//}

    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
   
    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.034 / 2; //距離を計算する
    
    deta[8] = distance;//1番新しい配列に今の値を入れる(1番後ろに)
    Serial.println(distance);//この2行で、シリアルモニタに
    Serial.println("cm");//距離データを表示して、改行(printlnのlnのところで)  

    
  detaX = 1; //データ番号変数を1に
  for (int i=0; i <= 210; i = i+30){//データを書く位置の指定用for文
    M5.Lcd.setCursor(0, i);//カーソルを書く位置へ
    M5.Lcd.print(deta[detaX]);//この2行で、M5stackGrayに
    M5.Lcd.print("cm");//距離データ配列の1つを表示して、改行(printlnのlnのところで)
    detaX = detaX + 1;//データ番号変数を増やす
  }//この繰り返しで、配列を表示する

 delay(1000); //1秒間隔
 M5.Lcd.fillScreen(BLACK);//スクリーンを黒にして、文字の重なりを防ぐ
}


こうすると、以下のようになります。
・シリアルモニタ表示
・スクロール化して、データ表示


ポイントは、スクロールの仕組みです。1列に8つデータが入るので、配列を使って以下のようにしています。
・配列の1番目(古いデータ)を削除する(0にする)       }
・後ろの配列を上に上げる                 }
 (1番目を2番目の値に。2番目を3番目の値に…)       }
・8番目(一番最後)の配列にリアルタイムデータを入れる。   }繰り返し
・データを表示(古い ~  新しい     ) }
       (1   ~   8   配列番号) }

この繰り返しです。このプログラムが一番見やすいと思います。(結果的に)

そして、1つ、このプログラムには、勘違いしそうな注意点があります。
はじめのほうの配列定義で、int deta[8]と書いてあります。これだと配列には9個、LCDには8個のデータが入ることになり、1つ配列が多くなります。そのわけは、配列の1番目は、0番目ということになり、わけがわからなくなるので、0番目は無視して、1番目から使うことで、プログラムをわかりやすくしています。勘違いがないように

88㎝がいっぱい
img_20200223_184547.557.jpg

新しいデータ12㎝が入ってきたら(下)古いデータ(上)は上にスクロールされた
img_20200223_184552.721.jpg

3.終わりに

今回は、3つの方法で、HC-SR04からの距離データをM5stackGrayに表示しました。是非やってみてください。

注意
このブログにはかき切れていないわならないところがたくさんあると思います。質問は、コメントでお願いします。また、その質問は、追記で答えさせていただきます。(自主追記あります。)めんどくさいかもしれませんが、お願いします。(ほんとにごめんなさい)

その他の改良・説明


nice!(0)  コメント(0) 
電子工作・プログラミング(Arduino系) ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。