Python通过RS232通讯控制步进电机

@DIY李小龙图标的串口调试助手!
在这里插入图片描述
在这里插入图片描述

Python有强大的serial库,可以直接使用,已通过串口指令测试控制步进电机,转速,转向,相对位移,更改波特率等操作。

安装的时候是pyserial, pycharm安装页面如下:

在这里插入图片描述

实际调用的时候是 serial

import serial  #安装的是pyserial

先上一段测试视频:

Python制作的串口助手控制步进电机

DIY龙哥图标和图片

# 插入李小龙图片 ^_^
        self.photo = PhotoImage(file='bruce.png')
        self.photo_label = Label(self.init_window_name, image=self.photo)
        self.photo_label.place(x=40, y=280)

也添加了自己的网址

# 加入超链接
        def open_url(event):
            webbrowser.open_new("https://www.stepping-motor.cn")
        self.signature_label.bind("<Button-1>", open_url)

最后就是通过打包工具pyinstaller生成exe文件

pyinstaller -F -w -i logo.ico bruce.py

bruce.exe

在这里插入图片描述

拒绝套路,全部代码如下:

import tkinter
from tkinter import ttk, scrolledtext
from tkinter import *
import threading
import time
from datetime import datetime
import serial  #安装的是pyserial
import serial.tools.list_ports
import re
import webbrowser

