2024年3月15日金曜日

python+matplotlibでCOM port受信データを動的plot

この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()が重要です.
def update(i):
引数のiは使わないけれど、空欄だとerrになります.

COM portから1行読み込む.
r = port.readline()

COMの1行はこんな文字行なのでこれをspace区切りでバラす.
”serial send test 7 7h 724”
s = r.split()

COMの開始行は文字化けしてるので、6つの文字列にバラせたかどうかを確認します.これを怠ってリストの[5]を踏むとerrで停まってしまいます.
if(len(s)==6):

整数リストyに5番目の整数を積んでゆきます.int()変換が必要です.
y.append(int(s[5]))

画面を消して、リストyをplotするです.結果的にCOM portから1行読む度毎にグラフが描画されるという外部data drivenな動作をします.またscalingはライブラリが勝手にやってくれます.
ax.clear()
ax.plot(y)

以上でpython codeの説明はおしまい.


plot画面に補助線を縦横に入れたいのだけど、、、縦線なんかどうやって入れるのかな?
line()で描画するとしたってauto scalingで動きまくるわけで、つかみどころがないぞ.
う~ん


追記:win10のAnacondaで上のcodeを試しましたが、動きませんでした.Jupiter notebookとSpyderでダメでした.COMというhardwareをAnacondaで制御するのが無理だったのかと推測しています.powershellからoythonを起動すると動きます

かしこ

