Click here to Skip to main content
14,773,652 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
Hello i have created a serial port to get value from a temperature sensor when i get the value , graph should be plotted depending upon the temp .

I have two buttons in my forms when i click button1 it should get data and plot graph . When i click button it should stop getting data . I wish to create a seperate function for graph but find difficulty in sending the temp value which i read through serial port to graph function .


namespace Graphtry1
{
    public partial class Form1 : Form
    {
        SerialPort sprt;
        string indata;
        GraphPane myPane;
        double d;
        
       

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            button1.Enabled = false;
            sprt = new SerialPort("COM3");

            sprt.BaudRate = 9600;
            sprt.Parity = Parity.None;
            sprt.StopBits = StopBits.One;
            sprt.DataBits = 8;
            sprt.Handshake = Handshake.None;
            

            
            try
            {
                sprt.Open();
            }
            catch (Exception)
            {
                MessageBox.Show("Check port");
            }
            Thread.Sleep(500); 
            indata = sprt.ReadExisting();
            MessageBox.Show(indata);
            this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { indata });


            zedGraphControl1.Location = new Point(10, 10);
            // Leave a small margin around the outside of the control

            zedGraphControl1.Size = new Size(ClientRectangle.Width - 20,
                                    ClientRectangle.Height - 20);
            ZedGraphControl zgc = zedGraphControl1;
            
            myPane = zgc.GraphPane;
            
            myPane.Title.Text = "My Test Graph\n(For CodeProject Sample)";
            myPane.XAxis.Title.Text = "My X Axis";
            myPane.YAxis.Title.Text = "My Y Axis";
            double x, y1, y2;
            PointPairList list1 = new PointPairList();
            PointPairList list2 = new PointPairList();
            for (int i = 0; i < 36; i++)
            {
                x = 3.5;
                y1 = d;
                //MessageBox.Show(d);
                //y2 = 3.0 * (1.5 + Math.Sin((double)i * 0.2));
                list1.Add(x, y1);
                //list2.Add(x, y2);
            }

            // Generate a red curve with diamond

            // symbols, and "Porsche" in the legend

            LineItem myCurve = myPane.AddCurve("Porsche",
                  list1, Color.Red, SymbolType.Diamond);

            // Generate a blue curve with circle

            // symbols, and "Piper" in the legend

            //LineItem myCurve2 = myPane.AddCurve("Piper",
            //      list2, Color.Blue, SymbolType.Circle);
            zgc.AxisChange();
            //sprt.DataReceived += new SerialDataReceivedEventHandler(sprt_DataReceived);
            
        }

        private delegate void SetTextDeleg(string text);

        //private void sprt_DataReceived(
        //                object sender,
        //                SerialDataReceivedEventArgs e)
        //{
            
            //Thread.Sleep(500);
            

            //try
            //{
            //    indata = sprt.ReadExisting();
            //}
            //catch (Exception)
            //{
            //    MessageBox.Show("Port Not closed . Try again");
            //}
            //this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { indata });
            //}
        
        private void si_DataReceived(string indata)
        {
            String[] datashort=indata.Split(':');
            string chop=datashort[2];
            string finaldata=chop.Remove(5);
            d = Convert.ToDouble(finaldata);
            
            
            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            button1.Enabled = true;
            sprt.Close();
        } 
    }
}


I want to send the final data to graph function finding problem in that . Help needed
Posted
Updated 28-Jul-11 23:44pm
v2

I suggest you use a BackgroundWorker to get the data from serial port, and update your graph regularly.

Try something like that:
BackgroundWorker worker;
List<float> measures;
public Form1()
{
    InitializeComponent();

    measures = new List<float>();

    worker = new BackgroundWorker();
    worker.DoWork += (sender, e) =>
    {
        //put all your serial port code here
        ...

        //when you want to update the measures list
        lock (measures)
        {
            measures.Add(...);
        }

        //sometimes update the graph
        BeginInvoke((Action)(() =>
        {
            lock (measures)
            {
                //fill your PointPairList from the measures
                ...
            }
            zedGraphControl1.AxisChange();
            zedGraphControl1.Invalidate();
        }));
    };
}
private void button1_Click(object sender, EventArgs e)
{
    //starts the worker
    worker.RunWorkerAsync();
}


-----------------------------------------------------------------

