2016-11-02 8 views
0

Я пытаюсь графически отображать температуры в реальном времени, которые считываются с использованием команд Modbus. В настоящее время я могу прочитать температуру и нарисовать ее. Однако, как только он рисует первую точку, он не постоянно обновляет график и графический интерфейс.Графическое отображение C# в режиме реального времени в приложении формы окна

Должен ли я запускать это способом, отличным от 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(); 
     } 
    } 
} 
+0

Это классическая проблема newb. В любом оконном приложении есть выделенный поток пользовательского интерфейса. Он запускает насос сообщений (который обрабатывает такие вещи, как когда пользователь нажимает на окно), и отвечает за рисование визуального представления окна. Вы работаете в потоке пользовательского интерфейса. Обычно это нормально, но когда вы выполняете много работы в потоке пользовательского интерфейса, поток пользовательского интерфейса больше не может запускать насос сообщений или рисовать окно. Ваше приложение, похоже, замерзает, обновляется только после завершения. Вот почему мы делаем тяжелую работу над * фоновыми потоками * и переходим к потоку пользовательского интерфейса для публикации обновлений. – Will

+0

Тонны ресурсов там, например, https://stuff.seans.com/2009/05/21/net-basics-do-work-in-background-thread-to-keep-gui-responsive/ или аналогичные результаты поиска. – Will

+0

Где ваша петля? – TaW

ответ

0

Сделайте свой последовательный порт переменной-членом, а затем добавьте таймер в свою форму. Затем вы можете анализировать последовательные данные и добавлять точки данных к своему графику в обратном вызове таймера.