如何用来自具有多个传感器的串行端口的数据绘制图形 [英] How to plot graphs with data from a SerialPort with multiple sensors
问题描述
我需要从pH,温度和湿度的传感器绘制数据,数据作为矩阵从arduino发送到PC通过串行端口。
我可以在TextBox中显示数据,但是当我试图绘制数据时,它不工作(我不知道该怎么做)。
我只是可以绘制数据时,不是一个矩阵,它是来自一个传感器的数据。
使用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 System.Threading.Tasks;
using System.IO.Ports;
using System.Windows.Forms.DataVisualization.Charting;
命名空间grafik1
{
public partial class Form1:Form
{
private SerialPort sensport;
private DateTime datetime;
private string data;
private string data2;
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender,EventArgs e)
{
comboBox1.DataSource = SerialPort.GetPortNames();
timer1.Start();
}
双rt = 0;
Boolean i = false;
private void timer1_Tick(object sender,EventArgs e)
{
rt = rt + 0.1;
}
private void Form1_FormClosed(object sender,FormClosedEventArgs e)
{
sensport.Close();
}
private void button1_Click(object sender,EventArgs e)
{
if(comboBox2.Text ==)
{
MessageBox.Show(Error);
}
else
{
sensport = new SerialPort();
sensport.BaudRate = int.Parse(comboBox2.Text);
sensport.PortName = comboBox1.Text;
sensport.Parity = Parity.None;
sensport.DataBits = 8;
sensport.StopBits = StopBits.One;
sensport.Handshake = Handshake.None;
sensport.DataReceived + = sensport_DataReceived;
try
{
sensport.Open();
textBox1.Text =;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message,Error);
}
}
}
void sensport_DataReceived(object sender,SerialDataReceivedEventArgs e)
{
if(i == false)
{
rt = 0;
i = true;
}
data = sensport.ReadLine();
this.chart1.Series [Data1]。Points.AddXY(rt,data);
this.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 。第二;
txtData.AppendText(time +\t+ data +\\\
);
}
private void button2_Click(object sender,EventArgs e)
{
string directorio = textBox1.Text;
if(directorio ==)
{
MessageBox.Show(Error);
}
else {
try
{
stringkayıtyeri= @+ directorio +;
this.chart1.SaveImage((+ kayityeri +),ChartImageFormat.Png);
MessageBox.Show(Grafica guardada en+kayıtyeri);
}
catch(Exception ex3)
{
MessageBox.Show(ex3.Message,Error);
}
}
}
private void label4_Click(object sender,EventArgs e)
{
}
private void comboBox1_SelectedIndexChanged(object sender,EventArgs e)
{
}
private void button3_Click sender,EventArgs e)
{
sensport.Close();
}
private void button4_Click(object sender,EventArgs e)
{
try
{
string pathfile = @C:\Users\MARIO GONZALEZ\Google Drive\VisualStudio\Arduino0_1\DATA;
string filename =arduinoRTPv1.xls;
System.IO.File.WriteAllText(pathfile + filename,txtData.Text);
MessageBox.Show(Data saved);
}
catch(Exception ex3)
{
MessageBox.Show(ex3.Message,Error);
}
}
private void button5_Click(object sender,EventArgs e)
{
}
private void chart1_Click(object sender,EventArgs e)
{
}
}
}
让我们假设你已经准备好了你的图表, :
chart1.Series.Clear();
chart1.Series.Add(ph);
chart1.Series.Add(Temp);
chart1.Series.Add(Hum);
chart1.Series [ph]。ChartType = SeriesChartType.Line;
chart1.Series [Temp]。ChartType = SeriesChartType.Line;
chart1.Series [Hum]。ChartType = SeriesChartType.Line;
chart1.ChartAreas [0] .AxisY2.Enabled = AxisEnabled.True;
chart1.ChartAreas [0] .AxisY2.Title =Temp;
chart1.ChartAreas [0] .AxisY2.Maximum = 100;
现在,您可以添加一个包含一些数据块的字符串,如注释中所示。
string data =7.5 23.8 67 \\\
8.5 23.1 72 \\\
7.0 25.8 66 \\\
;
..像这样:
var dataBlocks = data.Split('\\\
');
foreach(data block中的var块)
{
var numbers = block.Split(new [] {''},StringSplitOptions.RemoveEmptyEntries);
// rt + = someTime; (*)
for(int i = 0; i< numbers.Length; i ++)
{
double n = double.NaN;
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,0);
chart1.Series [i] .Points [p] .IsEmpty = true;
Console.WriteLine(some error message ..);
}
}
}
- 请注意,我没有计数你的计时器
rt
,这就是图表显示带有索引x值的点的原因。
如果你继续添加数据,你的图表很快会变得非常拥挤。
然后,您必须从开始删除旧数据,或至少设置最小和最大x值,以将显示限制为合理数量的数据点,或开启缩放!
请参阅
I need to plot data from sensors of pH, Temperature and Humidity, the data is sent as a matrix from arduino to PC through the serial port.
I can show the data in a TextBox, but when I try to plot the data, it doesn't work (I don't know how to do it).
I just can plot the data when is not a matrix and it's data from just one sensor.
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 System.Threading.Tasks;
using System.IO.Ports;
using System.Windows.Forms.DataVisualization.Charting;
namespace grafik1
{
public partial class Form1 : Form
{
private SerialPort sensport;
private DateTime datetime;
private string data;
private string data2;
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DataSource = SerialPort.GetPortNames();
timer1.Start();
}
double rt = 0;
Boolean i = false;
private void timer1_Tick(object sender, EventArgs e)
{
rt = rt + 0.1;
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
sensport.Close();
}
private void button1_Click(object sender, EventArgs e)
{
if (comboBox2.Text == "")
{
MessageBox.Show("Error");
}
else
{
sensport = new SerialPort();
sensport.BaudRate = int.Parse(comboBox2.Text);
sensport.PortName = comboBox1.Text;
sensport.Parity = Parity.None;
sensport.DataBits = 8;
sensport.StopBits = StopBits.One;
sensport.Handshake = Handshake.None;
sensport.DataReceived += sensport_DataReceived;
try
{
sensport.Open();
textBox1.Text = "";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
}
}
void sensport_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (i == false)
{
rt = 0;
i = true;
}
data = sensport.ReadLine();
this.chart1.Series["Data1"].Points.AddXY(rt, data);
this.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;
txtData.AppendText(time + "\t" + data + "\n");
}
private void button2_Click(object sender, EventArgs e)
{
string directorio = textBox1.Text;
if (directorio == "")
{
MessageBox.Show("Error");
}
else {
try
{
string kayıtyeri = @"" + directorio + "";
this.chart1.SaveImage(("+kayityeri+"), ChartImageFormat.Png);
MessageBox.Show("Grafica guardada en " + kayıtyeri);
}
catch (Exception ex3)
{
MessageBox.Show(ex3.Message, "Error");
}
}
}
private void label4_Click(object sender, EventArgs e)
{
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button3_Click(object sender, EventArgs e)
{
sensport.Close();
}
private void button4_Click(object sender, EventArgs e)
{
try
{
string pathfile = @"C:\Users\MARIO GONZALEZ\Google Drive\VisualStudio\Arduino0_1\DATA";
string filename = "arduinoRTPv1.xls";
System.IO.File.WriteAllText(pathfile + filename, txtData.Text);
MessageBox.Show("Data saved");
}
catch (Exception ex3)
{
MessageBox.Show(ex3.Message, "Error");
}
}
private void button5_Click(object sender, EventArgs e)
{
}
private void chart1_Click(object sender, EventArgs e)
{
}
}
}
Let's assume you have prepared your chart, maybe like this:
chart1.Series.Clear();
chart1.Series.Add("ph");
chart1.Series.Add("Temp");
chart1.Series.Add("Hum");
chart1.Series["ph"].ChartType = SeriesChartType.Line;
chart1.Series["Temp"].ChartType = SeriesChartType.Line;
chart1.Series["Hum"].ChartType = SeriesChartType.Line;
chart1.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True;
chart1.ChartAreas[0].AxisY2.Title = "Temp";
chart1.ChartAreas[0].AxisY2.Maximum = 100;
Now you can add a string that contains some data blocks as shown in the comments..
string data = "7.5 23.8 67 \n8.5 23.1 72 \n7.0 25.8 66 \n";
..like this:
var dataBlocks = data.Split('\n');
foreach (var block in dataBlocks)
{
var numbers = block.Split(new [] {' '}, StringSplitOptions.RemoveEmptyEntries);
// rt += someTime; (*)
for (int i = 0; i < numbers.Length; i++)
{
double n = double.NaN;
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, 0);
chart1.Series[i].Points[p].IsEmpty = true;
Console.WriteLine("some error message..");
}
}
}
I have modified the data a little to show the changes a little better..
- Note that I left out the counting up of your timer
rt
, which is why the chart shows the points with indexed x-values. For a real realtime plot do include it maybe here (*) !
If you keep adding data your chart will soon get rather crowded.
You will then either have to remove older data from the beginning or at least set a minimum and maximum x-values to restrict the display to a reasonably number of data points and or turn on zooming!
See here here and here for some examples and discussions of these things!
这篇关于如何用来自具有多个传感器的串行端口的数据绘制图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!