目次

ArduinoMega2560距離測定

 ArduinoMega2560を使い、超音波センサーによる
 距離の測定をやってみました。

 利用した超音波センサーは、以下。



 この超音波センサーは、電圧出力ではありません。

 トリガーを与えて、パルス幅により距離を
 出力するタイプのセンサー。

 音波は、温度により速度がかわるので
 温度をLM35DZで測定します。



 最近はLM60が主流ですが、手持ちがあったので
 これを使います。

 表示は、端末の他にLCDを活用。



 2行x8桁の小さなLCDを使います。

 全体の構成は、次のようにまとめました。



 情報を表示するLCD表示から記述していきます。

 ライブラリ指定

  ArduinoのAPIに、LCDを扱うライブラリがあるので
  それをインクルードして使います。

  #include <LiquidCrystal.h>

 温度表示

  温度は小数点を含まない、10進数2桁で
  表示するとして、関数を定義。

void showTmp(byte x)
{
  char msg[4] ;
  byte tmp ;
  /* copy */
  tmp = x ;
  /* convert */
  *(msg+3) = 0 ;
  *(msg+2) = 'C' ;
  *(msg+1) = getAsc( tmp % 10 ) ; tmp /= 10 ;
  *(msg+0) = getAsc( tmp % 10 ) ;
  /* clear */
  lcd.setCursor(0,0);lcd.print("        ");
  /* show */
  lcd.setCursor(0,0);lcd.print( msg );
}

  数値を数字に変換するため、別途定義する
  関数getAscを利用。
  LCD表示のために、配列を用意して、数字と
  単位を格納してから、表示します。

  2行のうちの上の行に、温度を表示。

  上の行の文字列を、一度消してから
  新しく温度と単位を書き込みます。

  数値を数字に変換する関数は、次のように定義。

char getAsc(byte x)
{
  char result ;
  /* default */
  result = '0' ;
  /* judge */
  if ( x < 10 ) { result = x + '0' ; }
  else          { result = x - 10 + 'A' ; }

  return result ;
}

  10進数だけでなく、16進数も扱えるように
  してあります。

 距離表示

  距離は、4000mmまでとして、次のように
  数値を与えると、LCDの下の行に表示する
  ように定義。

void showDistance(word x)
{
  char msg[7] ;
  word tmp ;
  /* copy */
  tmp = x ;
  /* convert */
  *(msg+6) = 0 ;
  *(msg+5) = 'm' ;
  *(msg+4) = 'm' ;
  *(msg+3) = getAsc( tmp % 10 ) ; tmp /= 10 ;
  *(msg+2) = getAsc( tmp % 10 ) ; tmp /= 10 ;
  *(msg+1) = getAsc( tmp % 10 ) ; tmp /= 10 ;
  *(msg+0) = getAsc( tmp % 10 ) ;
  /* zero surpress */
  if ( *(msg+0) == '0' ) {
    *(msg+0) = ' ' ;
    if ( *(msg+1) == '0' ) {
      *(msg+1) = ' ' ;
    }
  }
  /* clear */
  lcd.setCursor(0,1);lcd.print("        ");
  /* show */
  lcd.setCursor(2,1);lcd.print( msg );
}

  温度と距離では、表示開始位置を変えました。
  上下に分かれているとしても、異なる物理量と
  一目でわかる方がよいので。

 表示ができれば、計測をします。

 温度測定

  温度センサーは、アナログピンの0番に接続
  して、A/D値を入力。

#define THPIN 0

  adv = analogRead(THPIN);

  温度センサーLM35DZは、正の温度を10mV単位で
  求めますが、計算が面倒なので誤差を含めても
  よいと、次のように変換しました。

  temp = (byte)((adv / 1024.0) * 5000) ;

  計算が終わったなら、端末とLCDに表示する
  処理を連ねます。

  /* show thermometer to terminal */
  Serial.print("T=");
  Serial.print(temp);
  Serial.println('C');
  /* show thermometer to LCD */
  showTmp( temp );
  /* wait */
  delay( 1000 );

 距離測定

  超音波センサーは、トリガーを与えて音波を出力
  するので、トリガー出力専用の関数を用意。

void trgUSENSOR()
{
  digitalWrite(UTRG,HIGH);
  delayMicroseconds( 10 );
  digitalWrite(UTRG,LOW);
}

  超音波センサーが出力してくる、パス幅は
  ArduinoにAPIが用意されているので、それ
  を使います。

  duration = pulseIn(UECHO,HIGH);

  距離は、センサーと物体までの間隔の2倍に
  なっているので、半分にしてから音速を使い
  正確な距離に換算します。

    duration = duration / 2 ;
    distance = (word)(duration * (331.5 + 0.6 * temp) / 1000);

 loop()の中に、計測と表示を入れると、以下。

