C#开发上位机绘制光谱图

本文介绍了如何开发一个上位机程序,通过串口接收下位机传送的大量光谱数据,进行数据校验,然后利用PlotView控件实时绘制光谱图。详细展示了数据接收、校验机制以及不同数据处理策略,包括单次数据绘制和平均值计算。
摘要由CSDN通过智能技术生成

1.随笔

由于项目需要开发一款上位机来将下位机传上来的光谱数据绘制成光谱图,特编写了这个光谱图绘制软件。下位机会定时上传一组数据到上位机,每一组数据超过一万字节,上位机每次接收一组数据,就需要判断数据接收是否准确,再绘制成光谱图,并实现图形更新。下面来看下相关代码。

2.串口事件及数据校验

串口事件函数部分的代码

 private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                try
                {
                    //读取数据
                    byte[] ReceiveBytes = new byte[12295]; //用于校验数据
                    int count = serialPort1.BytesToRead; //待读字节数
                    byte[] res = new byte[count];                  
                    serialPort1.Read(res, 0, count); //读到的数据存储到res
                        
                    buffer.AddRange(res); //缓存数据

                    while(buffer.Count >= 2) //至少包含帧头1, 帧尾2
                    {
                        if (buffer[0] == '1')  //帧头验证成功
                        {
                            if (buffer.Count < 12295)
                            {
                                break;   //数据接收未完成
                            }
                            else
                            {                              
                                buffer.CopyTo(0, ReceiveBytes, 0, 12295);//得到完整数据,复制到ReceiveBytes中进行校验
                                buffer.RemoveRange(0, 12295);  //复制完成后删除缓存数据

                                //开始校验
                                if (ReceiveBytes[12290] != '2') //帧尾验证失败
                                {
                                    buffer.RemoveRange(0, buffer.Count);
                                    continue;
                                }
                                else  //帧尾验证成功
                                {
                                    dataList.Enqueue(Encoding.ASCII.GetString(ReceiveBytes.ToArray()));
                                }
                            }
                        } 
                        else    //帧头验证失败
                        {
                            buffer.Clear();
                        }
                    } 
                    
                }
                catch
                {
                    MessageBox.Show("错误!!!", "提示");
                }
            }
        }

3.绘图部分

绘图控件引用的是Plot View控件,可实现放大缩小空能。使用定时器去读取检验后的数据列表,可以选择来一组数就绘制一次光谱图,也可以选择,多组数求平均值绘制成光谱图。

private void Timer1_Tick(object sender, EventArgs e)  //定时器:图形显示事件
        {
            if (CountsSample == 1)
            {
                double temp;
                if (dataList.Count > 0)
                {
                    timer1.Stop();
                    var lineSer = plotView1.Model.Series[0] as LineSeries;
                    string str = dataList.Dequeue();
                    if (str[0] == '1' && str[12290] == '2')
                    {
                        string res = str.ToString(); //将字符转化成string
                        string[] data = res.Split(',');
                        if (data[0] == "1" && data[2049] == "2\r\n\r\n")
                        {
                            lineSer.Points.Clear();
                            for (int i = 1; i < 2049; i++)
                            {
                                temp = Convert.ToDouble(data[i]);
                                lineSer.Points.Add(new DataPoint(i, temp));
                            }
                            _myPlotModel.InvalidatePlot(true);
                            Thread.Sleep(100);
                        }
                    }
                    timer1.Start();
                }
                else
                {
                    timer1.Stop();
                    timer1.Start();
                }
            }
            else if (CountsSample != 1)
            {
                if (dataList.Count > CountsSample)
                {
                    timer1.Stop();
                    double[] temp = new double[12295];
                    string str = "";
                    string[,] array = new string[CountsSample,2050];
                    var lineSer = plotView1.Model.Series[0] as LineSeries;
                    for (int i = 0; i <= CountsSample; i++)
                    {
                        str = dataList.Dequeue() + "," + str;
                    }
                    string res = str.ToString(); //将字符转化成string
                    string[] data = res.Split(',');                    
                    for (int i = 0; i < CountsSample; i++)
                    {
                        for (int j = 0; j < 2050; j++)
                        {                                                    
                            array[i,j] = data[j];
                            timer1.Stop();
                            
                            data[j] = data[2050*(i+1)+j];
                        }
                    }                   
                    for (int i = 0; i < 2049; i++)
                    {
                        for (int j = 0; j < CountsSample; j++)
                        {
                            temp[i] = Convert.ToDouble(array[j,i]) + temp[i];
                        }
                    }
                    if (temp[0] == CountsSample )
                    {
                        lineSer.Points.Clear();
                        for (int i = 1; i < 2049; i++)
                        {                          
                            lineSer.Points.Add(new DataPoint(i, temp[i]/CountsSample));
                        }
                        _myPlotModel.InvalidatePlot(true);
                        Thread.Sleep(100);
                    }
                    timer1.Start();
                }
                else
                {
                    timer1.Stop();
                    timer1.Start();
                }               
            }
            else
            {
                timer1.Stop();
                timer1.Start();
            }
        }  

4.结果显示

	图形显示

在这里插入图片描述
数据显示 在这里插入图片描述

  • 15
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值