
MERIDIAN Thermal Imager Sensor
前言
Meridian提供先進的CMOS熱影像解決方案,使能夠量產接收紅外線波長8~14μm的熱影像感測器,主要應用於消費與商用產品.
與一般Image最大不同點在於價格低,與所需要的算力MCU即可處理大大降低應用成本
其中MI0802熱影像感測模組:包括thermal sensor, Lens鏡頭, 64 KB Flash記憶體, PCBA 10-pin FPC連接器。

How do Thermal Imager sensor work?
熱影像感測器原理,物體的熱幅射經由Lens鏡頭蒐集能量,通過選定的光譜頻帶Filter,到達pixel detector轉換紅外線IR成電子訊號,透過放大器與訊號處理將電子訊號轉換成溫度影像,每一個像素pixel代表一個溫度值並且可以即時彩色顯示影像。

MI48Dx Thermal Image Processor
MI48Dx 熱影像處理器是用來搭配MI0802熱影像感測模組.主要功能是處理每一個pixel的校正calibration,執行壞點修正bad pixel correction (BPC), 轉換raw data資料為溫度並抑制pixel雜訊。
簡單說就是一顆小MCU,先幫你處理好前面的校準clock ,因其走的規格非常規intil 8080 可以自己對街MCU但透過MI48轉接會相對方便快速

Hardwave接線
可以看下圖總共有12pin 需要連接,留意這邊 8 ,11 ,12 pin都要接就算沒用到耶要接GND


in ADDR (pin 11 of the 12 pins header) in order to use slave address of 0x40.

Also the MODE pin (pin 8 of the 12 pins header) has to be pulled low to enable SPI/I2C operation

STM32 sample code ON H7
這邊前面初始化會是以下幾個Fuction 都是 拉GPIO與 I2C與MI48通訊,如果卡住請檢察這些線路
mi48Reset();
mi48EnbleTemporalFilter();
mi48SetFrameRateDivisor(2);
mi48StartContinuousCapture();
對應詳細Fuction
void mi48Reset()
{
HAL_GPIO_WritePin(MI48_RST_GPIO_Port, MI48_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(MI48_RST_GPIO_Port, MI48_RST_Pin, GPIO_PIN_SET);
HAL_Delay(1000);
}
void mi48EnbleTemporalFilter()
{
uint8_t buf[16];
buf[0] = 0xd0;
buf[1] = 0x0b;
HAL_I2C_Master_Transmit(&hi2c1, 0x40<<1, buf, 2, HAL_MAX_DELAY);
HAL_Delay(1000);
}
void mi48SetFrameRateDivisor(uint8_t framerateDivisor)
{
uint8_t buf[16];
buf[0] = 0xb4;
buf[1] = framerateDivisor;
HAL_I2C_Master_Transmit(&hi2c1, 0x40<<1, buf, 2, HAL_MAX_DELAY);
}
void mi48StartContinuousCapture()
{
uint8_t buf[16];
buf[0] = 0xb1;
buf[1] = 0x03;
HAL_I2C_Master_Transmit(&hi2c1, 0x40<<1, buf, 2, HAL_MAX_DELAY);
}
再來其實就是把SPI資料讀取出來而已,但這邊的資料不是一般RGB565或RGB888所以她有給一個Color map去對照換算塞到顯示板上
while (1)
{
if(HAL_GPIO_ReadPin(MI48_DATA_READY_GPIO_Port, MI48_DATA_READY_Pin))
{
HAL_GPIO_WritePin(GPIOA, MI48_SSA15_Pin, GPIO_PIN_RESET);
if(HAL_SPI_Receive(&hspi3, (uint8_t *)spiBuf, 4960+80, HAL_MAX_DELAY) != HAL_OK)
{
HAL_GPIO_WritePin(GPIOA, MI48_SSA15_Pin, GPIO_PIN_SET);
Error_Handler();
}
else
{
HAL_GPIO_WritePin(GPIOA, MI48_SSA15_Pin, GPIO_PIN_SET);
processThermalData();
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
其中processThermalData取資料部分可參考下面(其實只是把最大最小抓出來和color map換算)

void processThermalData()
{
uint32_t min = 0;
uint32_t max = 0;
if (isFillRollingArray){
for (int i=0; i<minMaxRollingCount; i++){
minArray[i] = spiBuf[6]; // min
maxArray[i] = spiBuf[5]; // max
}
isFillRollingArray = false;
}
if (spiBuf[6]!=0){
minArray[minMaxRollingIndex] = spiBuf[6]; // min
maxArray[minMaxRollingIndex] = spiBuf[5]; // max
}
for (int i=0; i<minMaxRollingCount; i++){
min+= minArray[i];
max+= maxArray[i];
}
max = (max/minMaxRollingCount)+paddingOnMinMax;
min = (min/minMaxRollingCount)-paddingOnMinMax;
minMaxRollingIndex++;
if (minMaxRollingIndex==minMaxRollingCount){
minMaxRollingIndex = 0;
}
if (spiBuf[6]!=0){
mi48TemperatureToRGB565WithColorMap(spiBuf+80, outputBuffer, spiBuf[6], spiBuf[5], colorMapIndex, false);
ST7735_DrawImage(0, 30, 80, 62, (uint16_t*)outputBuffer);
printMaxMin(spiBuf[5],spiBuf[6], false);
min = 0xffff;
max = 0;
}
}