嵌入式产品级-超小尺寸热成像相机(从0到1 硬件-软件-外壳)

Thermal_Imaging_Camera

This is a small thermal imaging camera that includes everything from hardware and software.

小尺寸热成像相机-Pico-LVGL-RTOS

基于RP2040 Pico主控与RTOS,榨干双核性能实现LVGL和成图任务并行。ST7789驱动240×280屏,CST816T触摸IC,MLX90640传感器实现热成像功能。充电采用SGM4056,DC-DC使用SGM6031等等。

产品描述:树莓派RP204 Pico, 双核 LVGL RTOS,合理分配热成像呈现内容,UI画面的更新反馈。

探头既可支持长焦的BAB款,支持广角的BAA款,MCU + ST7789屏幕(240 * 280)+ CST816T 触摸IC + MLX90640热成像传感器 + 充电采用SGM4056,DC-DC使用SGM6031等等。

ui类似Apple Watch,按键1开启ui,支持卡尔曼滤波、插值切换、7种显示色彩和温度,折线图,电池电量。按键2拍照,触摸屏显示任意位置温度不限个数,支持调光。

传统热成像设备的痛点

  • 价格昂贵:大多数热成像设备由于采用高端传感器和复杂的硬件设计,导致成本高昂。
  • 体积较大:便携性较差,限制了其在移动应用或小型设备中的应用。
  • 开发门槛高:传统设备通常依赖复杂的嵌入式系统,难以快速定制化开发。

用户需求

  • 对于消费者和开发者而言,市场需要一种低成本、小尺寸、易用的热成像解决方案,同时具备良好的图像质量和功能拓展性。

产品优势

  • 低成本实现

    • 通过使用 RP2040 PicoMLX90640 这类性价比高的硬件组合,实现了功能的最大化。
    • 使用开源的 LVGL 图形库,避免高额商业软件授权费用。
  • 小尺寸设计

    • 紧凑的硬件结构使设备便于携带和嵌入其他系统,例如无人机、手持设备等场景。
  • 高性能多任务

    • 基于 RTOS 实现多任务调度,充分利用 RP2040 的双核性能,在图像处理和触摸交互中保持流畅性能。
  • 高扩展性

    • 支持通过触摸屏实现用户交互(例如温度调节、热图切换)。
    • 支持电池供电,搭配 SGM4056SGM6031 提供高效的电源管理。

