繁体   English   中英

Python串口监听器

[英]Python serial port listener

我已经开始使用 PySerial 编写一些代码来向串行设备发送和接收数据。

到目前为止,我一直致力于从终端启动事务并从串行设备接收响应。

伪:

main:
    loop:
        message = get_message()
        send_to_serial(message)
        time_delay(1 second)
        read_response()

现在,如果串行设备是发起通信的设备,我想在该端口上实现一个侦听器。 还要删除time_delay ,它可能最终太长,或者不足以让串行设备响应。

state = idle
register_interrupt(serial_device, read_response())

main:
    loop:
        message = get_message()
        state = sending
        send_to_serial(message)

到目前为止,我还没有发现任何使用中断进行通信的 PySerial 代码。

我只是不知道如何在 python 中设置任何类型的中断,怎么会

可以使用select模块在serial连接上进行选择:

import serial
import select

timeout = 10
conn = serial.Serial(serial_name, baud_rate, timeout=0)
read,_,_ = select.select([conn], [], [], timeout)
read_data = conn.read(0x100)

下面是在主线程中创建伪 tty 的完整示例。 主线程每隔 5 秒将数据写入 pty。 创建一个子线程,尝试使用select.select等待读取数据,以及使用正常的serial.Serial.read方法从 pty 读取数据:

#!/bin/bash

import os
import pty
import select
import serial
import threading
import time

def out(msg):
    print(msg, flush=True)

# child process
def serial_select():
    time.sleep(1)

    out("CHILD THREAD: connecting to serial {}".format(serial_name))
    conn = serial.Serial(serial_name, timeout=0)
    conn.nonblocking()

    out("CHILD THREAD: selecting on serial connection")
    avail_read, avail_write, avail_error = select.select([conn],[],[], 7)
    out("CHILD THREAD: selected!")

    output = conn.read(0x100)
    out("CHILD THREAD: output was {!r}".format(output))

    out("CHILD THREAD: normal read serial connection, set timeout to 7")
    conn.timeout = 7

    # len("GOODBYE FROM MAIN THREAD") == 24
    # serial.Serial.read will attempt to read NUM bytes for entire
    # duration of the timeout. It will only return once either NUM
    # bytes have been read, OR the timeout has been reached
    output = conn.read(len("GOODBYE FROM MAIN THREAD"))
    out("CHILD THREAD: read data! output was {!r}".format(output))

master, slave = pty.openpty()
serial_name = os.ttyname(slave)

child_thread = threading.Thread(target=serial_select)
child_thread.start()

out("MAIN THREAD: sleeping for 5")
time.sleep(5)

out("MAIN THREAD: writing to serial")
os.write(master, "HELLO FROM MAIN THREAD")

out("MAIN THREAD: sleeping for 5")
time.sleep(5)

out("MAIN THREAD: writing to serial")
os.write(master, "GOODBYE FROM MAIN THREAD")

child_thread.join()

PySerial 在内部使用 select 上的 read 方法(如果您在POSIX系统上),使用提供的超时。 但是,它将尝试读取 NUM 字节,直到已读取 NUM 字节总数或直到达到超时。 这就是为什么该示例从 pty 中显式读取len("GOODBYE FROM MAIN THREAD") (24 个字节)的原因,以便conn.read调用将立即返回而不是等待整个超时。

TL;DR可以使用带有select.select serial.Serial连接,我相信这是您正在寻找的。

暂无
暂无

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

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