发帖
7 1 0

【安信可雷达模组Rd-03_V2】测距仪

无垠的广袤
论坛元老

45

主题

80

回帖

5259

积分

论坛元老

积分
5259
QQ
Rd-03系列 133 7 4 天前
[i=s] 本帖最后由 无垠的广袤 于 2025-9-26 12:54 编辑 [/i]

【安信可雷达模组Rd-03_V2】测距仪

本文介绍了安信可 Rd-03 V2 雷达模组通过串口数据接收和打印、 OLED 显示距离数据、OLED 显示历史演化曲线等流程,实现便携式测距仪的项目设计。

项目介绍

  • 串口接收和终端打印距离测量数据;
  • 驱动 OLED 显示距离信息;
  • OLED 显示历史演化曲线;

硬件连接

将 Rd-03 V2 雷达模块的管脚与目标开发板的串口引脚连接。

Rd-03 V2 管脚序号 Rd-03 V2 管脚名称 开发板引脚 说明
1 3V3 3V3 供电
2 GND GND 接地
3 TXD RXD 数据发送端/接收端
4 RXD TXD 数据接收端/发送端
5 OT2 None 检测结果(高低电平)输出

终端打印

串口读取 Rd-03 V2 模组发送的数据并终端打印,包括流程图、代码、效果演示等。

流程图

flowchart TD A([开始]) --> B[初始化 UART] B --> D{串口有数据?} D -->|否| E[等待10ms] E --> D D -->|是| F[打印串口数据] F --> E

代码

from machine import UART, Pin
import time

uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1))

print("Serial Monitor Started")

while True:
    if uart.any():
        data = uart.readline()
        if data:
            text = data.decode('utf-8')
            print(text, end='')
  
    time.sleep_ms(10)

效果

pico-printf-rd03.gif

OLED 显示

驱动 IIC 协议的 4 线 OLED 显示距离信息,包括流程图、代码、效果演示、图片转换等。

流程图

flowchart TD A([开始]) --> B[初始化<br>UART, I2C, OLED] B --> C[显示 logo] C --> D{串口有数据?} D -->|否| E[等待10ms] E --> D D -->|是| F[打印串口数据] F --> G[解析距离数据] G --> H{解析成功?} H -->|否| E H -->|是| J[清空OLED显示] J --> K[显示距离] K --> M[更新OLED显示] M --> E

代码

from machine import UART, I2C, Pin
import ssd1306
import framebuf
import time

# 初始化硬件
uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1))
i2c = I2C(0, sda=Pin(4), scl=Pin(5))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

