用Python做一个上位机进行串口通讯发送16进制指令

Python上位机进行串口通讯发送16进制指令

文章目录

  • Python上位机进行串口通讯发送16进制指令
    • 一、要求
    • 二、python上位机设计
      • 1.内容描述
      • 2.串口设置
      • 3.程序流程图
      • 4.程序设计(python)
        • 4.1 导入所需库
        • 4.2 通过serial库获取当前串口列表
        • 4.3 创建一个上位机窗口
        • 4.4 设置串口下拉选择框
        • 4.5 创建按钮,用于获取选择的值,并打开串口默认配置相应参数
        • 4.6 创建文本框,用于显示发送的数据
        • 4.7 定义4个电机按钮触发的函数
        • 4.8 生成4个电机按钮
        • 4.9 运行窗口
        • 4.10 程序源码
    • 三、调试
      • 1.上位机界面
      • 2.串口检查提示
      • 3.打开串口
      • 4.发送指令(以16进制格式)
      • 5.实践操作(暂无)

一、要求

用Python做一个上位机进行串口通讯发送16进制指令_第1张图片

二、python上位机设计

1.内容描述

用Python做一个上位机进行串口通讯发送16进制指令_第2张图片


2.串口设置

用Python做一个上位机进行串口通讯发送16进制指令_第3张图片


3.程序流程图

用Python做一个上位机进行串口通讯发送16进制指令_第4张图片

4.程序设计(python)

4.1 导入所需库

import tkinter as tk
import tkinter.messagebox
import serial
import serial.tools.list_ports

4.2 通过serial库获取当前串口列表

#Python serial获取串口列表
#serial.tools.list_ports()方法可以获取到串口列表数组,遍历数组,每个元素的name属性就是串口名称(COMx)
plist = list(serial.tools.list_ports.comports())
ports = [p.name for p in plist]
print(ports)

4.3 创建一个上位机窗口

# 创建主窗口
window = tk.Tk()
window.title("python上位机--发送指令")
window.geometry("600x400") #设置窗口大小

4.4 设置串口下拉选择框

# 创建下拉选择框
options = ports
variable = tk.StringVar(window)
if len(options) == 0:
    print("The list is empty")
    options.append("暂无可选端口")  # 设置默认值
else:
    print("The list is not empty")
variable.set(options[0])  # 设置默认值
dropdown = tk.OptionMenu(window, variable, *options)
dropdown.grid(row=0, column=0)

4.5 创建按钮,用于获取选择的值,并打开串口默认配置相应参数

若串口无法使用,便提示相应错误信息

# 创建按钮,用于获取选择的值
def get_value():
    try:
        # 打开串口
        #指定串口号、波特率、校验位、停止位和字节大小等参数。这些参数要与设备使用的串口参数保持一致,否则可能无法正常通信。
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        print(f"当前选择的值:{variable.get()}")
        # 串口选择弹窗
        tk.messagebox.showinfo("提示", f"您选择了:{variable.get()}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")
            
button = tk.Button(window, text="打开串口", command=get_value)
button.grid(row=0, column=3)

4.6 创建文本框,用于显示发送的数据

# 创建文本框
frame = tk.Frame(window)  # 创建一个框架,用于放置文本框和滚动条
text = tk.Text(frame, width=50, height=20)  # 创建文本框,设置宽度和高度
scroll = tk.Scrollbar(frame)  # 创建滚动条
text.pack(side=tk.LEFT)  # 将文本框放在左侧
scroll.pack(side=tk.RIGHT, fill=tk.Y)  # 将滚动条放在右侧,垂直填充
frame.grid(row=0, column=7)

# 将文本框和滚动条关联起来
text.config(yscrollcommand=scroll.set)
scroll.config(command=text.yview)

4.7 定义4个电机按钮触发的函数

# 定义按钮触发的函数
def button_clicked1(button_text):
    try:
        # 打开串口
        #指定串口号、波特率、校验位、停止位和字节大小等参数。这些参数要与设备使用的串口参数保持一致,否则可能无法正常通信。
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        # 将命令数据转换为 16 进制数组
        data = [0xAA, 0x0A]
        # 发送数据
        ser.write(data)
        # 文本插入
        text.insert("end", "发送命令:AA 0A\n")  # 在文本框末尾插入
        print(f"您单击了按钮:{button_text}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")

