前面一篇文章介绍了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,常见物体发射率可以参考下图: