Hello,

I'm trying to read a serial port data from a controller and plot it using chart. I could read the data from the controller and see the data in a textbox earlier. Now I'm trying to use a chart along with the textbox. There are complication when I'm trying to use both together. I get an exception because I'm trying "data = sp.ReadLine();" for chart. I'd like to keep the textbox just to verify what I'm plotting, but I understand that I can also do that using putty. There's no response even when I use only the chart to plot. And I cannot pin-point the problem. Because to my understanding I think I have followed the steps to establish it, but then I'm failing anyway! Please do have a look at what I have tried so far and please do let me know if I'm doing something wong.

Chart and Form1

namespace Serial_receive
{
    public partial class Form1 : Form
    {
        string t;
        SerialPort sp;
        double rt = 0;
        //Boolean i = false;
        private string data;
        private DateTime datetime;

        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;

            // User can already search for ports when the constructor of the FORM1 is calling 
            // And let the user search ports again with a click
            // Searching for ports function

            SearchPorts();
        }     

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.DataSource = SerialPort.GetPortNames();
            timer1.Start();
            Text = "Serial Channel to FRDM-KW40Z";
        }

        private void TextBox1_TextChanged_1(object sender, EventArgs e)
        {

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            rt = rt + 0.1;
        }

        private void chart1_Click_1(object sender, EventArgs e)
        {
            ChartArea CA = chart1.ChartAreas[0];  // quick reference
            CA.AxisX.ScaleView.Zoomable = true;   // see small button on the horizontal scroll for reset??
            CA.CursorX.AutoScroll = true;
            CA.CursorX.IsUserSelectionEnabled = true;
            //
            var dataBlocks = data.Split('\n');

            foreach(var block in dataBlocks)
            {
                var numbers = block.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                rt += 100; //some time interval
                for (int i = 0; i<numbers.Length; i++)
                {
                    double n = double.NaN;  //represents a value that is Not a Number. Field is constant
                    bool ok = double.TryParse(numbers[i], out n);
                    if (ok) chart1.Series[i].Points.AddXY(rt, n);
                    else
                    {
                        int p = chart1.Series[i].Points.AddXY(rt, n);
                        chart1.Series[i].Points[p].IsEmpty = true;
                        Console.WriteLine("well shoot! try again..");
                    }

                }

            }

        }

Combox1 for listing available ports and connecting

private void button1_Click_1(object sender, EventArgs e)
        {
            //comboBox1.Items.Clear();
            SearchPorts();
        }

        void SearchPorts()
        {
            string[] ports = SerialPort.GetPortNames();
            foreach (string port in ports)
            {
                comboBox1.Items.Add(port);
            }
        }

        private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            if (sp == null || sp.IsOpen == false)
            {
                OpenCloseSerial();
            }
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            // Catch exception if it will be thrown so the user will see it in a message box
            OpenCloseSerial();
        }
        void OpenCloseSerial()
        {
            try
            {
                if (sp == null || sp.IsOpen == false)
                {
                    t = comboBox1.Text.ToString();
                    sErial(t);
                    button2.Text = "Close Serial port"; // button text
                }
                else
                {
                    sp.Close();
                    button2.Text = "Connect and wait for inputs";   // button text
                }
            }
            catch (Exception err)   // catching error message
            {
                MessageBox.Show(err.Message);   // displaying error message
            }
        }

        void sErial(string Port_name)
        {
            try
            {
                sp = new SerialPort(Port_name, 115200, Parity.None, 8, StopBits.One);   // serial port parameters
                sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                sp.Open();
            }
            catch (Exception err)
            {
                throw (new SystemException(err.Message));
            }
        }

Textbox and chart data and saving data as text file;

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            if (e.EventType == SerialData.Chars)
            {
                if (sp.IsOpen)
                {
                    string w = sp.ReadExisting();
                    if (w != String.Empty)
                    {
                        Text += "\r\n";
                        Invoke(new Action(() => TextBox1.AppendText(w)));
                    }
                }
            }
            data = sp.ReadLine();
            chart1.Series["Data1"].Points.AddXY(rt, data);
            Invoke(new EventHandler(displayData_Event));
        }

        private void displayData_Event(object sender, EventArgs e)
        {
            datetime = DateTime.Now;
            string time = datetime.Day + "/" + datetime.Month + "/" + datetime.Year + "\t" + datetime.Hour + ":" + datetime.Minute + ":" + datetime.Second;
            //data.AppendText(time + "\t" + data + "\n");
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.InitialDirectory = @"C:\Users\varman\Documents\";
            saveFileDialog1.Title = "Save text Files";
            saveFileDialog1.CheckFileExists = true;
            saveFileDialog1.CheckPathExists = true;
            saveFileDialog1.DefaultExt = "txt";
            saveFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
            saveFileDialog1.FilterIndex = 2;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllText(saveFileDialog1.FileName, TextBox1.Text);
                TextBox1.Text = saveFileDialog1.FileName;
            }
        }
    }
}

Thank you very much for your time. Good day.

Cheers,

Ram.

Recommended Answers

All 4 Replies

@Ram, while I have written too many apps that use the serial port in C (PalmOS), C# (VS2008), VB6 and maybe others the errror doesn't jump out to me.

I do worry why you used CheckForIllegalCrossThreadCalls though. That is discussed in prior discussions as something to not use.

Share more and why you used CheckForIllegalCrossThreadCalls.

Agreed that more context is needed in general.

What type of object is chart1?

One thing I noticed is that displayData_Event is invoked by DataReceivedHandler but this seems to not do anything.

It might be that you need to ask the chart to refresh itself (can't really be sure without knowing what chart you're using).

In general I'd try just a simple form with one chart and a timer that plots a new random value every second to make sure you can draw charts correctly, then try to hook it up to the serial port code.

@rproffitt : I'm teaching myself to program and I was just following tutorials. It seems fine but then it fails now and then. I'm replacing it with "Invoke". That'd be better I suppose.

@Isaac_4 : Thank you for the question and suggestions! I will again look into the invoke by DataReceivedHandler. Windows form application 'series chart', is what I'm using. Your sugestion will help me approach my problems, thanks again :) Let me know if you have any further pointers. Good day.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.