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

 
 1.所述产品 产品型号:TFmini Plus

相关资料下载地址:http://www.benewake.com/download

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

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

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

7091e51866a36ff389754f5ac1258e53.png

通信接口 UART 默认波特率 115200 数据位 8 停止位 1 奇偶校验 None
4. 串口数据输出格式及编码 

TFmini Plus 有两种数据输出格式,标准数据输出格式和字符串数据格式,两种格式可通过指 令代码相互切换。 

-。标准数据输出格式(默认) :  数据结构:数据帧长度为9字节。包含距离信息(Distance)、信号强度信息(Strength)、温度 (Temp)、数据校验字节(Checksum)等。数据格式为16进制(HEX)。具体数据编码详见下表:

7211d9c2d1d9550cbbc21975879bdda9.png

 -。字符串数据格式(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 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();}private Queue<double>[] dataQueue = new Queue<double>[4];//把Queue<double>看成一个类型 int[] a=new int [8]bool isStart = false;private void mainForm_Load(object sender, EventArgs e)
{dataQueue[0] = new Queue<double>(100);dataQueue[1] = new Queue<double>(100);dataQueue[2] = new Queue<double>(100);dataQueue[3] = 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;}}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;}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 默认值是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[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 + "\r\n";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 + "\r\n";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 + "\r\n";chartShow( recv[2] + (recv[3] << 8),4);});}}catch (Exception ex){MessageBox.Show(ex.Message + "\n" + ex.StackTrace);}}private void InitChart()
{Chart[] ch = new Chart[4] { chart1, chart2, chart3, chart4};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 = 5;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.Line;ch[i].Series[0].Points.Clear();}}public void chartShow(Double y, int ch)
{Chart[] chNum = new Chart[4] { chart1, chart2, chart3, chart4 };if (ch <= 8)chartDisplay(chNum[ch - 1], ch, y);}delegate void ChartDelegate(Chart chart, int ch, Double y);private void chartDisplay(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[0].Points.Clear();for (int i = 0; i < dataQueue[ch - 1].Count; i++)chart.Series[0].Points.AddXY((i + 1), dataQueue[ch - 1].ElementAt(i));}}private void UpdateQueueValue(int ch, Double y)
{if (dataQueue[ch - 1].Count > 100)//先出列dataQueue[ch - 1].Dequeue();dataQueue[ch - 1].Enqueue(y);}private void btnStart_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;}}}
}

运行结果:

61872fb739f524c541ca0d8a766bba5e.png

源代码和激光雷达相关说明文档百度网盘下载地址:

链接:https://pan.baidu.com/s/1KmIbP1I9Eq90bcFOiYSI6w 

提取码:ska8 

------------------------------------------------------------------------

如果这篇文章对你有帮助,就请多多点击,让更多朋友看到,需要进

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/470434.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL篇----第十四篇

系列文章目录 文章目录 系列文章目录前言一、MySQL 数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?二、锁的优化策略三、索引的底层实现原理和优化四、什么情况下设置了索引但无法使用前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽…

Android之Android.bp文件格式语法(一百八十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Docker 在window 2024版笔记 下载 安装 操作 配置

---Docker 前言--- Docker windows版官方版是一款专业开源的应用容器引擎&#xff0c;可以加快用户构建、共享和运行现代应用程序的速度&#xff0c;支持运行Linux和Windows Docker容器。 Docker 在容器的基础上&#xff0c;进行了进一步的封装&#xff0c;从文件系统、网络互…

fluent脱硝SCR相对标准偏差、氨氮比、截面速度计算

# -*- coding: utf-8 -*- """ Created on Wed Sep 20 20:40:30 2023 联系QQ:3123575367&#xff0c;专业SCR脱硝仿真。 该程序用来处理fluent通过export-solution-ASCII-Space导出的数据&#xff0c;可计算标准偏差SD、相对标准偏差RSD,适用于求解平面的相对均匀…

RK3568笔记十六:Framebuffer实验

若该文为原创文章&#xff0c;转载请注明原文出处。 本意是移植LVGL&#xff0c;但在编译DRM过程中一直编译失败&#xff0c;然后就想Framebuffer是否可以用&#xff0c;所以测试一下。 一、framebuffer介绍 FrameBuffer中文译名为帧缓冲驱动&#xff0c;它是出现在2.2.xx内…

23款奔驰S400商务版没有后排电动座椅那改装一套跟选装有区别吗

改装的后排电动座椅通常提供以下功能&#xff1a; 电动调节&#xff1a;座椅可以通过按钮或控制面板进行前后调节&#xff0c;以适应乘客的腿部空间需求。 靠背角度调节&#xff1a;乘客可以通过电动调节功能来调整座椅的靠背角度&#xff0c;以获得更舒适的坐姿。 座椅倾斜调…

Java与JavaScript的区别与联系

Java是目前编程领域使用非常广泛的编程语言&#xff0c;相较于JavaScript&#xff0c;Java更被人们熟知。很多Java程序员想学门脚本语言&#xff0c;一看JavaScript和Java这么像&#xff0c;很有亲切感&#xff0c;那干脆就学它了&#xff0c;这也间接的帮助了JavaScript的发展…

红队打靶练习:HACK ME PLEASE: 1

信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:69:c7:bf, IPv4: 192.168.61.128 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.61.2 00:50:56:f0:df:20 …

PMDG 737

在Simbrief中生成计划后下载两个文件 放到C:\Users\32497\AppData\Local\Packages\Microsoft.FlightSimulator_8wekyb3d8bbwe\LocalState\packages\pmdg-aircraft-737(微软商店版本) 加油 先在飞行计划中查看计划燃油数量 MCDU中, AIRPLANE SEVICE 第二页, REQUEST FUEL TR…

Android---Jetpack Compose学习005

动画 1. 简单值动画 示例&#xff1a;背景颜色在紫色和绿色之间&#xff0c;以动画形式切换。使用 animateColorAsState() val backgroundColor by animateColorAsState(if (tabPage TabPage.Home) Purple100 else Green300) 该句代码中&#xff0c;有一个 backgroundColo…

【Linux】并发解决(上)-中断屏蔽,原子操作

&#x1f525;博客主页&#xff1a;PannLZ &#x1f38b;系列专栏&#xff1a;《Linux系统之路》 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 文章目录 并发解决1.中断屏蔽2.原子操作2.1整形原子操作2.2位原子操作原子变量使用例子 并发解决…

VSCode python插件:找不到自定义包导致语法解析失败

众所周知&#xff0c;在python源码中&#xff0c;我们可以通过 sys.path.append("path-to-lib") 来为python解释器添加自定义包的寻找路径。 但是vscode的默认python插件可没法聪明到根据这句话去找这个包&#xff0c;这就会导致后续代码中使用了这个库的部分无法享…