373|4

33

帖子

4

TA的资源

一粒金砂(中级)

楼主
 

【2024 DigiKey创意大赛】+便携式红外智能吸烟器+结项贴 [复制链接]

  本帖最后由 老杰瑞 于 2024-11-11 10:31 编辑
【2024 DigiKey创意大赛】+便携式红外智能吸烟器+结项贴
先来看看(半)成品效果:
先来看看(半)成品效果

 
Emmm,热成像模块给我玩坏了,下面是没玩坏之前的效果:

没玩坏之前的效果
 
下面介绍一下项目想法:
我是一名自动化的电子开发者,在开发电路过程中老是需要焊接各种pcb元器件,有一天我在网上看到焊接烟雾会导致不孕不育,我害怕极了,我才20几.还没小孩呢!伤心~
我痛定思痛,决定开发一款桌面式焊接吸烟器.
在着手开发这款便携式红外智能吸烟器之前,我曾浏览淘宝,寻找市面上是否有类似产品。然而,我发现现有的吸烟器普遍存在体积庞大、必须连接电源且噪音大等问题,这与我心中理想的吸烟器相去甚远。因此,我决定自行设计一款既便携又智能的吸烟器。
作品目的:我们在焊接过程中用的焊锡丝,由焊锡和铅组成,并含有少量助焊剂。焊接时会产生金属颗粒物、金属氧化物和有机挥发物。长期吸入这些有害气体和颗粒物可能会导致焊工出现咳嗽、气喘、胸闷、慢性支气管炎、角膜炎等一系列呼吸道系统疾病。此外,焊接地点经常光线昏暗,不利于焊工的操作和视觉健康,容易导致疲劳和操作失误。,以及焊接环境光线昏暗的问题,设计一款智能吸烟器,以保护焊接人员的健康并改善工作环境。
采用方法:该智能吸烟器通过热电偶传感器检测烙铁是否开启,自动启动风扇和滤网系统,有效吸收和过滤焊接产生的有害气体和颗粒物。同时,内置可调光LED灯,提供充足照明,改善焊接环境。
项目启动与挑战
我在3D模型分享网站上找到了一款外壳模型,但它仅具备基本的开关功能,且必须连接电源。这激发了我对其进行改造的想法。Minimalist 3D Printed Fume Extractor by rdmmkr - Thingiverse
在尝试为其安装电池后,我面临了一个新问题:设备频繁耗尽电量,而我也经常忘记关闭它。由于焊接和调试是一个反复开关烙铁的过程,我决定开发一款能够通过红外检测温度自动控制风扇启停的吸烟器。幸运的是,本次大赛提供的物料中包含了一款红外热成像模块,这为项目的诞生提供了关键技术支持。
软硬件架构图:
流程图:
功能示意图:
系统工作的照片:
技术难题与解决方案
尽管项目本身难度不大,但使用ESP32C6芯片后,情况变得复杂。首先,我习惯使用PlatformIO进行代码开发,但发现其官方版本并未适配ESP32C6的Arduino环境。经过一番努力,我终于成功配置了ESP32C6。其次,屏幕驱动也是一个挑战。我通常使用TFT_eSPI库开发屏幕,但在ESP32C6上也未适配。经过数日的努力,我成功将屏幕库移植至ESP32C6。
接下来,热成像数据的读取成为了难题。最初,我尝试采用插值算法,但经过五六天的调试仍未达到预期效果,最终决定采用32×16像素的色块输出方案。
编码器配置是另一个技术挑战。通常情况下,编码器库可以解决这一问题,但ESP32C6的适配问题让我花费了两三天时间。由于涉及到底层脉冲寄存器配置,我尝试从ESP32C3的适配中逆向工程,但发现ESP32C3和ESP32S3系列的核心配置函数与ESP32C6并不相似。经过几天的努力,我最终放弃了库适配,转而采用中断方式实现编码器检测。然而,这又导致了一个新的问题:编码器快速转动时系统会卡死并重启。在朋友的指点下,我意识到可能是热成像数据读取时的中断导致的数据读取错误。最终,我改为使用定时器检测编码器状态,成功解决了这一问题。
界面设计与展示
在开发过程中,我还尝试了LVGL库,以期实现更高级的界面效果。以下是我的效果展示:
然而,由于时间限制与能力不够,发现热成像传感器只能通过打点函数进行显示。然后我又是用的图形化界面编辑的lvgl,不太会写lvgl的代码,经过五六天的努力尝试仍未能解决,我决定回归到更传统的显示方案。
源码及说明:
编码器与按键读取代码
编码器用定时器,按键用中断:
// 此函数将由定时器调用以检查编码器状态
void checkEncoder() {
    static unsigned long lastChangeTime = 0;  // 记录上次状态改变的时间
    unsigned long currentTime = millis();     // 获取当前时间
    int currentEncoderA = digitalRead(ENCODER_A);  // 读取编码器A的状态
    int currentEncoderB = digitalRead(ENCODER_B);  // 读取编码器B的状态
    static int lastEncoderB = LOW;  // 添加B信号的上一个状态
    // 检查编码器A状态是否发生变化,并加入时间间隔判断
    if (currentEncoderA != lastEncoderA && (currentTime - lastChangeTime) > 5) { // 5ms去抖
        if (currentEncoderA == HIGH) {
            // 通过比较A和B的变化序列来判断方向
            if (lastEncoderB != currentEncoderB) {
                encoderDirection = (currentEncoderB == HIGH) ? 1 : -1;
            }
            lastChangeTime = currentTime;  // 更新状态改变时间
        }
        lastEncoderA = currentEncoderA;  // 更新前一个状态
        lastEncoderB = currentEncoderB;  // 更新B的前一个状态
    }
}
// 风扇按钮中断服务例程
void IRAM_ATTR fanButtonISR() {
  unsigned long currentMillis = millis();  // 获取当前时间
  // 只有当当前时间与上次按下时间的间隔大于去抖动时间时,才认为是有效的按下
  if (currentMillis - lastFanButtonPress > DEBOUNCE_TIME) {
    fanButtonPressed = true;  // 设置风扇按钮按下状态为真
    lastFanButtonPress = currentMillis;  // 更新上次按下时间
    Serial.print("fanButtonPressed");  // 串口打印
  }
}
// LED按钮中断服务例程
void IRAM_ATTR ledButtonISR() {
  unsigned long currentMillis = millis();  // 获取当前时间
  // 只有当当前时间与上次按下时间的间隔大于去抖动时间时,才认为是有效的按下
  if (currentMillis - lastLedButtonPress > DEBOUNCE_TIME) {
    ledButtonPressed = true;  // 设置LED按钮按下状态为真
    lastLedButtonPress = currentMillis;  // 更新上次按下时间
    Serial.print("ledButtonPressed");  // 串口打印
  }
}

 

