【问题标题】:C# real time graphing in a windows form applicationWindows 窗体应用程序中的 C# 实时绘图
【发布时间】:2016-11-02 13:29:01
【问题描述】:

我正在尝试绘制使用 Modbus 命令读取的实时温度图。目前,我能够读取温度并绘制图表。但是,一旦绘制了第一个点,它就不会持续更新图形和 GUI。

我应该以Form1_Load 以外的方法运行它吗?

private void Form1_Load(object sender, EventArgs e)
{
    chart1.ChartAreas.Add("Area");
    chart1.ChartAreas["Area"].AxisX.Minimum = -100;
    chart1.ChartAreas["Area"].AxisX.Maximum = 100;
    chart1.ChartAreas["Area"].AxisX.Interval = 1;
    chart1.ChartAreas["Area"].AxisY.Minimum = -100;
    chart1.ChartAreas["Area"].AxisY.Maximum = 100;
    chart1.ChartAreas["Area"].AxisY.Interval = 1;

    //create a Data object array
    val[] data = new val[5];

    string[] ports = SerialPort.GetPortNames();
    this.comboBox1.DataSource = ports;
    serialPort1.PortName = "COM5";
    using (SerialPort port = new SerialPort("COM5"))
    {
        //start time object
        DateTime start = DateTime.Now;
        int startSec = start.Second;

        port.Open();
        byte slaveID = 1;
        ushort startAddress = 360;
        ushort numOfPoints = 2;
        ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port);

        for (int j = 0; j < 5; j++)
        {
            ushort[] holding_register = master.ReadHoldingRegisters(slaveID, startAddress,
            numOfPoints);

            ushort val1 = holding_register[0];
            ushort val2 = holding_register[1];

            uint t1 = (uint)(holding_register[0]);
            uint t2 = (uint)(holding_register[1] << 16);
            uint temp = (uint)(t1) | (t2);
            byte[] floatVals = BitConverter.GetBytes(temp);
            float f = BitConverter.ToSingle(floatVals, 0);
            c = 5.0 / 9.0 * (f - 32);

            textBox1.Text = c.ToString();

            DateTime current = DateTime.Now;
            int currentSec = current.Second;
            int time = currentSec - startSec;

            chart1.Refresh();

            data[j].time = time;
            data[j].temperature = c;

            chart1.Series[j].Points.Add(new DataPoint(data[j].time, data[j].temperature));

            chart1.Refresh();

            port.Close();
        }
    }
}

【问题讨论】:

  • 这是一个经典的新问题。在任何窗口应用程序中都有一个指定的 UI 线程。它运行一个消息泵(处理诸如用户点击窗口之类的事情),并负责绘制窗口的可视化表示。您正在 UI 线程中工作。通常,这没关系,但是当您在 UI 线程中执行大量工作时,UI 线程无法再运行消息泵或绘制窗口。您的应用程序似乎冻结,仅在您完成后更新。这就是我们在后台线程上做大量工作并过渡到 UI 线程以发布更新的原因。
  • 大量资源,例如 stuff.seans.com/2009/05/21/… 或类似的搜索结果。
  • 你的循环在哪里?
  • 我建议在backgroundworker 中运行您的代码并使用Invoke 来更新您的gui。但正如@TaW 提到的,我看不到你的图表在哪里更新。每次您的 modbus 事件触发并返回数据时,您都应该更新图表。

标签: c# user-interface graph mschart real-time-data


【解决方案1】:

使您的串行端口成为成员变量,然后在您的表单中添加一个计时器。然后,您可以解析串行数据并将数据点附加到计时器回调中的图表。

【讨论】:

    猜你喜欢
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多