2015年9月14日月曜日

超音波センサー2個同時 サンプルスケッチ



//********************************************************************
//超音波センサを2個同時に使って距離をserialとLCD表示するプログラム
//計算を早くするため、cm以下の精度は出さないとした。
//音波が戻ってこない場合、0cm と出力する。LCD表示は「---」。
//Trigerパルスを2個同時に出す方式。ハードは2つのTrigerを接続すること
//計測のタイムアウトは40ms。タイマー割り込みで測定している。
//********************************************************************
#include <LiquidCrystal.h>
#include <MsTimer2.h>  // Timer interrupt

LiquidCrystal lcd(8,9,4,5,6,7); //lcdタイプの変数を定義
const long serialBps = 115200; //シリアル通信レート
//超音波センサー
const int sensor = 2; //センサーの数
const int pinTrig = 2; //トリガーパルス出力用ピン番号 
const int pinEcho[sensor] = {3,12}; //エコーパルス入力用ピン番号 [x]要素番号がセンサー番号
long Duration[sensor] ; //測定したエコーパルス幅 usec [x]要素番号がセンサー番号
long Distance[sensor] ; //測定した距離 mm [x]要素番号がセンサー番号
unsigned long StartTime; //パルス長を測り始める時間
int EchoState[sensor] ; //Echoポートの状態 0:LOW 初期状態 1:HIGH 2:LOW
volatile int CountDownTimer =0;  //1msのタイマー割り込みでカウントダウンされ、ゼロで止まるタイマー


//SETUP*****************************
void setup() {

  // LCDの行と列を設定
  lcd.begin(16, 2);

  //シリアルポート使用開始
  Serial.begin(serialBps);
  
  //pin modeの設定
  pinMode( pinTrig, OUTPUT);
  pinMode( pinEcho[0], INPUT);
  pinMode( pinEcho[1], INPUT);

  //タイマー割り込みの設定
  MsTimer2::set(1,count);    // 1ms period
  MsTimer2::start();            //タイマースタート

  //LCDへタイトルを表示
  lcd.home();               // カーソル位置を1行目に設定
  lcd.print("Ultrasonic X2-2");  
  
}

//MAIN LOOP*************************
void loop() {

  //=================================
  //超音波センサー output = Distance[i]
  //=================================

  //超音波を出力(トリガーパルスの出力)
  digitalWrite( pinTrig, HIGH );     //HIGHを出す
  delayMicroseconds( 10 );           //10usec
  digitalWrite( pinTrig, LOW );      //LOWに戻す
  
  //Echoパルス幅を測る準備  
  for (int i=0; i<sensor; i++){
    EchoState[i]= 0;     //ポートのステータスを初期化
  }
  CountDownTimer = 40;   //40msのカウントダウンタイマーをセット(タイムアウト用)

    
  //Echoパルス幅の時間を測定 usec単位
  while(true) {
      
       //各センサーのEchoの値(HIGH/LOW)をチェックし,状態を記憶する
       //HIGH-->LOWとなったら、パルス幅時間を求める
       for (int i=0; i<sensor; i++){
         int dR =digitalRead(pinEcho[i]);
         
         //HIGH?
         if (( dR == HIGH) && (EchoState[i] == 0)) {     // HIGH=1 , LOW=0
           EchoState[i] = 1;             //Echoポートの状態:0-->1に変更
           StartTime = micros();         //時間測定開始時間を記録
         }
         
         //LOW? HIGH-->LOW?
         if ((dR == LOW ) && (EchoState[i] == 1)) {
           EchoState[i] = 2;             //Echoポートの状態:1-->2に変更
       
           //パルス幅の時間を開始時間と現在時間から求める
           unsigned long ms =micros();
           if (ms > StartTime) {
             Duration[i]= ms-StartTime;
           }
           else {
             Duration[i] = 4294967295-StartTime+ms;
           }
         }
       }
       
       //全てのセンサーの計測が終了したら、whileループを抜ける。      
       int EchoStateSum = 0;
       for (int i=0; i<sensor; i++){
         EchoStateSum += EchoState[i];
       }
       if (EchoStateSum == 2*sensor) {   //全てのセンサーの計測が終了していたら、echoStateSumの値は2×センサー数となる。
        break;
       }

       //タイムアウトになったら、whileループを抜ける。
       //タイムアウトになったら、計測が終わっていないセンサーの計測値は全てzeroを入れる。
       if ( CountDownTimer == 0){
        for (int i=0; i<sensor; i++){
         if (EchoState[i] < 2){
          Duration[i] = 0;
         }
        }
        break;
       }
  }


  //距離(単位mm)を計算。
  for (int i=0; i<sensor; i++){ 
    Distance[i] = Duration[i]*340/2/10000;  // 音速を340m/sとする.往復距離を半分にする
  }
  

  //=================================
  //Serial 通信
  //=================================
  
   //シリアルに距離を出力 
  Serial.print("Distance:");
  Serial.print(Distance[0]);
  Serial.print("cm  ");
  Serial.print(Distance[1]); 
  Serial.println("cm");

  
  //LCDへ距離を出力     
  lcd.setCursor(0,1);          // カーソル位置を2行目に設定 
  lcd.print("              cm");
  
  if (Distance[0] == 0){ 
    lcd.setCursor(2,1);
    lcd.print("---");
    }
  else if (Distance[0]< 10) { 
    lcd.setCursor(4,1);
    lcd.print(Distance[0]);}
  else if(Distance[0] < 100) {
    lcd.setCursor(3,1);
    lcd.print(Distance[0]);}
  else {
    lcd.setCursor(2,1);
    lcd.print(Distance[0]);}

  if (Distance[1] == 0){
    lcd.setCursor(7,1);
    lcd.print("---");
  }
  else if (Distance[1]< 10) { 
    lcd.setCursor(9,1);
    lcd.print(Distance[1]);}
  else if(Distance[1] < 100) {
    lcd.setCursor(8,1);
    lcd.print(Distance[1]);}
  else {
    lcd.setCursor(7,1);
    lcd.print(Distance[1]);}
  
  //0.1秒毎に計測
  delay(100);    
}

//TIMER INTERRUPT**************************
void count() {
  //タイマーをカウントダウンする。ゼロで止める。
  if ( CountDownTimer != 0){
    CountDownTimer--;
  }
}


  

0 件のコメント:

コメントを投稿