(初版) 2025-05-19 h-fukuda@photon.chitose.ac.jp (第2版) 2025-05-23 h-fukuda@photon.chitose.ac.jp 4系列対応,その2の手法の横軸反転 # シリアルモニタの値をグラフ化する その1 - シリアルプロッタを使う - 詳細は e-Book や説明資料 (ポータルサイトにアップロード済みのPDF) を参照のこと. <!-- ![Serial-Plotter_0](https://hackmd.io/_uploads/SJ0eotK-ee.png) --> <!-- ![Serial-Plotter](https://hackmd.io/_uploads/SkxzjFYbxg.png) --> ![SerialPlotter](https://hackmd.io/_uploads/rybTkoa-ex.png) # 動作確認用 Arduino スケッチ <!--https://code.visualstudio.com/Download --> ```C++= void setup() { Serial.begin(9600); } void loop() { int data_1 = analogRead(A0); int data_2 = analogRead(A1); float data_3 = (float)analogRead(A2); float data_4 = (float)analogRead(A3); Serial.print(data_1); Serial.print("\t"); Serial.print(data_2); Serial.print("\t"); Serial.print(data_3); Serial.print("\t"); Serial.print(data_4); Serial.print("\n"); } ``` なお,シリアルプロッタのバッファサイズの設定変更は,下記 URL を参照のこと. https://photonchitoseacjp-my.sharepoint.com/:p:/g/personal/y-takano_photon_chitose_ac_jp/ESH3ewrw-EJLnKtYvpq-SC8BV69wzqD0fj2jOoHp9kJv6g?e=E34eyY `C:\Users\H103-XX\AppData\Local\Programs\Arduino IDE\resources\app\lib\backend\resources\arduino-serial-plotter-webapp\static\js` :::warning XXの部分は机番号 ::: # シリアルモニタの値をグラフ化する その2 Pythonでデータを読んで,matplotlibでグラフ化する. :::warning Pythonスクリプトを実行する前に,Arduino IDEのシリアルモニタを閉じてください. Arduino IDEでシリアルモニタを開いていると,リソース競合してしまい Python 側でデータを読めません. ::: # 動作確認用 Arduino スケッチ <!--https://code.visualstudio.com/Download --> ```C++= void setup() { Serial.begin(9600); } void loop() { int data_1 = analogRead(A0); int data_2 = analogRead(A1); float data_3 = (float)analogRead(A2); float data_4 = (float)analogRead(A3); Serial.print(data_1); Serial.print("\t"); Serial.print(data_2); Serial.print("\t"); Serial.print(data_3); Serial.print("\t"); Serial.print(data_4); Serial.print("\n"); } ``` Visual Studio Code (VS Code) を開く. ![VS_Code_1](https://hackmd.io/_uploads/SywGjtK-xx.png) フォルダを指定して開く. ![VS_Code_2](https://hackmd.io/_uploads/H1ofittZee.png) ![VS_Code_3](https://hackmd.io/_uploads/SymQjtt-gl.png) ![VS_Code_4](https://hackmd.io/_uploads/B1vQstYZxg.png) 新しいテキストファイルを開く. ![VS_Code_5](https://hackmd.io/_uploads/B1e4sYF-ge.png) 下記コードを Copy & Paste する. ```Python= import serial import numpy as np import matplotlib.pyplot as plt ################################## COM_PORT = 'COM3' LENGTH = 400 Y_MIN = 0 Y_MAX = 1023 LABEL_Y1 = "Label_y1" LABEL_Y2 = "Label_y2" LABEL_Y3 = "Label_y3" LABEL_Y4 = "Label_y4" PAUSE = 0.1 SEPARATOR = "\t" ################################## ser = serial.Serial(COM_PORT, 9600) fig, ax = plt.subplots(1, 1) x = np.arange(0, LENGTH, 1) y1 = np.zeros(LENGTH) y2 = np.zeros(LENGTH) y3 = np.zeros(LENGTH) y4 = np.zeros(LENGTH) lines1, = ax.plot(x, y1, label = LABEL_Y1) lines2, = ax.plot(x, y2, label = LABEL_Y2) lines3, = ax.plot(x, y3, label = LABEL_Y3) lines4, = ax.plot(x, y4, label = LABEL_Y4) ax.set_ylim(Y_MIN, Y_MAX) ax.grid(axis='both') ax.legend() while True: x += 1 y1 = np.roll(y1, 1) y2 = np.roll(y2, 1) y3 = np.roll(y3, 1) y4 = np.roll(y4, 1) line_str = ser.readline().decode().strip() line = [float(x) for x in line_str.split(SEPARATOR)] tmp = np.array(line, dtype = np.float64) lines1.set_data(x, y1) lines2.set_data(x, y2) lines3.set_data(x, y3) lines4.set_data(x, y4) ax.set_xlim((x.min(), x.max())) ax.invert_xaxis() plt.pause(PAUSE) y1[-1] = tmp[0] y2[-1] = tmp[1] y3[-1] = tmp[2] y4[-1] = tmp[3] ``` :::info 6行目:各自のシリアルポートを指定する. 7行目:ジョイスティックの動作を把握できる長さに調整する. 8, 9行目:グラフに応じて縦軸の最小値,最大値を指定する. ::: ::: danger 10, 13行目:グラフのラベルを**必ず**指定すること. `Label_y1`, `Label_y2`, `Label_y3`, `Label_y4`のままだと何のグラフか分かりません... ::: :::info 14行目:グラフのリフレッシュ時間を指定する. 15行目:セパレータを指定する.カンマなら`','`,TABなら`"\t"`. ::: <!--::: danger 35, 36行目:データの型に応じて選択すること. :::--> ![VS_Code_6](https://hackmd.io/_uploads/rkVNsYtble.png) ファイル名を指定して保存する. ![VS_Code_7](https://hackmd.io/_uploads/SJdVsFtWgx.png) この例では mySerialPlotter.py とする. ![VS_Code_8](https://hackmd.io/_uploads/BJ6EjtF-lg.png) ターミナルを開く. ![VS_Code_9](https://hackmd.io/_uploads/By8tTYKbee.png) コマンドを実行する. `PS C:\Users\H103-XX> mkdir servo_data ` `PS C:\Users\H103-XX\servo_data> python .\mySerialPlotter.py` ここで `XX` は机の番号. :::warning シリアルポートとの通信の都合上,動作が不安定な場合あり. 何度か立ち上げなおすと動作する. ::: ## 実行例 <!-- ![mySerialPlotter](https://hackmd.io/_uploads/HyxXncpWex.png) --> ![mySerialPlotter](https://hackmd.io/_uploads/rybCDjaWex.png) ## グラフ保存 <!-- ![mySerialPlotter_save](https://hackmd.io/_uploads/rk_N6cTZle.png) --> ![mySerialPlotter_save](https://hackmd.io/_uploads/BywAvjaZeg.png) ファイルのアイコンを押下してダイアログでファイル名を指定する. ## 終了する時 コマンドラインまたは(VS-Codeの)ターミナルで `CTRL-C` を押下する. :::warning プロットウィンドを閉じてもプログラムは止まらないので注意 ::: # シリアルモニタの値をグラフ化する その3 Pythonでデータを読んでASCIIテキストでファイル保存し,グラフ描画アプリケーション(gnuplot, KyPlotなど)や表計算アプリケーション(MS-Excelなど)でグラフ化する. :::warning Pythonスクリプトを実行する前に,Arduino IDEのシリアルモニタを閉じてください. Arduino IDEでシリアルモニタを開いていると,リソース競合してしまい Python 側でデータを読めません. ::: ```python= import serial ser = serial.Serial('COM7', 9600) f = open('servo_data.txt','w') while 1: data = ser.readline().decode().strip() f.write(data) f.write("\n") ``` :::info 3行目:各自のシリアルポートを指定する. 4行目:保存するファイル名を指定する. ::: :::danger 縦軸,横軸,凡例などは各自で適切に設定すること. `系列1`とか`("servo_data.txt") using 0:1`のままだと何のグラフか分かりません... ::: ## 終了する時 コマンドラインまたは(VS-Codeの)ターミナルで `CTRL-C` を押下する. ## KyPlotでグラフ化した例 <!-- ![KyPlot](https://hackmd.io/_uploads/rkJGX7vWee.png)--> <!-- ![KyPlot](https://hackmd.io/_uploads/Hk14WjFWel.png) --> ![KyPlot](https://hackmd.io/_uploads/r1xeXoTWgl.png) https://www.kyenslab.com/ja-jp/kyplot/v6/ ## gnuplotでグラフ化した例 <!-- ![gnuplot](https://hackmd.io/_uploads/BJzVBmPZex.png) --> <!-- ![gnuplot](https://hackmd.io/_uploads/ryUDgjFZeg.png) --> ![gnuplot](https://hackmd.io/_uploads/SkPgNipbxx.png) http://www.gnuplot.info/ http://takeno.iee.niit.ac.jp/~foo/gp-jman/ ```gnuplot gnuplot> plot("servo_data.txt") using 0:1 with line gnuplot> replot("servo_data.txt") using 0:2 with line gnuplot> replot("servo_data.txt") using 0:3 with line gnuplot> replot("servo_data.txt") using 0:4 with line ``` ## MS-Excelでグラフ化した例 <!-- ![excel](https://hackmd.io/_uploads/rk0lLQPWex.png) --> <!-- ![Excel](https://hackmd.io/_uploads/ry2ZzjKbxg.png) --> ![Excel](https://hackmd.io/_uploads/rye6Nop-lg.png)