FeliceM
FeliceM

Reputation: 4219

Graph dynamic update

I have an application that acquires temperature data from the serial port every time that the temperature changes. The value get stored in a variable and is shown in a text box. I would like to show the temperature versus time in a graph. I have setup the graph as following but I don't know where to start to get the temperature line updated versus time every second.

 InitializeComponent();
        //Chart
        chart1.ChartAreas.Add("areas");
        chart1.ChartAreas["areas"].AxisX.Minimum = 0;
        chart1.ChartAreas["areas"].AxisX.Interval = 1;
        chart1.ChartAreas["areas"].AxisY.Minimum = 0;
        chart1.ChartAreas["areas"].AxisY.Maximum = 250;
        chart1.ChartAreas["areas"].AxisY.Interval = 10;
        chart1.ChartAreas["areas"].AxisX.Title = "Time [s]";
        chart1.ChartAreas["areas"].AxisY.Title = "Temperature [°C]";
        chart1.Series.Add("Temperature");
        chart1.Series["Temperature"].Color = Color.Red;
        chart1.Series["Temperature"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
        chart1.Titles.Add("Extruder Temperature");

       //this two lines are only to see something in the graph
        chart1.Series["Temperature"].Points.AddXY(0, 20);
        chart1.Series["Temperature"].Points.AddXY(1, 50);
    }

I think I need to update the "point" and the "value" (0, 20) by replacing the values with the variables but if I do so, I have only one point in the graph and I cannot show the previous values. Being a beginner I would appreciate some help.

Upvotes: 0

Views: 5768

Answers (2)

DasKrümelmonster
DasKrümelmonster

Reputation: 6060

After you acquired new data, simply add another Datapoint: Just to give you an idea (as you haven't posted your data receive method):

OnSerialReceive()
{
    var temp = serialport.read();
    var time = (int)stopwatch.Elapsed.TotalSeconds;
    chart1.Series["Temperature"].Points.AddXY(time, temp);
}

And yes, as soon as you get real data into your diagram, you will want to remove your fake data. Fake data is confusing.

Upvotes: 1

jle
jle

Reputation: 9489

An alternative way (to refresh every second) is to use a BackgroundWorker. This question give an example. Essentially, you start a background thread that updates the view every set amount of time.

private BackgroundWorker _bw;

....
    InitializeComponent();
    _bw = new BackgroundWorker
    {
      WorkerReportsProgress = true,
      WorkerSupportsCancellation = true
    };
    _bw.DoWork += bw_DoWork;
    _bw.ProgressChanged += bw_ProgressChanged;
    _bw.RunWorkerCompleted += bw_RunWorkerCompleted;

    _bw.RunWorkerAsync ("Hello to worker");
     if (_bw.IsBusy) _bw.CancelAsync();
  }

  private void bw_DoWork (object sender, DoWorkEventArgs e)
  {

      if (_bw.CancellationPending) { e.Cancel = true; return; }
      var dataPoints = YourConnectToSerialPortAndGetDataFunction();
      _bw.ReportProgress (dataPoints);
      Thread.Sleep (1000); 

    e.Result = dataPoints;    // This gets passed to RunWorkerCompleted
  }

  private void bw_RunWorkerCompleted (object sender,
                                     RunWorkerCompletedEventArgs e)
  {

}

  private void bw_ProgressChanged (object sender,
                                  ProgressChangedEventArgs e)
  {
//UPDATE YOUR LABEL
chart1.Series["Temperature"].Points.AddXY(0, 20);
        chart1.Series["Temperature"].Points.AddXY(1, 50);
  }

Upvotes: 2

Related Questions