232|7

280

帖子

7

TA的资源

一粒金砂(高级)

楼主
 

【DigiKey创意大赛】便携生命探测仪06+各模块整合联调 [复制链接]

 
006

 
上一帖介绍了如何获取心电数据并解析协议,最终显示在电脑上,实现了心电采集功能。本帖介绍如何把所有模块整合到一起,实现预期的作品功能。

一、预期功能

做一个便携生命探测仪,在发生危险时,能帮助救援人员方便找到遇险者。此方案主要采用热敏式图像传感器MLX90640ESF-BAB-000-TU检测人体红外信号,采用BME680气体,湿度,压力,温度传感器评估板记录环境信息,配合一个带屏幕的评估板,显示热成像图片。再额外添加一个心电采集模块,当发现遇险者后,能立即给遇险者采集心电图和心率并在屏幕上显示,方便救援人员判断生命体征状态,好制定下一步救援计划。

二、系统框图

整个系统框图如下图。
如上图所示,ESP32-S3评估板作为主控板,通过SPI接口连接一片480*320分辨率的触摸屏,用来显示各个检测数据、图像、心电波形。通过串口连接一片ESP32-C6评估板。ESP32-C6负责通过串口从LH001-91心电评估板接收字符串数据,然后选择心电波形、心率、导联脱落数据转换成浮点数,再从另外一个串口发给主控板。通过I2C接口连接热敏式图像传感器MLX90640ESF-BAB-000-TU检测人体红外信号,转换成热成像实时图片刷新到显示屏。通过I2C接口连接BME680气体,湿度,压力,温度传感器评估板记录环境信息,并显示在屏幕上。

三、硬件电路焊接

在之前帖子中已经详细介绍ESP32-S3主控板连接的各个传感器的焊接调试过程,在本贴中只展示一下ESP32-C6的两个串口焊接情况。如下图是焊接好的串口导线局部特写。
所有板子,传感器,屏幕等器件焊接好,并打胶加固后的效果如下图。
最终作品我计划使用硬纸板做个手枪型外壳,把这些模块全部套起来,方便使用。

四、软件编写

上一贴中介绍了如何将心电数据打包发送,此次不再赘述。此处介绍一下心电数据接收、解包过程。
为了不停从串口收数,我单开了一个任务,好在ESP32-S3有两个CPU内核,我让这个任务单独运行在另外一个内核上,防止影响屏幕刷新和热成像数据转换。
接收到的数据先是按照包头解包,然后通过数组转浮点数函数提取出来心电波形、心率、导联脱落三个独立的浮点数。其中心率和导联脱落只需简单判断一下合法性,就可以用于显示。但是心电波形是小数表达方式,需要映射成0-239范围内的整数,而且为了波形能占满全部波形区域,每显示一屏,还需要从新计算一下极值范围,保证波形不太小或太大。实际转换代码如下。
代码1:
#include <Arduino.h>
#include <ecg.h>
#include <lcd.h>

uint8_t ECG_data = 0;
uint16_t ECG_hr = 0;
bool ECG_lead = true;//导联脱落指示,true代表正常未脱落
bool ECG_flag = true;//心电数据更新指示,true代表更新了

float ecg_data = 0;
float ecg_data_max = 0;
float ecg_data_min = 0;
float ecg_data_max_temp = 0;
float ecg_data_min_temp = 0;
uint16_t ecg_data_num = 0;

float ecg_hr = 0;
float ecg_lead = 0;

uint8_t Rx_data = 0;
uint8_t Rx_buff[16] = {0};// only use 12 bytes

// float to 0,239
int map_ecg(float in, float a, float b)
{
    if (in < a)
        return 0;

    if (in > b)
        return 239;

    if(b == a)
        b = a + 1;

    return (int)((in - a) * 239 / (b - a));
}

//函数说明:将4字节数据转成单精度浮点数据并存入指定地址 
//附加说明:用户无需直接操作此函数 
//target:目标单精度数据
//buf:待写入数组
//beg:指定从数组第几个元素开始写入
//函数无返回 
void Byte2Float(float *target,unsigned char *buf,unsigned char beg)
{
    unsigned char *point;
    point = (unsigned char*)target;	  //得到float的地址
    point[0] = buf[beg];
    point[1] = buf[beg+1];
    point[2] = buf[beg+2];
    point[3] = buf[beg+3];
}


