使用 C# 设计ToF测距传感器 VL53L5CX 上位机软件_传感器上位机程序

189 阅读11分钟
 VL53L5CX  传感器上位机软件设计记录  ...... by  矜辰所致

前言

在上一篇文章,我们已经学会了 VL53L5CX 传感器的基本使用,对于传感器展示的效果来说,通过简单的串口终端显示展示效果不是那么理想,我们还可以做一个效果更好的展示软件。

对于不熟悉 C# 的博主来说,参考了好多资料才完成了一个可以使用的 Demo 软件,想着还是来做个记录供日后参考,所以本文的内容就是 VL53L5CX 传感器上位机软件设计记录 。

再次说明,本文面向于 C# 小白、初学者,只为做记录。

传感器 VL53L5CX 使用说明文章:
ToF 测距传感器 VL53L5CX 使用记录
.
我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

目录

一、 Visual Studio 下载安装

电脑没有 Visual Studio ,还得重新下载一个,直接网上搜索,然后在官网可以找到下载,如下图:

在这里插入图片描述

下载完毕后,点击打开安装,基本上按照流程来就可以,安装的时候选择时候,我们本次只需要选中如下两个应用安装即可,如下图:

在这里插入图片描述

剩下的就是等着安装完毕即可。

安装完毕打开工程后,我们要选择一个项目模板,这里不要选错了,如下图:

在这里插入图片描述

然后就到了给项目命名,设置项目保存位置的界面:

在这里插入图片描述

创建完毕,正式进入到设计界面,我们就可以开始设计我们的软件了:

在这里插入图片描述

到这里,我们准备好了开发环境,先别急着直接开始,先简单规划一下我们需要怎么开始。

二、设计思路

我们的目的其实很简单,只是为了展示一下 VL53L5CX 的使用效果,让我们能够直观的感受到它的效果。

我们软件要实现的功能主要有以下几点:

1、传感器示例是通过串口输出数据,所以我们首先要实现一个类似串口助手能够接受串口数据功能的界面;
2、传感器上报的数据是分区域的,能够根据传感器手册上面的示意一样,做一个对应的表格,进行对应坐标的数据展示;
3、为了效果更加直观,可以给不同的区域用不同的颜色来对应测量的距离。

三、设计流程

3.1 实现串口数据接收

C# 设计一个串口助手,实际上这在网上有太多太多前人做过,这里呢我就不从头到尾一步一步说明,这里我参考了 B 站一个很小白的教程,照着做就行了,而且 UP 主提供了 GitHub 下载。

【单片机课/毕设利器】B站最小白的串口调试助手教程上位机C#编程

这里我记录一下需要用到的基础控件,至于细节修改,大家可以参考上面视频。

GroupBox

分组框,用以区分串口设置,串口接收设置,串口发送等不同区域。

在这里插入图片描述

Button

按键,打开关闭串口等操作的按钮。

在这里插入图片描述
Label

不可编辑的信息,标题指示等,比如波特率,端口,下图端口用的 button,也可以用 Label 。

在这里插入图片描述

ComboBox

下拉列表框,在串口选择,波特率选择的时候需要用到:

在这里插入图片描述

对于 ComboBox 的列表选项,如果是需要自己定义,可点击控件,在软件右下角,控件属性界面进行修改,如下图:

在这里插入图片描述

RadioButton

单选按钮控件,选择是 HEX ,还是 ASCII 码接收发送,实际上我们可以不需要,这里照着写了,就算了。

在这里插入图片描述

TextBox

文本框控件,用来显示串口接收的数据

在这里插入图片描述

SeriaPort

串口

在这里插入图片描述

串口助手具体的实现大家可自己参考上面视频,或直接下载线程的 DEMO,可以直接运行的。

我们展示并不需要发送,所以我省去了一些功能,照着上面昨晚,我们先来验证一下效果:

在这里插入图片描述

没问题,可以正常的显示我们上一篇文章看到的效果。

3.2 VL53L5CX 数据格式修改

数据能够接收到了,接下来,就是数据处理了,但是如果是按照上面的方式发送数据的话,数据也没法处理,而且我们做效果,使用 8x8 的 区域效果就更好。

所以我们在上一篇文章 VL53L5CX 示例 Demo 的基础上,对串口上报的数据需要进行修改,这里我选择把数据修改成标准的 json 格式,这样在解析的时候也方便,这里直接上一下修改后的代码:

static void MX\_VL53L5CX\_SimpleRanging\_Process(void)
{
  uint32\_t Id;

  CUSTOM\_RANGING\_SENSOR\_ReadID(CUSTOM_VL53L5CX, &Id);
  CUSTOM\_RANGING\_SENSOR\_GetCapabilities(CUSTOM_VL53L5CX, &Cap);

  Profile.RangingProfile = RS_PROFILE_8x8_CONTINUOUS;
  Profile.TimingBudget = TIMING_BUDGET;
  Profile.Frequency = RANGING_FREQUENCY; /\* Ranging frequency Hz (shall be consistent with TimingBudget value) \*/
  Profile.EnableAmbient = 0; /\* Enable: 1, Disable: 0 \*/
  Profile.EnableSignal = 0; /\* Enable: 1, Disable: 0 \*/

  /\* set the profile if different from default one \*/
  CUSTOM\_RANGING\_SENSOR\_ConfigProfile(CUSTOM_VL53L5CX, &Profile);

  status = CUSTOM\_RANGING\_SENSOR\_Start(CUSTOM_VL53L5CX, RS_MODE_BLOCKING_CONTINUOUS);

  while (1)
  {
    /\* polling mode \*/
    status = CUSTOM\_RANGING\_SENSOR\_GetDistance(CUSTOM_VL53L5CX, &Result);

    if (status == BSP_ERROR_NONE)
    {
      print\_result(&Result);
    }

		HAL\_Delay(200);
  }
}
#endif /\* USE\_BARE\_DRIVER \*/

