---
# System prepended metadata

title: '公立千歳科学技術大学 情報システム工学科 情報システム工学演習 [5] 補足資料'

---

(初版) 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)

