The semaphore timeout period has expired exception when writing to virtual Serial port

4.8k views Asked by At

I'm trying to communicate with USB device that uses CDC. The device connection is seen in Device Manager as Serial Port. I see the device and able to open the serial port. However, when I try to send a message to device, the System.IO.IOException is thrown saying:

The semaphore timeout period has expired

I get the same exception with several third party C# Serial port terminal.

Using the same program with USB-RS232 Converter I'm able to communicate with another device with serial port (not CDC)

The CDC device manufacturer says that their module uses standard Windows CDC driver so the problem is on my end. What am I doing wrong?

My code:

namespace ConsoleApplication1
{
    class Program
    {
        private static readonly SerialPort _serial = new SerialPort();
        static void Main(string[] args)
        {
            var portList = SerialPort.GetPortNames().ToList();
            _serial.PortName = portList[0]; 
            _serial.BaudRate = 9600;
            _serial.Handshake = Handshake.None;
            _serial.Parity = Parity.None;
            _serial.DataBits = 8;
            _serial.StopBits = StopBits.Two;
            _serial.ReadTimeout = 3000;
            _serial.WriteTimeout = 3000;
            _serial.DataReceived += ReceiveData;
            _serial.Open();
            
            while (true)
            {
                string str = Console.ReadLine();

                if (str.Equals("exit"))
                    return;
                SerialCmdSend(str);
            }
            
        }

        public static void SerialCmdSend(string data)
        {
            if (_serial.IsOpen)
            {
                try
                {
                    byte[] hexstring = Encoding.ASCII.GetBytes(data);
                    foreach (byte hexval in hexstring)
                    {
                        byte[] _hexval = { hexval };

                         // The exception is thrown 3 sec. after the first call of the Write function
                        _serial.Write(_hexval, 0, 1); 
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    throw;
                }
            }
        }


        private static void ReceiveData(object sender, SerialDataReceivedEventArgs e)
        {
            if (!_serial.IsOpen)
            {
                return;
            }
            try
            {
                while (_serial.BytesToRead > 0)
                {
                    var b = _serial.ReadChar();
                    //Handle read data
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }
    }
}
1

There are 1 answers

0
wigster On

It is possible your USB device is checking if DTR (data terminal ready) is enabled before fully configuring a connection. I would suggest adding the following code to your c# program before opening your comport.

_serial.DtrEnable = true;