欢迎光临
我的个人博客网站

C#实例(经典):四路光电开关&激光雷达数据采集和波形图绘制

前言:本文全部纯手工打造,如有疏漏之处,还请谅解!

如果需要查看更多文章,请微信搜索公众号 csharp编程大,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! !

 

这篇文章涉及较多C#重要知识点,如果都能看懂,你至少可以算得上入门了!有兴趣的同志可以下载源码调试.

开始吧:

-》指令格式介绍

激光测距模块

UDP: 192.168.1.200  8008发往8010;192.168.1.201    8008发往8011;

协议:C3 00为195cm

C#实例(经典):四路光电开关&激光雷达数据采集和波形图绘制

 

 

 

光电开关模块

UDP:192.168.1.202  8008发往8012

帧头59 59

数据 01 01 01 01 为4个光电开关状态,依次为安检通道入口光电开关、安检门光电开关1、安检门光电开关2,安检通道出口光电开关。其中1为无人遮挡状态,0为有人遮挡状态

填充 44 55 66 77 88 99 00 12 23 34 45 56 67 ee

C#实例(经典):四路光电开关&激光雷达数据采集和波形图绘制

 

 

4个光电开关均无人

 

1、2、3光电开关有人 4光电开关无人

开发软硬件环境:

硬件:1. 4路光电开关,4路测距雷达,数据通过udp发送到主机192.168.1.119

 软件:1. vs2017 + win10 

 

-》重要知识点:

1. 多线程操作:thread和task的使用

2. winform的chart控件使用

3.队列Queue和list使用

4.双缓冲用法

5.定时器操作

6.线程中操作主窗体控件:

this.Invoke((EventHandler)delegate

 {

 richTextBoxEx1.Text += stringData + “rn”;

}):

7.通过循环的方式遍历操作控件

8.数据类型转换:

 Byte[] recv = client.Receive(ref endpoint);

 string stringData = “0x” + BitConverter.ToString(recv).Replace(“-“, ” 0x”).ToLower();

-》开发难点:

1. chart需要绘制所有采集上来的数据点,光电开关1毫秒就一组数据,绘图时间得跟得上

2. 多线程的灵活使用

全部代码:

using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting;  namespace lidarTest {     public partial class mainForm : DevComponents.DotNetBar.Office2007Form     {         public mainForm() {             this.DoubleBuffered = true;//设置本窗体             SetStyle(ControlStyles.UserPaint, true);             SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.             SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲              this.EnableGlass = false;             InitializeComponent();             InitChart();             checkBox2.Checked = false;             checkBox1.Checked = false;         }         private Queue<int>[] dataQueue = new Queue<int>[8];//把Queue<double>看成一个类型 int[] a=new int [8]         private List<int>[] dataList = new List<int>[8];         private Queue<string> dQueue = new Queue<string>();         bool isStart = false;         int count = 0;         private static readonly object Lock = new object();         Stopwatch elapsetime = new Stopwatch();         private void mainForm_Load(object sender, EventArgs e) {             dataQueue[0] = new Queue<int>();             dataQueue[1] = new Queue<int>();             dataQueue[2] = new Queue<int>();             dataQueue[3] = new Queue<int>();             dataQueue[4] = new Queue<int>();             dataQueue[5] = new Queue<int>();             dataQueue[6] = new Queue<int>();             dataQueue[7] = new Queue<int>();              dataList[0] = new List<int>();             dataList[1] = new List<int>();             dataList[2] = new List<int>();             dataList[3] = new List<int>();             dataList[4] = new List<int>();             dataList[5] = new List<int>();             dataList[6] = new List<int>();             dataList[7] = new List<int>();              this.WindowState = FormWindowState.Normal;             this.FormBorderStyle = FormBorderStyle.Sizable;             this.Top = 0;             this.Left = 0;             this.Width = Screen.PrimaryScreen.WorkingArea.Width;             this.Height = Screen.PrimaryScreen.WorkingArea.Height;             Start();              //MessageBox.Show( DateTime.Now.ToString("yyyy_MM_dd_hh_mm_ss_fff"));         }         // 防止闪屏                 //protected override CreateParams CreateParams         //{         //    get         //    {         //        CreateParams cp = base.CreateParams;         //        cp.ExStyle |= 0x02000000;         //        return cp;         //    }         //}          public void Start() {             Thread t1 = new Thread(StartDataRevThread1); //第一路激光雷达数据接收线程             t1.Start();             t1.IsBackground = true;              Thread t2 = new Thread(StartDataRevThread2); //第二路激光雷达数据接收线程             t2.Start();             t2.IsBackground = true;              Thread t3 = new Thread(StartDataRevThread3);//第三路激光雷达数据接收线程             t3.Start();             t3.IsBackground = true;              Thread t4 = new Thread(StartDataRevThread4);////第四路激光雷达数据接收线程             t4.Start();             t4.IsBackground = true;              Thread t5 = new Thread(StartDataRevThread5);//四个广电开关数据接受线程             t5.Start();             t5.IsBackground = true;              Thread t6 = new Thread(dataSaveThread6);//数据写入线程             t6.Start();             t6.IsBackground = true;         }         private void StartDataRevThread1() {             try             {                 UdpClient client = new UdpClient(8021);                 //IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);//                 IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.30"), 8008);                 //client.Client.ReceiveBufferSize = 40960;//40960 默认值是8192                 while (true)                 {                     Byte[] recv = client.Receive(ref endpoint);                     string stringData = "0x" + BitConverter.ToString(recv).Replace("-", " 0x").ToLower();                     this.Invoke((EventHandler)delegate                         {                             //richTextBoxEx1.Text += stringData + "rn";                             chartShow( recv[2] + (recv[3]<<8),1);                         }                         );                 }             }             catch(Exception ex)             {                 MessageBox.Show(ex.Message + "n" + ex.StackTrace) ;             }         }         private void StartDataRevThread2() {             try             {                 UdpClient client = new UdpClient(8022);                 IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.40"), 8008);                 while (true)                 {                     Byte[] recv = client.Receive(ref endpoint);                     string stringData = "0x" + BitConverter.ToString(recv).Replace("-", " 0x").ToLower();                     this.Invoke((EventHandler)delegate                     {                         //richTextBoxEx2.Text += stringData + "rn";                         chartShow(recv[2] + (recv[3] << 8),2);                     }                       );                 }             }             catch (Exception ex)             {                 MessageBox.Show(ex.Message + "n" + ex.StackTrace);             }         }         private void StartDataRevThread3() {             try             {                 UdpClient client = new UdpClient(8023);                 IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.100"), 8008);                 while (true)                 {                     Byte[] recv = client.Receive(ref endpoint);                     string stringData = "0x" + BitConverter.ToString(recv).Replace("-", " 0x").ToLower();                     this.Invoke((EventHandler)delegate                     {                         //richTextBoxEx3.Text += stringData + "rn";                         chartShow( recv[2] + (recv[3] << 8),3);                     }                       );                 }             }             catch (Exception ex)             {                 MessageBox.Show(ex.Message + "n" + ex.StackTrace);             }         }         private void StartDataRevThread4() {             try             {                 UdpClient client = new UdpClient(8024);                 IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.200"), 8008);                 while (true)                 {                     Byte[] recv = client.Receive(ref endpoint);                     string stringData = "0x" + BitConverter.ToString(recv).Replace("-", " 0x").ToLower();                     this.Invoke((EventHandler)delegate                     {                         //richTextBoxEx4.Text += stringData + "rn";                         chartShow( recv[2] + (recv[3] << 8),4);                     }                       );                 }             }             catch (Exception ex)             {                 MessageBox.Show(ex.Message + "n" + ex.StackTrace);             }         }          private void StartDataRevThread5() {             try             {                 UdpClient client = new UdpClient(8012);                 IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.202"), 8008);                 client.Client.ReceiveBufferSize = 1024*1024;//默认值是8192                 while (true)                 {                     Byte[] recv = client.Receive(ref endpoint);                     elapsetime.Restart();//计时开始                     this.Invoke((EventHandler)delegate                     {                         //if (count >= 100)                         {                             count = 0;                             Task.Run(() =>                             {                                 chartShow(recv[2], 5);                             }                             );                             Task.Run(() =>                             {                                 chartShow(recv[3], 6);                             }                             );                             Task.Run(() =>                             {                                 chartShow(recv[4], 7);                             }                            );                             Task.Run(() =>                             {                                 chartShow(recv[5], 8);                             }                           );                             //chartShow(recv[2], 5);                             //chartShow(recv[3], 6);                             //chartShow(recv[4], 7);                             //chartShow(recv[5], 8);                              if (checkBox2.Checked == true)                             {                                 string stringData = "0x" + BitConverter.ToString(recv).Replace("-", " 0x").ToLower();                                 dQueue.Enqueue(DateTime.Now.ToString("yyyy-MM-dd_HH:mm:ss:fff") + "  " + stringData);                             }                                                    }                         count++;                      } );                     elapsetime.Stop();//计时结束                     this.Invoke((EventHandler)delegate                     {                         label1.Text = "接收数据耗时:"+ elapsetime.ElapsedMilliseconds.ToString("0000");                     });                 }             }             catch (Exception ex)             {                 MessageBox.Show(ex.Message + "n" + ex.StackTrace);             }         }         private void dataSaveThread6() {             while (true)             {                 if (checkBox2.Checked == true)                 {                     String LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log");                     if (dQueue.Count() > 0)                         strWrite(dQueue.Dequeue(), LogPath, "log.txt");                 }             }         }         private void InitChart() {             Chart[] ch = new Chart[12] { chart1, chart2, chart3, chart4,chart5, chart6, chart7, chart8 , chart_1, chart_2, chart_3, chart_4 };             for (int i = 0; i < 4 ; i++)             {                 ch[i].ChartAreas.Clear();                 ChartArea chartArea1 = new ChartArea("C1");                 ch[i].ChartAreas.Add(chartArea1);                 //定义存储和显示点的容器                 ch[i].Series.Clear();                 Series series1 = new Series("S1");                 series1.ChartArea = "C1";                 ch[i].Series.Add(series1);                  ch[i].ChartAreas[0].AxisY.IsStartedFromZero = false;                 ch[i].Legends[0].Enabled = false;                  ch[i].ChartAreas[0].AxisX.Interval = 100;                 ch[i].ChartAreas[0].AxisX.Maximum = 1000;                 //ch[i].ChartAreas[0].AxisX.ScaleView.Size = 8;//设置图表可视区域数据点数,说白了一次可以看到多少个X轴区域                  ch[i].ChartAreas[0].Axes[0].MajorGrid.Enabled = false;                 ch[i].ChartAreas[0].Axes[1].MajorGrid.Enabled = false;                 //y轴上网格                 //ct.ChartAreas[0].Axes[1].MajorGrid.Enabled = false;                   //ch[i].ChartAreas[0].AxisX.IsStartedFromZero = false;                 //ch[i].ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Silver;                 //ch[i].ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Silver;                 //设置标题                 ch[i].Titles.Clear();                 //ch[i].Titles.Add("S01");                 //ch[i].Titles[0].Text = "通道" + (i + 1) + " 折线图显示";                 //ch[i].Titles[0].ForeColor = Color.RoyalBlue;                 //ch[i].Titles[0].Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);                 //设置图表显示样式                 ch[i].Series[0].Color = Color.Red;                 //this.chart1.Titles[0].Text = string.Format("{0}折线图显示", );                 ch[i].Series[0].ChartType = SeriesChartType.FastLine;                 ch[i].Series[0].Points.Clear();             }             for (int i = 4; i < 12; i++)             {                 ch[i].ChartAreas.Clear();                 ChartArea chartArea1 = new ChartArea("C1");                 ch[i].ChartAreas.Add(chartArea1);                 //定义存储和显示点的容器                 ch[i].Series.Clear();                 Series series1 = new Series("S1");                 series1.ChartArea = "C1";                 ch[i].Series.Add(series1);                  ch[i].ChartAreas[0].AxisY.IsStartedFromZero = false;                 ch[i].Legends[0].Enabled = false;                  //ch[i].ChartAreas[0].AxisX.Interval = 100;                 //ch[i].ChartAreas[0].AxisX.Maximum = 10000;                 //ch[i].ChartAreas[0].AxisX.ScaleView.Size = 8;//设置图表可视区域数据点数,说白了一次可以看到多少个X轴区域                  ch[i].ChartAreas[0].Axes[0].MajorGrid.Enabled = false;                 ch[i].ChartAreas[0].Axes[1].MajorGrid.Enabled = false;                 //y轴上网格                 //ct.ChartAreas[0].Axes[1].MajorGrid.Enabled = false;                   //ch[i].ChartAreas[0].AxisX.IsStartedFromZero = false;                 //ch[i].ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Silver;                 //ch[i].ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Silver;                 //设置标题                 ch[i].Titles.Clear();                 //ch[i].Titles.Add("S01");                 //ch[i].Titles[0].Text = "通道" + (i + 1) + " 折线图显示";                 //ch[i].Titles[0].ForeColor = Color.RoyalBlue;                 //ch[i].Titles[0].Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);                 //设置图表显示样式                 ch[i].Series[0].Color = Color.Red;                 //this.chart1.Titles[0].Text = string.Format("{0}折线图显示", );                 ch[i].Series[0].ChartType = SeriesChartType.FastLine;                 ch[i].Series[0].Points.Clear();             }         }          public void chartShow(int y, int ch) {              Chart[] chNum = new Chart[8] { chart_1, chart_2, chart_3, chart_4, chart5, chart6, chart7, chart8 };             if (ch <= 8)                 chartDisplay(chNum[ch - 1], ch, y);          }         delegate void ChartDelegate(Chart chart, int ch, int y);         private void chartDisplay(Chart chart, int ch, int y) {              if (chart.InvokeRequired)             {                 ChartDelegate chartDelegate = chartDisplay;                 chart.Invoke(chartDelegate, new object[] { chart, ch, y });             }             else             {                 lock (Lock)                 {                     if (isStart == true)                         UpdateQueueValue(ch, y);//点击开启按钮后,开始采集收集数据,并更新到队列或列表中                                     }             }         }         private void UpdateQueueValue(int ch, int y) {             lock (Lock)             {                 if (dataQueue[ch - 1].Count > 1000)                     //先出列                     dataQueue[ch - 1].Dequeue();                 dataQueue[ch - 1].Enqueue(y);                 //方法二 用list                 //if (dataList[ch - 1].Count > 20000)                //     dataList[ch - 1].RemoveAt(0);                                 //dataList[ch - 1-4].Add(2);                 dataList[ch - 1].Add(y);             }         }         private void btnStart_Click(object sender, EventArgs e) {              if (!isStart)             {                dataQueue[0] = new Queue<int>();                dataQueue[1] = new Queue<int>();                dataQueue[2] = new Queue<int>();                dataQueue[3] = new Queue<int>();                dataQueue[4] = new Queue<int>();                dataQueue[5] = new Queue<int>();                dataQueue[6] = new Queue<int>();                dataQueue[7] = new Queue<int>();                  dataList[0] = new List<int>();                 dataList[1] = new List<int>();                 dataList[2] = new List<int>();                 dataList[3] = new List<int>();                 dataList[4] = new List<int>();                 dataList[5] = new List<int>();                 dataList[6] = new List<int>();                 dataList[7] = new List<int>();                  chart_1.Series[0].Points.Clear();                 chart_2.Series[0].Points.Clear();                 chart_3.Series[0].Points.Clear();                 chart_4.Series[0].Points.Clear();                 chart5.Series[0].Points.Clear();                 chart6.Series[0].Points.Clear();                 chart7.Series[0].Points.Clear();                 chart8.Series[0].Points.Clear();                  btnStart.Text = @"停止采集";                 btnStart.DisabledImage = btnStart.Image;                 btnStart.Image = (Image)btnStart.PressedImage.Clone();                 isStart = !isStart;              }             else             {                 btnStart.Text = @"开始采集";                 btnStart.Image = btnStart.DisabledImage;                 isStart = !isStart;             }         }         /*************文件写入函数**************/         private void strWrite(string str, string filePath, string fileName) {             lock (Lock)             {                 if (!Directory.Exists(filePath))                     Directory.CreateDirectory(filePath);                 if (!File.Exists(filePath + "\" + fileName))                     File.Create(filePath + "\" + fileName).Close(); //.Close 很关键,不然会有问题                  StreamWriter sw = new StreamWriter(filePath + "\" + fileName, true);//true 追加数据                 sw.WriteLine(str);                 sw.Close();             }                  }         /*************chart图片保存函数**************/         private void imageSave( Chart chart, string filePath, string fileName) {             lock (Lock)             {                 if (!Directory.Exists(filePath))                     Directory.CreateDirectory(filePath);                 chart.SaveImage(filePath +"\" + fileName, ChartImageFormat.Png);             }         }          /*************定时器中更新chart**************/         private void timer1_Tick(object sender, EventArgs e) {              Chart[] ch = new Chart[8] { chart1, chart2, chart3, chart4, chart5, chart6, chart7, chart8 };             Chart[] cha = new Chart[4] { chart_1, chart_2, chart_3, chart_4 };             string[] str = new string[8] { "chart1", "chart2", "chart3", "chart4", "chart5", "chart6", "chart7", "chart8" };             string[] stri = new string[4] { "chart_1", "chart_2", "chart_3", "chart_4",  };             Label[] lb = new Label[4] { label2, label3, label4, label5 };                           for (int j = 4; j < 8; j++)             {                 Stopwatch sw = new Stopwatch();                 var k = j;//参数需要传入task中,不然j一直是7                 Task.Run(() =>             {                  sw.Start();                 this.Invoke((EventHandler)delegate                 {                     //chart5.Series[0].Points.Clear();                     for (int i = 0; i < dataList[k].Count; i++)                         ch[k].Series[0].Points.AddY(dataList[k][i]);//光电开关波形图-所有点                     dataList[k].Clear();                      ch[k-4].Series[0].Points.Clear();                     for (int i = 0; i < dataQueue[k].Count; i++)                         ch[k - 4].Series[0].Points.AddY(dataQueue[k].ElementAt(i));//光电开关波形图-最近1000个点                       for (int i = 0; i < dataList[k-4].Count; i++)                         cha[k - 4].Series[0].Points.AddY(dataList[k-4][i]);//激光测距雷达波形图--所有点                     dataList[k-4].Clear();                      if (checkBox1.Checked == true)                     {                         //保存曲线图片                         String imagePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "image//" + str[k]);                         imageSave(ch[k], imagePath, DateTime.Now.ToString("yyyy_MM_dd_hh_mm_ss_fff") + ".png");                     }                     sw.Stop();                     lb[k - 4].Text = sw.ElapsedMilliseconds.ToString(str[k] + "耗时:" + "0000");//记录chart绘制的好事呢                 });              });             }           }        } } 

  运行结果:

C#实例(经典):四路光电开关&amp;激光雷达数据采集和波形图绘制

 

 

项目源码下载地址:

链接:https://pan.baidu.com/s/1QfoIVNarj-rgK449JM40yQ 

提取码:v2nu 

————————————————————————

如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! !

赞(0) 打赏
未经允许不得转载:张拓的天空 » C#实例(经典):四路光电开关&激光雷达数据采集和波形图绘制
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

专业的IT技术经验分享 更专业 更方便

联系我们本站主机

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