超音波距離センサ HC-SR04 を使ってみる
このモジュールには超音波の送信器と受信器が載っています。
センシングの原理は簡単で、送信した信号が反射して戻ってくるまでの時間を測定します。
その時間と音速から、障害物が何cm先にあるのかを計算して求めることができます。
ハードウェアの接続
Seeeduino XIAOを使っていますが、他のマイコンでもOKです。

HC-SR04の駆動電圧は5Vに対してSeeediuino XIAOのIOは3.3Vなので
信号線の接続にはレベル変換モジュールを挟んでおきます。
HC-SR04の配線は5V, GND, TRIG, ECHOのみです。
写真はLCDも接続しているのでちょっと煩雑に見えます。
LCDはなくても大丈夫ですが、接続する場合は以下の記事を参考にしてみてください。
ソフトウェアをつくる
#define TRIG_PIN 0
#define ECHO_PIN 1
int pulseInTime = 0;
double distance = 0;
double calValue = 1;
void setup()
{
Serial.begin(9600);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
void loop()
{
digitalWrite(TRIG_PIN, HIGH);
delay(1);
digitalWrite(TRIG_PIN, LOW);
pulseInTime = pulseIn(ECHO_PIN, HIGH);
distance = 0.017*pulseInTime*calValue;
Serial.println(distance);
delay(1000);
}
大体1秒おきに距離を測定するプログラムです。
センサーのTRIG, ECHOに使うGPIOの番号は #define で指定しておきます。
pulseIn() の関数はマイクロ秒の単位で結果が出てきます。
このコードでは距離がセンチメートルの単位で得られるようにしています。
音速は340m/秒で計算していますが温度等によって変わってくるので
calValue という係数を用意しておいて調節できるようにしておきました。
※ calValue を0.99とか1.01とかにして調整するイメージ
まずはシリアル通信で結果が見れるように Serial.println() を使います。
実行してみる

センサーとダンボーの距離を測ってみることにします。
実行すると、シリアルモニタからこういう感じで見えます。

このとき、センサーとダンボーの距離は6cmくらいみたいです。
ダンボーの位置を変えて試してみたところまあまあ正確そうなので
調整用に用意した calValue はとりあえず使っていません。
おまけ:キャラクタLCDに結果を表示する
コード全文は以下です。
#include <Wire.h>
#define TRIG_PIN 0
#define ECHO_PIN 1
int pulseInTime = 0;
double distance = 0;
double calValue = 1;
void lcd_init();
void lcd_send_command(byte command_data);
void lcd_send_char(byte char_data);
void setup()
{
Wire.begin();
// Serial.begin(9600);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
delay(100);
lcd_init();
lcd_send_command(B10000000); //set DDRAM address
lcd_send_char(B01111000); // x
lcd_send_char(B01111000); // x
lcd_send_char(B01100011); // c
lcd_send_char(B01101101); // m
lcd_send_command(B00001100); //Display on
}
void loop()
{
digitalWrite(TRIG_PIN, HIGH);
delay(1);
digitalWrite(TRIG_PIN, LOW);
pulseInTime = pulseIn(ECHO_PIN, HIGH);
distance = 0.017*pulseInTime*calValue;
// Serial.println(distance);
lcd_send_command(B10000000); //set DDRAM address
lcd_send_char(int(distance)/10 + 0x30);
lcd_send_char(int(distance)%10 + 0x30);
delay(1000);
}
void lcd_init()
{
lcd_send_command(B00111100); //Function set
delay(100);
lcd_send_command(B00111100); //Function set
delay(100);
lcd_send_command(B00111100); //Function set
delay(100);
lcd_send_command(B00111100); //Function set
lcd_send_command(B00001000); //Display off
lcd_send_command(B00000001); //Display clear
lcd_send_command(B00000111); //Entry mode set
lcd_send_command(B00001100); //Display on
delay(100);
}
void lcd_send_command(byte command_data)
{
Wire.beginTransmission(0x3F); //I2C Address
Wire.write(B00000000); //controll byte
Wire.write(command_data); //data byte
Wire.endTransmission();
}
void lcd_send_char(byte char_data)
{
Wire.beginTransmission(0x3F); //I2C Address
Wire.write(B01000000); //control byte
Wire.write(char_data); //data byte
Wire.endTransmission();
}
このコードは 1cm ~ 99cm の表示にしか対応していません。
小数点まで表示したり3桁表示にする場合はちょっとアレンジが必要です。
コメント