【ラズベリーパイ3/Arduino】超音波距離センサの観測結果・S/N比を表示

この記事では、Arduinoと超音波距離センサの観測データをラズベリーパイ3(Raspberry Pi3)で表示する方法をソースコード付きで解説します。

距離データの表示(超音波距離センサ)

前回記事「【Arduino】超音波距離センサ(HC-SR04)の使い方」では、Arduinoと超音波距離センサ(HC-SR04)で対象物までの距離を観測しました。
今回はそれを応用して、観測データをシリアル通信でPCに転送し、ラズベリーパイ3(Raspberry Pi3+Python)で表示してみました。

※ラズベリーパイ3でなくWindowsパソコンで表示したバージョンは下記事で解説しています。
【Python/Arduino】超音波距離センサの観測結果・S/N比をパソコンで表示

事前準備(ラズベリーパイ3)

ラズベリーパイ3で始めてシリアル通信する際は、以下の操作①②を行う必要があります。
【ラズベリーパイ3】シリアル通信を有効化する方法
【ラズベリーパイ3】dmesgコマンドでArduinoのUSBシリアルポートを確認

回路構成

配線図

回路構成(左)と超音波距離センサHC-SR04(右)

赤:5V、黒:GND、黄:8番ピン、緑:9番ピン

部品リスト

部品名 個数
Arduino UNO 1個
超音波距離センサ(HC-SR04) 1個
ブレッドボード 1個
ジャンパーワイヤ 数本

接続構成

Arduinoと超音波センサ(HC-SR04)の接続は以下の通りです。

HC-SR04 Arduino
Vcc(電源入力 5V) 5Vピン
Trig(超音波信号を送信) 8番ピン
Echo(超音波信号を受信) 9番ピン
GND(グランド) GNDピン

HC-SR04の仕様

パラメータ 内容
電源電圧 5V
待機電流 2mA未満
信号出力 0-5V
センサ角度 15度以下
測定可能距離 2cm-450cm
分解能 0.3cm

プログラムの処理内容

Arduino側

Arduino側の処理内容は以下の通りです。

説明
出力ピン(8)で超音波を出力します。(トリガ端子を10μs以上Highにすると40kHzのパルスを8回送信)
入力ピン(9)で超音波を受信します。(エコー端子がHIGHになってからLOWに変化するまでの時間=超音波が送信されてから受信するまでの時間[μs]を計測)
以下の式で時間から距離を求めます。
【計算式】
距離[cm] = (0.034) × (②で求めた時間[μs]÷2)

※音速=340[m/s] = 34000[cm/s] = 0.034[cm/μs]

Python側

Python側の処理内容は以下の通りで

説明
Arduinoから送られてきた距離データをシリアルポートで受信します。
観測データをNumPyの配列に格納します。
配列の平均値・標準偏差を求め、S/N比を計算します。
時刻、最新の距離データ、S/N比をコンソールに表示します。

■参考
S/N比の概要・計算式については下記事で解説しています。
S/N比の計算式・センサーの品質評価

ソースコード

サンプルプログラムのソースコードです。

int trig = 8; // 出力ピン
int echo = 9; // 入力ピン

void setup() {
  Serial.begin(9600);
  pinMode(trig,OUTPUT);
  pinMode(echo,INPUT);
  }

void loop() {
  // 超音波の出力終了
  digitalWrite(trig,LOW);
  delayMicroseconds(1);

  // 超音波を出力
  digitalWrite(trig,HIGH);
  delayMicroseconds(11);

  // 超音波を出力終了
  digitalWrite(trig,LOW);

  // 出力した超音波が返って来る時間を計測
  int t = pulseIn(echo,HIGH);

  // 計測した時間と音速から反射物までの距離を計算
  float distance = t*0.017;

  // 計算結果をシリアル通信で出力
  Serial.println(distance);
  delay(1000);
}

Python(パソコン側)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import serial
import datetime


def queue(src, a):
    dst = np.roll(src, -1)
    dst[-1] = a
    return dst


def console_print(data):
    ave = np.average(data) # 平均の計算
    sigma = np.std(data)   # 標準偏差の計算
    sn = 20 * np.log10(ave/sigma) # SN比の計算

    # 時刻・距離・S/N比の表示
    print('--------------------------------')
    print("時刻:", datetime.datetime.today())
    print("距離:" + str(data[-1]) + "[cm]")
    print("S/N比:" + str(sn) + "[dB]")


def main():
    # カウント用変数
    i = 0

    # 1次元配列の生成(距離データ格納用)
    data = np.zeros(10)

    # シリアル接続するポート
    ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)

    while(i != 100):
        # シリアルデータを受信して距離データを取得
        line = ser.readline()    # 行終端まで読み込む
        line = line.decode()     # byteからstringに変換
        distance = line.rstrip() # 行終端コード削除

        # キュー操作
        data = queue(data, float(distance))

        # コンソールに結果表示
        console_print(data)
        i+=1

    ser.close()
    print("End")


if __name__ == '__main__':
    main()

実行結果

サンプルプログラムの実行結果です。

--------------------------------
時刻: 2017-10-07 15:13:09.490930
距離:15.01[cm]
S/N比:33.0041723478[dB]
--------------------------------
時刻: 2017-10-07 15:13:10.494628
距離:15.01[cm]
S/N比:35.3780434605[dB]
--------------------------------
時刻: 2017-10-07 15:13:12.502177
距離:15.01[cm]
S/N比:35.3046402065[dB]
--------------------------------

おすすめ記事

Arduino入門 サンプル集
Python入門 サンプル集

コメント