static void print\_result(RANGING_SENSOR_Result_t \*Result)
{
  int8\_t i;
  int8\_t j;
  int8\_t k;
  int8\_t l;
  uint8\_t zones_per_line;

  zones_per_line = ((Profile.RangingProfile == RS_PROFILE_8x8_AUTONOMOUS) ||
                    (Profile.RangingProfile == RS_PROFILE_8x8_CONTINUOUS)) ? 8 : 4;

	printf("{\"Databegin\":[");
  for (j = 0; j < Result->NumberOfZones; j += zones_per_line)
  {
		for (l = 0; l < RANGING_SENSOR_NB_TARGET_PER_ZONE; l++)
    {
      /\* Print distance and status \*/
      for (k = (zones_per_line - 1); k >= 0; k--)
      {
				if((j+k) == 56){
					printf("%ld",(long)Result->ZoneResult[j + k].Distance[l]);
				}
				else
				printf("%ld,",(long)Result->ZoneResult[j + k].Distance[l]);
      }
    }
		
  }
	printf("]}\n");
}

然后,我们在串口助手里面看一下,输出的数据变成如下形式:

在这里插入图片描述

当然,在我们上面设计的软件也是可以看到的:

在这里插入图片描述

3.3 数据处理

到了这个时候我们就要进行细节修改了。

数据解析说明

先说明一下,上面我们已经把数据修改成标准的 Json 格式,最开始我尝试过使用开源的类库 Newtonsoft.Json 进行解析,如果这样的话当然需要添加命名空间,如下图:

...
using System.IO.Ports;//SerialPort 命名空间
using Newtonsoft.Json;
using System.Runtime.Remoting.Contexts;
...

但是实际上后面出现了点问题,好在我们的数据比较简单,所以我干脆直接就自己写一个针对上面格式字符串的函数。

所以在上面串口接收显示的基础之上,我们修改了一下代码,加入了 ProcessReceivedData 数据处理函数:

        private void serialPort1\_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                if (radioBt_getAscii.Checked)  //如果接收是字符模式
                {
                    string content = serialPort1.ReadExisting();//从串口控件读取输入流返回为string
                    textBox_get.AppendText(content);//将接受到的string数据添加到接收窗

                    receivedDataBuffer.Append(content);

                    // 处理接收的数据,检查是否包含完整的一帧
                    ProcessReceivedData();

                }
                else //如果接收是HEX模式
                {

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("数据接受出错" + ex, "error");
            }
        }

数据处理函数

新建一个64个成员的数组,把接收到的距离数据保存到我们数组中:

在这里插入图片描述

函数源码:

        private void ProcessReceivedData()
        {
            lock (lockObject) // 确保线程安全
            {
                string receivedData = receivedDataBuffer.ToString();

                // 检查是否包含完整的一帧数据
                if (receivedData.Contains("Databegin") && receivedData.Contains("]"))
                {
                    // 提取一帧完整的数据
                    int startIndex = receivedData.IndexOf("[");
                    int endIndex = receivedData.IndexOf("]");

                    if (startIndex >= 0 && endIndex > startIndex)
                    {
                        string valuesSubstring = receivedData.Substring(startIndex + 1, endIndex - startIndex - 1);
                        string[] values = valuesSubstring.Split(',');

                        if (values.Length == 64)
                        {
                            try
                            {
                                for (int i = 0; i < values.Length; i++)
                                {
                                    dataArray[i] = uint.Parse(values[i]);
                                }
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show($"无法解析数据数组:{ex.Message}");
                            }
                        }
                        else
                        {
                            MessageBox.Show("接收到的数据无效:值数组长度不为 64。");
                        }
                    }
                    else
                    {
                        MessageBox.Show("接收到的数据无效:未找到值数组的起始和结束标记。");
                    }

                    // 清空缓冲区,准备接收下一帧数据
                    receivedDataBuffer.Clear();

                }
            }
        }

3.4 表格设计

我们要在界面上建立一个表格用来展示这 64 个不同的区域,我们要新建一个TableLayoutPanel 控件。

**TableLayoutPanel **

表格容器,用来对应传感器不同的 64 个区域,设置成 8x8 的表格,如下图:

在这里插入图片描述

对于表格我们还需要调整一下间距,选择属性,直接设置百分比,如下图:

这里在设置之前,需要自己先手动拖动一下表格行列的间距,然后再设置,要不然,表格不会自动切换成等份的,这里我也说不出来为什么。

在这里插入图片描述

最后做成的表格如下:

在这里插入图片描述

好的,上面我们只是做好了表格展示区域,对于我们要实现的效果:

1、不同区域显示对应的距离数据;
2、根据不同数据在不同区域显示不同的颜色;

我们都是需要通过代码实现的。

3.5 区域数据显示

我们先在尝试在表格上显示对应的数据,首先我们要初始化一下表格:

private void InitializeTableLabels()
{
    for (int row = 0; row < tableLayoutPanel1.RowCount; row++)
    {
        for (int col = 0; col < tableLayoutPanel1.ColumnCount; col++)
        {
            Label label = new Label
            {
                Dock = DockStyle.Fill,
                TextAlign = ContentAlignment.MiddleCenter,
                Font = new Font("Arial", 12),
            };

            tableLayoutPanel1.Controls.Add(label, col, row);
        }
    }
}

记得在开头应用一下:

在这里插入图片描述

然后在每次数据接收的地方添加数据显示函数:

在这里插入图片描述

函数内容如下:

img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取