Half-duplex serial communications in Python
Asked Answered
U

1

6

I have a device with a built-in USB/Serial adapter (shows up as a Prolific PL2303). The device documentation provides full details on how to communicate with it, and provides a sample Windows app. However, I need to use it on Linux - ideally with Python but I'm not too precious about that.

The device docs state the device runs at 9600, 8N1 with half duplex. The Windows app works fine - device works fine (so I know it's not a device problem). However, I can't communicate with it using Python on Linux. I'm using pySerial, and I've tried a similar (full duplex, also PL2303) device which works fine.

I've tried several combinations of setting xonxoff, rtscts etc. I've also tried RTS toggling using setRTS(True) and checking for CTS and DSR etc - gets all return False. I can successfully open the device using pySerial (I can see activity light flashing - simple but effective test) and pySerial complains if you unplug it during reads/writes.

Doesn't seem to matter what flags/lines I set or what data I send, always get the same result.

>>> s=serial.Serial()
>>> s.port('/dev/ttyUSB1')
>>> s.open()
>>> s
Serial<id=0x7fe94b533b50, open=True>(port='/dev/ttyUSB1', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=3, xonxoff=0, rtscts=0, dsrdtr=0)
>>> s.write('\2CMD2292\r')  
>>> s.inWaiting()
0
>>> s.setRTS(True)
>>> s.getCTS()
False
(several iterations of above with different flags).

Ignore the data in the write command - that's just a status check command. Doesn't matter what goes there, the device should either respond with an answer or an error.

I've even resorted to closing and re-opening the device in between setting various ctsrts flags etc., and unplugging / replugging it to force resets. As above it continues to work fine using the Windows test app. I can't use Portmon etc. to sniff the Windows port traffic as it's a 64bit Win7 install and I don't currently have time to build an XP machine.

Any thoughts?

UPDATE: I've also tried all of the above using Python on the same Windows box that the demo app works on. It definitely opens the port and communicates, but again no info back regardless of what's written.

UPDATE2: It looks like it might be device-driver related. Some additional background research suggests that some PL2303 chips have functionality to support half-duplex, but this isn't supported by the Linux drivers. The Windows demo app comes with a dedicated device driver and the app doesn't work on a clean test machine using default Windows drivers. This makes me think that while I can connect to it successfully through Python, I can't control the duplex comms (e.g. even in an STX/ETX way) and therefore this might be a hopeless case. sigh.

UPDATE3: Thanks for the comments below. However, I couldn't find any way round this. I tried a USB protocol analyser, and I tried disassembling the driver but it just became rather time-consuming, so in the end I took the device apart and after some tinkering I managed to replace the existing usb-serial adapter with a proper PL2303 part - on the device side, it was just a basic 2-wire serial interface so it didn't care what was talking to it. I can't seem to close this question so I'll leave it as-is.

Unswear answered 26/11, 2012 at 15:19 Comment(6)
Have you tried using a serial comm program, minicom, for instance to talk to the device on your Linux box? That should allow you to verify the device works on Linux before diving into a Python implementation.Atrophy
Yes - I've tried using minicom to talk to it, but I don't get any response - however I can't find any way to manually to RTS toggling in minicom which is why I tried Python. I know pySerial is connecting to the device and sending data (see above ref. flashy lights:) ).Unswear
Where did you get the driver? is it part of your distro or did you build it by hand? Are you root?Nosedive
Driver is part of kernel since ~2.4 AFAIK. Have also tried the same on two different distros (Debian and Fedora) and it's the same driver. Have tried as root (user has permissions to device as well) and no difference in behaviour.Unswear
Do you know some command that the device should respond to? Could you tell what device it is?Crouton
Did you try to send \r\n? Maybe it is somehow different on windows. You can also try wiresharking or usbmonitoring the usb under linux.Unsought
U
1

Try

s.flush()

just after your s.write call

Urano answered 12/12, 2012 at 19:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.