본문 바로가기

Software/Python

파이썬(Python)에서 시리얼 통신으로 받은 데이터 실시간으로 그래프 그리기

저는 한 3년 전쯤에 Python에서 matplotlib에서 그래프에서 애니메이션 효과로 그래프를 그리는 이야기를 했습니다. 그리고, 마우스 대응등 인터략티브한 그래프 이야기를 추가로 했었네요. 그리고 아주 예전에 Python에서 시리얼 통신하는 법에 대한 이야기도 했었죠. 오늘은 시리얼 통신으로 연결된 데이터를 받아서 간편하게 실시간 그래프를 그리는 것에 대한 이야기를 하려고 합니다. 일단, 그 대상으로 아두이노 보드를 잡았습니다. 아두이노 보드는 그냥 PC와 연결만 시켜 두어서 사진으로 보여드리지는 않겠습니다.^^

void setup() {
  	// put your setup code here, to run once:
  	Serial.begin(115200);
}

void loop() {
  	// put your main code here, to run repeatedly:  	
	Serial.println(random(10,20));
	delay(500);
}

먼저 아두이노 프로그램에는 저렇게 그냥 10과 20사이의 랜덤값을 시리얼 통신으로 보내는 프로그램을 만들어 두었습니다. 그리고, 아두이노를 실행하면 뭐~ 끝나는거죠^^

import serial

arduino = serial.Serial('/dev/tty.usbmodem14401', 115200)
y = arduino.readline()

Python에서 시리얼 통신은 저 코드가 전부입니다.^^ 아.. /dev/tty어쩌고는 윈도우 유저는 COM1과 같이 연결된 시리얼 포트 번호를 넣어 두면 됩니다. 저는 맥이라서 저렇게 됩니다. 아무튼, 문제는 저 데이터를 받은 다음 코드 상으로는 y 값이 문제죠^^ 아두이노에서 println 명령으로 보냈기 때문에 줄바뀜 기호가 들어가 있습니다.

터미널에서 실행해서 결과를 보면, b어쩌고로 시작해서 \n으로 끝나네요... 바이트 단위로 들어왔기 때문입니다.

바이트로 들어온 데이터는 decode()를 이용하면 해결됩니다.

뒤의 두 문자(\r\n)는 항상 붙는 거라 저렇게 잘라버리면 됩니다.

그리고서 float을 사용하면 숫자로 변경됩니다.^^ 그럼 이전에 글 앞부분에 이야기드린 애니메이션까지 넣어보죠

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

arduino = serial.Serial('/dev/tty.usbmodem14401', 115200)

fig = plt.figure()
ax = plt.axes(xlim=(0, 50), ylim=(0, 30))
line, = ax.plot([], [], lw=2)

max_points = 50
line, = ax.plot(np.arange(max_points), 
                np.ones(max_points, dtype=np.float)*np.nan, lw=2)

def init():
    return line,

def animate(i):
    y = arduino.readline()
    y = y.decode()[:-2]
    y = float(y)

    old_y = line.get_ydata()
    new_y = np.r_[old_y[1:], y]
    line.set_ydata(new_y)
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=False)

plt.show()

이렇게~ 됩니다. matplotlib의 FuncAnimation 함수를 사용하기 위해 init과 animate 함수를 만들어 두고, animate 함수에서 시리얼통신에서 데이터를 받도록 합니다. 이 코드의 실행 결과는 아래 동영상과 같습니다.

다음에는 아주 재미있는 것을 올려볼께용~^^

반응형