Seeeduino XIAO | 距離センサ HC-SR04 を使ってみる

スポンサーリンク

超音波距離センサ HC-SR04 を使ってみる

このモジュールには超音波の送信器と受信器が載っています。
センシングの原理は簡単で、送信した信号が反射して戻ってくるまでの時間を測定します。
その時間と音速から、障害物が何cm先にあるのかを計算して求めることができます。

ハードウェアの接続

Seeeduino XIAOを使っていますが、他のマイコンでもOKです。

HC-SR04とSeeeduino XIAOの接続

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桁表示にする場合はちょっとアレンジが必要です。

コメント

タイトルとURLをコピーしました