tmf8801为什么测量距离达不到2.5米

前言

       tmf8801是一个飞行时间(ToF)激光测距传感器,通过测量光波的脉冲差测量距离。能够在±5%范围内进行高精度距离测量,并且能够在黑暗环境和有阳光的情况下运行。

图1 tmf8801的技术特点

      在tmf881官方技术手册上写明了测量最大距离是2500mm,但是用户在使用官网提供的tmf8801驱动代码实现之后,发现实现的距离最多只能到达2200mm左右。本文章的目标主要描述的是如何让tmf8801能够测量达到2500距离的技术方法。

一、说明

tmf8801 内部算法是按照 5MHz 的晶振频率进行计算的,但实际上 tmf8801内部晶振 频率有偏差,并不是准确的 5MHz,这就会给距离测量带来误差。

         在博客《TMF8801的频偏校正》已经进行的解释。有两种方法可获取tmf8801 的频偏因子:第一种方法是主机设置一个固定周期T的定时器,在定时器中断服务函数里获取tmf8801的时间戳,第一次中断获取的时间戳为t1,第二次中断获取到时间戳为t2,则可算出频偏因子为(t2-t1)/T;第二种方法是主机设置一个计数器,在第一次获取tmf8801的距离值的时候,同时获取自身的时间戳 t_host_1 和tmf8801 的时间戳 t_tof_1,第二次获取tmf8801的距离值的时候,再同时获取自身的时间 戳 t_host_2 和 TMF8x01 的 时 间 戳 t_tof_2 , 则可算出频偏因子为 (t_tof_2-t_tof_1)/(t_host_2-t_host_1)。

       通过以上方法可以计算得到g_freq_bias_fac参数,我们只需要调节g_freq_bias_fac值,就可以达到要求。

二、使用步骤

    在tmf8801的驱动代码包含__tmf8801_app0_osc_trim、__tmf8801_app0_osc_trim_up和__tmf8801_app0_osc_trim_down三个函数,如下所示。

/**
 * \brief 调节TOF晶振频率
 */
static int8_t __tmf8801_app0_osc_trim (int32_t change)
{
    uint8_t  regval   = 0;
    uint8_t  fuse3    = 0;
    uint8_t  fuse6    = 0;
    int32_t  trim_val = 0;
    uint32_t tick     = 0;
    
    regval = 0x29;  
    if (my_iic_write(0x06, &regval, 1) == -1) {
        return TMF8x01_NK;
    }
    
    regval = 0x00;          /* PON = 0 */
    if (my_iic_write(0xE0, &regval, 1) == -1) {
        return TMF8x01_NK;
    }
    tick = my_tick_get();
    while (1) {             /* 等待进入待机模式 */
        if (my_iic_read(0xE0, &regval, 1) == 0) {
            if (regval == 0x00) {
                break;
            }
        }
        if (my_tick_over(tick, 1000) == true) {
            PRINTF("tmf8801_app0_osc_trim tmo!\r\n");
            return TMF8x01_NK;
        }
    }  
    
    if (my_iic_read(0x03, &fuse3, 1) == -1) {
        return TMF8x01_NK;
    }
    
    if (my_iic_read(0x06, &fuse6, 1) == -1) {
        return TMF8x01_NK;
    }
    
    trim_val = (((int32_t)fuse3) << 1) | ((fuse6 & (0x01 << 6)) >> 6);
    trim_val += change;
    trim_val &= 0x1FF;
    fuse6 &= ~(0x01 << 6);
    fuse6 |= ((trim_val & 0x01) << 6);
    fuse3  = ((trim_val >> 1) & 0xFF);
    
    if (my_iic_write(0x03, &fuse3, 1) == -1) {
        return TMF8x01_NK;
    }
    
    if (my_iic_write(0x06, &fuse6, 1) == -1) {
        return TMF8x01_NK;
    }
    
    regval = 0x01;          /* PON = 1 */
    if (my_iic_write (0xE0, &regval, 1) == -1) {
        return TMF8x01_NK;
    }
    
    tick = my_tick_get();
    while (1) {             /* 等待进入空闲模式 */
        if (my_iic_read(0xE0, &regval, 1) == 0) {
            if (regval == 0x41) {
                break;
            }
        }
        if (my_tick_over(tick, 1000) == true) {
            PRINTF("tmf8801_app0_osc_trim tmo!\r\n");
            return TMF8x01_NK;
        }
    }  
    return TMF8x01_OK;
}
/**
 * \brief 调快TOF晶振频率
 */
static int8_t __tmf8801_app0_osc_trim_up (void)
{
    int8_t error;

    error = tmf8801_app0_stop();
    if (error)
        return error;

    error =  __tmf8801_app0_osc_trim(1);
    if (error)
        return error;

    error = tmf8801_app0_start(&g_app_config);
    return error;
}
/**
 * \brief 调慢TOF晶振频率
 */
static int8_t __tmf8801_app0_osc_trim_down (void)
{
    int32_t error;

    error = tmf8801_app0_stop();
    if (error)
        return error;

    error = __tmf8801_app0_osc_trim(-1);
    if (error)
        return error;

    error = tmf8801_app0_start(&g_app_config);
    return error;
}

我们需要通过这三个函数动态调节g_freq_bias_fac的值。通过验证测试,将频率微调到[0.93,0.95]之间的情况下,tmf8801比较合适,测量距离大概就在2500mm左右。

if (g_freq_bias_fac < 0.93) 
{
     __tmf8801_app0_osc_trim_up();
                
}
if (g_freq_bias_fac > 0.95) 
{
     __tmf8801_app0_osc_trim_down();
}

总结

    验证测试g_freq_bias_fac的值在[0.93,0.95]之间的情况下,测量距离和精度都符合技术指标,在调节到其他值,我这里也没有去测试验证,大家可以用此方法验证测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小草xyz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值