风筝
发表于: 2025-11-15 08:37:09 | 显示全部楼层

在本篇帖子中,我们将主要介绍一种基于VL53L0x激光测距传感器的激光测距系统,该系统使用了OLED显示屏和树莓派RP2040控制器。我们将使用一块0.49英寸的超小型OLED显示屏,并通过I2C总线与RP2040通信。


所谓距离,是指我们可以测量物体与VL53L0x激光传感器之间的距离(以毫米为单位)。整个测量过程无需与传感器进行任何物理接触,仅通过无线方式即可完成。之所以选择树莓派RP2040作为控制器,是因为它价格低廉且易于获取,同时还支持Arduino和microPython两种编程语言。

rp2040-pinout.jpg


本文电路将直接通过USB连接供电,使用上图所示的RP2040 Zero开发板上的USB-C接口。我们的OLED显示屏和距离传感器都将从RP2040 Zero开发板连接3.3V和GND。因此,无需担心电源转换和外部电源,所有电源均使用USB线缆传输。


传感器和OLED基础知识

我们这款小巧的0.49英寸OLED显示屏是单色的,这意味着它只能显示一种颜色。根据您购买的型号和地点,还有其他型号和颜色可供选择。使用I2C总线扫描器,我发现该OLED显示屏的地址为0x3C。您无需担心,因为它已硬编码到u8g2lib库中。


传感器名称VL53L0x是意法半导体 (ST Semiconductors) 生产的飞行时间测距传感器,这个是数据手册。该传感器的应用包括机器人、液位检测和门禁控制。


它的激光可以探测到两米以内的物体,不受反射率的影响,同时对人眼完全不可见。我使用I2C扫描器程序确定了它的I2C地址为0x29。


vl53l0x.jpg



原理图

我们项目的原理图相当简单,如前所述,OLED 显示屏和距离传感器都使用I2C通信。因此,只需四根线即可连接两者:+3.3V、GND、SDA 和 SCL。此外,如前所述,电源通过USB-C接口供电,所以不用担心我们只需使用 RP2040 Zero开发板提供的3.3V电源即可。

vl53l0x-schematic-diagram.png


I2C的SDA连接到RP2040 Zero的引脚4,SCL连接到引脚5。

connection.jpg


准备使用 Arduino IDE

首先,请确保您的计算机上已安装 Arduino IDE版本。然后,我们将安装Waveshare提供的 RP2040 Zero 支持。为此,请复制以下URL并将其粘贴到“文件 > 首选项 > 附加开发板管理器URL”中。

  1. https://github.com/earlephilhower/arduino-pico/releases/download/4.0.2/package_rp2040_index.json
复制代码

然后打开 Arduino IDE,依次点击“工具 > 开发板 > 开发板管理器”,输入“Waveshare”。安装 RP2040/RP2350的库。接下来,我们需要在Arduino IDE中安装两个库:“u8g2lib”(用于 OLED 显示屏)和“VL53L0x by Pololu”(用于距离传感器)。


前往“Sketch > Include library > Manage libraries”,输入“u8g2”,安装Oliver提供的库。然后输入“VL53L0x”,安装Pololu提供的库。现在就可以开始编写代码了。


代码和函数

正如文章开头所述,我们的目标是实现一个电路,用于测量传感器到物体的距离。测量结果将以毫米为单位,并以10Hz的刷新率显示在OLED屏幕上。


我的做法是编写一段代码,实时读取距离并将其打印到显示屏上,每秒执行 10 次。如果不执行此函数,处理器将空循环执行。您可以在下方查看完整的代码,其中还添加了注释以便于理解。


此外,这个显示屏要求我们先“清除缓冲区”,告诉它哪个文本应该显示在哪里,然后再“发送缓冲区”。每次迭代(每次需要更改文本时)都是如此。

  1. #include <Arduino.h>
  2. #include <U8g2lib.h>
  3. #include <Wire.h>
  4. #include <VL53L0X.h>

  5. VL53L0X sensor;

  6. U8G2_SSD1306_64X32_1F_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // Configure our 64x32 pixels display

  7. int distancemm; // varible for the distance from the VL53L0x sensor
  8. long oldtime; // variable for keeping track of time


  9. void setup() {
  10.   u8g2.begin();

  11.   Serial.begin(115200);

  12.   sensor.setTimeout(500);
  13.   if (!sensor.init())
  14.   {
  15.     Serial.println("Failed to detect and initialize sensor!");
  16.     while (1) {}
  17.   }

  18.   // Start continuous back-to-back mode (take readings as
  19.   // fast as possible).  To use continuous timed mode
  20.   // instead, provide a desired inter-measurement period in
  21.   // ms (e.g. sensor.startContinuous(100)).
  22.   sensor.startContinuous(50);

  23. }

  24. // fonts https://github.com/olikraus/u8g2/wiki/fntlistall#4-pixel-height (I have picked two of them for this article)

  25. void loop()
  26. {

  27.   if(millis() - oldtime > 100){ // Only does anything every 100ms
  28.     oldtime= millis();

  29.     distancemm= sensor.readRangeContinuousMillimeters();
  30.     Serial.println(distancemm);  
  31.    
  32.     u8g2.clearBuffer();          // clear the internal memory  
  33.     u8g2.setCursor(0, 24);
  34.     u8g2.setFont(u8g2_font_t0_17_tn);  // choose a suitable font
  35.     u8g2.print(distancemm);
  36.     u8g2.setCursor(40, 24);
  37.     u8g2.setFont(u8g2_font_9x18_mf);
  38.     u8g2.print("mm");
  39.     u8g2.sendBuffer();          // transfer internal memory to the display
  40.   }
  41.      
  42. }
复制代码


结果

正如您在下面的图片看到的,每100毫秒读取一次距离并打印在OLED屏幕上。固定的文本“mm”不会受到周围任何物体的干扰。有一个“Serial.print”函数可以将数据发送到 Arduino IDE 的串口监视器,方便您查看和比较。

result.jpg



以上就是使用树莓派RP2040实现激光测距的全部内容,如果您有任何疑问,请在本帖下面留言。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



手机版|

GMT+8, 2025-12-1 07:19 , Processed in 0.144817 second(s), 6 queries , Gzip On, Redis On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表