忘備録-備忘録

技術的な備忘録

pythonでシリアルプロッタ

2021-11-11 18:24:25 | Windows
pythonを使いシリアルプロッタを作成しました。

動作画面

ソースコード
# pythonによるシリアルプロッタ
# シリアルに対するデータの出力も可能

from tkinter import Tk,ttk
from tkinter import StringVar
from tkinter import Canvas
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import serial
import time
import threading

#シリアルポートの設定
def initSerial():
    # ポートの設定
    COM="COM57"      #通信ポート
    bitRate=115200   #通信速度
    ser = serial.Serial(COM, bitRate, timeout=0.1)
    return ser

#シリアルポートからデータの読み込み
datanum = 0
fullFlag = False
strage = []
def readSerial():
    global ser,datanum,fullFlag,strage
    data = ser.readline()       # シリアルからデータの読み込み
    if data != b"":             # 読み込んだデータが存在するか
        dataSTR = data.decode('utf-8')
        dataFLOAT = float(dataSTR)
        strage.append(dataFLOAT)
        if fullFlag :
            strage.pop(0)
        else :
            datanum = datanum + 1
            if datanum == 200 :
                fullFlag = True
    drawGraph()
    win.after(100,readSerial)
        
#グラフ描画領域作成
def initGraph(cvs):
    #グラフ用オブジェクト生成
    fig = plt.figure(figsize=(7, 5.5), dpi=100)   #Figure
    canvas = FigureCanvasTkAgg(fig, cvs)
    canvas.get_tk_widget().pack()
    plt.ion()
    return canvas,fig

#グラフの描画
def drawGraph():
    global canvas,strage
    # データをクリア
    plt.cla()
    plt.plot(strage,'blue')                   #2DLine
    canvas.draw()

#ウインドウの生成
def initWindow():
    #ウインドウを作成
    win = Tk()
    #ウインドウの設定
    win.title('graph')
    win.geometry('800x600')

    #ラベルを作成
    lbl = ttk.Label(win,text='送信')
    #ラベルの位置
    lbl.place(x=15,y=20)

    #ボタンを作成
    btn_0 = ttk.Button(text='0',width=3)
    btn_1 = ttk.Button(text='1',width=3)
    btn_2 = ttk.Button(text='2',width=3)
    btn_3 = ttk.Button(text='3',width=3)
    btn_4 = ttk.Button(text='4',width=3)
    btn_end = ttk.Button(text='exit',width=3)
    #ボタンの位置
    btn_0.place(x=15,y=40)
    btn_1.place(x=15,y=60)
    btn_2.place(x=15,y=80)
    btn_3.place(x=15,y=100)
    btn_4.place(x=15,y=120)
    btn_end.place(x=15,y=140)

    #キャンバスを作成
    cvs = Canvas(win,width=700,height=550)
    #キャンバスの位置
    cvs.place(x=75,y=25)
    #ボタンにイベントを設定
    btn_0.bind('<Button-1>',btnHandle_0)
    btn_1.bind('<Button-1>',btnHandle_1)
    btn_2.bind('<Button-1>',btnHandle_2)
    btn_3.bind('<Button-1>',btnHandle_3)
    btn_4.bind('<Button-1>',btnHandle_4)
    btn_end.bind('<Button-1>',btnHandle_end)
    #ウィンドウを閉じるときにイベントを設定
    win.protocol('WM_DELETE_WINDOW', _destroyWindow)
    return win,cvs

#ボタンが押された時の処理
def btnHandle_0(ev):
    ser.write(b"0\n")
    ser.flush()
#ボタンが押された時の処理
def btnHandle_1(ev):
    ser.write(b"1\n")
    ser.flush()
#ボタンが押された時の処理
def btnHandle_2(ev):
    ser.write(b"2\n")
    ser.flush()
#ボタンが押された時の処理
def btnHandle_3(ev):
    ser.write(b"3\n")
    ser.flush()
#ボタンが押された時の処理
def btnHandle_4(ev):
    ser.write(b"4\n")
    ser.flush()
#ボタンが押された時の処理
def btnHandle_end(ev):
    _destroyWindow()
# ウインドウが閉じられたとき
def _destroyWindow():
    ser.close()
    win.quit()
    win.destroy()

#メインプログラム
def main():
    global win,ser,canvas
    ser = initSerial()
    win,cvs = initWindow()
    canvas,fig = initGraph(cvs)
    win.after(100,readSerial)
    #ウインドウのメイン処理
    win.mainloop()

if __name__ == "__main__":
    main()

参考サイト

最新の画像もっと見る

コメントを投稿