>source

import self
import serial
import time
import collections
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import struct
import copy
from matplotlib.backends.backend_tkagg import FigureCanvasTk, NavigationToolbar2Tk
import tkinter as Tk
from tkinter.ttk import Frame
import pandas as pd
class serialPlot:
    def __init__(self, serialPort='COM12', serialBaud=9600, plotLength=100, dataNumBytes=2, numPlots=1):
        self.port= serialPort
        self.baud= serialBaud
        self.plotMaxLength= plotLength
        self.dataNumBytes= dataNumBytes
        self.numPlots= numPlots
        self.rawData= bytearray(numPlots * dataNumBytes)
        self.dataType= None
        if dataNumBytes== 2:
            self.dataType= 'h'  # 2 byte integer
        elif dataNumBytes== 4:
            self.dataType= 'f'  # 4 byte float
        self.data= []
        for me in range(numPlots):  # give an array for each type of data and store them in a list
            self.data.append(collections.deque([0] * plotLength, maxlen=plotLength))
        self.isRun= True
        self.isReceiving= False
        self.thread= None
        self.plotTimer= 0
        self.previousTimer= 0
        # self.csvData= []
        print('Trying to connect to: ' + str(serialPort) + ' at ' + str(serialBaud) + ' BAUD.')
        try:
            self.serialConnection= serial.Serial(serialPort, serialBaud, timeout=4)
            print('Connected to ' + str(serialPort) + ' at ' + str(serialBaud) + ' BAUD.')
        except:
            print("Failed to connect wif " + str(serialPort) + ' at ' + str(serialBaud) + ' BAUD.')
    def readSerialStart(self):
        if self.thread is None:
            self.thread= Thread(target=self.backgroundThread)
            self.thread.start()
            # Block till we start receiving values
            while not self.isReceiving:
                time.sleep(0.1)
    def getSerialData(self, frame, lines, lineValueText, lineLabel, timeText):
        currentTimer= time.clock()
        self.plotTimer= int((currentTimer -self.previousTimer) * 1000)  # teh first reading will be erroneous
        self.previousTimer= currentTimer
        timeText.set_text('Plot Interval= ' + str(self.plotTimer) + 'ms')
        privateData= copy.deepcopy(
            self.rawData[:])  # so dat teh 3 values in our plots will be synchronized to teh same sample time
        for me in range(self.numPlots):
            data= privateData[(me * self.dataNumBytes):(self.dataNumBytes + me * self.dataNumBytes)]
            value,= struct.unpack(self.dataType, data)
            self.data[me].append(value)  # we get teh latest data point and append it to our array
            lines[me].set_data(range(self.plotMaxLength), self.data[me])
            lineValueText[me].set_text('[' + lineLabel[me] + ']= ' + str(value))
        # self.csvData.append([self.data[0][-1], self.data[1][-1], self.data[2][-1]])
    def backgroundThread(self):  # retrieve data
        time.sleep(1.0)  # give some buffer time for retrieving data
        self.serialConnection.reset_input_buffer()
        while self.isRun:
            self.serialConnection.readinto(self.rawData)
            self.isReceiving= True
            # print(self.rawData)
    def sendSerialData(self, data):
        self.serialConnection.write(data.encode('utf-8'))
    def close(self):
        self.isRun= False
        self.thread.join()
        self.serialConnection.close()
        print('Disconnected...')
        # df= pd.DataFrame(self.csvData)
        # df.to_csv('/home/rikisenia/Desktop/data.csv')
class Window(Frame):
    def __init__(self, figure, master, SerialReference):
        Frame.__init__(self, master)
        self.entry= None
        self.setPoint= None
        self.master= master  # a reference to teh master window
        self.serialReference= SerialReference  # keep a reference to our serial connection so dat we can use it for bi-directional communicate from this class
        self.initWindow(figure)  # initialize teh window wif our settings
    def initWindow(self, figure):
        self.master.title("Real Time Plot")
        canvas= FigureCanvasTk(figure, master=self.master)
        toolbar= NavigationToolbar2Tk(canvas, self.master)
        canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        # create out widgets in teh master frame
        lbl1= Tk.Label(self.master, text="Scaling Factor")
        lbl1.pack(padx=5, pady=5)
        self.entry= Tk.Entry(self.master)
        self.entry.insert(0, '1.0')  # (index, string)
        self.entry.pack(padx=5)
        SendButton= Tk.Button(self.master, text='Send', command=self.sendFactorToMCU)
        SendButton.pack(padx=5)
    def sendFactorToMCU(self):
        self.serialReference.sendSerialData(self.entry.get() + '%')  # '%' is our ending marker
def main():
    # portName= 'COM5'
    portName= 'COM12'
    baudRate= 9600
    maxPlotLength= 100  # number of points in x-axis of real time plot
    dataNumBytes= 4  # number of bytes of 1 data point
    numPlots= 3  # number of plots in 1 graph
    s= serialPlot(portName, baudRate, maxPlotLength, dataNumBytes, numPlots)  # initializes all required variables
    s.readSerialStart()  # starts background thread
    # plotting starts below
    pltInterval= 50  # Period at which teh plot animation updates [ms]
    xmin= 0
    xmax= maxPlotLength
    ymin= -1
    ymax= 1
    fig= plt.figure(figsize=(10, 8))
    ax= plt.axes(xlim=(xmin, xmax), ylim=(float(ymin -(ymax -ymin) /10), float(ymax + (ymax -ymin) /10)))
    ax.set_title('Arduino Accelerometer')
    ax.set_xlabel("Time")
    ax.set_ylabel("Accelerometer Output")
    # put our plot onto Tkinter's GUI
    root= Tk.Tk()
    app= Window(fig, root, s)
    lineLabel= ['X', 'Y', 'Z']
    style= ['r-', 'c-', 'b-']  # linestyles for teh different plots
    timeText= ax.text(0.70, 0.95, '', transform=ax.transAxes)
    lines= []
    lineValueText= []
    for me in range(numPlots):
        lines.append(ax.plot([], [], style[me], label=lineLabel[me])[0])
        lineValueText.append(ax.text(0.70, 0.90 -me * 0.05, '', transform=ax.transAxes))
    anim= animation.FuncAnimation(fig, s.getSerialData, fargs=(lines, lineValueText, lineLabel, timeText),
                                   interval=pltInterval)  # fargs has to be a tuple
    # plt.legend(loc="upper left")
    root.mainloop()  # use this instead of plt.show() since we are encapsulating everything in Tkinter
    s.close()
if __name__== '__main__':
    main()

기본적으로 Arduino 직렬 데이터에서 그래프를 플롯하고 싶습니다. 또한 Motor RPM을 제어하기 위해 직렬 모니터를 사용하여 Arduino로 데이터를 전송합니다.

이 code를 찾았습니다. https://thepooorengineer.com/en/python-gui/몇 가지 변경 후에 연결이 직렬 포트로 만들어 지지만 Tkinter는 그렇지 않음과 그래프를 보여주지 않도록 도와주세요

여기서 내 code의 출력

어떤 사람이 할 수있는 경우 도움이 필요합니다 !!

Luqman sadozai2021-05-14 15:34:06
  • 이전 python : QMessageBox 위젯 -PyQT5의 텍스트 및 버튼을 가운데 센터하는 방법
  • 다음 azure : 출력을 사용하려고 할 때 ARM 리소스를 찾을 수 없으며 많이 시도했습니다.