Arduino筆記(77):在Windows下使用Python 從序列埠讀取 Arduino 感測值

之前的實做如要繪製線型圖,是將傳感器的值,如溫度濕度的感測值送到 Thingspeak,再由 Thingspeak 繪出折線圖,來呈現溫度高低的狀況。一直想說不知是否可以在 Windows 系統中繪製圖形,不要再送到IoT的平台。我找到一個方法,實做一下從 Arduino Analog A0 將可變電阻值送到序列埠,再從 Windows 的 Python 程式讀取序列埠的值,透過 matplotlib 繪製成長條圖。


首先要在 Windows 系統安裝 Python,可到 這裡 下載程式安裝。我的環境安裝 Python 3.7.4,可以執行以下指令,看一下是否安裝 Python 以及目前的版本:
C:\>python --version
安裝好 Python 之後,再檢查一下是否安裝 Python 的安裝程式 pip,可執行以下指令看看是否已經安裝及檢查版本。
C:\>pip --version
如果出現以下畫面就表示已經完成安裝好 pip 程式:

如果沒有安裝 pip 程式,可以到 這裡 下載 get-pip.py 程式,執行以下指令來安裝 pip 程式:
C:\>python get-pip.py
安裝的結果如下圖:

[安裝Python繪圖函式庫matplotlib]

安裝繪圖函式庫 matplotlib 所需工具程式:
C:\>python -m pip install -U pip setuptools
安裝結果如下:

安裝繪圖函式庫matplotlib:
C:\>python -m pip install matplotlib
安裝結果如下:

安裝完成後,執行一個畫直線的測試程式看看繪圖功能是否正常。可將下列程式存成一個文字檔,附檔名加上 .py,例如:plottest.py。另外開啟命令列視窗,執行 C:\>Python plottest.py即可。
import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()

如果出現下圖,表示函式庫 matplotlib 已正確安裝。



[線路圖]


[程式]

以下是Arduino程式:讀取可變電阻的值,送到COM Port,並讓 LED燈每秒閃爍一次,表示程式正在執行。
const int analogIn = A0;
int analogVal = 0;
bool led = 1;

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  //讓Arduino板上的LED閃爍
  digitalWrite(LED_BUILTIN, led);
  led = !led; 
  analogVal = analogRead(analogIn);
  Serial.println(analogVal);
  delay(500);
}

以下是Python程式:讀取COM Port的資料,我的 Arduino 用的序列埠是COM11,可以實際執行的 COM Port修改程式,並在命令視窗執行以下繪圖程式。
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import serial
import platform

print("Python version: " + platform.python_version())
print("matplotlib version: " + mpl.__version__)

fig, ax = plt.subplots()
line, = ax.plot(np.random.rand(10))
ax.set_ylim(0, 1030)
xdata, ydata = [0]*100, [0]*100
SerialIn = serial.Serial("COM11",115200)

def update(data):
    line.set_ydata(data)
    return line,

def run(data):
    global xdata, ydata
    x,y = data
    if (x == 0):
        xdata = [0]*100
        ydata = [0]*100
    del xdata[0]
    del ydata[0]
    xdata.append(x)
    ydata.append(y)
    line.set_data(xdata, ydata)
    return line,

def data_gen():
    x = 9
    while True:
        if (x >= 9):
            x = 0
        else:
            x += 0.1            
        try:
            inRaw = SerialIn.readline()
            inInt = int(inRaw)
        except:
            inInt = 0            
        yield x, inInt

ani = animation.FuncAnimation(fig, run, data_gen, interval=0, blit=True)
plt.show()

[結果]






[參考資料]


Post a Comment

較新的 較舊