MLX90640 红外热成像仪开发笔记(一到十篇)完整过程

您所在的位置:网站首页 红外热成像模块 MLX90640 红外热成像仪开发笔记(一到十篇)完整过程

MLX90640 红外热成像仪开发笔记(一到十篇)完整过程

2023-09-03 05:34| 来源: 网络整理| 查看: 265

MLX90640 红外热成像仪测温模块开发笔记(一)概述及开发资料准备现在自己在做红外成像仪的越来越多了,两年前有个井下机电设备运行状态的科研项目,当时使用了 AMG8833(88 像素),科研毕竟就是科研,后来也没有听说成果得到应用的消息, 我想也是, 88 能干什么,也就能做个红外测温枪吧。 前段时间因为公司生产电路板测试需要,打算买一台红外成像仪测量电路板发热是否正常,商用的价格还是有些小贵的,我们电路板都不大所以就找了一台便宜的先用着,无意中发现了 MLX90640 这个东西, 32*24像素, 768 个测温点,基本上可以成像用了。现在都智能手机、信息化、人工智能了,能不能用 MLX90640 做个能和手机连接成像的红外模块呢,那样的话测试、存储岂不是很方便。 说做就做,马上行动。。。。。红外成像仪效果图.png

MLX90640 有两个型号, A 型和 B 型,各拍了一个,在等待物流的过程中索性先做些准备工作,也科普一下红外成像是怎么回事。首先是上 MLX 的官网下载几个必备文件,有用的其实只有两个文件。

(1) MLX90640 数据手册下载地址不好放上,大家可以私信。(2) MLX90640 驱动库和说明文档下载地址

关于官网下载的两个文件,手册写得很一般,说一点用处也没有也不至于,但看完后觉得大部分是没有意义和不知所以然要写的,但手册不看毕竟是不行的。同时也做了中文翻译, MLX90640 中文手册下载地址

另一个下载的文件 mlx90640-library-master.zip 问题比较严重(折腾了我大概一天多时间)。过程不多说了,直接说问题在哪。 这个压缩包里有 API 使用说明、 API 的 C 语言源代码以及一组用 Excel 文件计算完成的参数计算实例,实例的原数据和计算结果都是没有问题的,但我按照 API 使用说明里的指导调用函数库存里的函数,使用 Excel 里的原始数据无论如何也得到不正确的结果,后来发现问题出在下载的 API 函数。MLX90640_API.h 文件里定义了一个结构体类型,里面较为明显的错误有:uint16_t alpha[768];int8_t kta[768];int8_t kv[768];上面三个变量被定义为整型,但是, Excel 计算表里面,这三个数组的值分别显示为0.0000000397885742132、 0.00634766、 0.43750000 的样子,这是整数?其它的不说, Excel和 API 不是同一个版本或者说不一致是 100%的。经过不断找别人用过的 API、测试,下面的文件是可用的,同时也做了一份 API 说明文件的中文翻译。MLX90640 驱动库:MLX90640API 中文说明

MLX90640 红外热成像仪测温模块开发笔记(二)API 移植-I2C 和关键接口函数

API 说明文件里面有官方的移植指导,但我觉得可以把重点放在与 MLX90640 具体操作有关的几个函数上,而与标准 I2C 相关的函数和文件结构还是按照自己习惯的套路实现。这样更符合我们开发人员的可控性的习惯。步骤如下:(1) 建立标准 I2C 文件 IIC.h 和 IIC.c 用自己的方法实现如下几个函数(硬件也好,GPIO 模拟也好),函数名称用下面建议的。void IIC_Init(void); //I2C 接口初始化void IIC_Start(void); //发送开始信号void IIC_Stop(void); //发送结束信号void IIC_SendACK(void); //发送应答信号void IIC_SendNAK(void); //发送非应答信号unsigned char IIC_RecvACK(void); //读取应答信号unsigned char IIC_RecvData(void); //读取 1 个字节void IIC_SendData(char dat); //发送 1 个字节(2) 在工程中引入 MLX90640_API.c 并做如下几处修改第一行#include 改为#include (3) 添加 3 个函数 void MLX90640_I2CInit(void)unsigned char MLX90640_I2CRead (unsigned short startAddress, unsigned short nWordsRead, unsigned short *datas)unsigned char MLX90640_I2CWrite (unsigned short writeAddress, unsigned short word)

