zoukankan      html  css  js  c++  java
  • python串口助手

      最近项目中要使用模拟数据源通过向外发送数据,以前都是用C#编写,最近在研究python,所以就用python写了一个串口助手,方便以后的测试。

           在电脑上通过虚拟串口助手产生两个虚拟串口,运行编写的串口助手

    另外,打开一个串口调试助手,辅助测试

     

      两者互发数据,可以看到编写的串口助手能够正常接收发送,并且在后台我们也把接收到的数据打印了出来

     

    下面先讲解关于界面的代码,这里只是简单的使用tkinter做界面,如果想要更好的界面效果,可以尝试一下QT。

    首先是界面中串口设置区域的代码,界面布局统一用grid来布局,当然也有其他的布局方法

     1 #-------------------------------------------------------------------------
     2 #面板布局区
     3 root = Tk()
     4 root.title('xutopia 公众号:洛水梅家')
     5 
     6 #-------------------------------------------------------------------------
     7 #串口设置区
     8 label_com = Label(root, text="串口号", height=2).grid(row=0, column=0)
     9 label_bps = Label(root, text="波特率", height=2).grid(column=0, row=1)
    10 label_datBit = Label(root, text="数据位", height=2).grid(column=0, row=2)
    11 label_parity = Label(root, text="校验位", height=2).grid(column=0, row=3)
    12 label_stop_bit = Label(root, text="停止位", height=2).grid(column=0, row=4)

    接下来是串口号的combobox的设置,其中serialPortFile.GetCom()是获取所有串口号的函数,接下来会讲解

    #串口号
    varPort = StringVar()
    combo_com = ttk.Combobox(root, textvariable=varPort, width=8, height=2, justify=CENTER)
    serial_com = serialPortFile.GetCom()
    combo_com['values'] = serial_com
    #combo_com.bind("<<ComboboxSelected>>", lambda event: combo1_handler(var=varPort.get()))
    combo_com.current(0)
    combo_com.grid(column=1, row=0)

     1 #波特率
     2 varBitrate = StringVar()
     3 combo_bps = ttk.Combobox(root, textvariable=varBitrate, width=8, height=2, justify=CENTER)
     4 combo_bps['values'] = ("9600", "19200", "38400", "115200")
     5 #combo_bps.bind("<<ComboboxSelected>>", lambda event: combo2_handler(var=varBitrate.get()))
     6 combo_bps.current(0)
     7 combo_bps.grid(column=1, row=1)
     8 #数据位
     9 combo_byteBit = ttk.Combobox(root, width=8, height=2, justify=CENTER)
    10 combo_byteBit['values'] = ("5", "6", "7", "8")
    11 combo_byteBit.current(3)
    12 combo_byteBit.grid(column=1, row=2)
    13 #奇偶校验
    14 combo_parity = ttk.Combobox(root, width=8, height=2, justify=CENTER)
    15 combo_parity['values'] = ("N", "O", "E")
    16 combo_parity.current(0)
    17 combo_parity.grid(column=1, row=3)
    18 #停止位
    19 combo_stopBit = ttk.Combobox(root, width=8, height=2, justify=CENTER)
    20 combo_stopBit['values'] = ("1", "1.5", "2")
    21 combo_stopBit.current(0)
    22 combo_stopBit.grid(column=1, row=4)
    23 serialPortFile.text_rx = Text(root,width=70,height=20)
    24 serialPortFile.text_rx.grid(row=0,column=3,rowspan=5)
    25 serialPortFile.text_rx.insert(END,'这是一个xutopia用python编写的串口助手,公众号:洛水梅家
    ')
    26 text_tx = Text(root,width=70,height=10)
    27 text_tx.grid(row=5,column=3,rowspan=2)
    28 text_tx.insert(END,'xutopia 公众号:洛水梅家,发送数据12345,上山打老虎')
    29 button_send = Button(root, text='send', width=18, height=1)
    30 button_send.bind("<Button-1>", lambda event: serialPortFile.usart_sent(var=text_tx.get("0.0", "end")))
    31 button_send.grid(column=1, row=6)
    32 #串口开关按钮
    33 serialPortFile.button_var = StringVar()
    34 serialPortFile.button_var.set("打开串口")
    35 buttonOpenCom = Button(root, textvariable=serialPortFile.button_var, width=18, height=1)
    36 buttonOpenCom.bind("<Button-1>", lambda event: serialPortFile.usart_ctrl(combo_com.get(), combo_bps.get(),combo_parity.get(),combo_stopBit.get(),combo_byteBit.get()))
    37 buttonOpenCom.grid(column=1, row=5)

    以上就是界面相关的代码,最终效果也就是上图显示的效果,很简单。接下来介绍python串口的逻辑代码部分。在另外一个模块中serialPortFile.py

    获取电脑中所有的串口号的函数,注意这里通过serial.tools.list_ports.comports()获取所有的串口号之后进行了一步转换,存在一个数组中,这样,传入serial中才能被识别。

     1 # 获取并存储串口号到数组
     2 def GetCom():
     3     port_list = list(serial.tools.list_ports.comports())
     4     print(len(port_list))
     5     portcnt = len(port_list)
     6     serial_com = []
     7     for m in range(portcnt):
     8         port_list_1 = list(port_list[m])
     9         serial_com.append(port_list_1[0])
    10     return serial_com

    串口打开关闭函数,串口打开之后创建了一个线程threading,线程中一直监视串口的状态,一旦接受到数据,就把数据显示到接受数据显示框中。有关python线程threading的内容可以在我的公众号,洛水梅家中查看。

    注意在代码中加了一个if ser.is_open:的条件判断,不加入这个条件的话,很有可能重复打开串口而报错误。

    同时在按键Button的状态也随着串口的开关状态而变化。

    def usart_ctrl(com, bps,parity_,stopbits_,bytesize_):
        #print(__file__, sys._getframe().f_lineno, port_, bitrate_, var.get())
        global ser, button_var
        if button_var.get() == "打开串口":
            button_var.set("关闭串口")
            ser = serial.Serial(
                port=com,
                baudrate=int(bps),
                parity=parity_,
                timeout=0.2,
                stopbits=float(stopbits_),
                bytesize=int(bytesize_))
            if ser.is_open:
                pass
            else:
                ser.open()
            recv_data = threading.Thread(target=thread_recv)
            recv_data.start()
        else:
            button_var.set("打开串口")
            if ser.is_open:
                ser.close()
            else:
                pass
    def usart_sent(var):
        #print(__file__, sys._getframe().f_lineno, "-->", var)
        print(var)
        if ser.is_open:
            ser.write(var.encode("gb2312"))
    def thread_recv():
        global text_rx
        while True:
            try:
                read = ser.readall()
                if len(read) > 0:
                    print(bytes(read).decode('gb2312'))
                    # print(__file__, sys._getframe().f_lineno, "<--", bytes(read).decode('ascii'))
                    text_rx.insert(END,bytes(read).decode('gb2312'))
            except Exception as e:
                print(e)
                time.sleep(1)
                pass

    上面就是关于串口助手的所有代码介绍,更多详细内容,关注公众号 洛水梅家 免费获取源码

    后台回复python_com,免费获取源码

  • 相关阅读:
    ThreeJS中的点击与交互——Raycaster的用法
    threejs地球之后:动画的控制
    threejs创建地球
    3d模型一般怎么导入到到Threejs中使用
    用three.js开发三维地图实例
    threejs使用各种坑实验过程
    用threejs实现三维全景图
    用threejs 实现3D物体在浏览器展示
    小议线程之单线程、多线程、线程池
    小谈MVC 模式
  • 原文地址:https://www.cnblogs.com/xutopia/p/11651045.html
Copyright © 2011-2022 走看看