2024艾迈斯欧司朗竞赛 - 基于瑞芯微RV1106G3设计角度测算工具
该项目使用了TMF8821,实现了角度测算的设计,它的主要功能为:将板卡组合后固定,并保证与面前的平面存在一定夹角,通过程序测算出板卡距离屏幕的夹角和垂直最小距离。
标签
Linux
TMF8821
RV1106G3
bigzhu
更新2025-03-04
34

TMF8821 dToF 项目总结报告

项目背景

本项目基于2024年艾迈斯欧司朗竞赛,旨在将TMF8821直接飞行时间(dToF)传感器集成到瑞芯微RV1106G3平台上,并开发一款简易的角度测算工具。通过将板卡固定并与平面保持一定夹角,程序能够测算出板卡与平面之间的夹角和垂直最小距离。

项目目标

  1. 硬件集成:将TMF8821 dToF传感器成功集成到RV1106G3平台。
  2. 软件开发:开发一个简易的角度测算工具,能够实时计算板卡与屏幕之间的夹角和垂直距离。
  3. 性能优化:确保系统稳定运行,并优化算法以提高测量精度。

硬件介绍

TMF8821 dToF传感器

TMF8821是一款直接飞行时间(dToF)传感器,采用单一模组封装,配备VCSEL(垂直腔面发射激光器)。该传感器利用SPAD(单光子雪崩二极管)、TDC(时间数字转换器)和直方图技术,实现了最大5000 mm的检测范围。TMF8821支持3×3、4×4和3×6多区输出数据,并具有动态可调的视场角(FoV)。所有数据处理均在片上进行,通过I2C接口提供距离信息和置信度值。

RV1106G3处理器

RV1106G3是一款专为人工智能应用设计的高度集成IPC视觉处理器SoC。基于单核ARM Cortex-A7 32位内核,集成了NEON和FPU,内置NPU支持INT4/INT8/INT16混合运算,计算能力高达1TOPS。RV1106G3还配备了全新的硬件ISP(图像信号处理器),支持多种算法加速器,如HDR、3A、LSC、3DNR等。开发板支持多种接口,包括GPIO、UART、SPI、I2C、USB等,便于快速开发和调试。

项目设计思路

方案框图

  1. 硬件连接:TMF8821通过I2C接口与RV1106G3连接,GPIO引脚用于控制传感器的使能和中断信号。
  2. 软件流程
    • 初始化TMF8821传感器并加载固件。
    • 通过I2C读取传感器的距离数据。
    • 根据距离数据计算板卡与屏幕之间的夹角和垂直距离。
    • 输出计算结果并进行实时显示。

实际接线图

软件流程图

  1. 初始化:加载内核模块,配置设备树,初始化TMF8821传感器。
  2. 数据采集:通过I2C接口读取传感器的距离数据。
  3. 数据处理:根据采集到的距离数据,计算夹角和垂直距离。
  4. 结果输出:将计算结果输出到终端或显示设备。

关键代码介绍

内核模块

内核模块的编译和加载是项目的基础。通过修改Makefile和设备树,成功将TMF8821驱动集成到RV1106G3平台。

KDIR:=/home/bruce/Documents/luckfox-pico/sysdrv/source/kernel
PWD?=$(shell pwd)
MAKE := make
ARCH := arm
CROSS_COMPILE := /home/bruce/Documents/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-
KBUILD_OUTPUT := $(abspath $(dir $(lastword $(KDIR))))/objs_kernel

ifneq ($(KERNELRELEASE),)
#kbuild part of Makefile
include Kbuild
else
#normal Makefile
all:
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) modules

modules:
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) $@

sign:
$(SIGN_SCRIPT) sha512 $(LINUX_SRC)/signing_key.priv $(LINUX_SRC)/signing_key.x509 $(DEVICE_NAME).ko

clean:
$(MAKE) -C $(LINUX_SRC) M=$$PWD clean

endif

设备树配置

设备树配置中,启用了I2C3接口,并添加了TMF8821的节点,配置了GPIO引脚用于控制传感器的使能和中断信号。GPIO1_C6接ENABLE引脚,高电平有效。GPIO1_C7接irq引脚,下降沿有效。

&i2c3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c3m1_xfer>;
clock-frequency = <100000>;

tmf8821: tmf8821@41 {
compatible = "ams,tmf882x";
status = "okay";
reg = <0x41>;
enable-gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; // GPIO1_C6 enable
irq-gpios = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; // GPIO1_C7 irq
interrupt-parent = <&gpio1>;
interrupts = <RK_PC7 IRQ_TYPE_EDGE_FALLING>;
};
};

加载firmware

tmf8821传感器上电后需要加载固件才能进入app运行模式,将官方提供的hex文件放到开发板/lib/firmware/tmf882x_firmware.bin。注意:这里必须将官方提供的.hex文件重命名为tmf882x_firmware.bin,不要转换为hex文件。我刚开始用工具将hex文件转换成bin文件加载一直无法启动。

加载运行

将上面编译好的tmf882x.ko,官方提供的设备固件tmf882x_firmware.bin下载到设备中

运行

insmod tmf882x.ko

成功启动设备

测试

设备成功初始化后默认会关闭测量,进入低功耗状态。进入以下文件夹,打开设备,进入正常的测量状态。

cd /sys/bus/i2c/devices/i2c-3/3-0041
# 手动打开设备
echo 1 > chip_enable

一旦TMF882X注册成功,TMF882X会注册标准的Linux input设备

