この記事では、Arduinoと超音波距離センサの観測データをラズベリーパイ3(Raspberry Pi3)で表示する方法をソースコード付きで解説します。
距離データの表示(超音波距離センサ)
前回記事「【Arduino】超音波距離センサ(HC-SR04)の使い方」では、Arduinoと超音波距離センサ(HC-SR04)で対象物までの距離を観測しました。
今回はそれを応用して、観測データをシリアル通信でPCに転送し、ラズベリーパイ3(Raspberry Pi3+Python)で表示してみました。
※ラズベリーパイ3でなくWindowsパソコンで表示したバージョンは下記事で解説しています。
【Python/Arduino】超音波距離センサの観測結果・S/N比をパソコンで表示
【Python/Arduino】超音波距離センサの観測結果・S/N比をパソコンで表示
事前準備(ラズベリーパイ3)
ラズベリーパイ3で始めてシリアル通信する際は、以下の操作①②を行う必要があります。
①【ラズベリーパイ3】シリアル通信を有効化する方法
②【ラズベリーパイ3】dmesgコマンドでArduinoのUSBシリアルポートを確認
回路構成
配線図
赤: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)
距離[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] --------------------------------
コメント