[光学传感器] X-NUCLEO-53L4A3 飞行时间 (ToF) 传感器 [SSD1306 显示距离, GUI软件测试]

御坂10032号   2024-11-17 19:29 楼主

简介

 

在上一个章节中我开箱了  X-NUCLEO-53L4A3飞行时间 (ToF) 传感器, 也成功的烧写了Demo 和测试。但是由于我本身这次的测试目的是和其他的测距模块做对比, 比如雷达等。 它并不是十分方便的进行数据的显示。于是我翻箱倒柜的找了一下我的模块。 幸运的是手里正好有一个拓展版。上面板载了一个SSD1305 和一个ESP12-f 正好兼容Arduino 接口。于是我便把它简单的组装了一下。 使其将光照传感器的数据显示到SSD1306上. 那么这样的话就方便我来进行距离测试了。

 

拓展板正面

 

3dcbfe8afde5de0e16686a0dfd2055d.jpg  

 

拓展板背面

080cd3e970098975f8d63a86027d425.jpg  

组合在一起的图片

88722fb6bb57ad9e6e7a1ee15d9684e.jpg  

正文

 

由于这个拓展板使用的Arduino接口且SSD1306的通讯方式是I2C 因此只需要初始化下SCL和SDA就好。 TOF传感器的通讯方式也是I2C,但是我没有找到它的初始化代码在哪里。 所以我在系统初始化的时候直接初始化了I2C来用于屏幕的初始化。

 

image.png  

整合起来也比较简单, 就是在Print_result 的时候调用SSD1306的显示函数来使用SSD的替换掉串口打印。

 

//static void print_result(RANGING_SENSOR_Result_t *Result)
//{
//  uint8_t i;
//  uint8_t j;

//  for (i = 0; i < RANGING_SENSOR_MAX_NB_ZONES; i++)
//  {
//    printf("\nTargets = %lu", (unsigned long)Result->ZoneResult[i].NumberOfTargets);

//    for (j = 0; j < Result->ZoneResult[i].NumberOfTargets; j++)
//    {
//      printf("\n |---> ");

//      printf("Status = %ld, Distance = %5ld mm ",
//             (long)Result->ZoneResult[i].Status[j],
//             (long)Result->ZoneResult[i].Distance[j]);

//      if (Profile.EnableAmbient)
//        printf(", Ambient = %ld.%02ld kcps/spad",
//               (long)Result->ZoneResult[i].Ambient[j],
//               (long)decimal_part(Result->ZoneResult[i].Ambient[j]));

//      if (Profile.EnableSignal)
//        printf(", Signal = %ld.%02ld kcps/spad",
//               (long)Result->ZoneResult[i].Signal[j],
//               (long)decimal_part(Result->ZoneResult[i].Signal[j]));
//    }
//  }
//  printf("\n");
//}

static void print_result(RANGING_SENSOR_Result_t *Result)
{
  uint8_t j = 0;        
  uint8_t y_offset = 0;  
  char buffer[64];       

  ssd1306_Clear(&i2c1); 

  
  snprintf(buffer, sizeof(buffer), "Targets: %lu", (unsigned long)Result->ZoneResult[0].NumberOfTargets);
  ssd1306_SetCursor(0, y_offset);
  ssd1306_WriteString(buffer, Font_7x10, White);
  y_offset += 10;

  
  while (j < Result->ZoneResult[0].NumberOfTargets && y_offset < 64)
  {
    
    snprintf(buffer, sizeof(buffer), "D:%5ldmm S:%ld", 
             (long)Result->ZoneResult[0].Distance[j], 
             (long)Result->ZoneResult[0].Status[j]);
    ssd1306_SetCursor(0, y_offset);
    ssd1306_WriteString(buffer, Font_7x10, White);
    y_offset += 10;

    
    if (Profile.EnableAmbient)
    {
      snprintf(buffer, sizeof(buffer), "A:%ld.%02ldkcps", 
               (long)Result->ZoneResult[0].Ambient[j],
               (long)decimal_part(Result->ZoneResult[0].Ambient[j]));
      ssd1306_SetCursor(0, y_offset);
      ssd1306_WriteString(buffer, Font_7x10, White);
      y_offset += 10;
    }

   
    if (Profile.EnableSignal)
    {
      snprintf(buffer, sizeof(buffer), "S:%ld.%02ldkcps", 
               (long)Result->ZoneResult[0].Signal[j],
               (long)decimal_part(Result->ZoneResult[0].Signal[j]));
      ssd1306_SetCursor(0, y_offset);
      ssd1306_WriteString(buffer, Font_7x10, White);
      y_offset += 10;
    }

    j++; 
  }

  ssd1306_UpdateScreen(&i2c1); 
}

这样的话,当数据更新的时候便会在SSD1306上显示出来。

 

实际的效果如下:

WeChat_20241117192441

 

 

 

需要注意的是, 这个传感器支持检测多个目标。但是目前我还没弄明白多个目标究竟是怎么检测的(我的意思是怎么会被识别为一个目标)。 在实际的测量环境中, 如果测量的长度比较短的话, 那么检测到的Target为1, 距离信息会显示在Target 1 的变量中. 如果超出某一个距离的时候,检测的target将会变成2,然后远距离目标的距离信息会显示在第二个target的距离变量里。 具体的效果可以查看上述视频。(具体的原理没有搞明白, 当然也有可能是根据距离的长短在代码中自动的调整target的排序, 也有可能是我SSD1306显示的问题)。 

 

下图为VL53L4ED_GUI 软件检测到的目标信息。 这个上位机不好用, 不推荐使用。 建议根据镜花水月000大佬的帖子设置使用匿名助手来操作。

 

 

image.png  


 

 

 

 

本帖最后由 御坂10032号 于 2024-11-17 19:26 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复