AMS TMF8801 (arduino/STM32)-1
前言
A time-of-flight camera (ToF camera) is a range imaging camera system employing time-of-flight techniques to resolve distance between the camera and the subject for each point of the image, by measuring the round trip time of an artificial light signal provided by a laser or an LED.
這邊選用SparkFun Qwiic Time-of-Flight Sensor TMF8801模組來當驅動模板搭配STM32F401RE的Nucleo-F401RE板子
這邊使用TMF8801與Nucleo-F401RE作為開發工具以下開始程式範例與接線說明
TMF8801介紹
TMF8801是2019年AMS推出的用于测量(dToF)距離的集成式模塊,號稱當時體積最小。這個Sensor可以精準測量0.02m至2.5m範圍,實際量測在100KLux陽光底下大約剩下60cm可以外加一些裝置最大只能Gan到1M,暗室下能夠測量到2.5m,2m以内基本都能量測到。相比VL53L0X測距模組,测量距離與準度是相對好些。
Features
- Direct ToF technology with high sensitivity SPAD detection
- Fast Time-to-Digital Converter (TDC) architecture
- Sub-nanosecond light pulse
- 20 – 2500mm distance sensing @ 30Hz
- On-chip histogram processing
- 940nm VCSEL Class 1 Eye Safety
- High performance on-chip sunlight rejection filter and algorithm
- Industry’s smallest modular OLGA 2.2 x 3.6 x 1.0 mm package
Benefits
- Delivers high SNR, wide dynamic range and no multi-path reflections
- Enables dark and sunlight environment distance measurement within ±5%
- Provides best-in-class resolution ranging mode detection sensing
- Enables accurate distance measurements
- Provides high accuracy, greater distance between cover glass, dynamic cover glass calibration, dirt or smudge removal and crosstalk compensation
- Eye-safety circuitry stops VCSEL driver if VCSEL fault occurs
- Optical filters with algorithm support enables high ambient light resilience
- Reduce board space requirements, enables low-profile system designs in restricted space Industrial Designs
接線
Sensor板子與上圖Nucleo-F401RE對應腳位對接硬體部分即完成
PS:這邊注意板子是3.3V非5V,與I2C的腳為sensor board是已含電阻如果是自己焊電路板記得要外加電阻確保訊號正常
Coding Flow
這邊因為網路資源算多的不一一把STM32 的code貼上解讀這邊就截取幾個部分給大家參考
- 首先在開始Sensing前要先把TMF8801內的記憶體reset才不會造成I2C撰寫指令錯誤
The Sensor Initialization
void reset_SW()
{
uint8_t status=0,x=0,cmd_buf[3]={0x10,0x00,0xEF},ready=-1;
write_register(APPREQID,Bootloader);
TMF8801_reset();
if (!waitForCpuReady())
{
x=read_register(ENABLE);
printf("CPU staute= %#x nr",x);
return ;}
while(1)
{
status=currentApplication();
if(status==1)//Bootloader
{
HAL_I2C_Mem_Write(&hi2c1, Devadress, 0x08, I2C_MEMADD_SIZE_8BIT, &cmd_buf,3, 100);
HAL_Delay(10);
//remap_rst_RAM();
ready=__tmf8801_status_read ();
if(ready==TMF8x01_OK)
{printf("reset SW okrn");
return;}
else if(ready==TMF8x01_NK)
{printf("reset SW failrn");
for(;;);}
}
}
}
首先在開始Sensing前要先把TMF8801內的記憶體reset才不會造成I2C撰寫指令錯誤
簡單概述就是先切成Bootloader狀態去重開TMF8801的FW讓一切狀態都是最原始狀態
FactoryCalib(工廠校準)
void TMF8801_FactoryCalib()
{
uint8_t y=0,z=0;
printf("wait TMF8801 Factory Calibrationnr");
if (read_register(ID)!=0x07) {
y=read_register(ID);
printf("chipy ID= %#x nr",y);
printf("chip ID errornr");
return;
};
TMF8801_loadApplication();
if (!waitForApplication())
{
z=read_register(APPID);
printf("Application staute= %#x errornr",z);
return;
}
write_register( COMMAND,FACTORY_CALIB);
while(1){
// write_register( COMMAND,FACTORY_CALIB);
if(read_register(0x1E)==0x0A)
{ printf("Calibration completenr");
HAL_I2C_Mem_Read(&hi2c1,Devadress,0x20, I2C_MEMADD_SIZE_8BIT, &factory_calib_data, 14, 100);
//FACTORY_CALIB_0 = 0x20
return ;
}
HAL_Delay(20);
}
};
這步(FactoryCalib
)可以跳過但要事先輸入一組陣列讓後面初始化可以順利執行下去
Sensor 初始化設定
write_register(COMMAND,DOWNLOAD_CALIB_AND_STATE);//COMMAND = 0x10/DOWNLOAD_CALIB_AND_STATE = 0x0B
HAL_I2C_Mem_Write(&hi2c1,Devadress,FACTORY_CALIB_0,I2C_MEMADD_SIZE_8BIT,&factory_calib_data,14,100);//FACTORY_CALIB_0= 0x20/
HAL_I2C_Mem_Write(&hi2c1,Devadress,STATE_DATA_WR_0,I2C_MEMADD_SIZE_8BIT,TMF8801_ALGO_STATE,11,100);//STATE_DATA_WR_0= 0x2E
write_register(CMD_DATA7,0x03);//CMD_DATA7 0x08 Algorithm state and factory calibration is provided
write_register(CMD_DATA6,0xA3);//CMD 6 0xA7 long mode 0xA3 defaut
write_register(CMD_DATA5,0x00);//CMD 5 No GPIO control used
write_register(CMD_DATA4,0x00);//CMD 4 No GPIO control used
write_register(CMD_DATA3,0x00);//CMD 3 defaut 0x00 long 0x40
write_register(CMD_DATA2,measurement_period_ms);
write_register(CMD_DATA1,0xD8);//CMD 1 0x03 defaut 0x04 short mode
write_register(CMD_DATA0,0x04);//CMD 0 0x04 to actually perform the measurement
write_register(COMMAND,DISTANCE_MEASURE_MODE);//COMMAND = 0x10 /DISTANCE_MEASURE_MODE_1= 0x02
陣列factory_calib_datay在前面做FactoryCalib就已有存下數值,如果數值異常或未填會造成TMF8801無法正常量測距離
Pingback: AMS Time-of-Flight sensor ( TMF8801 )on STM32 -2
Pingback: AMS Time-of-Flight sensor ( TMF8801 )on STM32 -2