应变片信号采集--串口程序--借助python和tkinter

 应变片信号采集--串口程序

  • 解决方案

利用python中的serial串口通信工具包实现与下位机通信,利用tkinter工具包编写GUI界面用于实时显示采集到的信号和传输指令。

界面设计:

 最终效果:

 

 参考代码:

#应变信号采集(为保证测量精确度,可将砝码及物体的质量扩大100000倍,代入计算)
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import threading
import tkinter as tk
import serial.tools.list_ports
from tkinter import ttk
from tkinter import scrolledtext

#创建存档文件
file=open('data.csv', 'w+')
#定义父容器
SerialPort = serial.Serial()
GUI = tk.Tk()               # 父容器
GUI.title("Serial Tool")  # 父容器标题
GUI.geometry("440x600")  # 父容器大小

#显示操作信息的框图
Information = tk.LabelFrame(GUI, text="操作信息", padx=10, pady=10)  # 创建一个框架
Information.place(x=20, y=20)                 #将该框架放在x=20,y=20的地方
Information_Window = scrolledtext.ScrolledText(Information, width=20, height=5, padx=10, pady=10, wrap=tk.WORD)         #创建一个有滚动条的文本框
Information_Window.grid()

#创建发送指令框架
Send = tk.LabelFrame(GUI, text="发送指令", padx=10, pady=5)  # 水平,垂直方向上的边距均为 10
Send.place(x=240, y=20)
# 定义保存文本框内容的字符串
DataSend = tk.StringVar()          #输出窗的内容
EntrySend = tk.StringVar()      #输入窗的内容
#创建输入窗口
Send_Window = ttk.Entry(Send, textvariable=EntrySend, width=23)         #窗口的指令为 textvariable,
Send_Window.grid()

#将输入的指令输出到输出窗口,并执行指令
def WriteData():
    global DataSend
    DataSend = EntrySend.get()
    Information_Window.insert("end", '发送指令为:' + str(DataSend) + '\n')       # 在操作信息窗口显示发送的指令并换行,end为在窗口末尾处显示
    Information_Window.see("end")         # 此处为显示操作信息窗口进度条末尾内容,以上两行可实现窗口内容满时,进度条自动下滚并在最下方显示新的内容
    SerialPort.write(bytes(DataSend, encoding='utf8'))#将指定的字符串写入串行端口。发送命令,编码成utf8格式

#设置一个激活以上操作的按钮
tk.Button(Send, text="发送", command=WriteData).grid(pady=5, sticky=tk.E)     #放在最东面

#接收文本框(带滚动条)
Receive = tk.LabelFrame(GUI, text="接收区", padx=10, pady=10)  # 水平,垂直方向上的边距均为 10
Receive.place(x=240, y=124)
Receive_Window = scrolledtext.ScrolledText(Receive, width=18, height=9, padx=8, pady=10, wrap=tk.WORD)
Receive_Window.grid()

#建立系数
#设定初始值
k=1.0
b=0.0
text1=tk.Label(GUI, text="k:",padx=10, pady=10)             #Label组件用于显示文本和图像
text1.place(x=220, y=350)
text2=tk.Label(GUI, text="b:",padx=10, pady=10)
text2.place(x=220, y=380)
v1 = tk.StringVar()
v2 = tk.StringVar()
e1 = tk.Entry(GUI,textvariable=v1)
e2 = tk.Entry(GUI,textvariable=v2)
e1.place(x=290, y=360)
e2.place(x=290, y=390)
def insert_1():
    global k,b
    k = v1.get()
    k=float(k)
    b = v2.get()
    b = float(b)
b2=tk.Button(GUI,text='输入参数',width=8,height=1,command=insert_1)
b2.place(x=290, y=420)


