0

I am using Visual Studio 2015 Community and am coding using C#.

I am receiving a string from a Serial-port. I then need to display 12 sub-strings from it and display them in real time in 12 different text-boxes.

The values are to be displayed only when I click the LOAD button in the Windows form that I have created.

I was not able to do it until I used a timer with a time interval of 2 seconds.

So, now I get the real time values in the text-boxes, but I am unable to click other buttons in my form.

I am badly stuck at this. Is there any way I can load real time values in the form, and still be able to click other buttons too?

Here is my code thus far:

using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Diagnostics;

namespace Taskcontinue
{

    public partial class Form1 : Form
    {// defining a serial port in the code
        SerialPort myport = new SerialPort();
        int flag = 0;
        string input = " "; public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }
//detect a * in string and then start extracting the sub-string as defined              

        private void Skeleton()
        {
            {
                if(myport.IsOpen)
                {
                    myport.Close();
                }
                myport.BaudRate = 9600;
                myport.PortName = "COM9";
                myport.Parity = Parity.None;
                myport.DataBits = 8;
                myport.Open();
                 {
                    while (flag == 0)
                    {
                        input = "";
                        char data = Convert.ToChar(myport.ReadChar());
                        if (data == '*')
                        {
                            flag = 1;
                            input += data;
                            Debug.WriteLine("star is detected::");
                        }
                    }

                    if (flag == 1)
                    {
                       // Debug.WriteLine("WE RE INSIDE FLAG::");
                        for (int i = 0; i <= 129; i++)
                        {
                           // Debug.WriteLine("WE RE IN FOR LOOP::");
                            input += Convert.ToChar(myport.ReadChar());
                        }
                        realvalues();
                        flag = 0;
                    }
                    Debug.WriteLine(input);
                     }
                   } 
               }

     //this is the button which on clicking should display the values in text boxes  
        private void load_values_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void myport_DataReceived(objectsender,SerialDataReceivedEventArgs e)
        {
          string data = Convert.ToChar(myport.ReadChar()).ToString();
        }
//extracting substring from the string from serial port
        private void realvalues()
        {
            tb1.Text = input.Substring(4, 7);
            tb2.Text = input.Substring(14, 7);
            tb3.Text = input.Substring(24, 7);
            tb4.Text = input.Substring(34, 7);
            tb5.Text = input.Substring(44, 7);
            tb6.Text = input.Substring(54, 7);
            tb7.Text = input.Substring(64, 7);
            tb8.Text = input.Substring(75, 7);
            tb9.Text = input.Substring(86, 7);
            tb10.Text = input.Substring(97, 7);
            tb11.Text = input.Substring(108, 7);
            tb12.Text = input.Substring(123, 7);
        }

        private void timer1_Tick(object sender, EventArgs e)//timer tick event
        {
            timer1.Stop();
            timer1.Start();
            Skeleton();
        }
      }
   }
Warren Sergent
  • 2,542
  • 4
  • 36
  • 42
dartagnan
  • 13
  • 2
  • 6

1 Answers1

0

In your question: " Is there any way I can load real time values in the form" I will take real time literally.

You already use the DataReceived event. This one could be used to display the data. You open and close your port every 2 seconds. Unless this has a particular and unavoidable reason, you could just open it when the Form loads (or make a connect button) and keep it open.

Since your data will be read in another thread you need to use BeginInvoke to shove it to your boxes.

 public partial class Form1 : Form
    {
        // You will need these delegate to display your data from the other thread
        delegate void del(string data);    
        del MyDelegate;

        SerialPort port;

        public Form1()
        {
            InitializeComponent();
            // here you create your delegate that will display your data in the textboxes
            MyDelegate = new del(realvalues);
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {   // open your port once
                port = new SerialPort();
                port.PortName = "COM9";             
                port.BaudRate = 9600;
                port.Parity = Parity.None;
                port.DataBits = 8;
                port.Open();

                port.DataReceived += port_DataReceived;    
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }    

        }

        private void realvalues()
        {
            tb1.Text = input.Substring(4, 7);
            tb2.Text = input.Substring(14, 7);
            tb3.Text = input.Substring(24, 7);
            tb4.Text = input.Substring(34, 7);
            tb5.Text = input.Substring(44, 7);
            tb6.Text = input.Substring(54, 7);
            tb7.Text = input.Substring(64, 7);
            tb8.Text = input.Substring(75, 7);
            tb9.Text = input.Substring(86, 7);
            tb10.Text = input.Substring(97, 7);
            tb11.Text = input.Substring(108, 7);
            tb12.Text = input.Substring(123, 7);
        }


        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {   // read the data that has arrived
            String s = port.ReadLine();

            // call here your Skeleton method and pass the entire data string
            string input = Skeleton(s);
            // now give the input string to the display method
            this.BeginInvoke(MyDelegate, s);
        }

    private string Skeleton(string portOutput)
    {
         string input = "";

         // parse here through your received string with your algorithm
         // and return the constructed input string
         return input;
    }

}

This should display the values in real time and leave your GUI responsive. If you still really want an extra LOAD button to constrain your real time write me and I edit my answer.

More information on update the GUI from other threads here and here

Community
  • 1
  • 1
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
  • thank you mong zhu for your answer...but i looked up Background Worker on the web and it worked( although i didn't expect it )!! i appreciate your effort and willingness to help – dartagnan Jul 01 '16 at 08:38
  • I am glad that you found a working solution. Welcome to the world of parallel processing :) if you think that it answers your question you are welcome to mark this as the correct answer if not then not :) – Mong Zhu Jul 01 '16 at 09:03