# logo
buffer = bytearray(b"\x00\x00\x1f\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xff\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xff\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\xff\xff\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\xff\xff\xfe\x00\x00\x08\x00\x9f\x80\x00\x03\x86\x0c\x10\x03\xff\xff\xff\xff\x00\x00\x1c\x01\xbf\x8f\xff\xdf\xb6\x0c\x38\x07\xff\xff\xff\x3f\x80\x03\xff\xe1\xbf\xcf\xff\xde\x3e\x0d\xff\x07\xff\xff\xff\x1f\xc0\x03\xff\xe3\xff\xe0\x03\x06\x1e\x3f\xff\x0f\xff\xff\xfe\x0f\xc0\x03\x30\x23\x3f\xc3\xf3\x1f\x86\x1e\x38\x1f\xfe\x7f\xfe\x07\xe0\x00\x30\x27\x3f\xc7\xf3\x1f\x66\x0c\x38\x1f\xfc\x3f\xff\x07\xf0\x07\xff\xf7\x00\x06\x33\x06\x36\x0f\xfe\x3f\xfc\x3f\xff\x83\xf0\x00\xe3\x83\x3f\xc6\x33\x0f\x1e\x1f\xe6\x3f\xfc\x3f\xff\xff\xf8\x00\xc3\x03\x00\x06\x33\x0f\x87\xbc\xe6\x7f\xfb\xbf\xf1\xff\xf8\x00\xe3\x03\x3f\xc7\xf3\x1e\xff\x8c\x6c\x7f\xfb\xdf\xf1\xff\xf8\x00\xfe\x03\x7f\xc6\x03\x1e\x7e\x0c\x38\x7f\xf9\x9f\xf1\xff\xfc\x00\x3f\x03\x70\xc6\x03\x06\x06\x0c\x7c\x7f\xf9\x9f\xfb\xff\xfc\x01\xfb\xc3\x3f\xc0\x0f\x06\x06\x1d\xef\xff\xf1\x9f\xf1\xff\xfc\x03\xe0\xe3\x3f\xc0\x1f\x06\x06\x3b\xc7\xff\xf3\x9f\xf1\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xf3\x8f\xf1\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xf3\xcf\xf1\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xf3\xcf\xf1\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xf3\xcf\xf1\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xe3\xc7\xf1\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xe0\x07\xf1\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xe0\x07\xf1\xff\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xe0\x07\xf1\xff\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xe3\x87\xf1\xff\xf8\x01\xf0\x00\x7f\xc8\x00\x00\x40\x00\x00\x3f\xc3\x87\xf1\xff\xf8\x03\x18\x80\x06\x08\x00\x00\x40\x00\x00\x3f\xc3\x87\xf1\xff\xf0\x06\x04\x00\x06\x09\xc0\x18\x41\x83\x00\x1f\xc3\x83\xf1\xff\xf0\x06\x06\x80\x06\x0f\xe7\xfe\x47\x8f\xcf\x1f\xc3\x83\xf3\xff\xe0\x04\x06\x80\x06\x0c\x33\xc3\x7c\x18\x66\x0f\xc3\x83\xf3\xff\xc0\x06\x06\x80\x06\x08\x1b\x81\x60\x18\x6c\x0f\xc3\x83\x31\xff\xc0\x07\xfe\x9f\x06\x08\x0b\x81\xf8\x3f\xec\x07\x83\xc1\x30\xff\x80\x06\xf6\x9e\x06\x08\x0b\x81\xdc\x10\x0c\x03\xff\xff\xff\xff\x00\x04\x06\x80\x06\x08\x0b\x81\xce\x18\x6c\x01\xff\xff\xff\xfe\x00\x06\x06\x80\x06\x08\x0f\x81\xc3\x8c\xec\x00\xff\xff\xff\xfc\x00\x04\x06\x80\x06\x08\x0a\x01\xc1\x87\xcc\x00\x7f\xff\xff\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xff\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xff\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
fb = framebuf.FrameBuffer(buffer, 128, 45, framebuf.MONO_HLSB) # 反相使用 HMSB

# 显示初始信息
oled.fill(0)
oled.blit(fb, 0, 0)
oled.rotate(0)
oled.show()
time.sleep(1)

def update_display(distance):
    """更新OLED显示"""
    oled.fill(0)
    oled.text("Distance:", 0, 0)
    oled.text(f"{distance} cm", 75, 0)
    oled.rotate(0)
    oled.show()

# 主循环
print("Radar System Started ...")

while True:
    if uart.any():
        data = uart.readline()
        if data:
            try:
                text = data.decode('utf-8')
                print(text, end='')
              
                # 解析距离数据
                if text.startswith("distance:"):
                    distance = int(text.split(":")[1])
                    update_display(distance)
                  
            except Exception as e:
                print(f"Error: {e}")
  
    time.sleep_ms(10)

检查硬件连接,运行代码;

效果

oled_distance.jpg

动态演示

oled_distance.gif

图片转换

上面代码中 logo 图形显示部分,需要对图片文件进行二进制转换;

可使用 Python 实现该过程,相关代码如下

# image_converter.py
from io import BytesIO
from PIL import Image

# 在这里设置你的图片路径和尺寸
IMAGE_PATH = "logo_aithinker.bmp"
WIDTH = 128
HEIGHT = 45

# 转换图片
im = Image.open(IMAGE_PATH).convert('1')
im_resize = im.resize((WIDTH, HEIGHT))
buf = BytesIO()
im_resize.save(buf, 'ppm')
byte_im = buf.getvalue()

# 跳过文件头
header_len = len(str(WIDTH) + ' ' + str(HEIGHT)) + 4
image_data = byte_im[header_len:]

# 生成\x00格式的字节字符串
hex_escape = "".join([f"\\x{byte:02x}" for byte in image_data])

# 输出结果
print("复制以下代码到你的Pico程序中:")
print(f'buffer = bytearray(b"{hex_escape}")')
  • 根据需求配置相关参数,如输入图片的路径、名称、输出图片的尺寸等信息;
  • 保存文件并运行,终端即输出对应的二进制数组,便于直接调用。

详见:img2bytearray .

演化曲线

在获得雷达测距的实时距离数据的基础上,进一步通过储存历史数据的形式,在 OLED 屏幕显示雷达距离演化曲线,包括流程图、代码、效果演示等。

流程图

flowchart TD A([开始]) --> B[初始化<br>UART, I2C, OLED] B --> C[显示 logo] C --> D{串口有数据?} D -->|否| E[等待10ms] E --> D D -->|是| F[打印串口数据] F --> G[解析距离数据] G --> H{解析成功?} H -->|否| E H -->|是| I[更新历史数据] I --> J[清空OLED显示] J --> K[绘制界面布局<br>显示距离] K --> L[绘制演化曲线<br>坐标 + 连线] L --> M[更新OLED显示] M --> E

代码

新建 *.py 文件,添加如下代码

from machine import UART, I2C, Pin
import ssd1306
import framebuf
import time

# 初始化硬件
uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1))
i2c = I2C(0, sda=Pin(4), scl=Pin(5))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

