When developing software interfaces to serial devices the first step is always to get the device talking. With so many variables it can be incredibly frustrating when the application you are building does not properly communicate with the serial device.

One particular application I had was interfacing with a Questemp Humidex monitor.questemp36 The Questemp line of humidity monitors are used to measure temperature and humidex among other things. The protocol is a simple ASCII command followed by a CR/LF.

Plugging the device into a serial-port and communicating through a serial terminal like putty was the first step and everything worked as expected.


Type of Connector

These devices use an 8 pin DIN to 9 PIN DB9 serial connector2-6 DIN connector. If a device is using more than the minimum 3 pins (GND, TD, RD) then there is a good possibility that it uses some kind of hardware flow control. The flow control pins are CTS, and DTR they essentially tell the device and the computer when they are clear to send and clear to receive.






 USB-To-Serial Connectors


Laptops rarely come with embedded serial ports anymore. So USB-To-Serial adapters are used in there place. These devices have come a long way in the last 5 years to the point where they actually function better than an embedded serial port in the sense that they can detect and compensate for hardware flow control. We use the Tripp-Lite Keyspan (Model: USA-19HS) they are very affordable and work nearly perfectly.

When we plug the device into a USB serial port adapter like the  and run a simple serial terminal everything works as designed.

Use caution when developing with USB-To-Serial connectors they have a lot of internal intelligence and can easily mask programming mistakes.


.NET Serial Interface

When using mature libraries like the .NET serial communication libraries often the default settings will work as planned. We created a serial port object with it’s basic parameters, “Com1, 9600, N, 8, 1”,

SerialPort port;

port = new SerialPort(portName, baudrate, parity, dataBits, stopBits);

and call a simple sychronous serial read command.

string parsedResponse = “”;
port.ReadTimeout = this.timeout;
string response = “”;
port.Write(QTCommand + “\r”);byte

[] rbuffer = new byte[18];
int count = port.Read(rbuffer, 0, 18);port.Close();response = Encoding.ASCII.GetString(rbuffer);
parsedResponse = parseQTData(response);
catch (Exception ex)
parsedResponse = “Communication Error”;

return parsedResponse;

With the USB-to-Serial adapter this code works correctly. We send a command and we read a response like we would expect.

Hardware Serial Port Failure

When we connected to a computer that had a hardware serial port, we could not get communication. The Port.Read command would simply timeout without getting a response. We connected back to putty to ensure the port was working and we confirmed that it was.This can get frustrating when your software doesn’t appear to work but there is no obvious solution. After some time we realized that putty was actually taking care of the DTR CTS.

When we used the USB-To-Serial adapter we found the .NET application actually worked correctly. Again after some time we realized the it was usb device itself that was doing the flow control before the data made it to the .NET application.

Flow Control Solution

Once it was discovered the problem was a simple flow control the fix was quite simple:

SerialPort port;

port.RtsEnable = true;
port.DtrEnable = true;

port = new SerialPort(portName, baudrate, parity, dataBits, stopBits);

Although it would make more sense for microsoft to enable the Rts and Dtr by default it is not the case. We have explicitly set the Rts and Dtr to enable to get them to work.

By-Passing Rts and Dtr

Rts and Dtr do have a purpose so it is recommended you work with them rather than trying to by-pass their functionality. There are cases, however, where you will need to connect to a 9 pin hardware flow control device with a 3 pin connector. In this case there is no alternative other than by-passing the flow control. This can be done by simply placing a “jumper” between the RTS and DTR pins. The device will then essentially communicate with itself when asking if it is clear to send and clear to receive. When we are working with serial devices we are generally not reading large amounts of data. By-passing the flow control for reading small amounts of data should not adversly effect the functioning of the program.