SSブログ

Arduinoで距離を測る(1)【超音波測距センサ with XBee(動作確認)】 [Arduino]

前回で2byteのシリアル通信ができたので、本番です。

測定した距離をバイナリデータとしてXBee間でシリアル通信して、PCのシリアルモニタに表示をさせます。
一度実測した値をもとに、誤差を修正するための補正値を組み入れました。
補正値を入れる前後の実績値を示します。
SEN136B5B実測データ.jpg
超音波測距センサの「SEN136B5B」の測定レンジは3cm~4m(400cm)ですので、測定レンジを外れたら"Out of Range"と表示します。

【スケッチ】
<送信側>
/*******************************************************************************
超音波測距センサ(SEN136B5B)用XBeeトランスミッタ

++++++ note ++++++
超音波測距センサ(SEN136B5B)用にArduinoUNO-XBee送信機

*******************************************************************************/
// this constant won't change. It's the pin number of the sensor's output:
const int pingPin = 7;

// 初期化(電源投入/リセット時1回のみ実行):
void setup() {
  Serial.begin(9600);                       //9600bpsでシリアルポートを開く
}

// main loop:
void loop() {
  long duration;                            //変数を定義
  int cm;                                   //変数を定義
  
  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // モジュールに超音波発信のためのトリガーを与える
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);                 //pingPinを出力ピンに定義
  digitalWrite(pingPin, LOW);               //LOW出力
  delayMicroseconds(2);                     //2us停止
  digitalWrite(pingPin, HIGH);              //HIGH出力
  delayMicroseconds(5);                     //5us停止
  digitalWrite(pingPin, LOW);               //LOW出力
/*
 ①トリガー信号により40kHzの超音波パルスをモジュールは発信する。
 ②超音波パルス発信中に、pingPinを出力→入力ピンに変更する。
 ②超音波パルスを発信し終えたら、pinPinはHIGHに遷移する(超音波パルスをモジュールが受信する
  間HIGHを継続(受信したらLOWに遷移))。
 ④pinPinのHIGH継続時間を測定することで、距離に変換することができる。
 */

  // The same pin is used to read the signal from the PING))): a HIGH pulse
  // whose duration is the time (in microseconds) from the sending of the ping
  // to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);                  //pingPinを入力ピンに定義
  duration = pulseIn(pingPin, HIGH);        //pingPinがHIGHになっている時間(パルスの長さ)を計測する

  // convert the time into a distance
  cm = microsecondsToCentimeters(duration); //パルスの長さ(時間)を距離(センチ)に変換

  sendIntData(cm);
  delay(100);                               //シリアルポートを溢れさせないように ※delay():単位ms
}

 //パルスの長さ(時間)を距離(センチ)に変換する関数
long microsecondsToCentimeters(long microseconds) {
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the object we
  // take half of the distance travelled.
  return microseconds / 29 / 2;
}

 // int型のデータを送信する関数
void sendIntData(int value) {
  Serial.write('H'); // ヘッダの送信
  Serial.write(lowByte(value)); // 下位バイトの送信
  Serial.write(highByte(value)); // 上位バイトの送信
}


<受信側>
/*******************************************************************************
超音波測距センサ(SEN136B5B)用XBeeレシーバ

++++++ note ++++++
超音波測距センサ(SEN136B5B)用にArduinoUNO-XBee受信機
・実測データより受信データが195以上(約2m)には+5cmの補正を加える
・距離データが3(約3cm)未満又は400(約4m)を超えたら、Out of Rangeと表示する

*******************************************************************************/
#define VERSION "1.00a0"
#define hosei 5;                                      //補正値(実測データより求めた)

int recv_data;                                        //受信データ
int range_data;                                       //距離データ

// 初期化(電源投入/リセット時1回のみ実行):
void setup() {
  Serial.begin(9600);                                 //9600bpsでシリアルポートを開く
}
// main loop:
void loop(){
  // 受信バッファに3バイト(ヘッダ+int)以上のデータが着ているか確認
  if ( Serial.available() >= sizeof('H') + sizeof(int) ) {
    // ヘッダの確認
    if ( Serial.read() == 'H' ){
      int low = Serial.read();                        //下位バイトの読み取り
      int high = Serial.read();                       //上位バイトの読み取り
      recv_data = makeWord(high,low);                 //上位バイトと下位バイトを合体させてint型データを復元

  // 受信データから表示させる距離データを作成      
      if(recv_data >= 195){                           //195以上ならば補正値を加算する
        range_data = recv_data + hosei;
      }
      else{
          range_data = recv_data;
      }

  // 距離データの表示 range_dataの値をハード・シリアルへ出力する(Arduino→PCモニタ)
      if((range_data >= 3) && (range_data <= 400)){   //range_dataが3以上400以下ならば、距離を表示する
        Serial.print("Range= ");
        Serial.print(range_data);
        Serial.println("[cm]");
      }
      else{                                           //range_dataがそれ以外ならば、Out of Rangeと表示する
        Serial.println("Out of Range");
      }
    }
  }
}

これで遠隔から距離データを取得することができました。
同じプログラムを使い回せば、他にも温度センサからのデータだったりとか、いろいろと応用できそうです。



profile_picture_40×40.JPG
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

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