void task_ecg(void *ptr)
{
    int i = 0;
    Serial0.begin(1500000);  //pin 43/44  to C6-ECG
    Serial.println("uart0 init ok");
    while (true)
    {
        if (Serial0.available() > 0) 
        {
            // 读取串口数据
            Rx_data = Serial0.read();
            // Serial.println(Rx_data);
            if('$' == Rx_data)//如果是包头
            {
                Rx_data = Serial0.read(Rx_buff,12);//连续读取12个字节
                if(12 == Rx_data)
                {
                    Byte2Float(&ecg_data,Rx_buff,0);
                    Byte2Float(&ecg_hr,Rx_buff,4);
                    Byte2Float(&ecg_lead,Rx_buff,8);
                    ////////////////////
                    if(ecg_lead == 0)
                    {
                        ECG_lead = true;
                    }
                    else
                    {
                        ECG_lead = false;
                    }
                    /////////////////
                    if(ecg_hr != 0)
                    {
                        ECG_hr = int(ecg_hr);
                    }
                    //////////////////////
                    
                    if(ecg_data_max_temp < ecg_data)
                        ecg_data_max_temp = ecg_data;
                    if(ecg_data_min_temp > ecg_data)
                        ecg_data_min_temp = ecg_data;

                    ecg_data_num++;
                    if(ecg_data_num > 480)
                    {
                        ecg_data_num = 0;
                        /////
                        ecg_data_max = ecg_data_max_temp;
                        ecg_data_min = ecg_data_min_temp;
                        ecg_data_max_temp = ecg_data;
                        ecg_data_min_temp = ecg_data;
                        // Serial.println(ecg_data_max);
                        // Serial.println(ecg_data_min);
                    }

                    ECG_data = map_ecg(ecg_data, ecg_data_min, ecg_data_max);
                    ///////////////
                    ECG_flag = true;
                }
            }
        }
        vTaskDelay(1);
        // ECG_flag = true;
        // ECG_data = random(0, 239);
        // ECG_hr = random(60, 120);
        // if (ECG_hr > 110)
        //     ECG_lead = true;
        // else
        //     ECG_lead = false;
    }
    vTaskDelete(NULL);
}

 

代码调试好后,整个系统只需要一个充电宝供电就能独立运行,下图是运行效果图。
实际操作体验效果见开头视频。
截止到此就基本完成了本次作品设计,后续整理材料编写作品文档和制作总结视频。

 

最新回复

只是之前研究过这方面的技术。   详情 回复 发表于 2024-10-28 09:06
点赞 关注
 
 

回复
举报

6773

帖子

2

TA的资源

版主

沙发
 

我感觉那个心电图可以画的频率低一些,要不显示的不是很好看。

 

点评

是的,这个采样率低,处理的时候还丢点了,心电波就显得比较密集,要是想显示清楚,需要增加采样点和MCU处理能力,目前选的这个板板改起来比较费劲,当前这个波形主要是看心律情况。  详情 回复 发表于 2024-10-24 00:03
 
 
 

回复

280

帖子

7

TA的资源

一粒金砂(高级)

板凳
 
wangerxian 发表于 2024-10-21 15:32 我感觉那个心电图可以画的频率低一些,要不显示的不是很好看。  

是的,这个采样率低,处理的时候还丢点了,心电波就显得比较密集,要是想显示清楚,需要增加采样点和MCU处理能力,目前选的这个板板改起来比较费劲,当前这个波形主要是看心律情况。

点评

那确实,采样率不够,心电波形就会有点问题。  详情 回复 发表于 2024-10-24 09:02
 
 
 

回复

6773

帖子

2

TA的资源

版主

4
 
sipower 发表于 2024-10-24 00:03 是的,这个采样率低,处理的时候还丢点了,心电波就显得比较密集,要是想显示清楚,需要增加采样点和MCU ...

那确实,采样率不够,心电波形就会有点问题。

点评

对于单导的心电,主要还是看心律,计算心律不齐、室早房早啥的,看形态的少些。  详情 回复 发表于 2024-10-24 10:39
 
 
 

回复

280

帖子

7

TA的资源

一粒金砂(高级)

5
 
wangerxian 发表于 2024-10-24 09:02 那确实,采样率不够,心电波形就会有点问题。

对于单导的心电,主要还是看心律,计算心律不齐、室早房早啥的,看形态的少些。

点评

嗯嗯,单导只能看心率,我以前问过医生,单导其实看不出什么东西。  详情 回复 发表于 2024-10-24 16:13
 
 
 

回复

6773

帖子

2

TA的资源

版主

6
 
sipower 发表于 2024-10-24 10:39 对于单导的心电,主要还是看心律,计算心律不齐、室早房早啥的,看形态的少些。

嗯嗯,单导只能看心率,我以前问过医生,单导其实看不出什么东西。

点评

感觉您也是专业人士哈  详情 回复 发表于 2024-10-28 09:03
 
 
 

回复

280

帖子

7

TA的资源

一粒金砂(高级)

7
 
wangerxian 发表于 2024-10-24 16:13 嗯嗯,单导只能看心率,我以前问过医生,单导其实看不出什么东西。

感觉您也是专业人士哈

点评

只是之前研究过这方面的技术。  详情 回复 发表于 2024-10-28 09:06
 
 
 

回复

6773

帖子

2

TA的资源

版主

8
 
sipower 发表于 2024-10-28 09:03 感觉您也是专业人士哈

只是之前研究过这方面的技术。

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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