4

I have a USB to RS485 converter: enter image description here

It has a CH341 chip, that is all I know about it. When I plug it in, I can see that it is bound to port ttyUSB0. I want to be able to send and receive bytes from PC (Ubuntu) to a STM32 board. The board side is not a problem, but rather the PC side.

Does someone have experience with such a device? Do I write the bytes that I want to send onto this serial port and the magic will happen, or does it have some special protocol, config bytes or command bytes or such? The datasheet is basically 1 page with literally no information in it.

I am not familiar with serial port programming under Linux, but it will be fun to learn it. I just wanted to know whether I have to pay attention to anything special before I start working on this home project.

Any information, code snippet or just advice or experience is very welcome :)

Transistor
  • 168,990
  • 12
  • 186
  • 385
Marcell Juhász
  • 255
  • 2
  • 10
  • 1
    This device is broken by design. RS-485 to PC requires 3 signals: Tx/Rx-, Tx/Rx+ (sometimes called A and B) and signal ground. But you only have 2 signals so it won't work. Either you need to buy a new converter which wasn't designed by quacks (recommended), or you need to go chase down a ground somewhere else on your PC and connect that one to the target separately. – Lundin Apr 26 '21 at 10:40
  • @Lundin Unfortunately, a large part of the world thinks that signal ground is an unnecessary superfluous addition. And unfortunately or fortunately, a large number of devices seem to "just work" using just A and B. A sad state of affairs when you consider the fundamentals involved. – Milind R Jul 23 '23 at 18:23

1 Answers1

3

Linux supports this IC natively and the ch341 module is probably loading correctly since you see the /dev/ttyUSB0 entry created. I had to manually upgrade this driver a few years ago, but recent kernels should have a decent version.

At the Linux programming level (C or Python, for example) you don't handle configuration by writing/reading directly to the device, since the driver does that. You open the device file, configure it with ioctl system calls referencing the file descriptor and communicates using the regular write and read functions.

Applications will see the device as a regular serial port, so, the old Serial Programming HOWTO is a good place to start. Miniterm is also a good reference as well as man 3 termios for a full description of functions and arguments.

Going another level up, Python makes it easier: e. g. here and here.

Edit: moving my comment here to explain more clearly

You should be concerned with your application not being able to receive all data sent from the STM32 reliably. There is buffering in the IC itself but if your process is scheduled out for too long, you may loose bytes. You can change the process priority, limit the rate you send data from STM32, but if you really need a robust communication, you should add that flow control to your protocol.

For the command/response structure you mentioned, with small responses, it should work even without the delay at the STM32 side. If the higher level flow control is too complex, and it is acceptable to only detect that the received data is incomplete, you may just add sequence numbers, timestamps or even integrity checks.

devnull
  • 8,447
  • 2
  • 15
  • 38
  • 1
    Thank you very much once again, I could successfully establish communication between the board and the PC. I have one more question, maybe You know the answer to that as well: so my linux PC is not a real-time machine unlike the stm32 board. After receiving in the board, should I wait some time before answering so that the PC can get to the line where I want to read? Or it does not matter, because the PC buffer fills up independent of whether I am currently reading or not, and when it gets to the line where I read, it just reads the buffer? – Marcell Juhász Apr 25 '21 at 09:33
  • @MarcellJuhász The PC hardware buffer isn't limitless. So it all depends on how much data you are transmitting and at what speeds. Generally the PC needs some 10ms to 100ms to keep up with a microcontroller. An old trick is to make every protocol work with "echo", so that you know that the PC is awake before sending the next character. This comes at the expensive of speed though, since you get lots of overhead and have to wait for the sluggish PC at every byte. – Lundin Apr 26 '21 at 10:45
  • @MarcellJuhász Anyway, your communication just works by luck since the 230VAC of your PC and the supply of your target apparently don't differ that much in potential - it's within the spec of the RS485 transceiver. Probably they both come from the same 230VAC in your house? Power up the target from a different supply and you won't be so lucky. At any rate, using the 230VAC ground as signal reference for your digital signals is sheer quackery. – Lundin Apr 26 '21 at 10:52
  • I just want to transfer 8 bytes at a time. PC is master, transmits 8 bytes with some instructions or data, then immediately 8 bytes come back from the board. That is all the communication. And yeah, they both have the same 230V 0 potential as reference. It is just a hobby project for me at home, so there won't be that much difference there. – Marcell Juhász Apr 27 '21 at 11:07
  • Ohh an I use 38400 baud rate, so that is not the fastest as well, but fast enough for me. And the last byte of the 8 byte message is always used as a checksum field. Do you think that I could still have problems with this speed and only 8 bytes per message and master-slave architecture? @Lundin – Marcell Juhász Apr 27 '21 at 12:08
  • @MarcellJuhász That's sufficiently small to fit many times over into UART buffers (iirc PC uses around 1kb buffer). But you have to ensure that the PC can keep up in a timely fashion regardless. – Lundin Apr 27 '21 at 12:30