项目包含下述内容

  • 硬件部分、PCB制板、BOM表文件等等 (Hardware)
  • 软件程序、用于RP2040软件程序以及LVGL UI等等(Software)
  • 上位机(UpperComputerQT上位机 待更新!
  • 二次开发方案
  • 技术支持、全项目内容答疑
  • 项目持续更新中(任何问题和想法 功能都可以跟我提,我会慢慢跟进解决

功能图例

下图为用户配置设置界面,你可以设置配置你想要的参数,例如是否插值,是否启用卡尔曼滤波,色彩选择等。

下图是温度折线图界面,左滑即可。

下图为电源状态管理界面,右滑即可。

下图为相机状态,也就是捕捉热源成像。

下述就是不同色彩呈现的图示了。

更多内容附在资料包中~

代码部分如下所示:展示部分。

cpp 复制代码
void my_disp_flush( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p )
{
    uint32_t w = ( area->x2 - area->x1 + 1 );
    uint32_t h = ( area->y2 - area->y1 + 1 );

    tft.startWrite();
    #if (ROTATE == 0 || ROTATE == 2)
    tft.setAddrWindow( area->x1, area->y1, w, h );
    #endif
    #if (ROTATE == 1 || ROTATE == 3)
    tft.setAddrWindow( area->x1, area->y1, w, h );
    #endif
    tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );
    tft.endWrite();

    lv_disp_flush_ready( disp_drv );
}

/*Read the touchpad*/
void my_touchpad_read( lv_indev_drv_t * indev_drv, lv_indev_data_t * data )
{

    touch.update();
    // Serial.print( "touch called " );
    // Serial.println( touch.tp.touching );
    bool touched = touch.tp.touching;
    if( !touched )
    // if( 0!=touch.data.points )
    {
        data->state = LV_INDEV_STATE_REL;
    }
    else
    {
        data->state = LV_INDEV_STATE_PR;
        #if (ROTATE == 0)
        /*Change to your screen resolution*/
        data->point.x = touch.tp.x;
        data->point.y = touch.tp.y;
        #endif
        #if (ROTATE == 1)
        /*Change to your screen resolution*/
        data->point.x = touch.tp.y;
        data->point.y = 240-touch.tp.x;
        #endif
        #if (ROTATE == 2)
        /*Change to your screen resolution*/
        data->point.x = 240-touch.tp.x;
        data->point.y = 280-touch.tp.y;
        #endif

        #if (ROTATE == 3)
        data->point.x = 280-touch.tp.y;
        data->point.y = touch.tp.x;
        #endif
        // data->point.x = touch.tp.x;
        // data->point.y = touch.tp.y;
        // Serial.print( "Data x " );
        // Serial.println( touch.tp.x );

        // Serial.print( "Data y " );
        // Serial.println( touch.tp.y );  
    }
}

// 按键输入设备读取回调函数
void my_keypad_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
{
    int button_state = digitalRead(24);  // 读取按键的状态,假设按键接地为 LOW
    if (button_state == LOW) {
        // 如果按键按下,记录开始按下的时间
        if (btn2_pushed_start_time == 0) {
            btn2_pushed_start_time = millis();
        }
        // 检测是否为长按
        if (millis() - btn2_pushed_start_time >= BTN_LONG_PUSH_T) {
            if (!btn2_long_pushed) {
                btn2_long_pushed = true;  // 标记为长按
                // 长按的处理,例如切换到不同屏幕
                
            }
        }
        data->state = LV_INDEV_STATE_PRESSED;  // 按键按下
    } else {
        // 按键松开,判断是否为短按
        if (btn2_pushed_start_time != 0) {
            if (!btn2_long_pushed) {
                btn2_pushed = true;  // 短按标记
                // 短按的处理,例如切换到不同屏幕
                if (!btn2_long_pushed){freeze = !freeze; } //切换 freeze 状态
            }
            btn2_pushed_start_time = 0;  // 重置按下时间
        }
        // 清除长按标记
        btn2_long_pushed = false;
        data->state = LV_INDEV_STATE_RELEASED;  // 按键松开
    }
}

void my_keypad_bootsel_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
{
    if (BOOTSEL) {
        // 如果按键按下,记录开始按下的时间
        if (btn1_pushed_start_time == 0) {
            btn1_pushed_start_time = millis();
        }
        // 检测是否为长按
        if (millis() - btn1_pushed_start_time >= BTN_LONG_PUSH_T) {
            if (!btn1_long_pushed) {
                btn1_long_pushed = true;  // 标记为长按
                // 长按的处理,例如切换到不同屏幕
                _ui_screen_change(&ui_Screen3, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen3_screen_init);
            }
        }
        data->state = LV_INDEV_STATE_PRESSED;  // 按键按下
    } else {
        // 按键松开,判断是否为短按
        if (btn1_pushed_start_time != 0) {
            if (!btn1_long_pushed) {
                btn1_pushed = true;  // 短按标记
                // 短按的处理,例如切换到不同屏幕
                user_ui_flag = !user_ui_flag;
                if(user_ui_flag){
                  test_points[0][0] = 0; // 重置测试点数据
                  test_points[0][1] = 0;
                  _ui_screen_change(&ui_Screen2, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen2_screen_init);
                } else {
                  _ui_screen_change(&ui_Screen1, LV_SCR_LOAD_ANIM_FADE_ON, 0, 0, &ui_Screen1_screen_init);
                }
            }
            btn1_pushed_start_time = 0;  // 重置按下时间
        }
        // 清除长按标记
        btn1_long_pushed = false;
        data->state = LV_INDEV_STATE_RELEASED;  // 按键松开
    }
}
相关推荐
沉在嵌入式的鱼2 小时前
linux串口对0X0D、0X0A等特殊字符的处理
linux·stm32·单片机·特殊字符·串口配置
学习路上_write2 小时前
AD5293驱动学习
c语言·单片机·嵌入式硬件·学习
影阴3 小时前
存储器和寄存器
stm32·单片机·嵌入式硬件
吃西瓜的年年4 小时前
3. C语言核心语法2
c语言·嵌入式硬件·改行学it
李洛克074 小时前
RDMA CM UDP 通信完整指南
单片机·网络协议·udp
思茂信息4 小时前
CST电动车EMC仿真——电机控制器MCU滤波仿真
javascript·单片机·嵌入式硬件·cst·电磁仿真
小曹要微笑4 小时前
I2C总线技术解析(纯文字版)
单片机·嵌入式硬件·esp32·iic
我送炭你添花5 小时前
可编程逻辑器件(PLD)的发展历程、原理、开发与应用详解
嵌入式硬件·fpga开发
袖手蹲5 小时前
Arduino UNO Q 从 Arduino Cloud 远程控制闪烁 LED
人工智能·单片机·嵌入式硬件·电脑
北京耐用通信5 小时前
终结混合网络调试噩梦:耐达讯自动化实现EtherCAT对DeviceNet设备的直接读写
网络·人工智能·物联网·网络协议·自动化·信息与通信