この記事では、Arduinoマイコンと加速度センサで計測した傾斜角度をリアルタイムグラフ表示する方法をソースコード付きで解説します。
傾斜角度をリアルタイムグラフ表示
ArduinoとKXM52-1050(3軸加速度センサ)を用いて各軸の値を測定しました。
そして計測したデータをシリアル通信でPCに送り、Pythonでグラフ化させました。
回路構成(配線図)
Arduinoと電子部品の構成・配線は下記の通りです。
【電子部品】
・Arduino UNO (1個)
・KXM52-1050(3軸加速度センサ)
・ジャンパワイヤー(数本)
処理手順
実装したプログラムの処理手順は下記の通りです。
【Arduino側】
①シリアルポートを9600 bps[ビット/秒]で初期化する
②加速度センサの各軸からデータ取得する
③読み取ったデータを-1から1までの範囲にスケーリングする
④各値を-1から1までの範囲に制限する
⑤逆サインの値を計算し、単位を[rad]を[deg]に変換する
⑥計算したX軸とY軸の傾斜角をシリアル通信でPCに送信する
⑦2~6の処理を繰り返す
【Python側】
①Arduinoが接続されているコムポート(筆者の環境はCOM7)を指定して開く
②画面サイズを設定する
③Pygameを初期化する
④画面を作成する
⑤タイトルバーの文字列をセットする
⑥表示する文字のtype,サイズを決める
⑦画面のクリア(真っ黒に塗りつぶす)
⑧シリアルポートからデータ(傾斜角度)を行終端まで読み込む
⑨読み込んだデータ(傾斜角度)の行終端コードを削除する
⑩X軸とY軸の傾斜角度を画面の指定した位置に表示する
⑪画面を更新して、変更を反映する
⑫配列に左詰めで傾斜角度を挿入する
⑬Y軸のデータ(傾斜角度)を更新する
⑭リアルタイムグラフを表示する
⑮温度計測の画面にある終了ボタンが押されるまで7~14を繰り返す
ソースコード
サンプルプログラムのソースコードです。
Arduino側
void setup(){ // シリアルポートを9600 bps[ビット/秒]で初期化 Serial.begin(9600) ; } float mapFloat(float x, float iMin, float iMax, float oMin, float oMax) { return (x - iMin) * (oMax - oMin) / (iMax - iMin) + oMin; } void loop(){ int i ; long x , y , z ; // 加速度センサの各軸からデータ取得 x = analogRead(0); y = analogRead(1); z = analogRead(2); // 読み取ったデータを-1から1までの範囲にスケーリング float xSinTheta = mapFloat(x, 340, 777, -1, 1); float ySinTheta = mapFloat(y, 306, 716, -1, 1); // 各値を-1から1までの範囲に制限 xSinTheta = constrain(xSinTheta,-1,1); ySinTheta = constrain(ySinTheta,-1,1); // 逆サインの値[rad]を[deg]に変換 int xdeg = float(asin(xSinTheta) * 180 / PI ); int ydeg = float(asin(ySinTheta) * 180 / PI ); // 計算した傾斜角をシリアルモニターに表示 Serial.println(String(xdeg) + "," + String(ydeg)); delay(500) ; }
パソコン側(Python)
# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt import pygame from pygame.locals import * import serial import sys def main(): ser = serial.Serial("COM7") # COMポート(Arduino接続) xdegs = [0]*100 # 温度格納 ydegs = [0]*100 # 温度格納 t = np.arange(0,100,1) plt.ion() # Pygameの設定 pygame.init() # 初期化 screen = pygame.display.set_mode((200, 200)) # 画面作成(100×100) pygame.display.set_caption("傾斜角度") # タイトルバー font = pygame.font.Font(None, 30) # 文字の設定 while True: data = ser.readline().rstrip() # \nまで読み込む(\nは削除) (xdeg, ydeg) = data.split(",") # 角度データのリスト更新 xdegs.pop(99) xdegs.insert(0,float(xdeg)) ydegs.pop(99) ydegs.insert(0,float(ydeg)) # グラフ表示設定 line, = plt.plot(t, xdegs, 'r-',label="X-axis[deg]") # Y軸更新 line, = plt.plot(t, ydegs, 'b-',label="Y-axis[deg]") # Y軸更新 line.set_ydata(xdegs) line.set_ydata(ydegs) plt.title("Real-time inclination angle") plt.xlabel("Time [s]") plt.ylabel("Inclination angle [deg]") plt.legend();plt.grid() plt.xlim([1,100]); plt.ylim([-90,90]) plt.draw(); plt.clf() # Pygameの処理 screen.fill((0,0,0)) # 画面のクリア text = font.render("(X, Y) = ("+xdeg+", "+ydeg+")", False, (255,255,255)) screen.blit(text, (10, 10)) # レンダ,表示位置 pygame.display.flip() # 画面を更新して、変更を反映 # Pygameのイベント処理 for event in pygame.event.get(): # 終了ボタンが押されたら終了処理 if event.type == QUIT: pygame.quit() ser.close() plt.close() sys.exit() if __name__ == '__main__': main()
※上記のプログラムを動作させるのはライブラリ「Matplotlib」「NumPy」「Pygame」が必要です。
実行結果
サンプルプログラムの実行結果は下記の通りです。
【関連記事】
・Arduino入門 基本的な使い方
・Python入門 基本文法
・Pygameのインストール方法
・Matplotlibのインストール方法
・NumPyのインストール方法
コメント
パソコン側のpythonのコメントが加速度センサーなのに温度になっていますよ。
※イントロン様
コメントありがとうございます。
該当箇所を修正しました。