Plotting data stream received by a serial port
JohnnyPP wrote at 2012-11-01 21:27:
Hello,
I would like to plot data stream received by a serial port with sampling rate set to 1 Hz. Data stream is generated by a digital temperature sensor TMP102 connected to a microcontroller. The microcontroller sends the temperature values to the PC through serial port. In windows forms there is serial port control which I use to receive the data. All works well, with one exception the plot shows only last value received by the serial port. I am aware that the code I use right now is not optimized to draw a line between received points. I read other similar threads dealing with displaying real time data like:
http://oxyplot.codeplex.com/discussions/398856
http://oxyplot.codeplex.com/discussions/281036
http://oxyplot.codeplex.com/discussions/350457
I also looked at Realtimedemo and Refreshdemo. The answers and code are somehow confusing and complex (I am more involved in hardware than in software).
So my question is: how can I connect data points with a line? I would like to keep the code it as simple as possible.
Thanks in advance!
The code I use:
// -------------------------------------------------------------------------------------------------------------------- // <copyright file="Form1.cs" company="OxyPlot"> // http://oxyplot.codeplex.com, license: Ms-PL // </copyright> // -------------------------------------------------------------------------------------------------------------------- using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System; using System.Windows.Forms; using OxyPlot; using System.Globalization; namespace WindowsFormsDemo { public partial class Form1 : Form { private int i = 0; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { serialPort1.PortName = "COM3"; serialPort1.BaudRate = 9600; serialPort1.DtrEnable = true; serialPort1.Open(); serialPort1.DataReceived += serialPort1_DataReceived; } private void button2_Disconnect_Click(object sender, EventArgs e) { if (serialPort1.IsOpen) { serialPort1.Close(); } } private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { string line = serialPort1.ReadLine(); this.BeginInvoke(new LineReceivedEvent(LineReceived), line); } private delegate void LineReceivedEvent(string line); private void LineReceived(string line) { double dTemperature, dTemperatureRound; try { dTemperature = double.Parse(line, CultureInfo.InvariantCulture); dTemperatureRound = Math.Round(dTemperature, 4); label1.Text = Convert.ToString(dTemperatureRound); var pm = new PlotModel("TMP102 digital temperature sensor", "Temperature data stream") { PlotType = PlotType.Cartesian, Background = OxyColors.White, }; var linearAxisX = new LinearAxis(); linearAxisX.Title = "Sample number"; linearAxisX.Position = AxisPosition.Bottom; linearAxisX.MajorGridlineColor = OxyColor.FromArgb(40, 0, 0, 139); linearAxisX.MajorGridlineStyle = LineStyle.Solid; linearAxisX.MinorGridlineColor = OxyColor.FromArgb(20, 0, 0, 139); linearAxisX.MinorGridlineStyle = LineStyle.Solid; pm.Axes.Add(linearAxisX); var linearAxisY = new LinearAxis(); linearAxisY.Title = "Temperature [°C]"; linearAxisY.Position = AxisPosition.Left; linearAxisY.MajorGridlineColor = OxyColor.FromArgb(40, 0, 0, 139); linearAxisY.MajorGridlineStyle = LineStyle.Solid; linearAxisY.MinorGridlineColor = OxyColor.FromArgb(20, 0, 0, 139); linearAxisY.MinorGridlineStyle = LineStyle.Solid; pm.Axes.Add(linearAxisY); var lineSeries1 = new LineSeries(); lineSeries1.Color = OxyColor.FromArgb(255, 78, 154, 6); lineSeries1.MarkerFill = OxyColor.FromArgb(255, 78, 154, 6); lineSeries1.MarkerStroke = OxyColors.ForestGreen; lineSeries1.MarkerType = MarkerType.Circle; lineSeries1.StrokeThickness = 2; lineSeries1.DataFieldX = "Date"; lineSeries1.DataFieldY = "Value"; lineSeries1.Points.Add(new DataPoint(i, dTemperatureRound)); pm.Series.Add(lineSeries1); plot1.Model = pm; i++; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } }
objo wrote at 2012-11-01 21:41:
I would suggest to create the PlotModel, axes and LineSeries in your form constructor. Call plot1.InvalidatePlot(true) to refresh. Something like this (not tested):
public class Form1 : Form { private readonly LineSeries lineSeries1; private int i; public Form1() { InitializeComponent(); var pm = new PlotModel("TMP102 digital temperature sensor", "Temperature data stream") { PlotType = PlotType.Cartesian, Background = OxyColors.White }; var linearAxisX = new LinearAxis(); linearAxisX.Title = "Sample number"; linearAxisX.Position = AxisPosition.Bottom; linearAxisX.MajorGridlineColor = OxyColor.FromArgb(40, 0, 0, 139); linearAxisX.MajorGridlineStyle = LineStyle.Solid; linearAxisX.MinorGridlineColor = OxyColor.FromArgb(20, 0, 0, 139); linearAxisX.MinorGridlineStyle = LineStyle.Solid; pm.Axes.Add(linearAxisX); var linearAxisY = new LinearAxis(); linearAxisY.Title = "Temperature [°C]"; linearAxisY.Position = AxisPosition.Left; linearAxisY.MajorGridlineColor = OxyColor.FromArgb(40, 0, 0, 139); linearAxisY.MajorGridlineStyle = LineStyle.Solid; linearAxisY.MinorGridlineColor = OxyColor.FromArgb(20, 0, 0, 139); linearAxisY.MinorGridlineStyle = LineStyle.Solid; pm.Axes.Add(linearAxisY); this.lineSeries1 = new LineSeries(); this.lineSeries1.Color = OxyColor.FromArgb(255, 78, 154, 6); this.lineSeries1.MarkerFill = OxyColor.FromArgb(255, 78, 154, 6); this.lineSeries1.MarkerStroke = OxyColors.ForestGreen; this.lineSeries1.MarkerType = MarkerType.Circle; this.lineSeries1.StrokeThickness = 2; this.lineSeries1.DataFieldX = "Date"; this.lineSeries1.DataFieldY = "Value"; pm.Series.Add(this.lineSeries1); plot1.Model = pm; } private void button1_Click(object sender, EventArgs e) { serialPort1.PortName = "COM3"; serialPort1.BaudRate = 9600; serialPort1.DtrEnable = true; serialPort1.Open(); serialPort1.DataReceived += this.serialPort1_DataReceived; } private void button2_Disconnect_Click(object sender, EventArgs e) { if (serialPort1.IsOpen) { serialPort1.Close(); } } private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { string line = serialPort1.ReadLine(); this.BeginInvoke(new LineReceivedEvent(this.LineReceived), line); } private void LineReceived(string line) { double dTemperature, dTemperatureRound; try { dTemperature = double.Parse(line, CultureInfo.InvariantCulture); dTemperatureRound = Math.Round(dTemperature, 4); label1.Text = Convert.ToString(dTemperatureRound); this.lineSeries1.Points.Add(new DataPoint(this.i, dTemperatureRound)); plot1.InvalidatePlot(true); this.i++; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private delegate void LineReceivedEvent(string line); }
Customer support service by UserEcho
if I drag the plot with right click ,shifting was stop,how was it stopped,any offer.Also Can I set time axis? I mean time axis show me long time. I would like to show me for example 20 s update time.