4

I have a simple Python script to communicate with a micro-controller (STM32F103C8T6) using the serial port. I'm using pySerial to write a couple of 44-bytes messages at a time.

[...]
serial = serial.Serial(serial.tools.list_ports.comports()[0].device, 115200)

packet0 = bytearray(INSERT_RELEVANT_44-BYTES)
packet1 = bytearray(INSERT_RELEVANT_44-BYTES)
serial.write(packet0)

time.sleep(0.1)  # Delay between communications

serial.write(packet1)
[...]

I had to insert a delay between the communications, otherwise it wouldn't work. My reasoning is that for a baud rate of 115200 bps the messages should take 44*8/115200 = ~0,003 seconds to be sent, thus this should be the minimum ideal interval between sending the packets. The code, however, doesn't work for anything smaller than 0,1.

Why? Am I missing something? I suppose there is some delay due to the operating system and the USB, but it shouldn't account for ~0,7 seconds. How can I optimize this to use the minimum possible delay?

6
  • "it wouldn't work" -- That's a summary that doesn't contain any diagnostic information. Your "reasoning" is slightly off; it fails to account for 2 bits of framing per character. What makes you think that transmitting with minimal delay is practical; i.e. is the receiver capable of handling (receive and process) such a packet rate? Also consider the accuracy of the sleep function and overhead of an interpreted language. Commented Dec 3, 2016 at 3:38
  • it depends on how you use serial port in stm32. Is it possible to share code you write in stm32? Commented Dec 3, 2016 at 8:22
  • You seem to be looking for the cause on the sending side only. There's the sender that might lose characters, and the receiver (In your case, you apparently have an USB-to-serial adapter that might lose chars as well). Without more diagnostics on where the problem is, we probably cannot help. Commented Dec 3, 2016 at 12:24
  • 3
    This is an XY Problem. You would do far better to ask why the code does not work without a delay at all. It the STM32 target cannot cope with streaming data at 115200, you should address that rather then kludging your Python code. You mention "serial port" and then "USB" - how exactly is the connection implemented? Some USB serial adaptors have rather small buffers and if there is no hardware flow control used for the UART link, these buffers can be filled and data dropped. Commented Dec 3, 2016 at 16:40
  • Calculating the (minimum) delay based on the output RS232 baud rate and number of characters is not nice design but isn't unviable in itself, because that is how long the USB<>Serial adapter will take to output that data. The detail of your calculation is wrong, should allow 10 bauds/byte and factor in some overhead. However, that's not your problem. Perhaps you can make the micro at the other end send a confirmation back when it is ready to receive more data, so you can't overrun it's input buffer, and no need for timed delay. Size of buffer in USB<>Serial adapter is completely irrelevant. Commented Dec 5, 2016 at 9:28

1 Answer 1

1

Rather then calculating a nominal delay based on the UART link, you could simply poll the serial driver to determine whether the Tx buffer is empty:

serial.write(packet0)
while serial.outWaiting() > 0 :
    pass
serial.write(packet1)

This has the advantage of accounting automatically for any latency, software overhead and buffer limitations anywhere in the chain of application code, library, driver, USB-Serial bridge. It will not however solve any problem with the STM32 serial I/O implementation, you should probably address the root problem of why the data cannot be streamed, which is most likely down to poor implementation of the at the STM32 device end.

Sign up to request clarification or add additional context in comments.

7 Comments

The USB<>serial adapter still takes 10 bauds to output each byte just like a conventional COM port, so you "can" (not to say it's a good choice) calculate a minimum delay like that, probably adding a fudge factor for overhead. Size of buffer in USB<>serial adapter has no effect on this - completely irrelevant.
@barny : Perhaps my point was unclear. We do not know what the actual problem is, the question is about the solution not the problem. If the adaptor has say 128 bits of buffering, you can send both blocks of data with no delay and all the data will be transferred from the PC's point of view in far less than the time the UART link from the adaptor to the STM32. The USB part of the link will have flow control while the UART section may not. The buffering is of course irrelevant if the data is being streamed, but here the error occurs after just two 44 byte blocks.
You are still talking about buffering in the USB<>RS232 device as if it matters. Particularly with no flow control in place, as far as python code is concerned the COM port is a conventional one, and data will be transmitted as fast as it is transmitted out of the "UART" towards the STM32. I assume serial and Windows will both buffer too. Therefore the size of buffers in the USB<>RS232 adapters is completely irrelevant and a complete distraction in your "answer"
Look at a conventional com port UART - 16550 - it has 16 bytes of FIFO, and the original UART type used by the PC architecture has no FIFO. Both are (as far as the python serial code is concerned) perfectly capable of transmitting 44 bytes of data in one "send" even though the 44 bytes is larger than the hardware buffering capability, because of the serial/OS/driver data management. Of course, if the OP hadn't attempted to pace his 44 bytes at the baud rate, the serial/OS/driver buffering would very rapidly be overloaded. Even with his 20% error they wouldn't fill that quickly.
@barny : You are probably right, but I'm not sure we know what matters, since. I do know that if this is a solution, then there is some other problem (at the device end) that it is covering up, and am not really recommending this (or any kindof pacing or delay). I had hoped the OP would engage so that this answer might be improved, currently it is rather fishing for information. I agree that there should be no problem sending the data, so the question remains as to why there is.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.