void loop()
{
  /* get thermometer */
  adv = analogRead(THPIN);
  /* convert */
  temp = (byte)((adv / 1024.0) * 5000) ;
  /* show thermometer to terminal */
  Serial.print("T=");
  Serial.print(temp);
  Serial.println('C');
  /* show thermometer to LCD */
  showTmp( temp );
  /* wait */
  delay( 1000 );
  /* send trigger */
  trgUSENSOR();
  /* get duration */
  duration = pulseIn(UECHO,HIGH);
  /* convert */
  if ( duration > 0 ) {
    duration = duration / 2 ;
    distance = (word)(duration * (331.5 + 0.6 * temp) / 1000);
    /* show distance to terminal */
    Serial.print("Distance ");
    Serial.print( distance );
    Serial.println(" mm");
    /* show distance to LCD */
    showDistance( distance );
  }
  /* wait */
  delay( 1000 );
}

 setupの中に、必要な初期化をいれて
 次のようにまとめられます。

#include <LiquidCrystal.h>

#define OFF 0
#define ON  OFF+1

/* ultra sonic sensor */
#define UTRG  2
#define UECHO 3

/* thermometer */
#define THPIN 0

/*                RS E  DB4 DB5 DB6 DB7 */
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

/* variables */
word  adv ;
byte  temp ;
float duration ;
word  distance ;

/* function prototypes */
char getAsc(byte x);
void showTmp(byte x);
void init_usensor();
void trgUSENSOR();
void showDistance(word x);

void setup()
{
  /* Serial port */
  Serial.begin(9600);
  Serial.println("Hello !");
  /* ultra sonic sensor */
  init_usensor();
  /* thermometer /
  pinMode(14,INPUT);
  /* LCD */
  lcd.begin(8,2);
  lcd.setCursor(0,0); lcd.print("Hello ! ");
  lcd.setCursor(0,1); lcd.print("JH8BWH  ");
}

void loop()
{
  /* get thermometer */
  adv = analogRead(THPIN);
  /* convert */
  temp = (byte)((adv / 1024.0) * 5000) ;
  /* show thermometer to terminal */
  Serial.print("T=");
  Serial.print(temp);
  Serial.println('C');
  /* show thermometer to LCD */
  showTmp( temp );
  /* wait */
  delay( 1000 );
  /* send trigger */
  trgUSENSOR();
  /* get duration */
  duration = pulseIn(UECHO,HIGH);
  /* convert */
  if ( duration > 0 ) {
    duration = duration / 2 ;
    distance = (word)(duration * (331.5 + 0.6 * temp) / 1000);
    /* show distance to terminal */
    Serial.print("Distance ");
    Serial.print( distance );
    Serial.println(" mm");
    /* show distance to LCD */
    showDistance( distance );
  }
  /* wait */
  delay( 1000 );
}

char getAsc(byte x)
{
  char result ;
  /* default */
  result = '0' ;
  /* judge */
  if ( x < 10 ) { result = x + '0' ; }
  else          { result = x - 10 + 'A' ; }

  return result ;
}

void showTmp(byte x)
{
  char msg[4] ;
  byte tmp ;
  /* copy */
  tmp = x ;
  /* convert */
  *(msg+3) = 0 ;
  *(msg+2) = 'C' ;
  *(msg+1) = getAsc( tmp % 10 ) ; tmp /= 10 ;
  *(msg+0) = getAsc( tmp % 10 ) ;
  /* clear */
  lcd.setCursor(0,0);lcd.print("        ");
  /* show */
  lcd.setCursor(0,0);lcd.print( msg );
}

/* initialize ultra sonic sensor */
void init_usensor()
{
  /* direction */
  pinMode(UTRG,OUTPUT);
  pinMode(UECHO,INPUT);
  /* not send pulse */
  digitalWrite(UTRG,LOW);
}

void trgUSENSOR()
{
  digitalWrite(UTRG,HIGH);
  delayMicroseconds( 10 );
  digitalWrite(UTRG,LOW);
}

void showDistance(word x)
{
  char msg[7] ;
  word tmp ;
  /* copy */
  tmp = x ;
  /* convert */
  *(msg+6) = 0 ;
  *(msg+5) = 'm' ;
  *(msg+4) = 'm' ;
  *(msg+3) = getAsc( tmp % 10 ) ; tmp /= 10 ;
  *(msg+2) = getAsc( tmp % 10 ) ; tmp /= 10 ;
  *(msg+1) = getAsc( tmp % 10 ) ; tmp /= 10 ;
  *(msg+0) = getAsc( tmp % 10 ) ;
  /* zero surpress */
  if ( *(msg+0) == '0' ) {
    *(msg+0) = ' ' ;
    if ( *(msg+1) == '0' ) {
      *(msg+1) = ' ' ;
    }
  }
  /* clear */
  lcd.setCursor(0,1);lcd.print("        ");
  /* show */
  lcd.setCursor(2,1);lcd.print( msg );
}


目次

inserted by FC2 system