void MLX90640_I2CInit(void){IIC_Stop();}//从指定地址读取 n 个字(每个字占用 2 个字节)unsigned char MLX90640_I2CRead(unsigned short startAddress, unsigned short nWordsRead, unsigned short *datas){unsigned char c1,c2; unsigned short i; unsigned char Msb,Lsb;

Msb=(unsigned char)(startAddress>>8); Lsb=(unsigned char)(startAddress&0x00FF);

IIC_Start(); //发送起始命令

IIC_SendData(0x66); //发送设备地址+写命令IIC_RecvACK();IIC_SendData(Msb); //发送要操作的地址值 2 字节

IIC_RecvACK();IIC_SendData(Lsb);IIC_RecvACK();

IIC_Start(); //发送起始命令IIC_SendData(0x67); //发送设备地址+读命令IIC_RecvACK();for (i=0;i>8); IIC_RecvACK();IIC_SendData(word&0x00FF); IIC_RecvACK();

IIC_Stop(); return 0;

(4)修改 2 个函数 unsigned char MLX90640_DumpEE(unsigned short *eeData){return MLX90640_I2CRead(0x2400, 832, eeData);}

unsigned char MLX90640_GetFrameData(unsigned short *frameData){unsigned short statusRegister,controlRegister1;

MLX90640_I2CRead(0x8000, 1, &statusRegister); if (statusRegister&0x0008)//有测量完成的 Frame{MLX90640_I2CRead(0x800D, 1, &controlRegister1); MLX90640_I2CWrite(0x8000, statusRegister&(~0x0018)); MLX90640_I2CRead(0x0400, 832, frameData); frameData[832] = controlRegister1;frameData[833] = statusRegister & 0x0001; return 0;}Return -1;}

至此移植完成编译工程,若没有错误提示则基本上没有问题了,下一篇开始讲述如何操作MLX90640。

MLX90640 红外热成像仪测温模块开发笔记(三)工作流程和操作MLX90640 的一般步骤

默认参数时MLX90640 的工作流程 (1) 上电,内部初始化(约 40ms)(2) 读取工作参数到控制和状态寄存器(3) 开始以 2Hz 的速率测量实时数据并更新到 RAM,自动更新状态寄存器。

测量帧解释 MLX90640 共有 768 个测量像素点,每次测量其中的一半,称为 1 帧,故此完成 768 像素需要测量 2 帧,用帧 0 和帧 1 来表示。即:所谓的 1 帧数据其实是完整像素的一半。

可以修改的参数 可以修改的参数有以下几个方面: 自动测量:默认为自动测量,即自动循环测量帧 0 和帧 1 更新到RAM 中。与其对应的是手动测量,即:用指令来控制测量帧 0 还是帧 1。手动测量已经在官方的数据手册中被删除,看来 MLX 也不喜欢别人用,所以我们也就别用了。自动测量保持默认值,不要改就好。 帧分布:前面已经说了,1 帧实际上是测量完成了一半的像素点,这一半像素有两种分布模式,手册上称为 TV 模式和 Chess 模式,TV 模式以行为单位,是指每帧只测量奇数行或者偶数行,Chess 模式是指以像素为单位,每次交错着像素测 384 个像素点。我们可以称之为“行交错模式”和“像素交错模式”。在这方面,手册上又说了,出厂时是以 Chess 模式校准的,具有最好的精度(言下之意就是说如果修改为了 TV 模式时会不准),鉴于此,这个参数也不要动。 测量分辨率:可选的有 16~19 位 AD 转换精度,默认是 18 位,转换位数当然是越高越好了,但 18 和 19 位经过测试也没有发现有什么实际区别,这个参数可改可不改。 测量速率:每秒测量几帧数据,这个参数很有用处,毕竟我们希望成像后是连续的动画,每秒 2 次一定是不好的,我们可以调用 API 将这个参数修改为 8Hz 或者 16Hz 甚至 32Hz,64Hz 是不建议的,因为测量速率太快时噪声特别大,图像特别乱。普通相机的刷新速率也就 15Hz 左右,所以建议最高设置为 16Hz 吧。

所以,虽然数据手册上写的感觉好像可修改的参数挺多,这么一分析,其实只有 1 个测量速率是有用处的,其它都是浮云(鸡肋)。

参数修改方法讨论: 有两种修改方法,修改寄存器和修改 EEPROM。(1) 修改寄存器(推荐)传感器上电后会自动从 EEPROM 读取参数到寄存器,寄存器内的参数值是运行时实际执行的参数,直接通过 I2C 修改寄存器值即可,随用随改、立即生效。寄存器的值是掉电遗失的, 所以每次上电后都要修改一次。(2) 修改 EEPROMEEPROM 是掉电不丢失的,所以修改 EEPROM 内的运行参数只需要一次,下次启动生效。但EEPROM 内存储的不仅只是同步到运行寄存器的几个参数,大部分的是 768 个像素的校准参数,这些参数是出厂时写入的,特别重要,所以我的建议还是不要对 EEPROM 有任何的写操作,以免发生意外,EEPROM 里的像素校正参数一旦被意外修改就再也找不回来了。

MLX90640 底层驱动Keil 项目(STC 单片机)下载

建议的操作流程 unsigned short EE[832]; unsigned short Frame[834]; paramsMLX90640 MLXPars; float Vdd,Ta,Tr;float Temp[768];

IIC_Init(); //I2C 初始化MLX90640_I2CInit(); //MLX 传感器初始化Delay_ms(50); //预留一点时间让 MLX 传感器完成自己的初始化MLX90640_SetRefreshRate(0); //测量速率 1Hz(0~7 对应 0.5,1,2,4,8,16,32,64Hz)

MLX90640_I2CRead(0x2400, 832, EE); //读取像素校正参数MLX90640_ExtractParameters(EE, &MLXPars); //解析校正参数(计算温度时需要)

while (1){Delay_ms(5);if (MLX90640_GetFrameData(Frame)==0) //有转换完成的帧{Vdd=MLX90640_GetVdd(Frame, MLXPars); //计算 Vdd(这句可有可无) Ta=MLX90640_GetTa(Frame, MLXPars); //计算实时外壳温度Tr=Ta-8.0; //计算环境温度用于温度补偿//手册上说的环境温度可以用外壳温度-8℃ MLX90640_CalculateTo(Frame, MLXPars, 0.95, Tr, Temp); //计算像素点温度/*Temp 数组内即是转换完成的实时温度值,单位℃可以在这里对得到的 32*24=768 个温度值进行处理、转换为颜色值、显示关于温度转颜色方法,在后续的文章中会有专门介绍*/}}一点疑问 校正参数存储于传感器内部的 EEPROM,实时数据也来自传感器,如何利用实时数据和校正参数计算温度的方法也是事先规定好的,MLX 为什么不直接在内部完成这个温度计算让用户直接读取温度值?为了体现这个传感器的复杂性或者是让用户有成就感吗?本来可以在传感器内部解决的问题被厂家要求在外部完成,对 MCU 的性能要求是特别高的, 大量的浮点运算,大量的RAM 消耗,较低的效率。

MLX90640 红外热成像仪测温模块开发笔记(四)损坏和不良像素的处理 如前“开发笔记(一)”所说,MLX90640 可能存在不超过 4 个像素的损坏或者不良像素,在温度计算过程完成后,这些不良像素点会得到错误的温度数据,对于处理这些不良数据 MLX 也给出了推荐方法和具体的函数。(其实就是找相邻的正常的温度数据取平均来代替不良数据)

前面开发笔记(一)的内容中所说的 API 库,里面缺少了对不良像素点的处理函数,在这里补上。 int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2){int pixPosDif;

pixPosDif = pix1 - pix2;if(pixPosDif > -34 && pixPosDif < -30){return -6;}if(pixPosDif > -2 && pixPosDif < 2){return -6;}if(pixPosDif > 30 && pixPosDif < 34){return -6;}

return 0;}

float GetMedian(float *values, int n){float temp;

for(int i=0; i>5;column = pixels[pix] - (line



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3