1

I am developing a application with C# and Arduino.I reading values from Arduino and set the value on the textbox.I want always read value from Arduino and set this on the interface.However this code doesn't working. Shoul I run while statement in a different thread?

This is my code

     SerialPort port = new SerialPort("COM4", 9600);
        port.Open();
        while (true)
        {
            String s=port.ReadLine();
            txtValue.Text=s;

        }
        port.Close();

    }

I want show value which I read from Arduino to show in the textbox simultaneously.

Harun ERGUL
  • 5,770
  • 5
  • 53
  • 62
  • In given code snippet you are **not** *reading values from Arduino*. – Sinatr Jan 06 '15 at 15:07
  • I corrected it but still doesn't work.Maybe because of while statement.I want show value in the textbox simultaneously – Harun ERGUL Jan 06 '15 at 15:11
  • 1
    If given snippet is running in UI thread, then it will block it and you see no `txtValue` changes. You have to organize it differently. Create and run `Task` (or `Thread`) in which you open com-port and start reading. When you want to update `txtValue` - [invoke](http://stackoverflow.com/a/4016979/1997232) it. Don't forget to provide a safe mechanism to stop task (**do not** abort `Thread`!) and close com-port, to example, set some variable when form is closed, this variable is constantly checked inside your `while` to `break` it. – Sinatr Jan 06 '15 at 15:18
  • should I call thread in the constructor or different place? – Harun ERGUL Jan 06 '15 at 15:21
  • 1
    I'd highly recommend using the MVVM pattern, it will make your life much easier. With MVVM you won't have to move most code onto the UI thread for updating your display. – jtimperley Jan 06 '15 at 15:22
  • Is there good resource on the MVVM pattern.Thanks – Harun ERGUL Jan 06 '15 at 15:24

3 Answers3

1

This is code to start (put it in constructor, window Loaded or button click event):

Task.Run(() =>
{
    _stop = false; // define as private field of window class
    var port = new SerialPort("COM4", 9600);
    port.Open();
    while (!_stop)
    {
        var s=port.ReadLine();
        Dispatcher.Invoke(() => txtValue.Text = s); // InvokeAsync?
    }
    port.Close();
});

This is code to stop (put it into window Closing event):

_stop = true;

This doesn't uses any bindings, but should give you an idea of how to organize port operation (with or without bindings).

Sinatr
  • 20,892
  • 15
  • 90
  • 319
1

I can't speak to the arduino side, but if you are using .net 4.0 or 4.5 you could do something like below:

Task myTask = Task.Factory.StartNew(() => {
    while (true)
    {
        String s=port.ReadLine();
        txtValue.Text=s;

    }

 });

as mentioned by Sinatr be sure to have a way to stop execution. You could do this by setting a vairable instead of using "true". As for where to put the code it is really dependent on what your final program will be.

J. Melis
  • 86
  • 7
1

With MVVM Light and SolidSoils4Arduino you should be able to quickly create an observable binding with Arduino serial messages.

Here is a basic viewmodel class:

public class MainViewModel : GalaSoft.MvvmLight.ViewModelBase, IObserver<string>
{
    #region Fields

    private string _lastSerialMessageReceived;
    private readonly ObservableCollection<string> _serialMessages = new ObservableCollection<string>(); 

    #endregion

    #region Constructors

    public MainViewModel()
    {
        var connection = new Solid.Arduino.SerialConnection("COM3", Solid.Arduino.SerialBaudRate.Bps_115200);
        var session = new Solid.Arduino.ArduinoSession(connection);
        session.CreateReceivedStringMonitor().Subscribe(this);
    }

    #endregion

    #region Public Interface

    public void OnCompleted()
    {
        throw new NotImplementedException();
    }

    public void OnError(Exception error)
    {
        throw new NotImplementedException();
    }

    public void OnNext(string value)
    {
        _serialMessages.Add(value);
        LastSerialMessageReceived = value;
    }

    public ObservableCollection<string> SerialMessages
    {
        get { return _serialMessages; }
    }

    public string LastSerialMessageReceived
    {
        get { return _lastSerialMessageReceived; }
        private set { Set(() => LastSerialMessageReceived, ref _lastSerialMessageReceived, value); }
    }

    #endregion
}

You can bind your textbox to property LastSerialMessageReceived. Property SerialMessages could be bound to a listbox.

Henk van Boeijen
  • 7,357
  • 6
  • 32
  • 42