# logo
buffer = bytearray(b"\x00...") # 见前面关于 logo 的数组定义
fb = framebuf.FrameBuffer(buffer, 128, 45, framebuf.MONO_HLSB)

# 距离演化曲线相关变量
distance_history = []  # 存储历史距离数据
MAX_HISTORY = 20      # 最多存储20个数据点
graph_height = 35     # 曲线图高度
graph_width = 128     # 曲线图宽度
graph_y = 45          # 曲线图Y坐标(底部)

# 显示初始信息
oled.fill(0)
oled.blit(fb, 0, 0)
oled.text("Radar Module", 20, 47)
oled.text("Rd-03 V2", 40, 56)
oled.rotate(0)
oled.show()
time.sleep(1)

def update_display(distance):
    """更新OLED显示,包含距离演化曲线"""
    global distance_history
  
    # 添加新距离到历史数据
    distance_history.append(distance)
    if len(distance_history) > MAX_HISTORY:
        distance_history.pop(0)
  
    # 清屏
    oled.fill(0)
  
    # 显示当前距离
    oled.text(f"Distance: {distance:3d} cm", 0, 48)
  
    # 绘制距离演化曲线
    draw_distance_curve()
    oled.rotate(0)
    oled.show()

def draw_distance_curve():
    """绘制距离演化曲线"""
    if len(distance_history) < 2:
        return
  
    # 计算距离范围(用于缩放)
    min_dist = min(distance_history)
    max_dist = max(distance_history)
    dist_range = max_dist - min_dist if max_dist > min_dist else 1
  
    # 绘制坐标轴
    oled.hline(0, graph_y, graph_width, 1)  # X轴
    oled.vline(0, graph_y - graph_height, graph_height, 1)  # Y轴
  
    # 绘制曲线
    for i in range(1, len(distance_history)):
        x1 = (i - 1) * (graph_width // MAX_HISTORY)
        x2 = i * (graph_width // MAX_HISTORY)
      
        # 计算Y坐标(归一化到图表高度)
        y1 = graph_y - int((distance_history[i-1] - min_dist) * graph_height // dist_range)
        y2 = graph_y - int((distance_history[i] - min_dist) * graph_height // dist_range)
      
        # 限制Y坐标在图表范围内
        y1 = max(graph_y - graph_height, min(graph_y, y1))
        y2 = max(graph_y - graph_height, min(graph_y, y2))
      
        # 绘制线段
        oled.line(x1, y1, x2, y2, 1)
      
        # 绘制数据点
        oled.pixel(x1, y1, 1)
        oled.pixel(x2, y2, 1)
  
    # 显示范围信息
    range_text = f"Range: {min_dist}-{max_dist}cm"
    oled.text(range_text, graph_width - len(range_text)*8, graph_y - graph_height - 8)

# 主循环
print("Radar System with Distance Curve Started ...")

while True:
    if uart.any():
        data = uart.readline()
        if data:
            try:
                text = data.decode('utf-8')
                print(text)
              
                # 解析距离数据
                if text.startswith("distance:"):
                    distance = int(text.split(":")[1])
                    update_display(distance)
                    #print(f"Updated: {distance}cm, History: {len(distance_history)} points")
                  
            except Exception as e:
                print(f"Error: {e}")
  
    time.sleep_ms(10)

检查硬件连接,运行代码;

效果

curve.jpg

动态演示

curve.gif

总结

本文介绍了安信可 Rd-03 V2 雷达模组通过串口数据接收和打印、 OLED 显示距离数据、OLED 显示历史演化曲线等流程,实现便携式测距仪的项目设计,为相关产品的开发设计和快速应用提供了参考。

──── 1人觉得很赞 ────

使用道具 举报

(๑•̀ㅂ•́)و✧厉害,感谢分享!
molun 发表于 2025-9-26 19:08
(๑•̀ㅂ•́)و✧厉害,感谢分享!

感谢关注~后面会做个网页版的距离检测器
点赞
这个有点好玩
好想法
感觉默认输出的距离有点不准确,不知道串口输出的效果怎么样。
昨天 10:22
WT_0213 发表于 2025-9-28 17:08
感觉默认输出的距离有点不准确,不知道串口输出的效果怎么样。

默认参数需要结合具体的使用环境重新校正,这里我是手持测量,人体距离探测肯定是受影响了 提高精度的话,可以将雷达模块固定在墙上,重新生成门限即可
您需要登录后才可以回帖 立即登录
高级模式
返回
统计信息
  • 会员数: 29855 个
  • 话题数: 43656 篇