UAV-jack 发表于 2024-2-23 10:29:59

C# winfrom实例:四路激光测距雷达数据采集和波形图绘制

1.所述产品 产品型号:TFmini Plus
产品名称:TFmini Plus激光雷达模组
制造商
公司:北醒(北京)光子科技有限公司


2.产品功能:TFmini Plus是基于TFmini的升级项目,它是一款小型化,单点测距的产品,基于TOF(飞行 时间)原理,配合独特的光学、电学、算法设计,主要实现稳定、精准、高灵敏度和高速的距离测 量的功能。产品本身除了具有TFmini的低成本、小体积、测距远等特点外,还增加了IP65等级防 护,测距精度更高,对于室外强光、不同温度、不同反射率等不同环境下适应性更强,更低功耗, 探测频率也更加灵活。产品同时兼容UART和I2C通信接口,可通过指令进行切换


3. 串口数据通信 TFmini Plus串口数据通信,详见表 66。
表 6 TFmini Plus数据通信协议——UART

通信接口 UART 默认波特率 115200 数据位 8 停止位 1 奇偶校验 None
4. 串口数据输出格式及编码
TFmini Plus 有两种数据输出格式,标准数据输出格式和字符串数据格式,两种格式可通过指 令代码相互切换。
-。标准数据输出格式(默认) : 数据结构:数据帧长度为9字节。包含距离信息(Distance)、信号强度信息(Strength)、温度 (Temp)、数据校验字节(Checksum)等。数据格式为16进制(HEX)。具体数据编码详见下表:

-。字符串数据格式(Pix Mode) 以字符串形式输出,单位为m,比如测距为1.21m,则输出字符串1.21,后跟转义字符\r\n。此数据格式针对Ardupilot固件版本v3.6.2以下。如果您的Ardupilot固件版本大于或等于v3.6.2 可以直接使用标准数据格式。
5 输出数据说明
Dist(Distance):
代表TFmini Plus测量输出的距离值,默认单位为cm,解析为十进制的值范围 为0-1200。实际使用过程中,当信号强度值Strength<100或等于65535时,Dist的测量值被认为不 可信,默认输出0。
Strength:
指信号强度,默认输出值会在0-65535之间。当测距档位一定时,测距越远,信号 强度越低;目标物反射率越低,信号强度越低。当Strength大于100且不等于65535时,认为Dist 的测量值可信,客户可以根据使用场景自行调整。
Temp(Temperature):
表征芯片内部温度值。摄氏度 = Temp / 8 - 256


实例说明:开启四个线程分别接收四路激光测距雷达的数据并生成chart波形图
实例代码:

using System;using System.Collections.Generic;using System.Drawing;using System.Linq;using System.Net;using System.Net.Sockets;using System.Threading;using System.Windows.Forms;using System.Windows.Forms.DataVisualization.Charting;
namespace lidarTest{public partial classmainForm : DevComponents.DotNetBar.Office2007Form {publicmainForm(){this.DoubleBuffered = true;//设置本窗体 SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
this.EnableGlass = false; InitializeComponent(); InitChart(); }private Queue<double>[] dataQueue = new Queue<double>;//把Queue<double>看成一个类型 int[] a=new int bool isStart = false;privatevoidmainForm_Load(object sender, EventArgs e){ dataQueue = new Queue<double>(100); dataQueue = new Queue<double>(100); dataQueue = new Queue<double>(100); dataQueue = new Queue<double>(100);
//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(); }// 防止闪屏 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000;return cp; } }
publicvoidStart(){ 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;
}privatevoidStartDataRevThread1(){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 默认值是8192while (true) { Byte[] recv = client.Receive(ref endpoint);string stringData = "0x" + BitConverter.ToString(recv).Replace("-", " 0x").ToLower();this.Invoke((EventHandler)delegate {//richTextBoxEx1.Text += stringData + "\r\n"; chartShow( recv + (recv<<8),1); } ); } }catch(Exception ex) { MessageBox.Show(ex.Message + "\n" + ex.StackTrace) ; } }privatevoidStartDataRevThread2(){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 + "\r\n"; chartShow(recv + (recv << 8),2); } ); } }catch (Exception ex) { MessageBox.Show(ex.Message + "\n" + ex.StackTrace); } }privatevoidStartDataRevThread3(){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 + "\r\n"; chartShow( recv + (recv << 8),3); } ); } }catch (Exception ex) { MessageBox.Show(ex.Message + "\n" + ex.StackTrace); } }privatevoidStartDataRevThread4(){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 + "\r\n"; chartShow( recv + (recv << 8),4); } ); } }catch (Exception ex) { MessageBox.Show(ex.Message + "\n" + ex.StackTrace); } }
privatevoidInitChart(){ Chart[] ch = new Chart { chart1, chart2, chart3, chart4};for (int i = 0; i < 4; i++) { ch.ChartAreas.Clear(); ChartArea chartArea1 = new ChartArea("C1"); ch.ChartAreas.Add(chartArea1);//定义存储和显示点的容器 ch.Series.Clear(); Series series1 = new Series("S1"); series1.ChartArea = "C1"; ch.Series.Add(series1);
ch.ChartAreas.AxisY.IsStartedFromZero = false; ch.Legends.Enabled = false;
ch.ChartAreas.AxisX.Interval = 5; ch.ChartAreas.AxisX.MajorGrid.LineColor = System.Drawing.Color.Silver; ch.ChartAreas.AxisY.MajorGrid.LineColor = System.Drawing.Color.Silver;//设置标题 ch.Titles.Clear(); ch.Titles.Add("S01"); ch.Titles.Text = "通道" + (i + 1) + " 折线图显示"; ch.Titles.ForeColor = Color.RoyalBlue; ch.Titles.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);//设置图表显示样式 ch.Series.Color = Color.Red;//this.chart1.Titles.Text = string.Format("{0}折线图显示", ); ch.Series.ChartType = SeriesChartType.Line; ch.Series.Points.Clear(); } }
publicvoidchartShow(Double y, int ch){
Chart[] chNum = new Chart { chart1, chart2, chart3, chart4 };if (ch <= 8) chartDisplay(chNum, ch, y);
}delegate voidChartDelegate(Chart chart, int ch, Double y);privatevoidchartDisplay(Chart chart, int ch, Double y){
if (chart.InvokeRequired) { ChartDelegate chartDelegate = chartDisplay; chart.Invoke(chartDelegate, new object[] { chart, ch, y }); }else {if (isStart == true) UpdateQueueValue(ch, y); chart.Series.Points.Clear();for (int i = 0; i < dataQueue.Count; i++) chart.Series.Points.AddXY((i + 1), dataQueue.ElementAt(i)); } }privatevoidUpdateQueueValue(int ch, Double y){
if (dataQueue.Count > 100)//先出列 dataQueue.Dequeue(); dataQueue.Enqueue(y); }privatevoidbtnStart_Click(object sender, EventArgs e){
if (!isStart) { btnStart.Text = @"停止采集"; btnStart.DisabledImage = btnStart.Image; btnStart.Image = (Image)btnStart.PressedImage.Clone(); isStart = !isStart;
}else { btnStart.Text = @"开始采集"; btnStart.Image = btnStart.DisabledImage; isStart = !isStart; } } }}
运行结果:


链接:https://pan.baidu.com/s/1KmIbP1I9Eq90bcFOiYSI6w
提取码:ska8
------------------------------------------------------------------------
页: [1]
查看完整版本: C# winfrom实例:四路激光测距雷达数据采集和波形图绘制