0

I'm writing a control panel program with Python for a commercial Oxford instruments temperature controller, to which we can communicate by RS-232. I have a program written up with TkInter, but it's dropping characters when writing to/reading from the instrument. With PySerial, a minimal working example to reproduce the issue is

import serial
s = serial.Serial(port='COM2', baudrate=9600, timeout=2)  #temp controller on COM2
s.write(b'Q2\r\n')  #initial setup for instrument
for i in range(100):
    print(i, 
          s.write(b'@1R0\r\n'),  #asks for current temperature
          s.readline())

At random points throughout the 100 iterations, I receive a message back from the instrument indicating the command was garbled; for example,

0 6 b'R100.73\r\n'
1 6 b'R100.73\r\n'
2 6 b'R100.73\r\n'
...etc...
39 6 b'R100.73\r\n'
40 6 b'?@10\r\n'       <---*Error message from instrument
41 6 b'R100.73\r\n'
42 6 b'R100.73\r\n'
...etc...
99 6 b'R100.73\r\n'

When i=40, the instrument only received '@10\r\n' instead of '@1R0\r\n'. It shows it's unhappy with the '?' in the response. Data loss seems to happen both in writing and reading. I'm not sure how to proceed. This issue becomes particularly problematic when one of the final '\r' or '\n' bytes gets corrupted/lost.

Adding delays seems to change the error message I get (b'' instead of b'?@10\r\n' or similar) but these delays do not fix the issue:

import serial
from time import sleep
s = serial.Serial(port='COM2', baudrate=9600, timeout=2)
s.write(b'Q2\r\n')
for i in range(100):
    sleep(0.01)
    j = s.write(b'@1R0\r\n')
    sleep(0.01)
    k = s.readline()
    print(i, j, k)

Any ideas what could be causing the data loss? Is there a way I can prevent this from happening?

EDIT: It turns out my error was simply forgetting to ask for two stop bits instead of the default (one). After switching to two, the communication to the instrument became quite reliable.

ChemWes
  • 57
  • 2
  • 6
  • Can you replicate any data errors while using a terminal emulation program instead of your code? Besides bad software, there are environmental issues that can affect reliable RS-232 links, such as EMI and long distances. Shielded cable (w/grounding),(numerically) smaller-gauge wire, quality transceivers, and slower baudrate are possible solutions. A data analyzer that can capture data off the wire could help resolve HW vs SW question. – sawdust Aug 04 '20 at 05:00
  • Thanks for your comment. After playing around with a serial terminal program, it turns out my error was simply that I was using the default number of stop bits (1) instead of two. I'm surprised it ended up working 90% of the time and only randomly failed. – ChemWes Aug 04 '20 at 21:40
  • 1
    *"I'm surprised it ended up working 90% of the time ..."* -- The typical UART does not enforce the receipt of more than one stop bit. A "missing" stop bit, i.e. sampling a zero instead of a one, does cause a read framing error. But requiring more than one stop bit is typically some sort of timing workaround. In one case I know of, the manufacturer recommended sending two stop bits to compensate for its nonstandard, slightly-slow baudrate. – sawdust Aug 05 '20 at 07:19

0 Answers0