# 定义按钮触发的函数
def button_clicked2(button_text):
    try:
        # 打开串口
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        # 将命令数据转换为 16 进制数组
        data = [0xAA, 0x0B]
        # 发送数据
        ser.write(data)
        # 文本插入
        text.insert("end", "发送命令:AA 0B\n")  # 在文本框末尾插入
        print(f"您单击了按钮:{button_text}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")

# 定义按钮触发的函数
def button_clicked3(button_text):
    try:
        # 打开串口
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        # 将命令数据转换为 16 进制数组
        data = [0xAA, 0x0C]
        # 发送数据
        ser.write(data)
        # 文本插入
        text.insert("end", "发送命令:AA 0C\n")  # 在文本框末尾插入
        print(f"您单击了按钮:{button_text}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")

# 定义按钮触发的函数
def button_clicked4(button_text):
    try:
        # 打开串口
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        # 将命令数据转换为 16 进制数组
        data = [0xAA, 0x0D]
        # 发送数据
        ser.write(data)
        # 文本插入
        text.insert("end", "发送命令:AA 0D\n")  # 在文本框末尾插入
        print(f"您单击了按钮:{button_text}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")

4.8 生成4个电机按钮

# 创建四个按钮
button1 = tk.Button(window, text="启动电机1", command=lambda: button_clicked1("按钮:启动电机1"))
button1.grid(row=2, column=7)
button2 = tk.Button(window, text="启动电机2", command=lambda: button_clicked2("按钮:启动电机2"))
button2.grid(row=3,column=7)
button3 = tk.Button(window, text="启动电机3", command=lambda: button_clicked3("按钮:启动电机3"))
button3.grid(row=4, column=7)
button4 = tk.Button(window, text="停止电机", command=lambda: button_clicked4("按钮:停止电机"))
button4.grid(row=5, column=7)

4.9 运行窗口

# 运行窗口
window.mainloop()

4.10 程序源码

import tkinter as tk
import tkinter.messagebox
import serial
import serial.tools.list_ports

#Python serial获取串口列表
#serial.tools.list_ports()方法可以获取到串口列表数组,遍历数组,每个元素的name属性就是串口名称(COMx)
plist = list(serial.tools.list_ports.comports())
ports = [p.name for p in plist]
print(ports)



# 创建主窗口
window = tk.Tk()
window.title("python上位机--发送指令")
window.geometry("600x400") #设置窗口大小

# 创建下拉选择框
options = ports
variable = tk.StringVar(window)
if len(options) == 0:
    print("The list is empty")
    options.append("暂无可选端口")  # 设置默认值
else:
    print("The list is not empty")
variable.set(options[0])  # 设置默认值
dropdown = tk.OptionMenu(window, variable, *options)
dropdown.grid(row=0, column=0)
# dropdown.pack()

# 创建按钮,用于获取选择的值
def get_value():
    try:
        # 打开串口
        #指定串口号、波特率、校验位、停止位和字节大小等参数。这些参数要与设备使用的串口参数保持一致,否则可能无法正常通信。
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        print(f"当前选择的值:{variable.get()}")
        # 串口选择弹窗
        tk.messagebox.showinfo("提示", f"成功打开{variable.get()}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")

# # 打开串口
# ser = serial.Serial(variable.get(), baudrate=9600, timeout=1)

button = tk.Button(window, text="打开串口", command=get_value)
button.grid(row=0, column=3)
# button.pack()

# 创建文本框
frame = tk.Frame(window)  # 创建一个框架,用于放置文本框和滚动条
text = tk.Text(frame, width=50, height=20)  # 创建文本框,设置宽度和高度
scroll = tk.Scrollbar(frame)  # 创建滚动条
text.pack(side=tk.LEFT)  # 将文本框放在左侧
scroll.pack(side=tk.RIGHT, fill=tk.Y)  # 将滚动条放在右侧,垂直填充
frame.grid(row=0, column=7)
# frame.pack()

# 将文本框和滚动条关联起来
text.config(yscrollcommand=scroll.set)
scroll.config(command=text.yview)

