C#串口通信 [实战] (读取激光雷达数据,生成图像)

本文展示了如何使用C#进行串口通信读取激光雷达数据,并生成图像。通过分析雷达数据格式,编写串口读取类,处理数据并采用WinForm的Graphic绘制激光雷达扫描图像。源码可在GitHub找到。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果展示

话不多说,先上激光雷达数据显示效果图:



激光雷达用的是雷达大叔的二手货,基本上长这个样子:



操作步骤

要生成激光雷达图像,首先就是获取串口数据了,所以第一步就是读取串口数据:

由于是帮朋友调试,开始朋友给了错误的SDK,导致调试半天没有任何结果,索性用串口助手查看一下这货返回些什么数据:


眼神要好,有一列FA,没错,就是250,看样子是帧头,查询一下这款雷达的数据格式:

<start> <index> <speed_l> <speed_h> [Data 0] [Data 1] [Data 2] [Data 3] <checksum_l> <checksum_h> 

<start>:0xFA是固定格式表明数据包开始,可用来从数据流中分割数据包

<index>:数据包的索引号,范围从0xA0 到 0xF9 (每个包4个数据)。

<speed>:有两个speedL和speedH ,它们各一个字节,共同组成转速信息。

<data>:[ Data 0] 到 [Data 3] 是四组测量数据,其中每组测量数据分别由4个字节组成,如下: 

byte 0 : <distance 7:0="">  # 距离信息的0-7位 

byte 1 : <“invalid data” flag> <“strength warning” flag> <distance 13:8=""> # 错误信息标志位 , 警告位, 距离信息13-8位

byte 2 : <signal strength="" 7:0="">  # 信号强度 0-7位 

byte 3 : <signal strength="" 15:8=""> # 讯号强度 8-15位 

距离信息的单位是mm ,整个激光雷达的测量范围大概是15cm 到6m, 只需要把距离信息的两个字节组装成一个整数即可(注意判断无效数据位为0,如果为1意味是无效的数据,需丢弃)。 
<checksum>:由两个字节组成的校验码,用来校验整个数据包是否正确。


一、读取串口数据

有了上述信息之后,首先编写基本串口类,用来打开串口、读取数据:

有以下2点值得注意:

1. 使用DataReceived事件来读取数据;

2. 使用isReading和isClosing标识来保证正常关闭激光雷达(防止出现读取已关闭串口数据的情况);

还有就是,可以定义一个委托,用来读取完数据后,执行处理操作;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Ports;

namespace Laser {
    public class MPort {
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// Attribute(属性域)
        ///////////////////////////////////////////////////////////////////////////////////////////
        // 串口实例
      
### C# 中使用 SICK TIM561-2050101 激光雷达 为了在 C# 环境下成功操作 SICK TIM561-2050101 激光雷达,通常需要遵循特定的通信协议来初始化设备并获取扫描数据。考虑到该型号属于 SICK 的 TIM 系列产品之一,在实现过程中可以借鉴已有的 ROS 驱动程序设计思路[^3]。 #### 初始化网络连接 确保个人计算机与激光雷达处于同一 IP 子网内,例如将传感器设为 `192.168.0.1` 而主机则可设定为 `192.168.0.10` 来建立稳定可靠的 TCP/IP 连接[^1]。 #### 发送命令请求数据流 向激光雷达发送指令以启动数据传输服务是一项重要任务。对于 SICK TIM 设备而言,可以通过串口或以太网接口发出如下所示的消息格式: ```csharp // 构建用于激活LMDscandata模式的数据包 string command = "\u0002sEN LMDscandata 1\u0003"; byte[] buffer = Encoding.ASCII.GetBytes(command); ``` 这段代码片段展示了如何构建一个符合 SICK 定义的标准控制报文结构,并将其转换成字节数组形式以便后续在网络层面上进行传递处理[^4]。 #### 接收解析返回信息 当从硬件端接收到响应后,则需进一步解码这些原始二进制资料,提取出有用的距离测量值及其他辅助参数。由于具体编码细节较为复杂,建议参考官方文档说明或者利用开源项目中的现有解析逻辑作为起点来进行开发工作。 ```csharp using System.Net.Sockets; TcpClient client = new TcpClient("192.168.0.1", 2111); // 建立TCP客户端实例并与指定地址端口相连 NetworkStream stream = client.GetStream(); // 获取关联到当前会话上的输入输出通道对象 stream.Write(buffer, 0, buffer.Length); // 将之前准备好的查询语句写入目标节点等待回应... // 下面部分负责监听来自远端服务器传回的结果集... byte[] responseBuffer = new byte[client.ReceiveBufferSize]; int bytesRead = await stream.ReadAsync(responseBuffer, 0, (int)client.ReceiveBufferSize); if (bytesRead > 0){ string responseData = Encoding.ASCII.GetString(responseBuffer).TrimEnd('\0'); } ``` 上述示例简单介绍了怎样通过异步方法读取消息体的内容长度,并依据实际需求调整缓冲区大小;同时注意去除可能存在的多余终止符字符(`\0`)以免影响最终分析效果。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值