Plotting data from Arduino
In this video I show you how to continue the previous C# code and create a chart. By using a chart you'll be able to visualize the data that comes from the Arduino. I show you the tricks to process the received data and put them on a chart. I also show a simple example for saving the incoming data into a text file.
In order to fully understand this video, please check the previous two videos:
C# source code
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; //Serial port handling using System.Windows.Forms.DataVisualization.Charting; using System.IO; namespace Serial_Arduino { public partial class Form1 : Form { /* * Structure of the input data * col1 \t col2 \t col3 \n * col1 \t col2 \t col3 \n * col1 \t col2 \t col3 \n * . * . * . */ private string[] split = new string[3]; //3 -> because of col1,2,3. private double _split1, _split2, _split3; private double[] Split1, Split2, Split3; //arrays for the split data private int counter; //counter private string foutput; //file-output private SerialPort SerPort; //serial port private string ReceivedData; //received data from serial port. public Form1() { InitializeComponent(); FetchAvailablePorts(); //at the start we check the list of available COM ports InitChart(); //at the start we initialize the chart //creating the arrays. make sure that you have enough space (number in the []) //for dynamic array you might want to use List<>. Split1 = new double[1000]; Split2 = new double[1000]; Split3 = new double[1000]; } void FetchAvailablePorts() { String[] ports = SerialPort.GetPortNames(); //We get the available COM ports AvailablePortsBox.Items.AddRange(ports); } private void ConnectToPort_Click(object sender, EventArgs e) { SerPort = new SerialPort(); //instantiate our serial port SerPort //hardcoding some parameters, check MSDN for more SerPort.BaudRate = 9600; SerPort.PortName = AvailablePortsBox.Text; SerPort.Parity = Parity.None; SerPort.DataBits = 8; SerPort.StopBits = StopBits.One; SerPort.ReadBufferSize = 200000000; SerPort.DataReceived += SerPort_DataReceived; try { SerPort.Open(); } catch(Exception ex) { MessageBox.Show(ex.Message, "Error...!"); } } private void SerPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { ReceivedData = SerPort.ReadLine(); //read the line from the serial port this.Invoke(new Action(ProcessingData)); //at each received line from serial port we "trigger" a new processingdata delegate } private void ProcessingData() //processing received data and plotting it on a chart { try { ReceivedDataBox.Text += ReceivedData.ToString() + Environment.NewLine; //print the received data into the textbox //reminder: col1 \t col2 \t col3 \n split = ReceivedData.Split('\t'); //split the data separated by tabs; split[3] -> split[col1], split[col2], split[col3]; split[i] //parsing the string to double (we expect numbers from the Arduino) Double.TryParse(split[0], out _split1); Double.TryParse(split[1], out _split2); Double.TryParse(split[2], out _split3); //the ith element of the Split array will be the recently parsed _split. Split1[counter] = _split1; Split2[counter] = _split2; Split3[counter] = _split3; //plot DataChart.Series["Channel1"].Points.AddXY(Split1[counter], Split2[counter]); //col1 , col2 DataChart.Series["Channel2"].Points.AddXY(Split1[counter], Split3[counter]); //col1 , col3 DataChart.ChartAreas[0].RecalculateAxesScale(); //recalculate.rescale //handle the output foutput = _split1.ToString() + "\t" + _split2.ToString() + "\t" + _split3.ToString() + Environment.NewLine; //we put together the variables into a string (foutput) again if (FileSavingCheckBox.Checked == true) //file saving, same folder as executable { using (StreamWriter sw = File.AppendText("Outputfile.txt"))//appendtext = the previous file will be continued { sw.Write(foutput); //write the content of foutput into the file } } } catch { } counter++; //the value of the counter is increased by one at each loop (at each new data) //this makes sure that the next series of data is written in the next line of the arrays } private void SendSerialButton_Click(object sender, EventArgs e) { SerPort.WriteLine(SenderTextBox.Text.ToString()); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { try { SerPort.Close(); } catch { } } private void InitChart() //initializing the chart { DataChart.ChartAreas[0].AxisX.IsStartedFromZero = false; //in case we get negative number DataChart.ChartAreas[0].AxisX.MajorGrid.LineWidth = 0; //no grids DataChart.ChartAreas[0].AxisY.MajorGrid.LineWidth = 0; DataChart.ChartAreas[0].AxisX.Title = "X-axis ()"; //name of the x-y axis DataChart.ChartAreas[0].AxisY.Title = "Y-axis ()"; DataChart.ChartAreas[0].AxisX.Enabled = AxisEnabled.True; DataChart.ChartAreas[0].AxisY.Enabled = AxisEnabled.True; DataChart.ChartAreas[0].CursorX.AutoScroll = true; //Check the MSDN documentation! //series for the channel1 Series series = new Series() { Name = "Channel1", Color = System.Drawing.Color.Black, ChartType = SeriesChartType.FastLine, IsXValueIndexed = true }; DataChart.Series.Add(series); //series for the channel2 Series series2 = new Series() { Name = "Channel2", Color = System.Drawing.Color.Red, ChartType = SeriesChartType.FastLine, IsXValueIndexed = true }; DataChart.Series.Add(series2); } } }