色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          "); //-->

          博客專欄

          EEPW首頁 > 博客 > MLX90640 紅外熱成像儀測溫模塊開發(fā)筆記(完整篇)

          MLX90640 紅外熱成像儀測溫模塊開發(fā)筆記(完整篇)

          發(fā)布人:河北穩(wěn)控科技 時間:2022-08-01 來源:工程師 發(fā)布文章

          MLX90640 紅外熱成像儀測溫模塊開發(fā)筆記(一)概述及開發(fā)資料準備

          現(xiàn)在自己在做紅外成像儀的越來越多了,兩年前有個井下機電設備運行狀態(tài)的科研項目,當時使用了 AMG8833(8*8 像素),科研畢竟就是科研,后來也沒有聽說成果得到應用的消息, 我想也是, 8*8 能干什么,也就能做個紅外測溫槍吧。 前段時間因為公司生產(chǎn)電路板測試需要,打算買一臺紅外成像儀測量電路板發(fā)熱是否正常,商用的價格還是有些小貴的,我們電路板都不大所以就找了一臺便宜的先用著,無意中發(fā)現(xiàn)了 MLX90640 這個東西, 32*24像素, 768 個測溫點,基本上可以成像用了?,F(xiàn)在都智能手機、信息化、人工智能了,能不能用 MLX90640 做個能和手機連接成像的紅外模塊呢,那樣的話測試、存儲豈不是很方便。 說做就做,馬上行動。。。。。

          紅外成像儀效果圖.png

          MLX90640 有兩個型號, A 型和 B 型,各拍了一個,在等待物流的過程中索性先做些準備工作,也科普一下紅外成像是怎么回事。

          首先是上 MLX 的官網(wǎng)下載幾個必備文件,有用的其實只有兩個文件。


          (1) MLX90640 數(shù)據(jù)手冊

          下載地址不好放上,大家可以私信。

          (2) MLX90640 驅(qū)動庫和說明文檔

          下載地址


          關于官網(wǎng)下載的兩個文件,手冊寫得很一般,說一點用處也沒有也不至于,但看完后覺得大部分是沒有意義和不知所以然要寫的,但手冊不看畢竟是不行的。同時也做了中文翻譯, MLX90640 中文手冊下載地址


          另一個下載的文件 mlx90640-library-master.zip 問題比較嚴重(折騰了我大概一天多時間)。過程不多說了,直接說問題在哪。 這個壓縮包里有 API 使用說明、 API 的 C 語言源代碼以及一組用 Excel 文件計算完成的參數(shù)計算實例,實例的原數(shù)據(jù)和計算結(jié)果都是沒有問題的,但我按照 API 使用說明里的指導調(diào)用函數(shù)庫存里的函數(shù),使用 Excel 里的原始數(shù)據(jù)無論如何也得到不正確的結(jié)果,后來發(fā)現(xiàn)問題出在下載的 API 函數(shù)。

          MLX90640_API.h 文件里定義了一個結(jié)構體類型,里面較為明顯的錯誤有:

          uint16_t alpha[768];

          int8_t kta[768];

          int8_t kv[768];

          上面三個變量被定義為整型,但是, Excel 計算表里面,這三個數(shù)組的值分別顯示為0.0000000397885742132、 0.00634766、 0.43750000 的樣子,這是整數(shù)?其它的不說, Excel和 API 不是同一個版本或者說不一致是 100%的。經(jīng)過不斷找別人用過的 API、測試,下面的文件是可用的,同時也做了一份 API 說明文件的中文翻譯。

          MLX90640 驅(qū)動庫:

          MLX90640API 中文說明



          MLX90640 紅外熱成像儀測溫模塊開發(fā)筆記(二)API 移植-I2C 和關鍵接口函數(shù) 


          API 說明文件里面有官方的移植指導,但我覺得可以把重點放在與 MLX90640 具體操作有關的幾個函數(shù)上,而與標準 I2C 相關的函數(shù)和文件結(jié)構還是按照自己習慣的套路實現(xiàn)。這樣更符合我們開發(fā)人員的可控性的習慣。步驟如下:

          (1) 建立標準 I2C 文件 IIC.h 和 IIC.c 

          用自己的方法實現(xiàn)如下幾個函數(shù)(硬件也好,GPIO 模擬也好),函數(shù)名稱用下面建議的。

          void IIC_Init(void); //I2C 接口初始化

          void IIC_Start(void); //發(fā)送開始信號

          void IIC_Stop(void); //發(fā)送結(jié)束信號

          void IIC_SendACK(void); //發(fā)送應答信號

          void IIC_SendNAK(void); //發(fā)送非應答信號unsigned char IIC_RecvACK(void); //讀取應答信號unsigned char IIC_RecvData(void); //讀取 1 個字節(jié)void IIC_SendData(char dat); //發(fā)送 1 個字節(jié)

          (2) 在工程中引入 MLX90640_API.c 

          并做如下幾處修改

          第一行#include <MLX90640_I2C_Driver.h>改為#include <IIC.h>

          (3) 添加 3 個函數(shù) 

          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 個字節(jié))

          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(); //發(fā)送起始命令


          IIC_SendData(0x66); //發(fā)送設備地址+寫命令IIC_RecvACK();

          IIC_SendData(Msb); //發(fā)送要操作的地址值 2 字節(jié)


          IIC_RecvACK();

          IIC_SendData(Lsb);

          IIC_RecvACK();


          IIC_Start(); //發(fā)送起始命令

          IIC_SendData(0x67); //發(fā)送設備地址+讀命令IIC_RecvACK();

          for (i=0;i<nWordsRead;i++)

          {

          c1=IIC_RecvData(); IIC_SendACK();

          c2=IIC_RecvData();

          if (i==(nWordsRead-1)) IIC_SendNAK();

          else

          IIC_SendACK();


          datas[i]=c1; datas[i]<<=8; datas[i]|=c2;

          }

          IIC_Stop(); //發(fā)送停止命令


          return 0;

          }

          //向指定地址寫入 1 個字(2 字節(jié))

          unsigned char MLX90640_I2CWrite(unsigned int writeAddress, unsigned int word)

          {

          IIC_Start(); //發(fā)送起始命令

          IIC_SendData(0x66); //發(fā)送設備地址+寫命令IIC_RecvACK();

          IIC_SendData(writeAddress>>8); //發(fā)送要操作的地址值 2 字節(jié)

          IIC_RecvACK();

          IIC_SendData(writeAddress&0x00FF); IIC_RecvACK();


          IIC_SendData(word>>8); IIC_RecvACK();

          IIC_SendData(word&0x00FF); IIC_RecvACK();


          IIC_Stop(); return 0;

           

          (4)修改 2 個函數(shù) 

          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 紅外熱成像儀測溫模塊開發(fā)筆記(三)工作流程和操作MLX90640 的一般步驟 


          默認參數(shù)時

          MLX90640 的工作流程 

          (1) 上電,內(nèi)部初始化(約 40ms)

          (2) 讀取工作參數(shù)到控制和狀態(tài)寄存器

          (3) 開始以 2Hz 的速率測量實時數(shù)據(jù)并更新到 RAM,自動更新狀態(tài)寄存器。


          測量幀解釋 

          MLX90640 共有 768 個測量像素點,每次測量其中的一半,稱為 1 幀,故此完成 768 像

          素需要測量 2 幀,用幀 0 和幀 1 來表示。即:所謂的 1 幀數(shù)據(jù)其實是完整像素的一半。


          可以修改的參數(shù) 

          可以修改的參數(shù)有以下幾個方面:

          ? 自動測量:默認為自動測量,即自動循環(huán)測量幀 0 和幀 1 更新到RAM 中。與其對應的是手動測量,即:用指令來控制測量幀 0 還是幀 1。手動測量已經(jīng)在官方的數(shù)據(jù)手冊中被刪除,看來 MLX 也不喜歡別人用,所以我們也就別用了。自動測量保持默認值,不要改就好。

          ? 幀分布:前面已經(jīng)說了,1 幀實際上是測量完成了一半的像素點,這一半像素有兩種分布模式,手冊上稱為 TV 模式和 Chess 模式,TV 模式以行為單位,是指每幀只測量奇數(shù)行或者偶數(shù)行,Chess 模式是指以像素為單位,每次交錯著像素測 384 個像素點。我們可以稱之為“行交錯模式”和“像素交錯模式”。

          在這方面,手冊上又說了,出廠時是以 Chess 模式校準的,具有最好的精度(言下之意就是說如果修改為了 TV 模式時會不準),鑒于此,這個參數(shù)也不要動。

          ? 測量分辨率:可選的有 16~19 位 AD 轉(zhuǎn)換精度,默認是 18 位,轉(zhuǎn)換位數(shù)當然是越

          高越好了,但 18 和 19 位經(jīng)過測試也沒有發(fā)現(xiàn)有什么實際區(qū)別,這個參數(shù)可改可不改。

          ? 測量速率:每秒測量幾幀數(shù)據(jù),這個參數(shù)很有用處,畢竟我們希望成像后是連續(xù)的

          動畫,每秒 2 次一定是不好的,我們可以調(diào)用 API 將這個參數(shù)修改為 8Hz 或者 16Hz 甚至 32Hz,64Hz 是不建議的,因為測量速率太快時噪聲特別大,圖像特別亂。普通相機的刷新速率也就 15Hz 左右,所以建議最高設置為 16Hz 吧。


          所以,雖然數(shù)據(jù)手冊上寫的感覺好像可修改的參數(shù)挺多,這么一分析,其實只有 1 個測量速率是有用處的,其它都是浮云(雞肋)。


          參數(shù)修改方法討論: 

          有兩種修改方法,修改寄存器和修改 EEPROM。

          (1) 修改寄存器(推薦)

          傳感器上電后會自動從 EEPROM 讀取參數(shù)到寄存器,寄存器內(nèi)的參數(shù)值是運行時實際執(zhí)行的參數(shù),直接通過 I2C 修改寄存器值即可,隨用隨改、立即生效。寄存器的值是掉電遺失的, 所以每次上電后都要修改一次。

          (2) 修改 EEPROM

          EEPROM 是掉電不丟失的,所以修改 EEPROM 內(nèi)的運行參數(shù)只需要一次,下次啟動生效。但

          EEPROM 內(nèi)存儲的不僅只是同步到運行寄存器的幾個參數(shù),大部分的是 768 個像素的校準參數(shù),這些參數(shù)是出廠時寫入的,特別重要,所以我的建議還是不要對 EEPROM 有任何的寫操作,以免發(fā)生意外,EEPROM 里的像素校正參數(shù)一旦被意外修改就再也找不回來了。


          MLX90640 底層驅(qū)動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); //讀取像素校正參數(shù)MLX90640_ExtractParameters(EE, &MLXPars); //解析校正參數(shù)(計算溫度時需要)


          while (1)

          {

          Delay_ms(5);

          if (MLX90640_GetFrameData(Frame)==0) //有轉(zhuǎn)換完成的幀

          {

          Vdd=MLX90640_GetVdd(Frame, MLXPars); //計算 Vdd(這句可有可無) Ta=MLX90640_GetTa(Frame, MLXPars); //計算實時外殼溫度

          Tr=Ta-8.0; //計算環(huán)境溫度用于溫度補償

          //手冊上說的環(huán)境溫度可以用外殼溫度-8℃ MLX90640_CalculateTo(Frame, MLXPars, 0.95, Tr, Temp); //計算像素點溫度

          /*

          Temp 數(shù)組內(nèi)即是轉(zhuǎn)換完成的實時溫度值,單位℃

          可以在這里對得到的 32*24=768 個溫度值進行處理、轉(zhuǎn)換為顏色值、顯示關于溫度轉(zhuǎn)顏色方法,在后續(xù)的文章中會有專門介紹

          */

          }

          }

          一點疑問 

          校正參數(shù)存儲于傳感器內(nèi)部的 EEPROM,實時數(shù)據(jù)也來自傳感器,如何利用實時數(shù)據(jù)和校正

          參數(shù)計算溫度的方法也是事先規(guī)定好的,MLX 為什么不直接在內(nèi)部完成這個溫度計算讓用戶直接讀取溫度值?為了體現(xiàn)這個傳感器的復雜性或者是讓用戶有成就感嗎?

          本來可以在傳感器內(nèi)部解決的問題被廠家要求在外部完成,對 MCU 的性能要求是特別高的, 大量的浮點運算,大量的RAM 消耗,較低的效率。





          MLX90640 紅外熱成像儀測溫模塊開發(fā)筆記(四)損壞和不良像素的處理 

          如前“開發(fā)筆記(一)”所說,MLX90640 可能存在不超過 4 個像素的損壞或者不良像素,在溫度計算過程完成后,這些不良像素點會得到錯誤的溫度數(shù)據(jù),對于處理這些不良數(shù)據(jù) MLX 也給出了推薦方法和具體的函數(shù)。(其實就是找相鄰的正常的溫度數(shù)據(jù)取平均來代替不良數(shù)據(jù)) 

           

          前面開發(fā)筆記(一)的內(nèi)容中所說的 API 庫,里面缺少了對不良像素點的處理函數(shù),在這里補上。 

          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<n-1; i++)

          {

          for(int j=i+1; j<n; j++)

          {

          if(values[j] < values[i])

          {

          temp = values[i]; values[i] = values[j]; values[j] = temp;


          }

          }


          if(n%2==0)

          {

          return ((values[n/2] + values[n/2 - 1]) / 2.0);


           

          }

          else

          {


          }

           





          return values[n/2];

           


          }


          int IsPixelBad(uint16_t pixel,paramsMLX90640 *params)

          {

          for(int i=0; i<5; i++)

          {

          if(pixel == params->outlierPixels[i] || pixel == params->brokenPixels[i])

          {

          return 1;

          }

          }


          return 0;

          }

          void MLX90640_BadPixelsCorrection(uint16_t *pixels, float *to, int mode, paramsMLX90640

          *params)

          {

          float ap[4]; uint8_t pix; uint8_t line; uint8_t column;


          pix = 0;

          while(pixels[pix] != 0xFFFF)

          {

          line = pixels[pix]>>5;

          column = pixels[pix] - (line<<5);


          if(mode == 1)

          {

          if(line == 0)

          {

          if(column == 0)

          {

          to[pixels[pix]] = to[33];

          }

          else if(column == 31)

          {

           


          }

          else

          {


          }

          }

           

          to[pixels[pix]] = to[62];





          to[pixels[pix]] = (to[pixels[pix]+31] + to[pixels[pix]+33])/2.0;

           

          else if(line == 23)

          {

          if(column == 0)

          {

          to[pixels[pix]] = to[705];

          }

          else if(column == 31)

          {

           


          }

          else

          {


          }

          }

           

          to[pixels[pix]] = to[734];





          to[pixels[pix]] = (to[pixels[pix]-33] + to[pixels[pix]-31])/2.0;

           

          else if(column == 0)

          {

          to[pixels[pix]] = (to[pixels[pix]-31] + to[pixels[pix]+33])/2.0;

          }

          else if(column == 31)

          {

           


          }

          else

          {

           

          to[pixels[pix]] = (to[pixels[pix]-33] + to[pixels[pix]+31])/2.0;





          ap[0] = to[pixels[pix]-33];

          ap[1] = to[pixels[pix]-31]; ap[2] = to[pixels[pix]+31]; ap[3] = to[pixels[pix]+33];

          to[pixels[pix]] = GetMedian(ap,4);



          }

          else

          {

           

          }





          if(column == 0)

          {

           

          to[pixels[pix]] = to[pixels[pix]+1];

          }

          else if(column == 1 || column == 30)

          {

          to[pixels[pix]] = (to[pixels[pix]-1]+to[pixels[pix]+1])/2.0;

          }

          else if(column == 31)

          {

           


          }

          else

          {


          0)

           

          to[pixels[pix]] = to[pixels[pix]-1];





          if(IsPixelBad(pixels[pix]-2,params) == 0 && IsPixelBad(pixels[pix]+2,params) ==


          {

          ap[0] = to[pixels[pix]+1] - to[pixels[pix]+2]; ap[1] = to[pixels[pix]-1] - to[pixels[pix]-2];

          if(fabs(ap[0]) > fabs(ap[1]))

          {

           









          }

          else

          {

           


          }

          else

          {


          }

           

          to[pixels[pix]] = to[pixels[pix]-1] + ap[1];





          to[pixels[pix]] = to[pixels[pix]+1] + ap[0];

           

          to[pixels[pix]] = (to[pixels[pix]-1]+to[pixels[pix]+1])/2.0;

          }

          }

          }

          pix = pix + 1;

          }

          }

          用法很簡單,在開發(fā)筆記(三)MLX90640_CalculateTo(Frame, MLXPars, 0.95, Tr, Temp);之后添加兩行即可。如下(斜體是添加的內(nèi)容):

          ……

          MLX90640_CalculateTo(Frame, MLXPars, 0.95, Tr, Temp); MLX90640_BadPixelsCorrection(MLXPars.brokenPixels, Temp, 1, MLXPars); MLX90640_BadPixelsCorrection(MLXPars.outlierPixels, Temp, 1, MLXPars);

          ……

          /*

          經(jīng)過上面的處理后,Temp 中的損壞和不良像素點已經(jīng)處理,Temp 數(shù)組中是處理完成后的

          768 個溫度值。

          */



          MLX90640 紅外熱成像儀測溫模塊開發(fā)筆記(五)陣列插值-由 32*24 像素到 512*384 像素 


          MLX90640 的 32*24=768 像素雖然比以往的 8*8 或者 16*8 像素提高了很多,但若直接用這些像素還是不能很好的形成熱像圖,為了使用這些像素點平滑成像就需要對其進行插值,使用更多的像素來繪制圖像。

          看了一些別人的算法,感覺主要就是多項式插值,僅是插值方法的組合方式不同。 

          算法依據(jù) 

          比較有代表性的是杭州電子科技大學楊風健等《基于 MLX90620 的低成本紅外熱成像系統(tǒng)設計》,使用三次多項式+雙線性插值,將原 16*4 像素擴展為 256*64 像素。雙線性插值的本質(zhì)就是一次函數(shù)(一次多項式)。該文章得到的結(jié)論是: 

          (1) 雙線性插值法計算量小、速度快,但對比度低、細節(jié)模糊。 

          (2) 三次多項式插值,圖像效果較清晰,對比度較高,但計算量較大。 

          (3) 先雙線性插值再三次多項式插值,效果優(yōu)于上兩種單一插值方法。 

          (4) 先三次多項式插值再雙線性插值,高低溫分布更加明顯,圖像效果更接趨于真實。同時,該文章還使用了一種對圖像質(zhì)量的評估方法---熵&平均梯度 

          熵,熱力學中表征物質(zhì)狀態(tài)的參量之一,用符號 S 表示,其物理意義是體系混亂程度的度量。用于圖像評價表示圖像表達信息量的多少。圖像熵越高信息量越大。 

          平均梯度,指圖像的邊界或影線兩側(cè)附近灰度有明顯差異,即灰度變化率大,這種變化率的大小可用來表示圖像清晰度。它反映了圖像微小細節(jié)反差變化的速率,即圖像多維方向上密度變化的速率,表征圖像的相對清晰程度。值越大表示圖像越清晰。


          插值實現(xiàn) 

          每行或者列的首個像素在前面插值 2 個點 1~n-1 像素,每個像素后面插值 3 個點最后一個像素,在后面插值 1 個點 n+2+(n-1)*3+1=n+2+n*3-1*3+1=4n+2-3+1=4n,即:像素變?yōu)樵瓉淼?4 倍 上面的處理方法,首個像素之前插入 2 個點,最后一個像素之后插入 1 個點,下次插值時,應首個之前插值 1 個點,末個像素之后插值 2 個點,以達到圖像平衡。 每次插值后像素為插值前的 4 倍,經(jīng)過兩次插值,即可將 32*24 改變?yōu)?512*384 像素。下面是已經(jīng)實際使用的插值算法,不過是用 Pascal(Delphi)寫的,有興趣的可以改為C 語言的,語句對應直接改就行,語言本來就是相通的嘛。 

           

          //這是一維數(shù)組插值算法 

          //SourceDatas:TDoubles;插值前的一維數(shù)組 

          //Dir:Integer;在哪個方向和末尾插入 2 個值(0:前面;1:末尾) 

          //times:Integer 多項式的項數(shù),一次多項式是 2 項,二次多項式是 3 項 

          //返回值:插值后的一維數(shù)組(數(shù)量是插值前*4) function PolynomialInterpolationArr( 

          SourceDatas:TDoubles; Dir:Integer; 

          times:Integer):TDoubles;//一維數(shù)組插值 

          var 

              i,j,k:Integer; 

              arrCount:Integer; 



          MLX90640 紅外熱成像儀測溫傳感器模塊開發(fā)筆記(六)紅外圖像偽彩色編碼 

          什么是紅外成像偽彩編碼 

          紅外成像的最終目的是用圖像來表現(xiàn)溫度變化,并且可以通過顏色來區(qū)分出不同熱量的物體輪廓和形狀。那么,到底用什么顏色來表示什么溫度呢?是否有什么標準規(guī)范呢?

          這個問題一開始也是心里沒底的,因為我不是專業(yè)做紅外成像的,只能到處查資料了解溫度和顏色之間的關系,基本得到以下幾點結(jié)論:

          (1)溫度和顏色之間沒有絕對的對應關系,沒有人要求紅外成像必須要用什么顏色來表示某個溫度,這種對應關系完全是由設計人員自已決定的。

          (2)不同的應用領域和行業(yè)出于不同的目的,會進行一些溫度和顏色的研究,進而用一種適用的漸變色來突出顯示某些特別關心的熱元素。

          (3)顏色編碼絕大多數(shù)是漸變色。以下是幾種不同的顏色編碼



          另外,還有人提出了“符合人的生理”讓人看著更加“舒服”的 HIS 彩色



          溫度轉(zhuǎn)顏色的方法

          (1)首先假設溫度范圍的上下限并將實際的溫度數(shù)據(jù)轉(zhuǎn)換為 0~255 之間的數(shù)值


          (2)使用轉(zhuǎn)換后的數(shù)值代入下面的偽彩編碼計算函數(shù),生成偽彩色

          //偽彩 1

          procedure GrayToPseColor(grayValue:Integer; var colorR,colorG,colorB:Ingeger);

          Begin

          colorR:=Abs(0-grayValue);

          colorG:=Abs(127-grayValue);

          colorB:=Abs(255-grayValue);

          End;




          MLX90640 紅外熱成像儀測溫傳感器模塊開發(fā)筆記(七) 小結(jié)-注意事項

              Red Eye Camera(以下簡稱“IDF-x” 或“設備” )是基于紅外陣列高精度溫度傳感器以及先進軟件算法的非接觸式熱成像儀器,可對視場范圍內(nèi)任何物體進行紅外成像,成像分辨率512*384 像素,溫度靈敏度 0.1℃,絕對精度±1.5℃,刷新頻率最高 64Hz。自帶存儲和實時時鐘,具備數(shù)據(jù)實時輸出顯示、拍照存儲功能,數(shù)字接口包括 UART 和 USB,可直接連接計算機和 Android 手機,配合上位機軟件或者手機 APP 程序,使用十分方便。

          (1)硬件設計注意事項

          電源: MLX90640 使用 3.3V 供電,并且使用供電電壓做為溫度測量的參考電壓來使用,所以對電源的要求比較高,盡量使用 LDO 穩(wěn)壓元件,并且 10uF 和 0.1uF 的退耦電容不能省,一定要靠近 VDD 管腳放置。電源電流沒太多要求,能夠平衡的輸出 100mA 就足夠。通訊: I2C的兩個管腳到MCU的距離不能過長(小于5CM吧),由于通訊速率可以1MHz,所以上拉電阻不能太大,推薦使用 1k~2k 的電阻。

          (2)軟件設計注意事項

          I2C 部分: 盡量使用已經(jīng)經(jīng)過驗證的 I2C 驅(qū)動程序,可以從其它項目中復制過來稍加改動,這部分是通訊的基礎,一定要可靠。接口層: 主要是指讀和寫 MLX90640 的兩個函數(shù),可以先讀寫 MLX90640 的寄存器(地址 0x8000~0x8016) 對讀寫函數(shù)進行驗證。計算層: 這部分就直接用 API 庫中的對應函數(shù)就可以,基本不會有問題。

          (3)數(shù)據(jù)正確性驗證

          在操作過程中必須注意解算出的 Vdd 的值,如果這個值與實際值相差超過 0.1V 就應該檢查問題。

          (4)水平方向問題

          如果鏡頭向前, MLX90640 的像素排列規(guī)則是從右向左(和我們的習慣相反),即:有點像手機的自拍攝像頭,圖像會是左右顛倒的,在成圖之前記得把每行的像素前后顛倒一下,再顯示就對了




          MLX90640 紅外熱成像儀測溫傳感器模塊開發(fā)筆記(八)擴展知識-輻射率、靈敏度、精度、探測距離


          輻射率


          是描述面輻射源特性的物理量。它表示某物體的單位面積輻射的熱量和黑體在相同溫度、相同條件下的輻射熱量之比。即:輻射率通俗地說就是某物體會將自身溫度轉(zhuǎn)換為輻射擴散出去的能力, 1 表示可以將自身溫度轉(zhuǎn)換為 100%的輻射, 0.9 表示可以降低自身溫度的 90%轉(zhuǎn)換為熱輻射擴散出去。實際上輻射率為 1 的物質(zhì)(黑體)是不存在的,所以任何材料的輻射率均是 0~1 之間的數(shù)值。


          任何物體在高于絕對零度(-273.15℃)的時候,其物體表面就會有紅外能量也就是紅外線****出來,溫度越高,****的紅外能量越強。紅外線測溫儀和紅外熱像儀就是根據(jù)這個特點來測量物體表面的溫度的,因為紅外線測溫儀和紅外熱像儀是測量物體表面的溫度的,所以在測量時會被物體表面的光潔度所影響。實驗證明:物體表面越接近于鏡面(反射越強),其表面所發(fā)出的紅外能量衰減越厲害,就需要對不同物體的表面對紅外能量的衰減情況做出補償,即設置一個補償系數(shù),這個補償系數(shù)就是輻射率。


          不同材料的輻射率差別還是很大的,比如人體是 0.95~0.98,而光滑的不銹鋼是 0.16,生銹的鐵是 0.65 左右,當探測過程中想要得到較為準確的溫度值時,就需要設置被探測物體的輻射系數(shù)。(若僅是為了成像則無需這么嚴格)


          靈敏度與溫度探測精度


          噪聲等效溫差(NETD) 是指紅外探測器能探測到的最小溫差,即:當被測物體的溫度變化多少時紅外探測器可以探測出來。衡量紅外探測器性能的主要指標之一。


          熱探測器的噪聲等效溫差在 100mK 左右(0.1℃)。第二代光探測器在 20mK 左右(0.02℃)。第三代探測器目標是在 1mK(0.001℃)。


          紅外探測計算出的絕對溫度值與被測物體的輻射率參數(shù)有直接關系,不同材料的輻射率值是不同的,更為嚴重的是即便是同種材料,表面光潔度、含水率、溫度高低等因素的影響也會直接改變輻射率,這就導致了紅外探測絕對溫度無法絕對準確,問題不在于紅外探測器的對輻射量的感知準確度而在于材料的輻射率是隨時在小范圍變化的。所以,衡量紅外探測器的性能指標一般不能用絕對溫度,而應該用溫度靈敏度,即: 噪聲等效溫差(NETD)。這也可以得出一個結(jié)論,紅外熱成像儀的主要作用是盡量區(qū)分出不同區(qū)域的溫度差異,用數(shù)字表現(xiàn)出來,進而展示為帶有顏色的圖像,只有溫度區(qū)分開以后,圖像才會細致分明。


          紅外探測距離


          紅外熱成像儀是用光學鏡頭來收集被測物體的熱輻射能量的,故此探測距離會受到鏡頭視場角和熱成像像素分辨率有關。假如某成像儀的成像分辨率為 32*32 像素,視場角為 75 度,則可以理解為從鏡頭里****出 32*32=1024 條激光來探測 1024 個點的溫度(32 行*32 列), 每行 32 個點,每列 32 個點。每相鄰兩條激光線的夾角為 75/31=2.4193°發(fā)散出去。隨著距離的增長,兩條激光線的間距會變大,當被測物體足夠小時,有可能處于兩條激光線之間未被探測到,這就是探測距離的問題。


          即:當成像儀的像素數(shù)量和視場角一定時,它的有效探測距離就與被測物體的大小有關。當被測物體尺寸已知時,對其進行探測的理論最遠距離為:





          MLX90640 紅外熱成像儀測溫傳感器模塊開發(fā)筆記(九) EEPROM、 RAM、寄存器說明


          EEPROM


          地址范圍為 0x2400~0x273F,共 832 個字(1664 字節(jié)), 前 16 個字包含了唯一 ID 碼、工作參數(shù)(上電后自動同步到寄存器)、 MLX90640 的 I2C 地址。后面的 816 個字全部是每個像素的校正或者測量參數(shù),數(shù)據(jù)手冊也沒有寫每個數(shù)據(jù)到底是什么意思,直接用就是了,不要問為什么。


          RAM


          地址范圍為 0x0400~0x073F,共 832 個字(1664 字節(jié)),前 768 個字是實時的 768 像素的測量數(shù)據(jù),后面 64 個字是與當前剛剛測量完成的一半像素有關的計算因數(shù)。 RAM 是只讀的。


          寄存器


          地址范圍為 0x8000~0x8010,共 16 個字(32 字節(jié)),其中用戶可以訪問的有狀態(tài)寄存器0x8000、控制寄存器 0x800D,改變控制寄存器可以直接控制 MLX90640 的運行行為,是既有讀又有寫的部分。


          三部分建議的操作


          上電后讀取一下 EEPROM,扔給 API 函數(shù) MLX90640_ExtractParameters 得到的參數(shù)項變量。根據(jù)需要修改控制寄存器的值。循環(huán)讀取狀態(tài)寄存器,當有新的數(shù)據(jù)測量完成時讀取全部 RAM 扔給 API 函數(shù)MLX90640_CalculateTo 得到每個像素的溫度值。


          狀態(tài)寄存器說明


          狀態(tài)寄存器從字面來理解應該是只讀的,但數(shù)據(jù)手冊里卻定義了一些位是參數(shù)(可修改的),不管寄存器叫什么了,根據(jù)參數(shù)功能來用吧。


          STA[15:5]:保留,只能寫入 0STA[4]: RAM 是否可寫, 0:不可寫; 1:可寫。在幀測量完成后,是否允許 MLX90640將測量的數(shù)據(jù)寫入(更新)到 RAM 里,這個功能可以在讀取一幀數(shù)據(jù)的過程中設置為不允許,即:當上位機正在讀取 RAM 的過程中,不允許再更新 RAM。這個位置同時還受控制寄存器中的 bit2 的限制,當 CTR[2]=0 時,無論這個位置怎樣設置,都會自動更新 RAM,僅當 CTR[2]=1時, STA[4]參數(shù)才會起作用。STA[3]:子頁測量完成標志位。 0:表示沒有完成; 1 表示已經(jīng)完成了一幀的測量。STA[2:0]:剛剛完成的是幀 0 還是幀 1。


          控制寄存器說明


          CTR[15:13]:保留,只能寫入 0


          CTR[12]:幀交錯模式,默認為 1(像素交錯模式),數(shù)據(jù)手冊上說了只有這種模式才能保證精度,那就不要改這一位,保持默認 1。


          CTR[11:10]:測量精度, 00~11 表示 16 位~19 位,默認為 10(18 位)。改成 11 也沒什么效果,所以這個參數(shù)也保持默認吧。


          CTR[9:7]:設置測量速率, 0~7 表示 0.5、 1、 2、 4、 8、 16、 32、 64Hz,默認為 010(2Hz),這個參數(shù)是唯一有用的參數(shù)。


          CTR[6:4]:手動測量時,指定要測量哪個子頁(幀 0 還是幀 1)。數(shù)據(jù)手冊已經(jīng)把手動測量部分刪除了,所以手動測量相關的參數(shù)可以忽略。


          CTR[3]:手動測量還是自動測量,默認為 0(自動測量),不要使用手動測量(原因同上)。


          CTR[2]:如何更新 RAM。 0:測量完成后自動更新; 1:根據(jù) STA[4]參數(shù)。


          CTR[1]:保留,只能寫入 0。


          CTR[0]: 0:所有數(shù)據(jù)更新在一頁里; 1:使能子頁模式(頁 0 和頁 1),默認





          MLX90640 紅外熱成像儀測溫傳感器模塊開發(fā)筆記(十) 成果展示-紅眼睛相機


              現(xiàn)在自己在做紅外成像儀的越來越多了,兩年前有個井下機電設備運行狀態(tài)的科研項目,當時使用了 AMG8833(8*8 像素),科研畢竟就是科研,后來也沒有聽說成果得到應用的消息, 我想也是, 8*8 能干什么,也就能做個紅外測溫槍吧。 前段時間因為公司生產(chǎn)電路板測試需要,打算買一臺紅外成像儀測量電路板發(fā)熱是否正常,商用的價格還是有些小貴的,我們電路板都不大所以就找了一臺便宜的先用著,無意中發(fā)現(xiàn)了 MLX90640 這個東西, 32*24像素, 768 個測溫點,基本上可以成像用了。

              現(xiàn)在都智能手機、信息化、人工智能了,能不能用 MLX90640 做個能和手機連接成像的紅外模塊呢,那樣的話測試、存儲豈不是很方便。 說做就做,馬上行動。

          最終的成果是一個微型的 USB 接口紅外成像模塊(微型紅外成像儀 30*30mm),可以連接到 Android 手機或者計算機的 USB 接口,實時顯示熱像視頻,和手機相機差不多,只不過它是熱紅外成像,所以叫“紅眼睛相機”。模塊圖片如下:


          Red Eye Camera(以下簡稱“IDF-x” 或“設備” )是基于紅外陣列高精度溫度傳感器以及先進軟件算法的非接觸式熱成像儀器,可對視場范圍內(nèi)任何物體進行紅外成像,成像分辨率512*384 像素,溫度靈敏度 0.1℃,絕對精度±1.5℃,刷新頻率最高 64Hz。自帶存儲和實時時鐘,具備數(shù)據(jù)實時輸出顯示、拍照存儲功能,數(shù)字接口包括 UART 和 USB,可直接連接計算機和 Android 手機,配合上位機軟件或者手機 APP 程序,使用十分方便。


          優(yōu)勢與特點

            可 USB 接口供電,即插即用。

            多種濾波方法,參數(shù)自由設置。

            多種顏色方案,滿足不同需求。

            高斯濾波,保留原始信息不畸變。


          應用領域:安防生物識別,發(fā)熱檢測,水暖電施工,故障排查,空調(diào)熱度檢測,安檢通道等。

          紅外成像儀安防生物識別 發(fā)熱檢測.jpeg


          關于 MLX90640 的文章暫時先寫這么多,文章中的各種資料、程序、產(chǎn)品,均可通過****獲取。


          *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯(lián)系工作人員刪除。

          物聯(lián)網(wǎng)相關文章:物聯(lián)網(wǎng)是什么





          相關推薦

          技術專區(qū)

          關閉