#建立物品质量框图
result = tk.LabelFrame(GUI, text='物品质量 /g', padx=10, pady=10)  # 水平,垂直方向上的边距均为 10
result.place(x=20, y=350)
result_Window = scrolledtext.ScrolledText(result, width=18, height=9, padx=8, pady=10, wrap=tk.WORD)
result_Window.grid()

#传输数据选项框图
option = tk.LabelFrame(GUI, text="选项", padx=10, pady=10)  # 水平,垂直方向上的边距均为10
option.place(x=20, y=150, width=203)  # 坐标位置
# 创建下拉列表
ttk.Label(option, text="串口号:").grid(column=0, row=0)  # 添加串口号标签,第0行第0列
ttk.Label(option, text="波特率:").grid(column=0, row=1)  # 添加波特率标签
#建立端口号列表
Port = tk.StringVar()  # 端口号字符串
Port_list = ttk.Combobox(option, width=12, textvariable=Port, state='readonly')#创建下拉菜单栏
ListPorts = list(serial.tools.list_ports.comports())#扫描当前可用串口保存到表ListPorts
Port_list['values'] = [i[0] for i in ListPorts]## 下拉列表的值为ListPorts的所有值
Port_list.current()# 初始显示表中第一个值
Port_list.grid(column=1, row=0)  # 设置其在界面中出现的位置
#建立波特率列表
BaudRate = tk.StringVar()  # 波特率字符串
BaudRate_list = ttk.Combobox(option, width=12, textvariable=BaudRate, state='readonly')
BaudRate_list['values'] = (1200, 2400, 4800, 9600, 14400, 19200, 38400, 43000, 57600, 76800, 115200)
BaudRate_list.current(5)# 初始显示19200
BaudRate_list.grid(column=1, row=1)  # 设置其在界面中出现的位置  column代表列   row 代表行

#开关框图
switch = tk.LabelFrame(GUI, text="开关", padx=10, pady=10)  # 水平,垂直方向上的边距均为 10
switch.place(x=20, y=250, width=203)  # 定位坐标

#不断读取串口数据,并计算
def ReceiveData():
    while SerialPort.isOpen():
        Receive_Window.insert("end", str(SerialPort.readline()) + '\n') #在接收窗口不断显示接受的数据,一行一行地读数据
        Receive_Window.see("end")
        #number = int.from_bytes(str(SerialPort.readline()), byteorder='big')   #全部读取的方式,一般不用
        # 转换字符串为16进制,再转换为10进制。
        data = SerialPort.readline()#读取的数据类型为字节类型
        str1 = data.hex()  # 转换为16进制,解码
        num0 = str1[6:]  # 截取需要的数据部分
        num1 = int(num0, 16)  # 转换为10进制
        print(num1)
        file = open('data.csv', 'a')
        file.write(str(num1) + '\n')
        file.close()
        num1=float(num1)
        result_Window.insert("end", str(b+k*num1) + '\n')#将字节串转换为数字并求出方程
        result_Window.see("end")
#关闭数据的读取
def Close_Serial():
    SerialPort.close()
#打开数据读取
def Open_Serial():
    if not SerialPort.isOpen():
        SerialPort.port = Port_list.get()# 读取端口下拉菜单栏的选择,将其设为串口的端口
        SerialPort.baudrate = BaudRate_list.get()# 读取波特率下拉菜单栏的选择,将其设为串口的波特率
        SerialPort.timeout = 0.1
        SerialPort.open()   # 打开串口
        if SerialPort.isOpen():
            t = threading.Thread(target=ReceiveData) # 新建线程用来不断接收数据并显示,与主线程并行
            t.setDaemon(True)# 守护线程
            t.start()# 开始线程
    else:
        SerialPort.close()
#设置开始和结束按钮,并执行指令
tk.Button(switch, text="开始采集", command=Open_Serial).pack(side="left", padx=13)
tk.Button(switch, text="停止采集", command=Close_Serial).pack(side="right", padx=13)

GUI.mainloop()

#程序还是有点小问题,敬请改正#

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值