python串口助手及实时波形显示(serial库+matplotlib库)

一、所用库

线程模块、serial模块、tkinter(没有用)、matplotlib画图

二、大致框架

串口:com1.inWaiting()判断有无接收到数据

        k == '\n':判断有无换行

        将每次接收到的数据添加到字符串中,最后用“\r\n”分割

        每四个数据分为一组,最后一起画图

画图:清除上一次所画的图、画此次的图、显示

三、用法

输入COM口名称

输入波特率

等待接收数据

四、扩展

 draw_new_pic(self, dat_in: list, width=100):

修改此函数传入的width可以决定同时显示的最大数据量。(发送的数据量超过这个值时图像会向左平移以显示新的数据)

get_data(self, group_number=4):

修改这个函数传入的group_number参数可以改变数据的分组(最大4)

五、代码

import threading
import serial
import tkinter as tk
import matplotlib.pyplot as plt

wait = 1

on = 1
time_jia = 0
ax = []
ay = []
INT_TYPE = 0
STR_TYPE = 1
STR_AND_INT = 2


class Rcom:
    def __init__(self, comn, boud):
        self.receive_data = []
        self.write_data = []
        self.receive_number = []
        self.com1 = serial.Serial(comn, boud, timeout=0.5)
        self.com1.write("ready".encode('utf-8'))

    def get_data(self, group_number=4):
        string_k = ''
        return_number_list = []
        times = 0
        while 1:
            if self.com1.inWaiting() > 0:
                k = self.com1.read().decode('ascii')
                string_k = string_k + k
                if k == '\n':
                    times = times + 1
                    if times == 4:
                        new_list = string_k.split("\r\n")
                        break
        # print(new_list)
        for s1 in new_list:
            if s1.isdigit():
                return_number_list.append(eval(s1))
        return return_number_list

    def write_data(self):
        pass

    pass


class DrawPic:
    def __init__(self):
        self.x = [[] for i in range(4)]
        self.y = [[] for i in range(4)]
        self.len = 0

    def draw_new_pic(self, dat_in: list, width=100):
        self.len = self.len + 1
        for i in range(4):
            self.x[i].append(self.len)
            self.y[i].append(dat_in[i])
        if self.len < width + 1:
            plt.ion()  # 启用交互模式,不需要关闭图片让代码继续执行
            plt.clf()  # 清除上一次画的图
            plt.subplot(2, 2, 1)
            plt.plot(self.x[0][0:width], self.y[0][(self.len - width):self.len])
            plt.subplot(2, 2, 2)
            plt.plot(self.x[1][0:width], self.y[1][(self.len - width):self.len])
            plt.subplot(2, 2, 3)
            plt.plot(self.x[2][0:width], self.y[2][(self.len - width):self.len])
            plt.subplot(2, 2, 4)
            plt.plot(self.x[3][0:width], self.y[3][(self.len - width):self.len])
            plt.pause(0.1)
            plt.ioff()  # 关掉交互模式
        else:
            plt.ion()
            plt.clf()
            plt.subplot(2, 2, 1)
            plt.plot(self.x[0][0:width], self.y[0][(self.len - width):self.len])
            plt.subplot(2, 2, 2)
            plt.plot(self.x[1][0:width], self.y[1][(self.len - width):self.len])
            plt.subplot(2, 2, 3)
            plt.plot(self.x[2][0:width], self.y[2][(self.len - width):self.len])
            plt.subplot(2, 2, 4)
            plt.plot(self.x[3][0:width], self.y[3][(self.len - width):self.len])
            plt.pause(0.1)
            plt.ioff()
        pass

    pass


def threading_1():
    global com1
    global pic1
    while True:
        pic1.draw_new_pic(com1.get_data())


def threading_tk():
    root1 = tk.Tk()
    button1 = tk.Button(root1)
    button1.pack()
    root1.mainloop()
    pass


if __name__ == '__main__':
    com_name = input("输入COM口的名字:COM1,COM2,COM3 ...")
    com_bound = input("输入波特率:")
    if com_name == '':
        com_name = 'COM1'
    if com_bound == '':
        com_bound = 9600
    else:
        com_bound = eval(com_bound)
    com1 = Rcom(com_name, com_bound)
    pic1 = DrawPic()
    thread1 = threading.Thread(target=threading_1())
    thread1.start()

六、完善

1. 数据分组还没完善

2. 只能输入纯数字

3. 还得加入用户界面

觉得可以的,希望大家点个赞!

2022/8/8 添加注释给draw_new_pic()

猜你喜欢

转载自blog.csdn.net/weixin_52013159/article/details/125890776