首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

怎么在serialport控件的dataReceived事件中将读取的数据更新到UI上

2013-08-13 
如何在serialport控件的dataReceived事件中将读取的数据更新到UI上,求助大家好,小弟正在接触一个温度测量

如何在serialport控件的dataReceived事件中将读取的数据更新到UI上,求助
大家好,小弟正在接触一个温度测量方面的项目,采集到的温度数据通过串口传递到上位机,我用的C#的serialport控件,在控件的dataReceived事件里处理接收到的数据(主要是将数处理后显示在波形控件和文本框中),程序运行后出现问题,波形控件一开始可以更新,读取几个数据后就停止不再更新。调试半天找不到问题,看到有网友说,invoke里面不宜放太多方法,是不是这出现什么问题了,有没有什么方法可以不用invoke,将数据分离出去处理呢,求解。多谢。以下是我的代码:


private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
             isReceving = true;//当前正在接收数据
                int Len = serialPort.BytesToRead;//获取缓冲区数据字节数
                if ((Len < 1)||(Len != 7))// 数据包为7个字节
                {
                    isReceving = false;//接收完成标志
                        return;
              }
             byte[] recData = new byte[Len];//新建字节数组,用以接收缓冲区数据
                serialPort.Read(recData, 0, Len);//读取Len字节数据到recData数组

                string recHex = string.Empty;//新建字符串变量
                for (int i = 0; i < recData.Length; i++)
             {
               string strTemp = Convert.ToString(recData[i], 16);//转换成16进制字符
                 if (recData.Length < 2)
                 {
                   strTemp = '0' + strTemp;
                 }


              if (strTemp.Length < 2)
                 {
                   strTemp = '0' + strTemp;
                 }
                  recHex += strTemp;
                }
     string strHead = recHex[0].ToString()+recHex[1].ToString() ;//取出包头
     string strData = recHex[6].ToString() + recHex[7].ToString() + recHex[8].ToString() + recHex[9].ToString();//取出数据

   this.Invoke(new EventHandler(delegate
              {
                    doingHex = true;
                    DateTime dt = new DateTime(year, month, day);
                    switch (strHead)
                     {
                        case "02":
                           {
                           float floatData = Convert.ToInt32(strData, 16) / 10;
                           tbxTemp2.Text = floatData.ToString();
                    xData.Add((float)((DateTime.Now - dt).Ticks) /10000000);//画x轴
                                 yData.Add(floatData);//y轴


                                 zGraph.Refresh();//画波形
                                string strSQL = "insert into tb_Data([反应釜],[日期],[时间],[温度值]) values('" + 2 + "','" + DateTime.Now.ToShortDateString() + "','" + DateTime.Now.ToLongTimeString() + "','" + floatData + "')";
                           dataoperate.getCom(strSQL);//存数据库
                                 }
                              break;
                  case "03":
                       {
                        float floatData = Convert.ToInt32(strData, 16) / 10;
                        tbxTemp3.Text = floatData.ToString();
                  x1Data.Add((float)((DateTime.Now - dt).Ticks) / 10000000);//画x轴
                            y1Data.Add(floatData);//y轴
                            zGraph.Refresh();//更新UI数据
                           string strSQL = "insert into tb_Data([反应釜],[日期],[时间],[温度值]) values('" + 3 + "','" + DateTime.Now.ToShortDateString() + "','" + DateTime.Now.ToLongTimeString() + "','" + floatData + "')";


                       dataoperate.getCom(strSQL);//存数据库
                            }
                             break;
                                                                             
                   default: return;
                         }
                         
                         doingHex = false;
                     }
                 ));

                while (doingHex)
                {
                    //处理串口接收事件及其它系统消息。
                    Application.DoEvents();
                }
                //// ***接收完成状态指示。
                isReceving = false;
           } 
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);


            }
        }

UI 串口
[解决办法]
将所有的耗时操作  绘制图形、访问数据库等  移到Invoke之外

serialport_datareceived()
{
           //处理数据
          //绘制图形
         image = ...
         string = ...
         this.Invoke
         {
              更新界面
              textBox1.Text = string;
              波形控件.data = image
         }
        //访问数据库(如果你确实需要放在这里)
}
[解决办法]
你这里就不该用invoke,不过建议你把处理数据的代码放到线程中,主线程中就是接受数据,然后放入内存,后台线程逐条处理,并通过委托反馈到ui上
[解决办法]
楼主程序是卡在哪里啊?
不知道单片机传递数据的时候是怎么传递的,每次都传递7个字节吗?是不是连续的?
if ((Len < 1)
[解决办法]
(Len != 7))// 数据包为7个字节
{
   isReceving = false;//接收完成标志
   return;
}
如果接收到下位机的数据是连续的,可能Len会超过7字节,那么就执行不了下面的代码

热点排行