FirstStep FirstStep - 3 months ago 14
C# Question

Serial Port Communication on the same Windows machine not working

Excuse me, quick question:

I have this hardware setup:


Same machine: "Com3" -> USB -> To Serial -> To USB -> "Com4"


And I followed MSDN SerialPort Class and MSDN SerialPort.ReadLine() to build this routine:

SerialPort SendSerialPort = new SerialPort("Com3", 9600);
SerialPort ReceiveSerialPort = new SerialPort("Com4", 9600);

SendSerialPort.Open();
ReceiveSerialPort.Open();

SendSerialPort.WriteLine("Test");
var message = ReceiveSerialPort.ReadLine(); // console opens here

SendSerialPort.Close();
ReceiveSerialPort.Close();

Console.WriteLine(message);


However, when I tend to
ReadLine()
, my console window pops up and waits. I did not expect that.

I am expecting to receive the string
Test
and assign it to my
var message
. Could you please tell me what am I doing wrong here?

EDIT:

I tested my hardware using the Serial Port Utility Application and it worked just fine.

Answer

I've altered from the example you linked:

To actually have both ports running to read and write back and forth you will actually need to implement threading for reading and writing for both.

It can be a good idea to use a timer.

public static void Main()
{
    SerialPort SendSerialPort = new SerialPort("Com3", 9600);
    SerialPort ReceiveSerialPort = new SerialPort("Com4", 9600);

    StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
    Thread readThread = new Thread(Read);


    // Set the read/write timeouts
    _serialPort.ReadTimeout = 500;
    _serialPort.WriteTimeout = 500;

    SendSerialPort.Open();
    ReceiveSerialPort.Open();
    _continue = true;
    readThread.Start();

    Console.Write("Name: ");
    name = Console.ReadLine();

    Console.WriteLine("Type QUIT to exit");

    while (_continue)
    {
        message = Console.ReadLine();

        if (stringComparer.Equals("quit", message))
        {
            _continue = false;
        }
        else
        {
            SendSerialPort.WriteLine(
                String.Format("<{0}>: {1}", name, message));
        }
    }

    readThread.Join();
    SendSerialPort.Close();
}

public static void Read()
{
    while (_continue)
    {
        try
        {
            string message = ReceiveSerialPort.ReadLine();
            Console.WriteLine(message);
        }
        catch (TimeoutException) { }
    }
}

Usually there will be a beginning and end value within the written data to tell the other port that the message is finished and also for the ports to validate that they are reading data they should be, usually with commands of what to do with that data. (out of scope for this question).

Also lacking and important is the intialisation of your ports.

_serialPort.BaudRate = SetPortBaudRate(_serialPort.BaudRate);
_serialPort.Parity = SetPortParity(_serialPort.Parity);
_serialPort.DataBits = SetPortDataBits(_serialPort.DataBits);
_serialPort.StopBits = SetPortStopBits(_serialPort.StopBits);
_serialPort.Handshake = SetPortHandshake(_serialPort.Handshake);

as Hans Passant gives a good brief into why this is important.