简体   繁体   English

Python代码从串口连续接收变量数据

[英]Python code to receive variable data continuously from serial port

I have Python 2.7.4 and pyserial-2.5 win32 installed on my PC.我的 PC 上安装了 Python 2.7.4 和 pyserial-2.5 win32。 Here I am using a microcontroller device as a master (primary) and my pc as a slave (secondary).在这里,我使用微控制器设备作为主设备(主设备),而我的电脑作为从设备(辅助设备)。 Here every time microcontroller will transmit data, and my PC has to receive the data through serial port.这里每次微控制器都会传输数据,我的电脑必须通过串口接收数据。 I want a code in Python to receive continuous data.我想要一个 Python 代码来接收连续数据。 Here the transmitted data size will vary all the time.这里传输的数据大小将一直变化。 Here I wrote a code to transmit data, and the code is这里我写了一段代码来传输数据,代码是

import serial
ser= serial.serial("COM10", 9600)
ser.write("Hello world\n")
x = ser.readline()
print(x)     

With this code I can transmit data to the other PC, I crosschecked by opening HyperTerminal on the other PC and I can see the transmitted data (hello world).使用此代码,我可以将数据传输到另一台 PC,通过在另一台 PC 上打开超级终端进行交叉检查,我可以看到传输的数据(hello world)。

I also wrote the code to receive data:我还写了接收数据的代码:

import serial
ser=serial.serial("COM10", 9600)  
while 1:
if ser.inwaiting():
val = ser.readline(ser.inwaiting())
 print(val)  

if I send the data (how are you) from HyperTerminal, I can receive the data in my PC, with the above code.如果我从超级终端发送数据(你好吗),我可以用上面的代码在我的 PC 中接收数据。

Until this every thing is fine.直到这一切都很好。

My question now is, when the microcontroller is transmitting variable data at variable time periods, I need to receive that data in my PC with Python.我现在的问题是,当微控制器在可变时间段传输可变数据时,我需要使用 Python 在我的 PC 中接收该数据。 Do I need to use a buffer to store the received data?我是否需要使用缓冲区来存储接收到的数据? If yes, how will the code be?如果是,代码将如何? Why and how to use a buffer in Python?为什么以及如何在 Python 中使用缓冲区? According to my search in internet, buffer is used to slice the string.根据我在互联网上的搜索,缓冲区用于对字符串进行切片。

Typically what you do for communicating with a micro is to use single characters for something lightweight or create a communication protocol.通常,您与微型通信所做的工作是使用单个字符表示轻量级或创建通信协议。 Basically you have a start flag, end flag, and some sort of checksum to make sure the data gets across correctly.基本上,您有一个开始标志、结束标志和某种校验和,以确保数据正确传递。 There are many ways to do this.有很多方法可以做到这一点。

The below code is for Python 3. You may have to make changes for bytes data.以下代码适用于 Python 3。您可能需要对字节数据进行更改。

# On micro
data = b"[Hello,1234]"
serial.write(data)

On the computer you would run在您将运行的计算机上

def read_data(ser, buf=b'', callback=None):
    if callback is None:
        callback = print

    # Read enough data for a message
    buf += ser.read(ser.inwaiting()) # If you are using threading +10 or something so the thread has to wait for more data, this makes the thread sleep and allows the main thread to run.
    while b"[" not in buf or b"]" not in buf:
        buf += ser.read(ser.inwaiting())

    # There may be multiple messages received
    while b"[" in buf and b']' in buf:
        # Find the message
        start = buf.find(b'[')
        buf = buf[start+1:]
        end = buf.find(b']')
        msg_parts = buf[:end].split(",") # buf now has b"Hello, 1234"
        buf = buf[end+1:]

        # Check the checksum to make sure the data is valid
        if msg_parts[-1] == b"1234": # There are many different ways to make a good checksum
            callback(msg_parts[:-1])

   return buf

running = True
ser = serial.serial("COM10", 9600)
buf = b''
while running:
    buf = read_data(ser, buf)

Threading is useful if you are using a GUI.如果您使用 GUI,线程处理很有用。 Then you can have your thread read data in the background while your GUI displays the data.然后您可以让您的线程在后台读取数据,同时您的 GUI 显示数据。

import time
import threading

running = threading.Event()
running.set()
def thread_read(ser, callback=None):
    buf = b''
    while running.is_set():
        buf = read_data(ser, buf, callback)

def msg_parsed(msg_parts):
    # Do something with the parsed data
    print(msg_parsed)

ser = serial.serial("COM10", 9600)
th = threading.Thread(target=thread_read, args=(ser, msg_parsed))
th.start()


# Do other stuff while the thread is running in the background
start = time.clock()
duration = 5 # Run for 5 seconds
while running.is_set():
    time.sleep(1) # Do other processing instead of sleep
    if time.clock() - start > duration
        running.clear()

th.join() # Wait for the thread to finish up and exit
ser.close() # Close the serial port

Note that in the threading example I use a callback which is a function that gets passed as a variable and gets called later.请注意,在线程示例中,我使用了一个回调函数,该函数作为变量传递并稍后调用。 The other way this is done is by putting the data in a Queue and then processing the data in the Queue in a different part of the code.另一种方法是将数据放入队列,然后在代码的不同部分处理队列中的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM