X-NUCLEO-53L4A3 飞行时间 (ToF) 传感器 [SSD1306 显示距离, GUI软件测试]
本帖最后由 御坂10032号 于 2024-11-17 19:26 编辑<p><span style="font-size:22px;"><strong>简介</strong></span></p>
<p> </p>
<p>在上一个章节中我开箱了 X-NUCLEO-53L4A3飞行时间 (ToF) 传感器, 也成功的烧写了Demo 和测试。但是由于我本身这次的测试目的是和其他的测距模块做对比, 比如雷达等。 它并不是十分方便的进行数据的显示。于是我翻箱倒柜的找了一下我的模块。 幸运的是手里正好有一个拓展版。上面板载了一个SSD1305 和一个ESP12-f 正好兼容Arduino 接口。于是我便把它简单的组装了一下。 使其将光照传感器的数据显示到SSD1306上. 那么这样的话就方便我来进行距离测试了。</p>
<p> </p>
<p><strong>拓展板正面</strong></p>
<p> </p>
<p> </p>
<p> </p>
<p>拓展板背面</p>
<p> </p>
<p><strong>组合在一起的图片</strong></p>
<p> </p>
<p><strong><span style="font-size:24px;">正文</span></strong></p>
<p> </p>
<p>由于这个拓展板使用的Arduino接口且SSD1306的通讯方式是I2C 因此只需要初始化下SCL和SDA就好。 TOF传感器的通讯方式也是I2C,但是我没有找到它的初始化代码在哪里。 所以我在系统初始化的时候直接初始化了I2C来用于屏幕的初始化。</p>
<p> </p>
<p> </p>
<p>整合起来也比较简单, 就是在Print_result 的时候调用SSD1306的显示函数来使用SSD的替换掉串口打印。</p>
<p> </p>
<pre>
<code class="language-cpp">//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.NumberOfTargets);
// for (j = 0; j < Result->ZoneResult.NumberOfTargets; j++)
// {
// printf("\n |---> ");
// printf("Status = %ld, Distance = %5ld mm ",
// (long)Result->ZoneResult.Status,
// (long)Result->ZoneResult.Distance);
// if (Profile.EnableAmbient)
// printf(", Ambient = %ld.%02ld kcps/spad",
// (long)Result->ZoneResult.Ambient,
// (long)decimal_part(Result->ZoneResult.Ambient));
// if (Profile.EnableSignal)
// printf(", Signal = %ld.%02ld kcps/spad",
// (long)Result->ZoneResult.Signal,
// (long)decimal_part(Result->ZoneResult.Signal));
// }
//}
//printf("\n");
//}
static void print_result(RANGING_SENSOR_Result_t *Result)
{
uint8_t j = 0;
uint8_t y_offset = 0;
char buffer;
ssd1306_Clear(&i2c1);
snprintf(buffer, sizeof(buffer), "Targets: %lu", (unsigned long)Result->ZoneResult.NumberOfTargets);
ssd1306_SetCursor(0, y_offset);
ssd1306_WriteString(buffer, Font_7x10, White);
y_offset += 10;
while (j < Result->ZoneResult.NumberOfTargets && y_offset < 64)
{
snprintf(buffer, sizeof(buffer), "D:%5ldmm S:%ld",
(long)Result->ZoneResult.Distance,
(long)Result->ZoneResult.Status);
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.Ambient,
(long)decimal_part(Result->ZoneResult.Ambient));
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.Signal,
(long)decimal_part(Result->ZoneResult.Signal));
ssd1306_SetCursor(0, y_offset);
ssd1306_WriteString(buffer, Font_7x10, White);
y_offset += 10;
}
j++;
}
ssd1306_UpdateScreen(&i2c1);
}
</code></pre>
<p>这样的话,当数据更新的时候便会在SSD1306上显示出来。</p>
<p> </p>
<p>实际的效果如下:</p>
<p>c7b8e062db8a318361a4104a166adbc8<br />
</p>
<p> </p>
<p> </p>
<p>需要注意的是, 这个传感器支持检测多个目标。但是目前我还没弄明白多个目标究竟是怎么检测的(我的意思是怎么会被识别为一个目标)。 在实际的测量环境中, 如果测量的长度比较短的话, 那么检测到的Target为1, 距离信息会显示在Target 1 的变量中. 如果超出某一个距离的时候,检测的target将会变成2,然后远距离目标的距离信息会显示在第二个target的距离变量里。 具体的效果可以查看上述视频。(具体的原理没有搞明白, 当然也有可能是根据距离的长短在代码中自动的调整target的排序, 也有可能是我SSD1306显示的问题)。 </p>
<p> </p>
<p>下图为<strong>VL53L4ED_GUI </strong>软件检测到的目标信息。 这个上位机不好用, 不推荐使用。 建议根据镜花水月000大佬的<a href="https://bbs.eeworld.com.cn/thread-1298195-1-1.html" target="_blank">帖子</a>设置使用<strong>匿名助手</strong>来操作。</p>
<p> </p>
<p> </p>
<p> </p>
<p><br />
</p>
<p> </p>
<p> </p>
<p> </p>
页:
[1]