-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
open() returns before port is ready #329
Comments
Consider this (over simplified) code:
Running this in a terminal while having another terminal open in read produces the expected result, the write operation is performed immediately. So, the open() method actually returns when the port is ready. Now, I'm no expert, but I think the issue that you are having has nothing to do with how the pyserial library reports port readiness, but rather with how serial buffers are managed along the transmission line. A (rudimental) solution to your situation might be to just wait for the first byte and then attempt to read, like so:
|
Thanks for the response Riccardo. Your example (the immediate write of b'aaa') works because write() blocks until the port is ready. Try it with some non-blocking function, such as flushInput() or (non-blocking read()) when you know there is something in the input buffer. It will fail to empty (or read) it unless you wait for a while after opening. I'd be curious to know if the behavior is the same in *nix as it is in Windows. |
Hello @jimbo1969, Have a look at the following code:
This produces the following outcome:
However, if you move the sleep statement, like this:
It outputs:
Of course, I'm going at default baud (9600?) on a Linux PC with two real serial ports cross-connected, so it's probably attempting to read too soon. It doesn't look like your specific case though. I don't have a windows machine to try it myself; just out of curiosity, would you mind running something like that on your machine? Thank you, |
Riccardo, Thanks, |
Hi Jim, For now, I can only confirm that this also happens to me under Linux, regardless of whether I use the in_waiting value or a fixed value (provided I set the timeout to zero). I'll update when I know more. Bye, |
Thanks Riccardo, but what you did doesn't actually confirm that the issue at hand happens in Linux. Your sample writes to one serial port, and then immediately tries to read that data from another, connected, serial port, without any delay between the write and the read. I'm not sure that is unexpected behavior. The issue discussed here involves writing to a serial port that is connected to another serial port, like in your case, but then going and having a cup of coffee, and then coming back and reading from the connected port immediately after opening it, but long after we know it has had ample opportunity to receive & buffer what we sent to it (much) earlier. To confirm, I opened a TeraTerm serial port on COM12 (with no flow control), which is connected to COM13. Using TeraTerm, I send a handful of random characters, which I record for posterity. Then I close TeraTerm, to ensure that it isn't simply buggy and waiting for some RTS signal or something from the other end. Then I answer an email to kill some time. Then I run my Python test script that I posted in the first post here, on COM13, which is attached to COM12. The result: I suspect there is double-buffering occurring. Is, perhaps, the OS buffering serial input on the port, followed by pyserial opening it at that level and returning control to Python, while the OS then asynchronously starts dumping the contents of its own buffer into pyserial's input buffer? If so, can anyone explain, for curiosity's sake why we get just the oldest two bytes from that buffer when the other end has long disconnected, but a larger number of bytes when the other end is still present, even though there is no flow control turned on? Or more importantly, how to avoid getting leftover garbage in the response when I reopen a closed pyserial connection, write to it, and then read the response from the remote device? (my sleep() workaround is a cheesy and ultimately unreliable non-solution, it seems) Thanks, |
I'm having the same issue. If I try to write to the serial port right after open, it will fail silently. ser = serial.Serial(port, 57600, timeout=7)
time.sleep(2)
ser.write("\nR{}\n".format(pulses).encode("ascii", "ignore")) |
Also having this issue, with MacOS Mojava and a RaspPi. A delay of around 2 seconds is needed in order for comms (write fixed length message, get fixed length reply) to happen with an embedded device. I should add that my serial device is an FT232R USB UART, is this a common factor with other experiencing this delay? |
Same issue here. Fixed delay is the only workaround. My setup:
Tried software flow control, hardware flow control, setting read/write-timeout. In addition I put As a workaround I need to wait for 2 seconds (1 is not enough) and then I can query with the device with read delays of about 30 ms no problem. If you need to have something tested on my setup, just let me know! |
Chiming in on this as well. This code works:
and appropriately returns:
Where this code does not work:
and returns:
Arduino Code for reference:
What seems counter-intuitive is that the Serial object is returned before its ready to be written to. Is there a way to block the process until its completely instantiated? |
try |
Seems to be some common experience. It'd be great to hear from the developer, some activity from a couple of months back, but the releases are now quite old. Did anybody dive into the code and have a look, I haven't yet. |
@harryberlin the b isn't a typo and instead it controls python sending the data as byte-encoded. EX: If I leave it out, I get the error message:
|
For anybody who comes across this thread and is working with an arduino type microcontroller, the issue is not with pyserial. The arduino will auto reset when the serial port connection is opened. I believe that this is the cause of the delay. If you watch the onboard leds when you connect, you should be able to confirm that is the case. Experimenting a little bit, setting dsrdtr=True when creating the connection seems to stop the auto resetting on an arduino uno (windows 10) and may be a work around. |
You can stop Arduino from resetting by using a 1uF -10uF capacitor between ground and reset. You will need to remove it in order to upload new code into the Arduino. |
Use pure C code to test, also have same problem, I use HL-340 usb-serial. |
When opening a pyserial port and immediately reading from it or flushing it or whatever, the immediate action fails silently. To reproduce (note mine is Windows 10, python 3.5, but I've seen reports of the same behavior on Linux):
Output will be:
Desired Output:
The text was updated successfully, but these errors were encountered: