立创开源|基于MLX90640传感器的热成像仪设计方案

MLX90640作为传感器的热成像仪,主控stm32f401ccu6,板载flash当个u盘存图片,锂电池供电,2寸屏幕,测试电路板是否发烫小工具

mlx90640,虽然价格并不便宜,不过相比于成品产品的便宜不少(功能也对应少一点),主控stm32f401ccu6,充电芯片ip2312,外置flash焊接了一个8m的“大”flash,感觉存图片足够了,屏幕使用的是2寸的spi的屏,没用并口功能已经后悔了,刷新有点慢(能用),懒得改了,电路板图片如下

 solidworks绘制外壳:

 程序部分使用双线性插值,把传感器像素对应转到屏幕显示大小减去边缘留的一点空,拿来写界面用,用了dsp库中的现成函数,实测和手写的处理速度没差 加了文件系统,存图片有点慢,要好几秒

dsp代码主要如下(总体代码在工程链接中):

// 双线性插值
uint8_t Besize_draw(BMP_8 input_bmp8[],uint8_t method,uint8_t ifsavefile)
{//注释的是自己的插值,现在使用dsp库中提供的
//    BMP_8 bmp8[IMG_INITIAL_HEIGHT][IMG_INITIAL_WIDTH];
    BMP_8 temp;
    BMP_24 temp_24;
    RGB565 TEMP_RGB565;
    uint16_t color[1];
    char filename[20];
    int i, j;
    int w = IMG_INITIAL_WIDTH;
    int h = IMG_INITIAL_HEIGHT;
    int iw = IMG_WIDTH;
    int ih = IMG_HEIGHT;
    float dx=((float)IMG_INITIAL_WIDTH-2.0f)*1.0f/(IMG_WIDTH-1);
    float dy=((float)IMG_INITIAL_HEIGHT-2.0f)*1.0f/(IMG_HEIGHT-1);
//    for(int a=0;a<IMG_INITIAL_HEIGHT;a++)
//    {
//        for(int b=0;b<IMG_INITIAL_WIDTH;b++)
//            bmp8[a][b].gray_val=input_bmp8[a*IMG_INITIAL_WIDTH+b].gray_val;
//    }
    arm_bilinear_interp_instance_f32 bilinear_data;
    bilinear_data.numCols=IMG_INITIAL_WIDTH;
    bilinear_data.numRows=IMG_INITIAL_HEIGHT;
    float data[IMG_INITIAL_WIDTH*IMG_INITIAL_HEIGHT];
    for(int a=0;a<IMG_INITIAL_HEIGHT*IMG_INITIAL_WIDTH;a++)
    {
        data[a]=(float)input_bmp8[a].gray_val;
    }
    bilinear_data.pData=data;
    if(ifsavefile)
    {
        sprintf(filename,"photo%d.bmp",get_filenum());
        retSD = f_mount(&spi_fs, "", 1);
        if(retSD != FR_OK)
        {
            if(retSD == FR_NO_FILESYSTEM)
            {
                //f_mount 没有文件系统,开始格式化spi-flash
                retSD = f_mkfs("",FM_FAT32,0,work,sizeof(work));
                if(retSD != FR_OK)
                {
                //f_mkfs 格式化失败
                    return 1;
                }
                else
                {
                    //格式化成功,开始重新挂载spi-flash
                    retSD = f_mount(&spi_fs, "", 1);
                    if(retSD != FR_OK)
                    {
                        return 1;
                        ;//f_mount 发生错误
                    }
                    else
                    {
                        save_bmp_header(&fil,&bmpinfo);
                        f_lseek(&fil,66);
                    }//spi-flash文件系统挂载成功
                }
            }
            else
            {
                return 1;
            }
        }
        else
        {//spi-flash文件系统挂载成功
            retSD = f_open(&fil, filename, FA_OPEN_ALWAYS | FA_WRITE);
            if(retSD == FR_OK)
            {
                save_bmp_header(&fil,&bmpinfo);
                f_lseek(&fil,66);
            }
            else
            {
                return 1;
            }
        }
    }
    ST7789_SetAddressWindow((320-IMG_WIDTH)/2, (240-IMG_HEIGHT)/2, IMG_WIDTH+(320-IMG_WIDTH)/2-1, IMG_HEIGHT+(240-IMG_HEIGHT)/2-1);
    ST7789_Select();
    ST7789_DC_Set();
    uint16_t imgdata[IMG_WIDTH*IMG_HEIGHT/4];
    uint32_t index=0;
    for (j = 0; j < ih; j++)
    {
//        float fy = ((float)j + 0.5f) * dy - 0.5f;
        float fy=(float)j  * dy+1 ;
        for (i = 0; i < iw; i++)
        {
//            float fx = ((float)i + 0.5f) * dx - 0.5f;
            float fx = (float)i  * dx+1 ;
            temp.gray_val=(uint8_t)arm_bilinear_interp_f32(&bilinear_data,fx,fy);
//            // 四邻域
//            int Lx = (int)fx;
//            int Rx = Lx + 1;
//            int Ly = (int)fy;
//            int Ry = Ly + 1;
//            Lx = Lx > w - 2 ? w - 2 : Lx < 0 ? 0 : Lx;
//            Rx = Rx > w - 1 ? w - 1 : Rx < 0 ? 0 : Rx;
//            Ly = Ly > h - 2 ? h - 2 : Ly < 0 ? 0 : Ly;
//            Ry = Ry > h - 1 ? h - 1 : Ry < 0 ? 0 : Ry;
//            float u = (float)Rx - fx;
//            float v = (float)Ry - fy;
//            float r1=u*(float)bmp8[Ly][Lx].gray_val+(1-u)*(float)bmp8[Ly][Rx].gray_val;
//            float r2=u*(float)bmp8[Ry][Lx].gray_val+(1-u)*(float)bmp8[Ry][Rx].gray_val;
//            temp.gray_val=(uint8_t)(v * r1 + (1 - v) * r2);
            bmp8_to_color(method,temp.gray_val,&temp_24);
            TEMP_RGB565.r_bit =temp_24.r_val>>3;
            TEMP_RGB565.g_bit =temp_24.g_val>>2;
            TEMP_RGB565.b_bit =temp_24.b_val>>3;
            color[0] =(TEMP_RGB565.r_bit << 11 |TEMP_RGB565.g_bit << 5 |TEMP_RGB565.b_bit);
            color[0] =( color[0] >> 8) | ((color[0] & 0xFF) << 8);
            if(index<IMG_WIDTH*(IMG_HEIGHT/4))
                imgdata[index++]=color[0];
            else
            {
                index=0;
                imgdata[index++]=color[0];
            }
        }
        if((j+1)%(IMG_HEIGHT/4)==0)
        {
            HAL_SPI_Transmit(hspi, (uint8_t*)imgdata, sizeof(uint16_t)*IMG_WIDTH*(IMG_HEIGHT/4), HAL_MAX_DELAY);
            if(ifsavefile)
            {
                for(int y=0;y<IMG_HEIGHT/4;y++)
                {
                    for(int x=0;x<IMG_WIDTH;x++)
                    {
                        imgdata[y*IMG_WIDTH+x] =( imgdata[y*IMG_WIDTH+x] >> 8) | ((imgdata[y*IMG_WIDTH+x] & 0xFF) << 8);
                    }
                }
                f_write(&fil,(uint8_t*)imgdata,sizeof(uint16_t)*IMG_WIDTH*(IMG_HEIGHT/4),&count);
               // UART_printf(&huart1,"count=%d\n",count);
            }
        }
    }
    ST7789_UnSelect();
    if(ifsavefile)
    {
        if(retSD != FR_OK)
        {
            f_close(&fil);
            return 1;
        }
        f_close(&fil);
    }
    return 0;
}

​​​​​​​

 实际效果

 电路原理图:

 pcb图:

 工程连接:MLX90640热成像仪 - 嘉立创EDA开源硬件平台 (oshwhub.com)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值