Arduino で測定したデータを Matplotlib でリアルタイムプロット

Arduino から送信されたデータを Matplotlib でリアルタイムプロットしてみたのでメモ。

Arduino 側の準備

簡単な例として Aruduino には以下のように書き込み、アナログ端子(A0)に入力される電圧値を送信させるようにします。 時間計測は Arduino 側でやった方が精度が高いので、Mstimer2 で指定間隔で割り込みを発生させています。

#include <MsTimer2.h>
unsigned long time;
unsigned int val0;

void ad(){
  interrupts();
  if ( Serial.available() > 0 ) {
    time = micros();
    val0 = analogRead(0);
    Serial.print(time);
    Serial.print(" ");
    Serial.print(val0);
    Serial.print("\n");
    Serial.read();
  }   
}

void setup() {
  Serial.begin(9600);
  MsTimer2::set(100, ad);
  MsTimer2::start();
}

void loop() {
  //
}

Matplotlib でリアルタイムプロット

以下のプログラムで一応は時間に対する電圧値をリアルタイムにプロットできました。

import serial
import numpy as np
from matplotlib import pyplot as plt

ser = serial.Serial()
ser.baudrate = 9600
ser.port = "/dev/ttyACM0"
ser.open()

t = np.zeros(100)
y = np.zeros(100)

plt.ion()
plt.figure()
li, = plt.plot(t, y)
plt.ylim(0, 5)
plt.xlabel("time[s]")
plt.ylabel("Voltage[V]")

ser.write("*".encode())
data = ser.readline().strip().rsplit()
tInt = float(data[0])

while True:
    try:
        ser.write("*".encode())
        data = ser.readline().strip().rsplit()
        # 配列をキューと見たてて要素を追加・削除
        t = np.append(t, (float(data[0])-tInt)/10**6)
        t = np.delete(t, 0)
        y = np.append(y, float(data[1])*5/1023)
        y = np.delete(y, 0)

        li.set_xdata(t)
        li.set_ydata(y)           
        plt.xlim(min(t), max(t))
        plt.draw()

    except KeyboardInterrupt:
        ser.close()
        break

プログラムを実行し電圧値を変化させた様子は以下のようになります。

15070301.gif

コメント

Comments powered by Disqus
書籍更新情報
2017-02-18
Pythonによる科学技術計算 基礎編
1.4版への更新が可能になりました。
サポートページはこちら
電子書籍