Skip to content
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

Cannot read data from serial when no longer connected #9609

Open
bbilger opened this issue Sep 10, 2024 · 1 comment
Open

Cannot read data from serial when no longer connected #9609

bbilger opened this issue Sep 10, 2024 · 1 comment
Milestone

Comments

@bbilger
Copy link

bbilger commented Sep 10, 2024

CircuitPython version

Adafruit CircuitPython 9.1.3 on 2024-08-29; Adafruit Feather RP2040 USB Host with rp2040

Code/REPL

import time
import usb_cdc

serial = usb_cdc.data
# serial.reset_input_buffer() # ensure a clean initial state during testing
# serial.timeout = 0 # just to be sure but doesn't really change anything
while True:
    in_waiting = serial.in_waiting
    if in_waiting > 0:
        print(f'time={time.time()} connected={serial.connected} in_waiting={in_waiting} data={serial.readline()}')
    time.sleep(1)

Behavior

Sending data like this to the device works (note the sleep after the write!)

python -c 'import serial; import time; ser = serial.Serial("/dev/ttyACM1"); ser.write(b"hi\n"); time.sleep(2); ser.close();'
# time=1577838411 connected=True in_waiting=3 data=b'hi\n'                                                                                                                                                                                                                                                               

Sending data like this does NOT work (empty bytes). The data is there (in_waiting > 0) but it can't be read

python -c 'import serial; import time; ser = serial.Serial("/dev/ttyACM1"); ser.write(b"hi\n"); ser.close();'
# time=1577838507 connected=False in_waiting=3 data=b''                                                                                                                                                                                                                                                                
# time=1577838508 connected=False in_waiting=3 data=b''
# ...

As soon as one does establish a connection (without writing new data), the data from the previous command can be read

python -c 'import serial; import time; ser = serial.Serial("/dev/ttyACM1"); time.sleep(2); ser.close();'
# time=1577838525 connected=True in_waiting=3 data=b'hi\n'      

Description

It seems like the read* functions only return data when a sender is connected. The data that was received (in_waiting > 0) should, however, be readable even if the sender disconnected before the device was able to read it.

Additional information

It's irrelevant whether readline() or read(in_waiting) is used. The current behavior is especially problematic since one cannot send data doing something like this: echo 'hi' > /dev/ttyACM1.

@bbilger bbilger added the bug label Sep 10, 2024
@tannewt tannewt added the usb label Sep 11, 2024
@tannewt tannewt added this to the Long term milestone Sep 11, 2024
@bbilger
Copy link
Author

bbilger commented Sep 11, 2024

In case anyone else runs into this, my current workaround is to write something back from the device (serial.write(b'ok\n')) after read, and make the sender wait and as such keep the connection open until it receives the response:

python -c 'import serial; import time; ser = serial.Serial("/dev/ttyACM1"); ser.write(b"hi\n"); print(ser.readline()); ser.close();'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants