使用串口工具python包时如何打开串口

时间:2019-01-06 14:54:53

标签: python python-3.x tkinter pyserial

我一直试图在与Arduino连接的python外壳(通过USB端口连接到我的笔记本电脑)中显示temperature sensor

我正在尝试使用python包serial.tools.list_ports获取串行端口的值,但同时使用下面提到的代码

np.array(t).flatten()

我必须面对无法打开串行端口的错误。

import serial
import json
import tkinter
from tkinter import messagebox
from tkinter import *
import tkinter as ttk
import serial.tools.list_ports

ard = serial.Serial();
root = ttk.Tk()
root.title("Read Sensor")

B = None
C = None 
ser_dict = {}

# Add a grid
mainframe = Frame(root)
mainframe.grid(column=0,row=0, sticky=(N,W,E,S) )
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
mainframe.pack(pady = 100, padx = 100)

# Create a Tkinter variable
tkvar1 = StringVar(root)
tkvar = StringVar(root)

#Serial Port
a=serial.tools.list_ports.comports()
for w in a:
    print(w.device)
    k = [w.device]
    print(k)
ser_dict = { i for i in k }
print (ser_dict)
val1 = tkvar1.get()
if val1 in ser_dict:
    ard.port = str (ser_dict[val1])
    ard.isOpen()
    if C:
        C.destroy()
        C = ttk.Button(root, text =val1, command = dropCall)
        C.pack()


# Dictionary with options
baud = { '9600','119200','34800'}

#Pop Up desciption
popupMenu1 = OptionMenu(mainframe, tkvar1, *ser_dict)
Label(mainframe, text="Serial Port").grid(row = 1, column = 1)
popupMenu1.grid(row = 2, column =1)

popupMenu2 = OptionMenu(mainframe, tkvar, *baud)
Label(mainframe, text="Baudrate").grid(row = 3, column = 1)
popupMenu2.grid(row = 4, column =1)


#Serial Callback Functions
def helloCallBack():
    k = ard.readline().decode('ascii');
    if(len(k)>0):
        print (k);
        size = len(k);
        #print (k[0:size-2]);
        print (size);
        messagebox.showinfo('Message From Arduino',k[0:size-2]+'\n'+str(size))  

#def portCall(*kargs):

   #global C
   #global ser_dict


#baudrate functions
def dropCall(*args):
   global B
   value = tkvar.get()
   ## using a dictionary instead of if statements
   ## to show how dictionaries are used
   baud_dict={'9600':value, '34800':value, '119200':value}
   if value in baud_dict:
      ard.baudrate = int(baud_dict[value])
      if B:
         B.destroy()
      B = ttk.Button(root, text =value, command = helloCallBack)
      B.pack()

#Link Function
tkvar.trace('w', dropCall)

对此的建议将有很大帮助。

1 个答案:

答案 0 :(得分:0)

请找到一些示例代码,该代码查找并打开与连接到串行端口的设备的串行端口连接。这已在Linux下使用Python 3.6进行了测试。它应该可以在Windows下运行,但我尚未对此进行测试。我使用PID和VID将附加设备选择为:

  1. 可能有几个活动的串行端口。
  2. 重新连接设备时,端口名称可能会更改。
  3. 它在不同的操作系统上更强大。 Windows将端口称为“ COMx”,而Linux使用端口“ ttyx”。

您的Arduino的PID和VID可能与我的示例不同。该脚本将列出所有已连接设备的PID和VID。将PID_VARIABLE和VID_VARIABLE更改为适用于Arduino的那个。

import logging
import serial
import serial.tools.list_ports as list_ports
from time import sleep

BAUD =  115200
PID_TARGET = 67
VID_TARGET= 9025
TIMEOUT = 0.1

logging.basicConfig(level=logging.DEBUG, format='%(message)s')


class SerialPort():
    def __init__(self, pid=PID_TARGET, vid=VID_TARGET, baud=BAUD, timeout=TIMEOUT):
        self.serial_port = self.open_serial_port(pid, vid, baud, timeout)


    def get_serial_data(self, serial_port):
        ''' get serial port data '''
        inWaiting = serial_port.inWaiting()
        read_bytes = serial_port.readline(inWaiting)
        if not read_bytes:
            return
        return read_bytes.decode()


    def get_serial_port(self):
        ''' Return the serial port. '''
        return self.serial_port


    def open_serial_port(self, pid=PID_TARGET, vid=VID_TARGET, baud=BAUD, timeout=TIMEOUT):
        ''' Open a serial connection. '''
        print('looking for attached microbit on a serial port')
        serial_port = serial.Serial(timeout=timeout)
        serial_port.baudrate = baud
        ports = list(list_ports.comports())
        print('scanning ports')
        ports.sort(reverse=True)
        for p in ports:
            print('pid: {} vid: {} device: {}'.format(p.pid, p.vid, p.device))
            if (p.pid == pid) and (p.vid == vid):
                print('found target device pid: {} vid: {} port: {}'.format(
                    p.pid, p.vid, p.device))
                serial_port.port = str(p.device)
        if not serial:
            print('no serial port found')
            return None
        try:
            serial_port.open()
            serial_port.flush()
            print('opened serial port: {}'.format(serial_port.port))
        except Exception as e:
            print('cannot open serial port: {}'.format(e))
            return None
        sleep(0.1)
        return serial_port


if __name__ == '__main__':
    print('instatiating SerialPort()')
    serial_port = SerialPort()
    print('finished')