none
C# SerialPort.Read() always returns 0 RRS feed

  • Question

  • I have communicating to Display monitor using RS-232C 9-Pin D-Sub to Stereo Cable to control power ON/OFF, Volume Up/Down etc. I created a sample program based on Microsoft Docs System.IO.Ports. I can open COM PORT, write some byte arrays (based on protocol document) and no issue. But, reading in another thread always time out and receives '0' only. According to document, I should receive ACK or NAK (which will send back to me as byte array starting with 0xAA as well). 

    How can I troubleshoot for this issue? 

    public class ComPortDemo
        {
            private static bool _continue;
            private static SerialPort _serialPort;
     
            public ComPortDemo()
            {
                _serialPort = new SerialPort
                {
                    PortName = "COM1",
                    Parity = Parity.None,
                    StopBits = StopBits.One,
                    BaudRate = 9600,
                    DataBits = 8,
                    WriteTimeout = 2000,
                    ReadTimeout = 5000,
                    Handshake = Handshake.None,
                };
     
                _serialPort.DataReceived += SerialPortOnDataReceived;
                _serialPort.ErrorReceived += SerialPortOnErrorReceived;
                _serialPort.PinChanged += SerialPortOnPinChanged;
                _serialPort.DtrEnable = true;
                _serialPort.RtsEnable = true;
            }
     
            private void SerialPortOnPinChanged(object sender, SerialPinChangedEventArgs e)
            {
                Console.WriteLine($"Pin changed event occurred. " + e.EventType);
            }
     
            public void Write()
            {
                int bufferLength = 6;
                byte[] commands = new byte[bufferLength];
     
                commands[0] = 0xAA;
                commands[1] = 0x11;
                commands[2] = 0x02;
                commands[3] = 0x01;
                commands[4] = 0x01;
                commands[5] = 0x15;
     
                if (_serialPort.IsOpen)
                    _serialPort.Close();
     
                _serialPort.Open();
                _continue = true;
                Thread readThread = new Thread(Read);
                readThread.Start();
                Console.WriteLine("Reader thread started and wait for response..");
     
                Console.Write("Sent: ");
                foreach (var command in commands)
                {
                    Console.Write($"0x{command:X2} ");
                }
     
                Console.WriteLine();
     
                _serialPort.DiscardInBuffer();
                _serialPort.DiscardOutBuffer();
                _serialPort.Write(commands, 0, commands.Length);
     
                Console.WriteLine("ENTER to end reading thread..");
                Console.ReadLine();
                _continue = false;
                readThread.Join();
            }
     
            private static void SerialPortOnErrorReceived(object sender, SerialErrorReceivedEventArgs e)
            {
            
                Console.WriteLine("serial port on error : " + e.EventType);
            }
     
            private static void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                //var serialPort = (SerialPort) sender;
                //string data = serialPort.ReadExisting();
                //Console.WriteLine($"{data}");
                Console.WriteLine("data received event");
            }
     
            public static void Read()
            {
     
                while (_continue)
                {
                    try
                    {
                        if (_serialPort.BytesToRead <= 0)
                        {
                            Console.WriteLine("No data to read");
                        }
     
                        byte[] buffer = new byte[7];
                        Console.WriteLine("trying to read..");
                        int readByte = _serialPort.Read(buffer, 0, buffer.Length);
                        Console.WriteLine($"Read byte : {readByte}");
                        //if (readByte > 0)
                        foreach (var b in buffer)
                            Console.Write($"0x{b:X2} ");
     
                    }
                    catch (TimeoutException toe)
                    {
                        Console.WriteLine(toe.Message);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                        Console.WriteLine(e.StackTrace);
                    }
     
                    Thread.Sleep(2000);
                }
            }
     
            public void Close()
            {
                _continue = false;
                if(_serialPort.IsOpen)
                    _serialPort.Close();
            }
        }
    

    Tuesday, February 25, 2020 8:38 AM

All replies

  • Almost always a handshake problem.

    You should check whether there is HandShake setting required, or some byte sequence to indicate you have nothing to send now and ready to receive.

    Tuesday, February 25, 2020 9:49 AM
    Answerer
  • The protocol documentation said flow control is none. If flow control is NONE, can I assume that Handshake is none as well? Other than that, other configurations are correct. Thank you very much. 
    Thursday, March 5, 2020 10:03 AM
  • If that's what the documentation say then it's okay.

    Is the documentation there specified whether there is certain sequence to send after you complete sending message?

    Say, for GSM modems you have to append "carriage return" to the end of command to signal you've done with your turn of command sending.

    Friday, March 6, 2020 1:58 AM
    Answerer