查看/proc/bus/input/devices文件可以获取到系统中注册的所有输入设备相关的信息,如下所示:

[root@luckfox app]# cat /proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="adc-keys"
P: Phys=adc-keys/input0
S: Sysfs=/devices/platform/adc-keys/input/input0
U: Uniq=
H: Handlers=kbd event0
B: PROP=0
B: EV=3
B: KEY=c0000 0 0 0

I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="tmf882x"
P: Phys=
S: Sysfs=/devices/platform/ff460000.i2c/i2c-3/3-0041/input/input1
U: Uniq=
H: Handlers=event1
B: PROP=0
B: EV=9
B: ABS=3ff

编写C语言测试程序

#include "ams/tmf882x.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <linux/input.h>

int main(int argc, char *argv[])
{
   struct input_event in_ev = {0};
   int fd;
   // cat /proc/bus/input/devices
   // /devices/platform/ff460000.i2c/i2c-3/3-0041/input/input1
   fd = open("/dev/input/event1", O_RDONLY);
   if (fd < 0) {
       perror("open error");
       exit(-1);
  }
   while (1)
  {
       if (sizeof(struct input_event) != read(fd, &in_ev, sizeof(struct input_event))) {
           perror("read error");
           exit(-1);
      }
       printf("type:%d code:%d value:%d\n", in_ev.type, in_ev.code, in_ev.value);
  }

   close(fd);

   return 0;
}

已知三角形的两条边和夹角,可计算出第三条边。使用最近比较火的deepseek搜索计算方法


数据分析

type:3 code:6 value:12715503
type:3 code:7 value:5637566
type:3 code:8 value:7079289
type:0 code:0 value:0
type:3 code:1 value:3540985
type:3 code:2 value:5834647
type:3 code:3 value:1377967
type:3 code:4 value:2426319
type:3 code:5 value:4588905
type:3 code:6 value:2819379
type:3 code:7 value:3999051
type:3 code:8 value:5768423
type:3 code:9 value:5834050
type:3 code:1 value:1247611
type:3 code:2 value:1640725
type:3 code:3 value:4327255
type:3 code:4 value:7079565
type:3 code:5 value:14550566


测试程序

根据以上三角形的计算公式,编写C语言测试程序,读取TMF8821传感器的数据,并计算夹角和垂直距离。

#include "ams/tmf882x.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <linux/input.h>
#include <math.h>

#define DEFAULT_ANGLE 60.0

static float calculateDistance(uint16_t a, uint16_t b, uint8_t gamma) {
float gamma_rad = gamma * M_PI / 180.0;
float c = sqrt(a * a + b * b - 2 * a * b * cos(gamma_rad));
float S = 0.5 * a * b * sin(gamma_rad);
float h = (2 * S) / c;
return h;
}

static void calculateAngles(float a, float b, float gamma, float *alpha, float *beta) {
float gamma_rad = gamma * M_PI / 180.0;
float c = sqrt(a * a + b * b - 2 * a * b * cos(gamma_rad));

*alpha = asin((a * sin(gamma_rad)) / c);
*beta = M_PI - *alpha - gamma_rad;
}

int main(int argc, char *argv[])
{
uint16_t dis_array[9] = {0};
struct input_event in_ev = {0};
char buf[128];
int fd;
// cat /proc/bus/input/devices
fd = open("/dev/input/event1", O_RDONLY);
if (fd < 0) {
perror("open event1 error");
exit(-1);
}
while (1)
{
if (sizeof(struct input_event) != read(fd, &in_ev, sizeof(struct input_event))) {
perror("read error");
exit(-1);
}
if (in_ev.type == EV_ABS) {
int pos = 0;
uint16_t channel = in_ev.code;
uint32_t value = in_ev.value;
uint8_t confidence = (value >> 16) & 0xFF;
uint16_t distance = value & 0xFFFF;
if (channel < 9 && confidence > 150) {
dis_array[channel] = distance;
float angle[2];
float max;
float real_angle;
float a = dis_array[1];
float b = dis_array[2];
if (a > 0 && b > 0) {
calculateAngles(a, b, DEFAULT_ANGLE, &angle[0], &angle[1]);
angle[0] = angle[0]*180.0/M_PI;
angle[1] = angle[1]*180.0/M_PI;
if (angle[0] > angle[1]) {
max = angle[0];
} else {
max = angle[1];
}
real_angle = max - (180 - DEFAULT_ANGLE) / 2;
float min_dis = calculateDistance(a, b, DEFAULT_ANGLE);
printf("%.1f,%.1f -> %.1f, %.1f\n", angle[0], angle[1], real_angle, min_dis);
}
}
}
}
close(fd);
return 0;
}

测试与数据分析

通过测试程序,成功读取了TMF8821传感器的距离数据,并计算出了板卡与屏幕之间的夹角和垂直距离。测试结果表明,系统能够稳定运行,并且测量结果具有较高的精度。


总结

本项目成功将TMF8821 dToF传感器集成到RV1106G3平台,并开发了一款简易的角度测算工具。通过硬件和软件的协同工作,实现了与板卡夹角和垂直距离的实时测量。未来可以进一步优化算法,提高测量精度,并扩展更多功能。

附件下载
tmf8821bin.zip
编译好的二进制文件
main.c
app源程序
ams_tmf8820_linux_driver_src_v3.56.zip
修改好的驱动源代码
rv1106g-luckfox-pico-max.dts
rv1106g3设备树
dtof驱动.pdf
整理的移植文档
团队介绍
个人爱好者
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号