使用MLX90640自制红外热像仪:API函数的使用

Posted qlexcel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用MLX90640自制红外热像仪:API函数的使用相关的知识,希望对你有一定的参考价值。

  前面一篇文章介绍了MLX90640的相关信息和API库的移植,接下来介绍一下API库中的函数,和使用方法。
  首先给出API函数的调用顺序,再对每个用到的API函数做说明:

#define  FPS2HZ   0x02
#define  FPS4HZ   0x03
#define  FPS8HZ   0x04
#define  FPS16HZ  0x05
#define  FPS32HZ  0x06

#define  MLX90640_ADDR 0x33
#define	 RefreshRate FPS4HZ 
#define  TA_SHIFT 8 //Default shift for MLX90640 in open air

static uint16_t eeMLX90640[832];  
static float mlx90640To[768];
uint16_t frame[834];
float emissivity=0.95;
int status;

int main(void)
{
	HAL_Init();
	
	SystemClock_Config();
	
	MX_GPIO_Init();
	MX_USART1_UART_Init();
	MLX90640_I2CInit();
	
	MLX90640_SetRefreshRate(MLX90640_ADDR, RefreshRate);  //设置帧率
	MLX90640_SetChessMode(MLX90640_ADDR);                 //棋盘模式   
	paramsMLX90640 mlx90640;
	status = MLX90640_DumpEE(MLX90640_ADDR, eeMLX90640);  //读取像素校正参数 
	if (status != 0) printf("\\r\\nload system parameters error with code:%d\\r\\n",status);
	status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);  //解析校正参数
	if (status != 0) printf("\\r\\nParameter extraction failed with error code:%d\\r\\n",status);

	while (1)
	{
			int status = MLX90640_GetFrameData(MLX90640_ADDR, frame);  //读取一帧原始数据
			if (status < 0)
			{
				//printf("GetFrame Error: %d\\r\\n",status);
			}
			float vdd = MLX90640_GetVdd(frame, &mlx90640);  //计算 Vdd(这句可有可无)
			float Ta = MLX90640_GetTa(frame, &mlx90640);    //计算实时外壳温度

			float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature
			//printf("vdd:  %f Tr: %f\\r\\n",vdd,tr);
			MLX90640_CalculateTo(frame, &mlx90640, emissivity , tr, mlx90640To);            //计算像素点温度
			MLX90640_BadPixelsCorrection(mlx90640.brokenPixels, mlx90640To, 1, &mlx90640);  //坏点处理
			MLX90640_BadPixelsCorrection(mlx90640.outlierPixels, mlx90640To, 1, &mlx90640); //坏点处理
			
			printf("\\r\\n==========================IAMLIUBO MLX90640 WITH STM32 SWI2C EXAMPLE Github:github.com/imliubo==========================\\r\\n");
			for(int i = 0; i < 768; i++){
				if(i%32 == 0 && i != 0){
					printf("\\r\\n");
				}
				printf("%2.2f ",mlx90640To[i]);
			}
			printf("\\r\\n==========================IAMLIUB0 MLX90640 WITH STM32 SWI2C EXAMPLE Github:github.com/imliubo==========================\\r\\n");
	}
}

API函数介绍

1. 设置测量分辨率函数

int MLX90640_SetResolution(uint8_t slaveAddr, uint8_t resolution)
此函数用于设置 MLX90640 的测量分辨率值(0~3 表示分辨率为 16~19 位)。需要注意的是在下次重新上电时,此函数修改的值会自动恢复为默认值(即:此函数修改后不会保存,掉电即失)。返回 0 表示设置成功, -1 表示设备未应答, -2 表示重新读取后发现不是预期的值。
例如:
设置分辨率为 19 位: MLX90640_SetResolution(0x33,0x03);

2. 读取测量分辨率函数

int MLX90640_GetCurResolution (uint8_t slaveAddr)
此函数用于读取当前的测量分辨率(0~3),若此函数返回了-1 则表示读取失败。

3. 设置测量速率函数

int MLX90640_SetRefreshRate (uint8_t slaveAddr,uint8_t refreshRate)
此函数用于设置 MLX90640 的测量速率(即:每秒测量几帧数据),参数值可以是 0~7 代表 0.5、1、 2、 4、 8、 16、 32 和 64Hz。返回 0 表示设置成功, -1 表示设备未应答, -2 表示重新读取后发现不是预期的值。
例如:
设置为每秒测量 16 帧: MLX90640_SetRefreshRate (0x33,0x05);//5 的意思就是 16Hz

