none
How to continuously read from serial COM port RRS feed

  • Question

  • I am reading information from Arduino into a C# program that supposed to parse the data, analyze it and execute tasks on the host (PC). At this stage I need only to read from the serial port. I can get the available ports, set the baud rate and read data. The problem is that I can only read it into a form's text box. This was good for debug, but now I need to parse the data. so I need it as a list/array of strings (lines).

    My current code is: 

    while (true) {
                    oneLine = myPort.ReadLine();
                    this.Invoke(new EventHandler(display_data_Event));
    
                    // TBD: add analysis of data from port
                    // TBD: execute according to data from Arduino
                }
    The handler is:
           private void display_data_Event(object sender, EventArgs e) {
            string curr_time = DateTime.Now.ToString("h:mm:ss tt");
            port_in_TextBox.AppendText(curr_time + "       " + oneLine + "\n");
        }

    How can I use the "one line" string only when the event occurs, instead of the "while true"? I tried calling functions from the handler - I guess it failed because it is another thread. So perhaps the problem is how to share the string from one thread to another.

    Saturday, February 8, 2020 4:26 PM

Answers

  • Hi YigalB,

    The listbox doesn't seem to provide such an event, but we can add one manually.

    Please refer to the following code, I bind the listbox with the BindingList, and then by monitoring the changes of the BindingList content, I can detect the change of the listbox content.

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            
            BindingList<string> list = new BindingList<string>();
            private void Form1_Load(object sender, EventArgs e)
            {
                list.ListChanged += new ListChangedEventHandler(list_ListChanged);
                listBox1.DataSource = list;
            }
    
            private void list_ListChanged(object sender, ListChangedEventArgs e)
            {
                switch (e.ListChangedType)
                {
                    case ListChangedType.ItemAdded:
                        MessageBox.Show("Add one item.");
                        break;
                    case ListChangedType.ItemChanged:
                        break;
                    case ListChangedType.ItemDeleted:
                        break;
                    case ListChangedType.ItemMoved:
                        break;
                        // some more minor ones, etc.
                }
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                list.Add(textBox1.Text);
            }
        }

    Result:

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, February 14, 2020 2:09 AM

All replies

  • Hi YigalB,

    Thank you for posting here.

    According to your description, the question now is how to modify the value of the textbox from another thread, right?

    If so, please refer to the following code.

            public Form1()
            {
                InitializeComponent();
                new Thread(SampleFunction).Start();
            }
    
            public void AppendTextBox(string value)
            {
                if (InvokeRequired)
                {
                    this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
                    return;
                }
                textBox1.Text += value;
            }
    
            void SampleFunction()
            {
                // Gets executed on a seperate thread and 
                // doesn't block the UI while sleeping
                for (int i = 0; i < 5; i++)
                {
                    AppendTextBox("hi.  ");
                    Thread.Sleep(1000);
                }
            }

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, February 10, 2020 2:25 AM
  • Thank you Timon.

    I need something else: the existing thread writes lines to the textbox. 

    Another thread needs to read the lines in real time, time after time, parse and execute them. 

    So I need to read each line after written, parse it, and delete it from the text box.


    • Edited by YigalB Monday, February 10, 2020 4:57 AM fix small error
    Monday, February 10, 2020 4:56 AM
  • Hi YigalB,

    You can use the following code to get value from textbox.

    var text = (string)textBox1.Invoke(new Func<string>(() => textBox1.Text));

    And then you can parse it as you want, then set the value to null.

    In fact, this is similar to the original question.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, February 11, 2020 9:37 AM
  • Thanks again Timon.

    This is good, but it doesnt answer the multiline problem: If the text box has few lines (because the other thread writes lines to this text box), I need to delete a the line I read, after I read and parse it.

    Can this be done?

    Tuesday, February 11, 2020 10:04 AM
  • Hi YigalB,

    When the text is more than one line, perhaps listBox is a better choice than textbox.

    The content of the textbox is a string. According to your requirements, we need to write, read, process, delete, and need to perform a lot of operations on this string, but listBox provides a variety of methods such as Add, Remove and so on.

    It will be much simpler to use.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 12, 2020 8:15 AM
  • Thanks Timon. I added a list box, currently in parallel to the text box, until I am sure it works fine.

    I can see the data received from the COM port displayed  well. 

    So now I can do polling on the list box, but I don't like the approach - I need to find a way to trigger event when the the other thread add a string to the list box. 

    Thursday, February 13, 2020 12:54 PM
  • Hi YigalB,

    The listbox doesn't seem to provide such an event, but we can add one manually.

    Please refer to the following code, I bind the listbox with the BindingList, and then by monitoring the changes of the BindingList content, I can detect the change of the listbox content.

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            
            BindingList<string> list = new BindingList<string>();
            private void Form1_Load(object sender, EventArgs e)
            {
                list.ListChanged += new ListChangedEventHandler(list_ListChanged);
                listBox1.DataSource = list;
            }
    
            private void list_ListChanged(object sender, ListChangedEventArgs e)
            {
                switch (e.ListChangedType)
                {
                    case ListChangedType.ItemAdded:
                        MessageBox.Show("Add one item.");
                        break;
                    case ListChangedType.ItemChanged:
                        break;
                    case ListChangedType.ItemDeleted:
                        break;
                    case ListChangedType.ItemMoved:
                        break;
                        // some more minor ones, etc.
                }
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                list.Add(textBox1.Text);
            }
        }

    Result:

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, February 14, 2020 2:09 AM