37 件のコメント:

  1. >python+matplotlib
    Matplotlib って、名前が示してるように、
    ・python で、MATLABみたいなことがしたい!と思った作者が作ったみたいですね。
    (ちなみに、オリジナルの作者は 2012年に亡くなってるんですね。開発は現在、コミュニティに引き継がれてるみたいですが。)
    何となくですが、この組み合わせが、現代の、
    ・一般解
    なんだろうな・・・ふつーのやり方、と言うか。このソースだと、下手すると、
    ・ラズパイ+液晶ボード(つまり、そのまま「組み込み系」)
    に、まで、展開できる。他のやり方だと、そうは行かない・・・

    恐ろしや、pythonのちから

    返信削除
    返信
    1. pythonのライブラリ制作者達のやる気のおかげでしょうか.
      なかなか他の言語ではこうゆう便利さを享受できないかも.
      ぱいぱい

      削除
    2. ここ5~6年くらいですかね(もっと前かもですが)
      「AI系の開発言語」として、pythonが注目を集め出してから、
      ・一挙にメジャーな言語
      に、伸(の)しあがりましたね。python自体は、2000年代以前からありましたが、「ちょっと変わった言語」くらいの認識しかされてなかった。開発者も個人だったし。

      削除
    3. pyと並行してRももてはやされてたけれどもうすっかり下火なんですかね?

      削除
    4. >pyと並行してRももてはやされてた
      「R言語」は、「統計やデータ解析に特化した言語」ですね。
      現在のAIの使われ方としては、
      ・ビッグデータ収集 ⇒ 分析・解析 ⇒ 応用・合成
      だと思われますが、このうち「分析・解析」に、特化してるのが「R言語」ですね。
      昨今の「GPTブーム」を見るまでもなく、現在は「応用・合成」に、主眼が置かれているので、あまり「R言語」には、注目されなくなって来たのではないでしょうか?
      ※ちなみに、python自体は「汎用言語」に近いのですが、この「分析・解析」のために、「NumPy」と言うライブラリが活用されたために、一躍有名になったみたいです。↑のmatplotlibも、「a part of NumPy」みたいです。
      あと、「応用・合成」でも、勿論「NumPy」が活躍してます。
      (R言語は、この辺(「応用・合成」)が弱かったため、主流に成れなかったのかも知れません。まぁでも、「分析・解析」の需要自体はまだまだあるので、そういう意味では下火とは言えないと思います。)

      削除
    5. R使ってみようかと思ったこともあったけど、そうですかRは人気短かったのね.さよならR.こんにちはぱいぱい.

      削除

  2. アパートに戻ると机かわりの座卓のうえの14インチブラウン管テレビが、ない 盗まれた そんなはず 曇りガラスのサッシは、スキマあけてロックはかかるが完全閉じてしめるロックはこわれている 近所の、おばさん トタンの金物が当たって閉まらないんだとどこからか聞こえてくる
    部屋は一階 たてこんでいて 隣とのすきまは1mくらいか狭い たぶん木造 学生アパートの昔住んでいたアパートに似ているかも サッシ窓はながくて一枚1mくらい 部屋は夕方なのか薄暗い 電気はつけていなかった 部屋はかたずいていなかった 夢ではじめて出てきた家だった 夢では家がアップグレードしているときある ひろくなったり それは 現実の家でなくて 夢の中だけで出てきてる いくつか種類あり ゲゲゲの鬼太郎の家の中みたいな内装もあったりする 夢の話でした おぼえちいたのでかいただけです

    返信削除
    返信
    1. いわゆる下宿ですね、昭和の下宿はこんなかんじ

      削除
    2. 下宿といえば 学生さんは栄養が悪いから ラーメンやコーラばかりで 下宿ならごはんつきですよと 下宿は、ごはん代前払いで 入学すると げろまずい晩飯で 学生街食堂でうまい定食をたべることになるそうだ という伝説があった

      削除
    3. わたしの学校は学生食堂が不味くてほとんど食べませんでした.
      今思えば何を喰ってたのか記憶がないです.
      麻雀やりながらモスバーガー食べました.

      削除
  3. python嫌う人が結果いるのですが、慣れると仕事では他の言語使う気がしなくなりますね。ありそうな機能は誰か親切な人がが作ってくれていますし。
    chatGPTとの相性もいい感じがします。

    返信削除
    返信
    1. なんでもありのお手軽言語が生き残るというのはおもろいもんですね

      削除
    2. N88BASICみたいなもので
      いいですね

      削除
    3. 99x99=9801
      これを知ったのはだいぶ後でした

      削除
    4. >99x99=9801
      だから、「ツクモ電機」で、パソコン売ってたのか・・・

      と言うネタを思いつきました、つか、これ知らなかったです。

      削除
    5. いますぐ電卓で検算せよ!

      √8801=93.8、、、こちらはダメだ

      削除
    6. >python嫌う人
      まぁ、特段「嫌ってる」ワケでは無いですが、あんまり身近になかったので。
      ※「Python」使うなら、「Ruby」にして欲しかったな、と言う気はする。
      個人的には、一時「Ruby本」とか買って勉強してたし(AIとかが、ブームになるず~っと前の話)
      「Python」も「Ruby」も、既存の言語に飽き足らなくて、
      ・個人で開発し出した言語
      と言う意味では似ている。両者とも「既存の言語の問題点」を、かなり意識して作られてます。両者は、よく比較ネタでも出てきます。
      https://xtech.nikkei.com/atcl/nxt/column/18/00682/011200067/
      Pythonの波に飲み込まれたRuby、日本のケータイ敗戦との共通点
      ※「Ruby vs Python」で、検索すると色々出てくる
      https://tech-reach.jp/column/912/
      Ruby vs Python|どっちのプログラミング言語がおすすめか
      ※Ruby は、「Ruby on Rails」が、ピークだったのかな・・・ 最近、あんまり名前を聞かなくなったし。

      削除
    7. 記事によるとぱいぱいはライブラリの豊富さだそうで.それに一票.

      削除
    8. ruby好きです.そんなには使ってないけど.

      削除
    9. 言語が変わっちまうとかsoft屋って大変ですね.
      回路屋はあんまり変わらない.

      削除
    10. そんなことないのでは?
      仕事で回路設計してると、
      ・この部品は、何時までメーカーが供給してくれるのだろう?
      (「定番」の、2SC1815でさえ、廃盤になる世の中ですから・・・)
      と、いつも思わざるを得ません。
      「これが、後継機種です」と、メーカーに提示されるのはまだ良いほうで
      (それでも、また新しく、イロイロ習得しないといけなくなったりする)
      真の「ディスコン」になったら、
      ・もうお手上げです。この製品は作れません!
      と、言うしかない。
      ※実際、大手メーカーでも、こういう話が、頻発してるんですよね・・・

      ソフトだろうが、ハードだろうが、「一寸先は闇」

      削除
    11. >あんまり変わらない
      まぁ、回路で、
      ・オームの法則は不変
      と言うのは、ソフトの
      ・If 文は、どんな言語にもある
      って、言ってるのと同じですからね・・・
      そういう意味では、本質はソフトも変わんないですが。

      削除
    12. hardwareは生産一瞬、保守数年、あとはしらねー ですから.
      かるーく足抜けでさよならです.業務用はもすこし長いけど.

      回路設計技術にはほとんど設計改革めいたものはなくて、ゲート設計→verilogに変わったのが最大級の変貌だったかなぁ.
      あとはanalog処理→digital処理への移り変わりもあったけど、わたしは両刀使いなのでシームレスにどっちに進むも戻るも自由自在ですまる

      削除
    13. murasaki
      一般にエンジニア気質の人はPythonを嫌うというか好きにならないような気がします。自分もそうでしたが。(^。^;)
      メモリとかポインタみたいな具体的な要素を見えなくして抽象化した世界観なので。
      自分は最初for文書くたびにイライラしていました・・。

      削除
    14. メモリ展開をイメージしつつprogramします、わたしは.
      Let's malloc.
      マロックだーんす

      削除
    15. murasaki
      遊技機はc言語で開発するのですが、先週から若い人達が変数の内容が勝手に書き換わると言って悩んでいます。c言語あるあるですが。
      mapファイル見て近傍の変数(か配列)調べればすぐに原因わかるんじゃないのかなと思うのですが。口出ししないように言われていて見守っています。
      自分のような年寄はc言語使う時はメモリマップ書かないと気持ち悪くて落ち着きません。

      削除
    16. >口出ししないように

      あははー

      削除
  4. TK80 > 8001 > 8801 > 9801
    となっているので
    数字が大きくなったとばかり
    99x99 なんですね

    返信削除
    返信
    1. √8001=89.4
      だめだぁくそぉ

      削除
    2. FDDは 80S31 だったかな?
      8インチ FDD 8881 だったかな?
      PC98用FDD 9881だったかな?
      プリンタは PR201V ドットインパクト

      削除
    3. √8881=94.2
      √9881=99.4
      みんな残念!

      削除
    4. 手計算ならすごい
      やり方わされたかも

      削除
    5. 暗算です.うそです

      削除
    6. インド式暗算ですね
      えー うそ だったん?
      電卓はカシオ シャープ
      本来の意味で計算器なコンピューターで計算
      すごい科学計算か ただの計算をいまやCRY1よりすごいインテルCPUの14世代でも10万円しないで時間従量料金なしでいくらでも使える
      神田古本屋で科学計算の古本まで買っておいて
      性能をいかせないのは プログラム能力のなさは残念な自分

      シュミレーターでpc98のHソフトに興じてみようと思うと なぜか ものすごく やる気がでます

      削除
  5. ディスコンといえば
    このicなら当面廃盤ならないから
    使えるといって回路作っているひといますね
    次のロットになると急に値上げする秋葉原有名パーツ屋の餌食な気もする
    100円のicがオーディオに使われて400円とかひどい値上げ

    返信削除