pyserial / pyserial-asyncio

asyncio extension package for pyserial
Other
249 stars 65 forks source link

What is the expected response time of asyncio-serial? #100

Open zapta opened 1 year ago

zapta commented 1 year ago

I am using a simple test program to measure the latency of asyncio-serial and the stack below it. The test program, in --no-master mode, sends back every data it receives, and I measure the time difference between the incoming and outgoing on the wire using a logic analyzer.

The latency I get is ~15ms on a Windows 10 with an FTDI USB/Serial interface. Is this reasonable?

BTW, If I use an Arduino echo program instead, I get latency of ~50us.

import argparse
import asyncio
import serial_asyncio

parser = argparse.ArgumentParser()
parser.add_argument("--port", dest="port", default=None, help="Serial port to use.")
parser.add_argument('--master',
                    dest="master",
                    default=False,
                    action=argparse.BooleanOptionalAction)
args = parser.parse_args()

class SerialProtocol(asyncio.Protocol):
    def __init__(self):
        self.__transport = None

    def connection_made(self, transport):
        print(f"port opened", flush=True)
        self.__transport = transport
        transport.serial.rts = False

    def data_received(self, data: bytes):
        if args.master:
            print(f"Master rx", flush=True)
        else:
            # print(f"Slave rx/tx", flush=True)
            self.__transport.write(data)

    def connection_lost(self, exc):
        print('port closed', flush=True)

    def pause_writing(self):
        print('Writing paused', flush=True)

    def resume_writing(self):
        print('Writing resumed', flush=True)

async def async_main():
    transport, protocol = await serial_asyncio.create_serial_connection(
        asyncio.get_event_loop(), SerialProtocol, args.port, 115200)
    while True:
        await asyncio.sleep(0.5)
        if args.master:
            print(f"Master tx", flush=True)
            transport.write(bytearray([0x55]))

print("Main started")
asyncio.run(async_main())
maljac commented 1 year ago

@zapta I was wondering if you found a solution for the latency.

I discovered the same ~15ms latency issue on a linux machine (RPi, FTDI USB/Serial). Even with setting USB Latency to 1 (see https://granitedevices.com/wiki/FTDI_Linux_USB_latency) I am still experiencing latency issues.

zapta commented 1 year ago

@maljac, I didn't find any solution, just living with it.

Your link is interesting. I will try it if I will find an equivalent configuration in Windows.

positron96 commented 4 months ago

Does it affect only asyncio library? Did you try it with a base pyserial?

I am now deciding on whether to use pyserial_asyncio, and I'd rather not have this latency.