【问题标题】:Inconsistent data logging from 3 serial ports using python.使用 python 从 3 个串行端口记录不一致的数据。
【发布时间】:2017-10-20 21:25:04
【问题描述】:

我正在使用 pyserial 同时从 3 个串行端口读取数据,并使用 python 将这些数据记录到 3 个单独的带时间戳的文本文件中。但是,经过一段时间(不到 5 分钟)后,写入文本文件的数据无法正确打印。

准确数据示例:

2017-10-16 10:41:27

传感器读数平均读数/平均左上角:1
7.00 0.14 midLeft: 2 8.00 0.25 botLeft: 3 9.00 0.33 topRight: 4 10.00
0.40 midRight: 5 11.00 0.45 botRight: 6 12.00 0.50

不准确数据示例:

2017-10-16 10:55:11

传感器读数 3 g 读数/平均 topLeft:1
7.00 0.14 midLeft: 2 8.00 0.25 botLeft: 3 9.00 00.50 ht: 4 10.00 0.40 midRight: 5 11.00
0.45 右下角:6 12.00 0.50 0.45 右下角:6 12.00 0.50

这是我正在使用的代码:

# to use microseconds, delete ".replace(microsecond = 0)"

## includes
from __future__ import print_function
import threading, serial, time, io, datetime
from serial import Serial

device1 = "_base_station" ## device name used for filename
addr1 = "COM39" ## edit serial port here

device2 = "_collector" ## device name used for filename
addr2 = "COM40" ## edit serial port here

device3 = "_receiver" ## device name used for filename
addr3 = "COM42" ## edit serial port here

baud = 57600 ## edit baud rate here

## function for initializing serial ports
def init_port(addr, baud):
    return serial.Serial(
        port = addr,\
        baudrate = baud,\
        parity=serial.PARITY_NONE,\
        stopbits=serial.STOPBITS_ONE,\
        bytesize=serial.EIGHTBITS,\
        timeout=.01)

## initialize serial ports
ser1 = init_port(addr1, baud)
ser2 = init_port(addr2, baud)
ser3 = init_port(addr3, baud)

## print port numbers so the user knows the script is working
print("Collecting data from port: " + ser1.portstr + "\r\n") ## give status update
print("Collecting data from port: " + ser2.portstr + "\r\n") ## give status update
print("Collecting data from port: " + ser3.portstr + "\r\n") ## give status update

def handle_data(ser, device):
    while True:
        line = ser.readline() ## get line from serial port
        filename = datetime.datetime.now().strftime("%Y-%m-%d-%H") + device + ".txt" ## create filename based on device and time. updates at midnight.
        filehandle = open(filename, 'a') ## append data to file.

        if str(line) == "#\r\n": ## logging delimiter
            filehandle.write("\r\n" + str(datetime.datetime.now().replace(microsecond = 0)) + "\r\n") ## start each data entry with a timestamp
        else:
            filehandle.write(str(line)[:-1]) ## log line (strip off extra line, data is already being parsed by line)
            filehandle.flush()

        filehandle.close() ## close file
    ser.close() ## close serial port

## create threads
thread1 = threading.Thread(target = handle_data, args = [ser1, device1])
thread2 = threading.Thread(target = handle_data, args = [ser2, device2])
thread3 = threading.Thread(target = handle_data, args = [ser3, device3])

## start threads
thread1.start()
thread2.start()
thread3.start()

我也尝试过使用多个没有线程的脚本,但同样的问题仍然存在。

关于为什么会发生这种情况的任何理论?有什么解决办法吗?

提前致谢。

【问题讨论】:

  • 在使用多线程或多处理时,最好使用成语:if __name__ == "__main__":
  • 看起来您正在同时写入同一个文件而没有任何同步。不过,为此启动多个进程或线程似乎有点过头了,你可以这样做stackoverflow.com/questions/16255807/…
  • 谢谢 pvg。看起来它正在写入同一个文件,但设备名称正在从线程参数传递给文件名。我会检查一下。另外,感谢亚伦。我是 Python 新手,欢迎大家提供帮助。
  • 文件名每次都是唯一的并不完全清楚,但您应该做的一件事就是完全去掉并发部分。在一段时间内使用固定文件名一次从一个端口读取而不使用线程,看看您的数据是否看起来不错。如果没有,你还有其他问题

标签: python pyserial


【解决方案1】:

超时看起来非常快,我会延长串口的超时时间。我怀疑您获得的碎片数据来自超时击败传入数据时。

def init_port(addr, baud):
    return serial.Serial(
        port = addr,\
        baudrate = baud,\
        parity=serial.PARITY_NONE,\
        stopbits=serial.STOPBITS_ONE,\
        bytesize=serial.EIGHTBITS,\
        timeout=1.0)

您正在使用 .readline(),它将寻找 '\n' 终止,但如果超过超时,它将提前退出。

【讨论】:

    猜你喜欢
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多