この1つ前の投稿の続きというか、小さな結論みたいなものです.
やりたい事は、、、
・COM portから整数の文字列が毎秒数個ぐらいで入って来ます
・それを逐次windows画面にグラフ表示させたい
・めんどうなことはやりたくない
で、いろいろと味見して、python+matplotlibでそれなりに思ったような感じになりました.勝手にscalingして描画してくれるのでこりゃいいやってところ.
でもこれで満足かというと微妙なんですけどね.罫線入れたり、start/stopボタンを追加したりしたいのだけれど、そこに手が届くのかな?
以下は技術的なことを書きます.
ーーーー
COM portの先につないであるのはarduinoです.よくあるUSB COMですね.CH340とかFT232とかで繋がります.
arduinoは115200bpsでこんなascii文字行を0.2Sec間隔で打ってくるように作ってあります.
serial send test 5 5h 666
serial send test 6 6h 695
serial send test 7 7h 724
末尾の数字が、512*(1+Sin(x))になっています.0~1024の整数です.
文字列の切り出し方法を学ぶためにわざとめんどうな文字行にしてます.
PC上のpythonでCOM経由のSin波をグラフ表示するのが目的です.(上の動画がそれ)
netによくあるexampleは、code内部で発生させたdataをplotするような形式が多いのですが、わたしはそうではなくてCOM portに描画速度が律速される形式にしたいです.
そのためにこんなことをしています.
・COMから1行読み取り ←pyserialを使う
・切り出し
・リストy[]にappend
・その都度plot(y) ←matplotlib.animationを使う
python環境の準備は、、、これは少なくともやったと思うんだがその他は忘れました.
pip install matplotlib
pip install animation
pip install pyserial
pip install numpy
それでpython codeはこれです.意外と短いですね.
import serial
import matplotlib.pyplot as plt
import matplotlib.animation as anime
def main():
port = serial.Serial('COM7', baudrate=115200, parity=serial.PARITY_NONE)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
y=[]
def update(i):
r = port.readline()
s = r.split()
if(len(s)==6):
print(int(s[5]))
y.append(int(s[5]))
ax.clear()
ax.plot(y)
a = anime.FuncAnimation(fig, update, range(110), repeat=False)
plt.show()
if __name__ == '__main__':
main()
上から説明しますと、、、
これはCOMに接続してます.とくにトラブルはありませんでした.
port = serial.Serial('COM7', baudrate=115200, parity=serial.PARITY_NONE)
まず描画windowsがfigなのでしょう.figの中に小窓としてaxを設けてるのだと思います.figの大きさを変えることもできますが、ここではdefaultの大きさのままです.subplot(111)の意味は余白を指定してるんでしょう.しらんけど.
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
codeの先に飛びますが、これが動的描画のキモです.
1枚描画するためにupdateという関数をcallするの意味.
range(110)は描画フレームに0~109という名前をふるの意味.不要な気がするけどサボると災いを招きます.また、110回描画したら止まります.
a=は不要な気がするけど、無いとerrになるみたいよ.
いろいろと気難しい.....
a = anime.FuncAnimation(fig, update, range(110), repeat=False)
というわけでupdate()が重要です.
引数のiは使わないけれど、空欄だとerrになります.
COM portから1行読み込む.
COMの1行はこんな文字行なのでこれをspace区切りでバラす.
”serial send test 7 7h 724”
COMの開始行は文字化けしてるので、6つの文字列にバラせたかどうかを確認します.これを怠ってリストの[5]を踏むとerrで停まってしまいます.
整数リストyに5番目の整数を積んでゆきます.int()変換が必要です.
画面を消して、リストyをplotするです.結果的にCOM portから1行読む度毎にグラフが描画されるという外部data drivenな動作をします.またscalingはライブラリが勝手にやってくれます.
以上でpython codeの説明はおしまい.
plot画面に補助線を縦横に入れたいのだけど、、、縦線なんかどうやって入れるのかな?
line()で描画するとしたってauto scalingで動きまくるわけで、つかみどころがないぞ.
う~ん
追記:win10のAnacondaで上のcodeを試しましたが、動きませんでした.Jupiter notebookとSpyderでダメでした.COMというhardwareをAnacondaで制御するのが無理だったのかと推測しています.powershellからoythonを起動すると動きます.
かしこ