You didn't follow what I said... Let's write it another way, maybe it will be simpler like that:

    public partial class Form1 : Form
    {
        /// List of double: do not forget the <double>!!
        /// This is a the list of the new measures since the last update
        List<double> measures;
        /// The ZedGraph curve
        LineItem myCurve;
        BackgroundWorker worker;
        public Form1()
        {
            InitializeComponent();
            //create an empty list
            measures = new List<double>();
            //init your zegGraphControl here
            ...
            //create an empty curve: it will be filled later
            myCurve = myPane.AddCurve("Porsche", null, Color.Red, SymbolType.Diamond);
            //create the worker
            worker = new BackgroundWorker();
            // set this to true so that you can cancel the worker
            worker.SupportsCancellation = true;
            worker.DoWork += worker_DoWork;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            //start the worker
            worker.RunWorkerAsync();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            //stop the worker
            worker.CancelAsync();
        }
        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //the worker has completed
            //do whatever you want here
            ...
        }
        private worker_DoWork(object sender, DoWorkEventArgs e)
        {
            //put all your serial port code here
            SerialPort sprt = new SerialPort("COM3");
            sprt.BaudRate = 9600;
            sprt.Parity = Parity.None;
            sprt.StopBits = StopBits.One;
            sprt.DataBits = 8;
            sprt.Handshake = Handshake.None;
            try
            {
                sprt.Open();
            }
            catch (Exception)
            {
                MessageBox.Show("Check port");
                return;
            }
            //worker.CancellationPending will change to true when CancelAsync is called
            //(so when the user clicks button2).
            //while the worker should still continue, read incoming data
            while (!worker.CancellationPending)
            {
                //wait for data to come...
                System.Threading.Thread.Sleep(100);
                string indata = sprt.ReadExisting();
                //extract the values from the read data
                //be careful here: make sure the read data is complete...
                string[] splt = indata.Split(':');
                string chop = splt[2];
                string final = chop.Remove(5);
                float d = Convert.ToSingle(final);
                //update the measures
                //measures is shared by several threads: you must lock it to access it safely
                lock (measures)
                {
                    measures.Add(d);
                }
                //update the graph
                BeginInvoke((Action)(() => UpdateGraph()));
            }
            //user wants to stop the worker
            sprt.Close();
        }
        /// This function is called when the graph should be updated
        private void UpdateGraph()
        {
            //messures is shared by several threads: you must lock it to access it safely
            lock (measures)
            {
                //add each measure into the curve
                for (int i = 0; i < measures.Count; i++)
                {
                    //fill each with what ever you want
                    double x = myCurve.Points.Count;
                    double y = measures[i];
                    //add a new point to the curve
                    myCurve.AddPoint(x, y);
                }
                //all measures have been added
                //we can empty the list
                measures.Clear();
            }
            //the curve has been updated so refresh the graph
            zedGraphControl1.AxisChange();
            zedGraphControl1.Invalidate();
        }
    }
</double>


I suggest that your read tutorials about using BackgroundWorker: there is a lot on internet.
The code I gave you should work at least for updating the graph (for example, try it without the serial port code, give some fake values after ReadExisting).

If you still can't get your data, check that you read proper data from the serial port with the debugger.
   
v4
Comments
steven8Gerrard 29-Jul-11 8:17am
   
Thanks for the reply . never used BGworker before tried this .

Cant understand this line measures = new List<float>();

and when i use measures.Add(...); it shows error . What identifier should i give
Olivier Levrey 29-Jul-11 9:58am
   
List is a generic class, you must specialize it with a type: write List<float> or List<int> for example.

Use the Add method to add values to your measures list.

And don't recreate the curve inside BeginInvoke. Initialize your graph and create the curve in the constructor for example, and inside BeginInvoke put only the code to update the curve points.
steven8Gerrard 30-Jul-11 3:18am
   
I tried using your method but it has problems receiving the data from serial port . This is the code . Have i done it correctly .

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;
using System.IO.Ports;
using System.Threading;

namespace BGworker
{
public partial class Form1 : Form
{
List measures;
SerialPort sprt;
string indata,final;
double d;
BackgroundWorker worker;

public Form1()
{
InitializeComponent();
measures = new List();
//fill your PointPairList from the measures
zedGraphControl1.Location = new Point(10, 10);
// Leave a small margin around the outside of the control

zedGraphControl1.Size = new Size(ClientRectangle.Width - 20,
ClientRectangle.Height - 20);
ZedGraphControl zgc = zedGraphControl1;
GraphPane myPane = zgc.GraphPane;
myPane.Title.Text = "Zedgraph";
myPane.XAxis.Title.Text = "Battery";
myPane.YAxis.Title.Text = "Temp";
double x, y1;

PointPairList list1 = new PointPairList();

worker = new BackgroundWorker();
worker.DoWork += (sender, e) =>
worker = new BackgroundWorker();
worker.DoWork += (sender, e) =>
{
//put all your serial port code here
sprt = new SerialPort("COM3");

sprt.BaudRate = 9600;
sprt.Parity = Parity.None;
sprt.StopBits = StopBits.One;
sprt.DataBits = 8;
sprt.Handshake = Handshake.None;


try
{
sprt.Open();
}
catch (Exception)
{
MessageBox.Show("Check port");
}
indata = sprt.ReadExisting();
//MessageBox.Show(indata);

string[] splt = indata.Split(':');
string chop = splt[2];
final = chop.Remove(5);
d = Convert.ToDouble(final);


//when you want to update the measures list
lock (measures)
{
measures.Add(d);
}

//sometimes update the graph
BeginInvoke((Action)(() =>
{
lock (measures)
{


for (int i = 0; i < 3; i++)
{
x = (double)i + 3.5;
//y1 = 5;
//d = 10;

list1.Add(x, d);

}
LineItem myCurve = myPane.AddCurve("Porsche",
list1, Color.Red, SymbolType.Diamond);
}
zedGraphControl1.AxisChange();
zedGraphControl1.Invalidate();
}));
};
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button2_Click(object sender, EventArgs e)
{
sprt.Close();
}

private void button1_Click(object sender, EventArgs e)
{
worker.RunWorkerAsync();
}
}
}
steven8Gerrard 31-Jul-11 5:07am
   
I'm unable to read the data using the above coding
leemingug 6-Feb-13 4:57am
   
kk
Steven and Olivier, greetings.
I ask permission to join with you.
I'm looking for a solution in C # for the following problem:
I have a converter USB/485 connected to your PC, plugged into the converter, I have six Laser Particle Counter (LPC).
What identifies each of the LPC is ID:
ID01, ID02, ID03, ID04, ID05 and ID06.
How do I put my equipment within your code?
Help needed.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900