4. 读取测量分辨率函数

int MLX90640_GetRefreshRate (uint8_t slaveAddr)
此函数用于读取当前的测量速率值(0~7),若此函数返回了-1 则表示读取失败。

5. 读取完整实时数据

int MLX90640_GetSubPageNumber (uint16_t *frameData)
此函数用于读取一次完整的测量数据(832 个字),返回值表示当前帧是哪个子页(0 或 1)。
例如:

static int mlx90640Frame[834];
int subPage;
subPage = MLX90640_GetSubPageNumber(mlx90640Frame);

6. 设置子页模式为 TV

int MLX90640_SetInterleavedMode (uint8_t slaveAddr)
此函数用于设置测量分布模式为 TV 模式(行交错模式)。 返回 0 表示设置成功, -1 表示设备未应答, -2 表示重新读取后发现不是预期的值。

7. 设置子页模式为棋盘

int MLX90640_SetChessMode (uint8_t slaveAddr)
此函数用于设置测量分布模式为棋盘模式(像素交错模式)。 返回 0 表示设置成功, -1 表示设备未应答, -2 表示重新读取后发现不是预期的值。

8. 读取子页测量模式

int MLX90640_GetCurMode (uint8_t slaveAddr)
此函数用于读取当前的测量分布模式,返回 0 表示工作于 TV 模式,返回 1 表示工作于棋盘模式。

9. 读取全部校正参数

int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData)
此函数用于读取保存于EEPROM内的全部832个字的温度计算校准数据,保存于eeData数组内。
例如:

static uint16_t eeMLX90640[832];
int status;
status = MLX90640_DumpEE (0x33, eeMLX90640); //eeMLX90640 数组内是读取得到的EEPROM 参数数据

10. 解析校正参数为计算参数

int MLX90640_ExtractParameters(uint16_t * eeData,paramsMLX90640 *mlx90640)
此函数用来将MLX90640_DumpEE函数读取的所有 EEPROM 数据解析到定义于 MLX90640_API.h 中的自定义结构体变量中,此变量特别重要,是完成各种计算的必需参数(以下简称“计算参数” )。当解析完成后,原来的 EEPROM 数据基本再没有意义了(可以根据需要释放,也可以不管)。此函数返回-7 表示提供的 EEPROM 参数错误。
例如:

static uint16_t eeMLX90640[832];
paramsMLX90640 mlx90640;
int status;
status = MLX90640_DumpEE (0x33, eeMLX90640);//将 EEPROM 数据读取到 eeMLX90640 数组中
status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);//将 eeMLX90640 数组中的数据解析计算参数变量中

11. 读取一帧计算用实时数据

int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData)
此函数用于读取完整的一帧实时测量数据。计算所需要的完整的一帧数据为 834 个字(包括 832个字 RAM 数据+控制寄存器+状态寄存器)。如果返回-1 表示 MLX90640 未应答, -8 表示读取异常(最可能的情况是读取速率太低了),若返回 0 或者 1 则表示读取到了刚刚测量完成的子页 0 或者子页 1(读取成功),此时参数 frameData 数组内即是 834 个字的实时数据。
例如:

static uint16_t mlx90640Frame[834];
int status;
status = MLX90640_GetFrameData (0x33, mlx90640Frame);

12. 计算 Vdd

float MLX90640_GetVdd(uint16_t *frameData,const paramsMLX90640 *params)
此函数用于计算并返回 Vdd 电压值。需要的参数说明如下:

  • uint16_t *frameData:读取到的完整的一帧实时数据(MLX90640_GetFrameData得到的 834 个字的数组)
  • const paramsMLX90640 *params:由EEPROM解析得到的自定义结构体变量(MLX90640_ExtractParameters函数计算得到的“计算参数” )

此函数的返回值是浮点数,单位为 V。若不是 3.3V 左右,则说明发生了较为严重的问题。
Vdd 在计算点阵温度时用做参考电压, 故此计算结果必须为实际电压, 否则无法得到正确的温度值。(Vdd 的值在MLX90640_CalculateTo 函数体中会用到)
例如:
为了得到 Vdd 电压值,需要如下步骤:

