AMS TMF8801 (arduino/STM32)-1

前言

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板子

SparkFun Qwiic Time-of-Flight Sensor TMF8801
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無法正常量測距離

2 thoughts on “AMS Time-of-Flight sensor ( TMF8801 ) -1”

  1. Pingback: AMS Time-of-Flight sensor ( TMF8801 )on STM32 -2

  2. Pingback: AMS Time-of-Flight sensor ( TMF8801 )on STM32 -2

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart