代码之家  ›  专栏  ›  技术社区  ›  Schütze

Python3双向串行通信:读入数据

  •  6
  • Schütze  · 技术社区  · 7 年前

    我需要的是一种方便的实时方式。到目前为止,我有以下代码:

    import serial, time
    
    SERIALPORT = "/dev/ttyUSB0"
    BAUDRATE = 115200
    
    ser = serial.Serial(SERIALPORT, BAUDRATE)
    ser.bytesize = serial.EIGHTBITS #number of bits per bytes
    ser.parity = serial.PARITY_NONE #set parity check: no parity
    ser.stopbits = serial.STOPBITS_ONE #number of stop bits
    ser.timeout = None          #block read
    ser.xonxoff = False     #disable software flow control
    ser.rtscts = False     #disable hardware (RTS/CTS) flow control
    ser.dsrdtr = False       #disable hardware (DSR/DTR) flow control
    ser.writeTimeout = 0     #timeout for write
    
    print ("Starting Up Serial Monitor")
    
    try:
        ser.open()
    except Exception as e:
        print ("Exception: Opening serial port: " + str(e))
    
    if ser.isOpen():
        try:
            ser.flushInput()
            ser.flushOutput()
            ser.write("1\r\n".encode('ascii'))
            print("write data: 1")
            time.sleep(0.5)
            numberOfLine = 0
            while True:
                response = ser.readline().decode('ascii')
                print("read data: " + response)
                numberOfLine = numberOfLine + 1
                if (numberOfLine >= 5):
                    break
            ser.close()
        except Exception as e:
            print ("Error communicating...: " + str(e))
    else:
        print ("Cannot open serial port.")
    

    因此,在上面的代码中,我发送了“1”,它应该触发激光探测器的“getDistance()”函数,并返回以毫米为单位的距离。我在Putty上尝试了这个方法,它可以工作,返回最多4位数字的距离。然而,当我启动上述Python脚本时,我的输出只有以下内容:

    Starting Up Serial Monitor
    Exception: Opening serial port: Port is already open.
    write data: 1
    read data: 
    

    它会一直持续下去。没有读取数据或任何内容。

    我哪里弄错了?

    3 回复  |  直到 7 年前
        1
  •  7
  •   Schütze    7 年前

    显然,更简单的代码版本解决了这个问题。

    import serial
    import time
    
    ser = serial.Serial('/dev/ttyUSB0', 115200, timeout = 1) # ttyACM1 for Arduino board
    
    readOut = 0   #chars waiting from laser range finder
    
    print ("Starting up")
    connected = False
    commandToSend = 1 # get the distance in mm
    
    while True:
        print ("Writing: ",  commandToSend)
        ser.write(str(commandToSend).encode())
        time.sleep(1)
        while True:
            try:
                print ("Attempt to Read")
                readOut = ser.readline().decode('ascii')
                time.sleep(1)
                print ("Reading: ", readOut) 
                break
            except:
                pass
        print ("Restart")
        ser.flush() #flush the buffer
    

    Writing:  1
    Attempt to Read
    Reading: 20
    Restart
    Writing:  1
    Attempt to Read
    Reading:  22
    Restart
    Writing:  1
    Attempt to Read
    Reading:  24
    Restart
    Writing:  1
    Attempt to Read
    Reading:  22
    Restart
    Writing:  1
    Attempt to Read
    Reading:  26
    Restart
    Writing:  1
    Attempt to Read
    Reading:  35
    Restart
    Writing:  1
    Attempt to Read
    Reading:  36
    
        2
  •  1
  •   Alton Campbell    7 年前

    在我看来,你的 ser.timeout = None 可能是这里出了问题。您的第一个周期 while 循环似乎很顺利,但您的程序在尝试时挂起 ser.readline() 这是第二次。

    有几种方法可以解决这个问题。我更喜欢的方法是指定一个非- None 序列号readline() 即使设备不发送结束行字符也返回值。

    另一种方法是改变你的 序列号readline() 像这样 ser.read(ser.in_waiting) ser.read(ser.inWaiting())

        3
  •  1
  •   Reyhaneh Torab    5 年前

    try:
      ser = serial.Serial("/dev/ttyS0", 9600) #for COM3
      ser_bytes = ser.readline()
      time.sleep(1)
      inp = ser_bytes.decode('utf-8')
      print (inp)
    except:
      pass