Search code examples
pythonc#serial-portpyserial

python serial readline() vs C# serial ReadLine()


I'm trying to read serial input from my device, and have gotten it to work in Python using pyserial, e.g.

import serial
port = serial.Serial(port='COM1', baudrate=19200, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)

while 1:
    N = port.in_waiting
    
    if N>4:
        msg = port.readline(N)
        print(list(msg))

I'm trying to implement this same code in C#, but it does not quite seem to work, e.g.

port = new SerialPort(COM1);
port.BaudRate = baudRate;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.ReadTimeout = SerialPort.InfiniteTimeout;
port.Handshake = Handshake.None;
port.RtsEnable = false;
port.DtrEnable = false;
port.DataReceived += new SerialDataReceivedEventHandler(DataReceived);

and

void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    
    int N = port.BytesToRead;
    if (N > 4)
    {
         string line = port.ReadLine();

    }
}

I'm able to read stuff properly using port.Read() in C#, however it seems like ReadLine doesn't quite work properly--it doesn't seem to be able to find the end-of-line character ("\n")? And the program just freezes. Yet I am not sure why it works with pyserial.ReadLine() which also seeks the same character (and works without timeout). As far as I can tell, the rest of the port settings are identical.

Thanks!


Solution

  • Because the DataReceived event indicates that data has been received through a port, the data is already read and you should call SerialPort.ReadExisting to get it.

    void DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        var data = port.ReadExisting();
    }
    

    This event does not guarantee that its data is a single line, if you want a similar way to pySerial, you should not use the event and use ReadLine directly:

    port.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
    
    while(true)
    {
        int N = port.BytesToRead;
        if (N > 4)
        {
             string line = port.ReadLine();
        }
    }