Shahin
Shahin

Reputation: 12851

Communicate with COM port in a WPF application

In a WPF project I bound Polyline control to a DependencyProperty with the type PointCollection.
Coordinates of points should come from a hardware (it is physiotherapy force-plate hardware).
I wrote some code in a console application to read data from port com and it works right. I should use the code in my WPF application
Codes :

public class Hardware
{
    private SerialPort _serialPort;

    public void TestData()
    {
        InitSerialPort();
        Console.WriteLine("Send data:");
        string input = string.Empty;
        while (input != "exit")
        {
            Thread.Sleep(3000);
            input = "~";
            SendData(input);
        }
    }

    private void SendData(string input)
    {
        if (!_serialPort.IsOpen)
            _serialPort.Open();

        _serialPort.Write(input);
        Console.WriteLine("data '{0}' has been sent to serial port", input);
    }

    private void InitSerialPort()
    {
        _serialPort = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One)
                          {
                              Handshake = Handshake.None,
                              ReadTimeout = 500,
                              WriteTimeout = 500
                          };

        _serialPort.DataReceived += SerialPortDataReceived;
        _serialPort.Open();
        return;
    }

    private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        Thread.Sleep(2000);
        var buffer = new byte[100];
    double deltaV1 = ((buffer[1]*65535 + buffer[2]*255 + buffer[3])*5)/102400;
        double X = (25.73*deltaV1) + (-4.27);
        double Y = (25.61*deltaV1) + (-3.79);
        Console.WriteLine("X: {0}; Y: {1}", X, Y);
    }
}

In ViewModel I bound PolyLine to collection of points :

  internal class RadarViewModel : DependencyObject, INotifyPropertyChanged
    {
        public static readonly DependencyProperty PtsProperty =
            DependencyProperty.Register("Pts", typeof (PointCollection), typeof (RadarViewModel),
                                        new UIPropertyMetadata(new PointCollection()));
   public PointCollection Pts
        {
            get { return (PointCollection) GetValue(PtsProperty); }
            set { SetValue(PtsProperty, value); }
        }
    public void AddPoint()
        {
            var rnd = new Random();
            Pts.Add(new Point(rnd.Next(90), rnd.Next(90)));
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("Pts"));
        }

}

Now I have no idea that how can I update PointCollection when the data was read from the COM port to reflect last changes from hardware in UI.
I read some articles like this : Dependency property getters and setters in multithreaded environment
I don't know how to implement in my scenario.

Upvotes: 1

Views: 18409

Answers (2)

Jake Berger
Jake Berger

Reputation: 5377

Note that the SerialPort DataReceived event handler is triggered/run on a NON-UI thread.

private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // create your points
    // INVOKE update to Point collection
}

An internet search for wpf thread observablecollection yields promising results on how to use a collection in a multi-threaded environment.

You shouldn't need to know when to to read data from COM, that's what DataReceived event is for. And it depends on the frequency of the data coming in and how much. If it's really frequent and a LOT of data, then you may want to filter some of it and only display every N updates. If it's small chunks and not that often, then just update it every time.

Upvotes: 0

ppiotrowicz
ppiotrowicz

Reputation: 4614

The problem is, that you can only update UI from the UI thread.

When you receive data from SerialPort, you will get it on some thread from the threadpool. You have to switch thread context to UI thread. And for that purpose you can use the Dispatcher object.

Upvotes: 1

Related Questions