float vdd;
uint8_t slaveAddress;
static int eeMLX90640[832];
static int mlx90640Frame[834];
paramsMLX90640 mlx90640;
int status;
status = MLX90640_DumpEE (slaveAddress, eeMLX90640); //读取 EEPROM
status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640); //由 EEPROM 计算得到计算参数
status = MLX90640_GetFrameData (0x33, mlx90640Frame); //读取一帧实时数据
vdd = MLX90640_GetVdd(mlx90640Frame, &mlx90640); //由计算参数和实时数据计算得到 Vdd

13. 计算 Ta

float MLX90640_GetTa(uint16_t *frameData,const paramsMLX90640 *params)
此函数计算得到 Ta(MLX90640 外壳温度)。
所需要的参数与 12 相同。
此函数的返回值是浮点数,单位为℃。若与环境温度相差甚远,则说明发生了较为严重的问题。
例如:
为了得到 Ta 温度值,需要如下步骤:

float Ta;
uint8_t slaveAddress;
static int eeMLX90640[832];
static int mlx90640Frame[834];
paramsMLX90640 mlx90640;
int status;
status = MLX90640_DumpEE (slaveAddress, eeMLX90640); //读取 EEPROM
status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640); //由 EEPROM 计算得到计算参数
status = MLX90640_GetFrameData (0x33, mlx90640Frame); //读取一帧实时数据
Ta = MLX90640_GetTa(mlx90640Frame, &mlx90640); //由计算参数和实时数据计算得到 Ta

14. 计算物体绝对温度数据

void MLX90640_CalculateTo(uint16_t *frameData,const paramsMLX90640 *params,float emissivity, float tr,float *result)
此函数计算一帧温度值(768 像素点)。计算结果为浮点型,保存于 result 数组内。参数说明如下:

  • uint16_t *frameData:读取到的一帧实时数据
  • const paramsMLX90640 *params:由 EEPROM 计算得到的计算参数
  • float emissivity:被测物体的辐射率(人体为 0.95,其它材料的辐射率请上网查)
  • float tr:校正温度,一般取 Ta-8
  • float *result:计算结果, 768 个浮点数

例如:
计算一帧刚刚读取到的实时数据为温度值,假设被测物体的辐射率为 0.95。

float emissivity = 0.95;
float Ta,tr;
unsigned char slaveAddress;
static uint16_t eeMLX90640[832];
static uint16_t mlx90640Frame[834];
paramsMLX90640 mlx90640;
static float mlx90640To[768];
int status;
status = MLX90640_DumpEE (slaveAddress, eeMLX90640);
status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
status = MLX90640_GetFrameData (0x33, mlx90640Frame);
Ta= MLX90640_GetTa(mlx90640Frame, &mlx90640);
tr = Ta-8.0;
MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To)

计算完成后, mlx90640To 数组中保存的即是 768 个单位为℃温度值。

15. 计算热图像数据

void MLX90640_GetImage(uint16_t *frameData,const paramsMLX90640 *params,float *result)
此函数的功能与上一节计算温度几乎完全相同,不同点仅为计算结果中的数值没有规划为温度单位,而是一些仅有数值大小意义的数值,用这些数值大小来绘图是足够的,这个函数的优点就是速度要比计算温度要快很多(仅需要绘图而不关心绝对温度值时可以使用这个函数来计算完成)。
例如:

static uint16_t eeMLX90640[832];
static uint16_t mlx90640Frame[834];
paramsMLX90640 mlx90640;
static float mlx90640Image[768];
int status;
status = MLX90640_DumpEE (0x33, eeMLX90640);
status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
status = MLX90640_GetFrameData (0x33, mlx90640Frame);
MLX90640_GetImage(mlx90640Frame, &mlx90640, mlx90640Image);

发射率(emissivity)

发射率(emissivity),这是物体的一种属性,根据材料的不同而不同,一般非金属(如塑料、油漆、皮革、纸张等)发射率通常为 0.95,常见物体发射率可以参考下图:

以上是关于使用MLX90640自制红外热像仪:API函数的使用的主要内容,如果未能解决你的问题,请参考以下文章

使用MLX90640自制红外热像仪:图像插值图像彩色编码

使用MLX90640自制红外热像仪:stm32f103c8t6刷320x240分辨率屏的时间测试

MLX90640 红外热成像仪测温模块开发笔记

MLX90640 红外热成像仪测温传感器模块开发笔记

MLX90640 红外热成像仪测温模块开发笔记(完整篇)

MLX90640 红外热成像仪开发笔记