快速排列,得出温度最大值:
    //快排-得到最大值
    qusort(frame, 0, 32 * 24 - 1);
    max_temp += frame[767];
//Quick sort
//通过递归分治的方式将一个大数组分为两个子数组,子数组的元素分别小于和大于基准值。
void qusort(float s[], int start, int end) //自定义函数 qusort()
{
    int i, j;        //定义变量为基本整型
    i = start;       //将每组首个元素赋给i
    j = end;         //将每组末尾元素赋给j
    s[0] = s[start]; //设置基准值
    while (i < j)
    {
        while (i < j && s[0] < s[j])
            j--; //位置左移
        if (i < j)
        {
            s[i] = s[j]; //将s[j]放到s[i]的位置上
            i++;         //位置右移
        }
        while (i < j && s[i] <= s[0])
            i++; //位置左移
        if (i < j)
        {
            s[j] = s[i]; //将大于基准值的s[j]放到s[i]位置
            j--;         //位置左移
        }
    }
    s[i] = s[0]; //将基准值放入指定位置
    if (start < i)
        qusort(s, start, j - 1); //对分割出的部分递归调用qusort()函数
    if (i < end)
        qusort(s, j + 1, end);
}

 

关键的热成像数据显示代码:
        //Display with 32*24 pixel-160*120  172-52-26
        for (uint8_t h = 0; h < 24; h++)
        {
            for (uint8_t w = 0; w < 32; w++)
            {
                //看看什么原理
                uint8_t colorIndex = map_f(temp_frame[h * 32 + w], MINTEMP, MAXTEMP);
                tft.fillRect(5 * w, 5 * h+26, 5, 5, camColors[colorIndex]);
            }
        }

 

把温度值通过函数map_f转换为颜色值,通过tft色块代码显示
其余代码看下面这个链接,里面有完整的项目代码
模型后续我会发在评论区,因为还不是最终版本,还在迭代中
项目展望
尽管面临重重挑战,我并未放弃。新的板子已经在来的路上,这次我将采用ESP32-WROOM-32芯片,并更换热成像模块为热电偶模块,类似于疫情期间用于检测人体温度的那种。这样的改动将使成本控制在50元以内,更适合大家复刻。敬请期待我的新作品!

下面是项目过程中的分享贴

【2024 DigiKey创意大赛】+便携式红外智能吸烟器+ESP32C6使用MLX90640显示图像测试 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)

【2024 DigiKey创意大赛】+便携式红外智能吸烟器+ESP32C6驱动1.54寸st7789屏幕 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)

 

【2024 DigiKey创意大赛】+便携式红外智能吸烟器+结项贴.docx

1007.95 KB, 下载次数: 7

最新回复

LVGL(light and versatile Graphics library)学习曲线这么陡峭吗? 还没尝试过。   详情 回复 发表于 2024-11-8 17:36
点赞 关注
 
 

回复
举报

33

帖子

4

TA的资源

一粒金砂(中级)

来自 2楼
 
本帖最后由 老杰瑞 于 2024-11-10 21:39 编辑
wangerxian 发表于 2024-11-7 17:48 没坏之前的效果视频是不是没有传成功?

好像是欸,我重新上传

没玩坏之前的效果

 
 
 

回复

7158

帖子

2

TA的资源

版主

板凳
 

没坏之前的效果视频是不是没有传成功?

点评

好像是欸,我重新上传  详情 回复 发表于 2024-11-10 21:34
 
 
 

回复

1364

帖子

1

TA的资源

五彩晶圆(初级)

4
 

LVGL(light and versatile Graphics library)学习曲线这么陡峭吗?

还没尝试过。

点评

可以试试,用gui来配置挺快的  详情 回复 发表于 2024-11-10 21:41
 
 
 

回复

33

帖子

4

TA的资源

一粒金砂(中级)

5
 
hellokitty_bean 发表于 2024-11-8 17:36 LVGL(light and versatile Graphics library)学习曲线这么陡峭吗? 还没尝试过。

可以试试,用gui来配置挺快的

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表