class MY_GUI():

    # 构造函数
    def __init__(self, name):
        self.init_window_name = name
        self.connected = False

    # 窗口控件设置初始化
    def set_init_window(self):

        self.init_window_name.title('Bruce(ComHelper)')
        self.init_window_name.geometry('740x620+220+10')
        self.init_window_name.resizable(False, False)
        self.init_window_name.attributes('-alpha', 1)

        # 新添加icon
        self.init_window_name.iconbitmap('wu.ico')

        # 串口选择控制框架
        self.com_choose_frame = Frame(self.init_window_name, width=10, height=100)
        self.com_choose_frame.place(x=20, y=12)
        # 1串口号标签
        self.com_label = Label(self.com_choose_frame, text='Serial Port: ')
        self.com_label.grid(row=1, column=0, sticky=W)
        # 串口号下拉框
        self.com_choose = StringVar()
        self.com_choose_combo = ttk.Combobox(self.com_choose_frame, width=12, textvariable=self.com_choose)
        self.com_choose_combo['state'] = 'readonly'
        self.com_choose_combo.grid(row=1, column=1, sticky=W + E, padx=12)
        self.com_choose_combo['values'] = self.com_name_get()
        # 串口框架内部按钮
        self.connect_button = Button(self.com_choose_frame, text='Open', bg='lightblue', width=12,
                                     command=self.com_connect)
        self.connect_button.grid(row=1, column=3, columnspan=2, padx=1, pady=4)

        # 2波特率标签
        self.baudrate_label = Label(self.com_choose_frame, text='Baud Rate: ')
        self.baudrate_label.grid(row=2, column=0, sticky=W, padx=2)
        # 波特率选项框
        self.baudrate_value = StringVar(value='9600')
        self.baudrate_choose_combo = ttk.Combobox(self.com_choose_frame, width=12, textvariable=self.baudrate_value)
        self.baudrate_choose_combo['values'] = ('4800', '9600', '19200', '38400', '57600', '115200')
        self.baudrate_choose_combo['state'] = 'readonly'
        self.baudrate_choose_combo.grid(row=2, column=1, sticky=W, padx=12)
        self.buttonN1 = Button(self.com_choose_frame, text='Confirm', bg='lightblue', width=12,
                               command=self.get_baudrate)
        self.buttonN1.grid(row=2, column=3, columnspan=2, padx=1, pady=4)
        # 3数据位标签
        self.bytesize = Label(self.com_choose_frame, text='Byte Size: ')
        self.bytesize.grid(row=3, column=0, sticky=W, padx=2)
        # 数据位选项框
        self.bytesize_value = StringVar(value='8')
        self.bytesize_choose_combo = ttk.Combobox(self.com_choose_frame, width=12, textvariable=self.bytesize_value)
        self.bytesize_choose_combo['values'] = ('5', '6', '7', '8')
        self.bytesize_choose_combo['state'] = 'readonly'
        self.bytesize_choose_combo.grid(row=3, column=1, padx=2)
        self.buttonN2 = Button(self.com_choose_frame, text='Confirm', bg='lightblue', width=12, command=self.get_bytesize)
        self.buttonN2.grid(row=3, column=3, columnspan=2, padx=1, pady=4)
        # 4停止位标签
        self.stopbits = Label(self.com_choose_frame, text='Stop Bits: ')
        self.stopbits.grid(row=4, column=0, sticky=W, padx=2)
        # 停止位选项框
        self.stopbits_value = StringVar(value='1')
        self.stopbits_choose_combo = ttk.Combobox(self.com_choose_frame, width=12, textvariable=self.stopbits_value)
        self.stopbits_choose_combo['values'] = ('1', '1.5', '2')
        self.stopbits_choose_combo['state'] = 'readonly'
        self.stopbits_choose_combo.grid(row=4, column=1, padx=2)
        self.buttonN3 = Button(self.com_choose_frame, text='Confirm', bg='lightblue', width=12, command=self.get_stopbits)
        self.buttonN3.grid(row=4, column=3, columnspan=2, padx=1, pady=4)
        # 5校验位标签
        self.parity = Label(self.com_choose_frame, text='CRC: ')
        self.parity.grid(row=5, column=0, sticky=W, padx=4)
        # 校验位选项框
        self.parity_value = StringVar(value='None')
        self.parity_choose_combo = ttk.Combobox(self.com_choose_frame, width=12, textvariable=self.parity_value)
        self.parity_choose_combo['values'] = ('None', 'Odd', 'Even', 'Mark', 'Space')
        self.parity_choose_combo['state'] = 'readonly'
        self.parity_choose_combo.grid(row=5, column=1, padx=2, pady=2)
        self.buttonN1 = Button(self.com_choose_frame, text='Confirm', bg='lightblue', width=12, command=self.get_CRC)
        self.buttonN1.grid(row=5, column=3, columnspan=2, padx=1, pady=4)
        # 6 发送标签输入框和按钮
        self.command_label = Label(self.com_choose_frame, text='Command: ')
        self.command_label.grid(row=6, column=0, sticky=W, padx=4)
        self.command = Entry(self.com_choose_frame, width=15)
        self.command.insert(0, "ENA;")
        self.command.grid(row=6, column=1, padx=2, pady=2)

        self.command_send = Button(self.com_choose_frame, text='Send', bg='lightblue', width=12, command=self.com_send)
        self.command_send.grid(row=6, column=3, columnspan=2, padx=1, pady=4)


        # 插入签名,超链接和龙哥图片
        self.signature_label = Label(self.init_window_name, text='  www.stepping-motor.cn', font=('Monospace', 14),  cursor="hand2")
        self.signature_label.place(x=20, y=580)
        # 签名加入超链接
        def open_url(event):
            webbrowser.open_new("https://www.stepping-motor.cn")
        self.signature_label.bind("<Button-1>", open_url)
        # 插入李小龙图片 ^_^
        self.photo = PhotoImage(file='bruce.png')
        self.photo_label = Label(self.init_window_name, image=self.photo)
        self.photo_label.place(x=40, y=280)
        # 处理结果显示滚动文本框
        self.result_data_label = Label(self.init_window_name, text='  Output & Result')
        self.result_data_label.place(x=360, y=19)
        self.clear_button = Button(self.init_window_name, text='Clear', bg='lightblue', width=12,
                                   command=self.clear_result_text)
        self.clear_button.place(x=480, y=14)
        self.result_text = scrolledtext.ScrolledText(self.init_window_name, width=48, height=42)
        self.result_text.place(x=360, y=50)

    # 自动获取当前连接的串口名
    def com_name_get(self):
        self.port_list = list(serial.tools.list_ports.comports())
        self.com_port_names = []
        if len(self.port_list) > 0:
            for i in range(len(self.port_list)):
                self.com_name = str(self.port_list[i])
                self.com_port_names.append(self.com_name)
        return self.com_port_names

    # 打开串口按键的执行内容
    def com_connect(self):
        if self.connected:
            self.com_cancel()
            return
        self.ser_name = str(self.com_choose.get())
        for i in range(len(self.port_list)):
            if self.ser_name == str(self.port_list[i]):
                self.ser_name, desc, hwid = self.port_list[i]
        self.result_text.insert(END, f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]}: connecting {self.ser_name}\n")
        self.ser_baudrate = int(self.baudrate_value.get())
        self.ser_bytesize = int(self.bytesize_value.get())
        self.ser_stopbits = float(self.stopbits_value.get())
        self.ser_parity = str(self.parity_value.get())[0:1]
        try:
            self.ser = serial.Serial(port=self.ser_name, baudrate=self.ser_baudrate, bytesize=self.ser_bytesize,
                                     parity=self.ser_parity, stopbits=self.ser_stopbits)
            self.ser.timeout = 0.01
            self.result_text.insert(END, f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]}: {self.ser_name} connected\n")
            #参数显示下^_^
            self.result_text.insert(END, f"Baud Rate: {self.get_baudrate()}\n")
            self.result_text.insert(END, f"Byte Size: {self.get_bytesize()}\n")
            self.result_text.insert(END, f"Stop Bits: {self.get_stopbits()}\n")
            self.result_text.insert(END, f"CRC: {self.get_CRC()}\n")

            self.result_text.see(tkinter.END)
            self.result_text.update()
            # 按钮变成“关闭串口”
            self.connected = True
            self.connect_button['text'] = 'Close'
            # 开启接收串口数据线程
            self.ReadUARTThread = threading.Thread(target=self.ReadUART, daemon=True)
            self.ReadUARTThread.start()
        except:
            newline = f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]}: {self.ser_name}connection failed\n"
            self.result_text.insert(END, newline)
            self.result_text.see(tkinter.END)
            self.result_text.update()

    # 关闭串口按键的执行内容
    def com_cancel(self):
        try:
            self.ser.close()
            # 按钮变成“打开串口”
            self.connected = False
            self.connect_button['text'] = 'Open'
        except:
            newline = time.ctime(time.time()) + ':' + "Serial Port is not connected" + '\n'
            self.result_text.insert(END, newline)
            self.result_text.see(tkinter.END)
            self.result_text.update()

    def clear_result_text(self):
        self.result_text.delete('1.0', END)

    def ReadUART(self):
        try:
            while self.connected:
                newline = self.ser.readline()  # 字节类型
                if newline:
                    # print(newline)
                    self.result_text.insert(END,
                                            f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]}{newline.decode('gbk')}\n")
                    self.result_text.see(tkinter.END)
                    self.result_text.update()
        except:
            # print(e)
            newline = f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]}: {self.ser_name} is closed\n"
            self.result_text.insert(END, newline)
            self.result_text.see(tkinter.END)
            self.result_text.update()
    # 确认波特率等参数
    def get_baudrate(self):
        return self.baudrate_value.get()
    def get_bytesize(self):
        return self.bytesize_value.get()
    def get_stopbits(self):
        return self.stopbits_value.get()
    def get_CRC(self):
        return self.parity_value.get()

    def com_send(self):
        data = self.command.get()
        if data:
            self.writeSerial(data)

    def writeSerial(self, data):
        try:
            if self.connected and self.ser:
                # print(data)
                self.ser.write(data.encode('gbk'))
                self.ser.flush()
                newline = f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]}{data}\n"
                self.result_text.insert(END, newline)
                self.result_text.see(tkinter.END)
                self.result_text.update()
        except:
            newline = f"{datetime.now().strftime('%H:%M:%S.%f')[:-3]}: {self.ser_name} data is not sent\n"
            self.result_text.insert(END, newline)
            self.result_text.see(tkinter.END)
            self.result_text.update()

# 主线程
def start():
    init_window = Tk()
    my_window = MY_GUI(init_window)
    my_window.set_init_window()
    init_window.mainloop()

start()
# 打包生成exe : pyinstaller -F -w -i logo.ico bruce.py

所需的文件在百度网盘里,py文件写好后,同目录下还需这两文件bruce.png 和 wu.ico

在这里插入图片描述

链接:https://pan.baidu.com/s/1-7gKzXF0sJyqnvw2WZoCmA

提取码:8h8q

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值