# 定义按钮触发的函数
def button_clicked1(button_text):
    try:
        # 打开串口
        #指定串口号、波特率、校验位、停止位和字节大小等参数。这些参数要与设备使用的串口参数保持一致,否则可能无法正常通信。
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        # 将命令数据转换为 16 进制数组
        data = [0xAA, 0x0A]
        # 发送数据
        ser.write(data)
        # # 数字转16进制 0x形式的字符串,再截取后面2位数
        # hex_string1 = hex(data[0]).upper()[2:]
        # hex_string2 = hex(data[1]).upper()[2:]
        # # print(hex_string1)
        # # 文本插入
        # text.insert("end", "发送命令:"+hex_string1+" "+hex_string2+"\n")  # 在文本框末尾插入
        # print(f"您单击了按钮:{button_text}")
        # 文本插入
        text.insert("end", "发送命令:AA 0A\n")  # 在文本框末尾插入
        print(f"您单击了按钮:{button_text}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")

# 定义按钮触发的函数
def button_clicked2(button_text):
    try:
        # 打开串口
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        # 将命令数据转换为 16 进制数组
        data = [0xAA, 0x0B]
        # 发送数据
        ser.write(data)
        # 文本插入
        text.insert("end", "发送命令:AA 0B\n")  # 在文本框末尾插入
        print(f"您单击了按钮:{button_text}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")

# 定义按钮触发的函数
def button_clicked3(button_text):
    try:
        # 打开串口
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        # 将命令数据转换为 16 进制数组
        data = [0xAA, 0x0C]
        # 发送数据
        ser.write(data)
        # 文本插入
        text.insert("end", "发送命令:AA 0C\n")  # 在文本框末尾插入
        print(f"您单击了按钮:{button_text}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")

# 定义按钮触发的函数
def button_clicked4(button_text):
    try:
        # 打开串口
        ser = serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)
        # 将命令数据转换为 16 进制数组
        data = [0xAA, 0x0D]
        # 发送数据
        ser.write(data)
        # 文本插入
        text.insert("end", "发送命令:AA 0D\n")  # 在文本框末尾插入
        print(f"您单击了按钮:{button_text}")
    except Exception as e:
            #未选择端口发送,会报错
            print("---异常---:", e)
            # 按钮报错触发弹窗
            tk.messagebox.showinfo("提示", f"---异常---:{e}")



# 创建四个按钮
button1 = tk.Button(window, text="启动电机1", command=lambda: button_clicked1("按钮:启动电机1"))
button1.grid(row=2, column=7)
# button1.pack()
button2 = tk.Button(window, text="启动电机2", command=lambda: button_clicked2("按钮:启动电机2"))
button2.grid(row=3,column=7)
# button2.pack()
button3 = tk.Button(window, text="启动电机3", command=lambda: button_clicked3("按钮:启动电机3"))
button3.grid(row=4, column=7)
# button3.pack()
button4 = tk.Button(window, text="停止电机", command=lambda: button_clicked4("按钮:停止电机"))
button4.grid(row=5, column=7)
# button4.pack()

# 运行窗口
window.mainloop()


三、调试

1.上位机界面

用Python做一个上位机进行串口通讯发送16进制指令_第5张图片

2.串口检查提示

无可用串口时,打开串口

用Python做一个上位机进行串口通讯发送16进制指令_第6张图片


3.打开串口

当有多个串口时,默认选择第一个,可自己手动调整

用Python做一个上位机进行串口通讯发送16进制指令_第7张图片

成功打开串口

用Python做一个上位机进行串口通讯发送16进制指令_第8张图片

当串口成功打开后,串口的参数会默认自动配置

#指定串口号、波特率、校验位、停止位和字节大小等参数。这些参数要与设备使用的串口参数保持一致,否则可能无法正常通信。
ser =
serial.Serial(variable.get(),baudrate=9600,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=1)

4.发送指令(以16进制格式)

指令默认以16进制发送,不同按钮具有对应的指令,例如“启动电机1”按钮:

# 将命令数据转换为 16 进制数组
data = [0xAA, 0x0A]
# 发送数据
ser.write(data)

当发送后,文本框会显示已发送相应的指令

# 文本插入
text.insert("end", "发送命令:AA 0A\n")  # 在文本框末尾插入

点击相应按钮,会以16进制发送相应的指令,并显示在文本框

用Python做一个上位机进行串口通讯发送16进制指令_第9张图片


5.实践操作(暂无)

你可能感兴趣的:(Python小玩意/课堂作业,python,开发语言,单片机)