Andrius
Andrius

Reputation: 35

C# WPF Serial Port Reading data continuously

I'm trying to build a WPF application that would read data from Serial Port and would not block UI thread, but I'm a bit stuck at how I should do it.

I got code as follows in my *.xaml.cs file

private void testConnection_Click(object sender, RoutedEventArgs e)
{
    string correctPort = "COM6";
    SerialPortConnection serialPortTestConnection = new SerialPortConnection(correctPort);

}

In my SerialPortCommunications I got it like this:

public SerialPortCommunications(string comPort)
{
        SerialPort mySerialPort = new SerialPort(comPort);
        mySerialPort.BaudRate = 2400;
        mySerialPort.Parity = Parity.None;
        mySerialPort.StopBits = StopBits.One;
        mySerialPort.DataBits = 7;
        mySerialPort.Handshake = Handshake.None;
        mySerialPort.Encoding = ASCIIEncoding.ASCII;

        mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        mySerialPort.Open();
        mySerialPort.WriteLine("C");
}

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    String s = sp.ReadExisting();
    if (s == "\r")
    {
        Console.WriteLine(tempReadingString);
        tempReadingString = string.Empty;
    } else
    {
        tempReadingString += s;
    }
}

I do get the first response from the device, however it stops after that even though the port stays open. I know for sure that passing value "C" continuously returns values (tested with Hyperterminal).

Would appreciate any help.

Upvotes: 1

Views: 17241

Answers (2)

Mark Feldman
Mark Feldman

Reputation: 16148

Generally speaking you should avoid using ReadExisting, it has known issues, particularly when the incoming stream contains binary data. Here's what I do:

this.SerialDevice = new SerialPort(this.Port);
this.SerialDevice.BaudRate = 115200;
this.SerialDevice.DataReceived += OnDataReceived;
this.SerialDevice.Open();
...
private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
{
    var serialDevice = sender as SerialPort;
    var buffer = new byte[serialDevice.BytesToRead];
    serialDevice.Read(bytes, 0, buffer.Length);

    // process data on the GUI thread
    Application.Current.Dispatcher.Invoke(new Action(() => {
        ... do something here ...
    }));
}

Upvotes: 4

Joe
Joe

Reputation: 1

You should put an object of your class SerialPortCommunications in a new thread and then start reading data from a COM port. Also if you need data from the COM port in WPF for example TextBlock you need to create an event in the class SerialPortCommunications, and in the WPF to implement an event handler. But in that handler you will need to use Dispatching for showing data in that TextBlock.

Upvotes: 0

Related Questions