目次
前
次
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 );
}
目次
前
次