如何使用具有多个传感器的SerialPort中的数据绘制图形

时间:2016-03-13 04:55:04

标签: c# graph charts arduino serial-port

我需要从pH,温度和湿度传感器绘制数据,数据通过串口从arduino发送到PC。

我可以在TextBox中显示数据,但是当我尝试绘制数据时,它不起作用(我不知道该怎么做)。

我可以在不是矩阵时绘制数据,只从一个传感器绘制数据。

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)
    {

    }



}
}

1 个答案:

答案 0 :(得分:0)

让我们假设您已准备好图表,可能是这样的:

    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 \n8.5 23.1 72 \n7.0 25.8 66 \n";

..像这样:

    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..");
            }
        }
    }

我稍微修改了数据,以便更好地显示更改。

  • 请注意,我省略了计时器rt的计数,这就是图表显示带索引x值的点的原因。对于真实的实时情节,可以在这里包括它(*)!

如果您不断添加数据,您的图表很快会变得非常拥挤。

然后您必须从头开始删除旧数据,或者至少设置最小和最大x值以将显示限制为合理数量的数据点,或者打开缩放!

有关这些内容的一些示例和讨论,请参阅here here and here

enter image description here