695|6

286

帖子

7

TA的资源

一粒金砂(高级)

楼主
 

【DigiKey创意大赛】便携生命探测仪05+心电数据解析并在PC显示 [复制链接]

 
播放器加载失败: 未检测到Flash Player,请到安装
000

 
上一帖介绍了驱动BME680并将检测结果显示在屏幕上,然后设计一个操作交互界面,实现用户操作功能。本帖介绍如何获取心电数据并解析协议,最终显示在电脑上。

一、方案和开发板的选择

本次作品为了实现心电采集,我选用了领慧立芯推出的医疗级模拟前端心电采集方案。具体实现采用的是领慧立芯的心电采集评估板,该评估板基于LH001-91设计。
LH001-91是专门针对心电信号采集而开发的医疗级模拟前端,集成了24位Σ-Δ ADC,可编程增益放大器,150Hz带内噪声3μVpp,包括右腿驱动,导电脱落监测等功能的AFE。产品的性能指标优越,其中输入参考噪声2.9 μVpp ,共模抑制比 117dB,内部参考温漂16ppm/℃;静态功耗0.1μW,各项核心指标均达到国际品牌的水平,甚至整体性能优于国际厂商同类型产品,并得到国内医疗客户的专业评测,是目前国内极少能够通过医疗测试的国产芯片。使国内高精度信号链产品有望进入医疗领域,结束被欧美品牌垄断的局面。
更详细资料见如下链接:
下图是我申请到的LH001-91的评估板,主要由AFE(LH001-91),通用MCU和两侧的三个电极组成。
领慧立芯同时提供全套的软件演示方案,下图是基于领慧立芯的评估板获得的心电图实时波形图,心电特征明显,满足医疗级应用。
为了降低主控端的软件复杂度,我还选用了一块ESP32-C6开发板做心电数据解析,该开发板由DFRobot设计研发,型号是FireBeetle 2 ESP32-C6。如下图所示。
FireBeetle 2 ESP32-C6是一款基于ESP32-C6芯片设计的低功耗物联网主控板,适用于智能家居项目。ESP32-C6支持Wi-Fi 6、Bluetooth 5、Zigbee 3.0、Thread 1.3通讯协议,可接入多种通讯协议的物联网网络。FireBeetle 2 ESP32-C6支持Type-C、5V DC、太阳能供电,部署时有更多的供电方式选择。
在本次作品中主要是用到了ESP32-C6的两个串口做协议转换。原理框图如下图。
我在PC端用了一个能显示串口数据波形的软件,ESP32-C6负责从LH001-91评估板接收字符串数据,然后转换成上位机软件能识别的协议,再从另外一个串口发出去。

二、硬件电路连接

LH001-91评估板只有一个type-c接口,采集心电用的板子上的焊盘做电极。为了能跟ESP32-C6板连接,需要将电源和串口飞线出来。为了方便采集心电,也需要引出导联线接口。
电源和串口飞线:电源部分直接从USB的5V网络焊盘上引出电源和接地。串口是从板子上的CH340E芯片TX和RX直接飞线出来,为了防止TX线输出信号线与导致烧IO口,我把PCB走线割断串联了一个100欧姆的电阻。最终将飞线出来的接头汇总到一个PH端子上,并用热熔胶固定好。
心电电极飞线:板子上有留有三个电极的焊盘测试点,我找到一个耳机插头形式的导联线,只需要在板上焊接一个耳机插座即可,这个比较容易,焊好后用热熔胶固定。最终的成品如下图。
  1. 软件编写
首先是分析LH001-91评估板的程序可知,最终输出的每个采样点数据是一个字符串,如下图所示。
这个字符串中包含心电原始数据,滤波后数据,心率,导联状态等信息,最后以回车换行结尾。数据格式有整型和浮点两种,解析的时候可以都转换成浮点数。实际转换代码如下。
代码1:
  • #include <Arduino.h>
  • // 定义一个足够大的数组来存储浮点数
  • float dataArray[10]; // 假设我们知道数组的最大长度
  • int dataArrayIndex = 0;
  • String data = "";
  • void setup() {
  • // 初始化串口通信
  • Serial0.begin(1500000); //pin 16/17 to ECG
  • Serial1.begin(1500000); //pin 4/5 to PC or Main board
  • // reserve 200 bytes for the inputString:
  • data.reserve(200);
  • }
  • void loop() {
  • // 检查是否有数据可读
  • data = "";
  • if (Serial0.available() > 0) {
  • // 读取串口数据
  • data = Serial0.readStringUntil('\n');
  • // 移除字符串末尾的换行符
  • data.trim();
  • // 使用 split 方法按照逗号拆分字符串
  • int lastIndex = 0;
  • for (int i = 0; i < data.length(); i++) {
  • if (data[i] == ',') {
  • // 将子字符串转换为浮点数并存储在数组中
  • String numberString = data.substring(lastIndex, i);
  • dataArray[dataArrayIndex++] = numberString.toFloat();
  • lastIndex = i + 1;
  • }
  • }
  • // 处理最后一个元素
  • String lastNumberString = data.substring(lastIndex);
  • dataArray[dataArrayIndex++] = lastNumberString.toFloat();
  • // 重置索引,准备发送数据
  • dataArrayIndex = 0;
  • if (0 != dataArray[6]) {
  • // 将浮点数数组转换回字符串,以逗号分隔,并添加回车符
  • for (int i = 0; i < 10; i++) {
  • Serial1.print(dataArray[9 - i]);
  • if (i < 9) {
  • Serial1.print(",");
  • } else {
  • Serial1.println();
  • }
  • }
  • }
  • }
  • }

 

设计此代码我取了个巧,直接把需求写清楚发给Kimi,然后Kimi会给出一份参考代码,我在参考代码上修改成我需要的形式,省去不少脑细胞。下图是我截取的转换后数据,程序转换效果不错。
然后按照上位机软件的协议要求修改发送代码,上位机显示只需要滤波后的波形数据,心率,导联信息,其他的可以都舍弃掉。改完的代码如下。
代码2:
  • #include <Arduino.h>
  • // 定义一个足够大的数组来存储浮点数
  • float dataArray[10]; // 假设我们知道数组的最大长度
  • int dataArrayIndex = 0;
  • String data = "";
  • unsigned char DataScope_OutPut_Buffer[15] = {0}; //串口发送缓冲区
  • //函数说明:将单精度浮点数据转成4字节数据并存入指定地址
  • //附加说明:用户无需直接操作此函数
  • //target:目标单精度数据
  • //buf:待写入数组
  • //beg:指定从数组第几个元素开始写入
  • //函数无返回
  • void Float2Byte(float *target,unsigned char *buf,unsigned char beg)
  • {
  • unsigned char *point;
  • point = (unsigned char*)target; //得到float的地址
  • buf[beg] = point[0];
  • buf[beg+1] = point[1];
  • buf[beg+2] = point[2];
  • buf[beg+3] = point[3];
  • }
  • void setup() {
  • // 初始化串口通信
  • Serial0.begin(1500000); //pin 16/17 to ECG
  • Serial1.begin(256000); //pin 4/5 to PC or Main board
  • // reserve 200 bytes for the inputString:
  • data.reserve(200);
  • }
  • int fps_num = 0;//丢点计数
  • void loop() {
  • // 检查是否有数据可读
  • data = "";
  • if (Serial0.available() > 0) {
  • // 读取串口数据
  • data = Serial0.readStringUntil('\n');
  • // 移除字符串末尾的换行符
  • data.trim();
  • // 使用 split 方法按照逗号拆分字符串
  • int lastIndex = 0;
  • for (int i = 0; i < data.length(); i++) {
  • if (data[i] == ',') {
  • // 将子字符串转换为浮点数并存储在数组中
  • String numberString = data.substring(lastIndex, i);
  • dataArray[dataArrayIndex++] = numberString.toFloat();
  • lastIndex = i + 1;
  • }
  • }
  • // 处理最后一个元素
  • String lastNumberString = data.substring(lastIndex);
  • dataArray[dataArrayIndex++] = lastNumberString.toFloat();
  • // 重置索引,准备发送数据
  • dataArrayIndex = 0;
  • if (fps_num > 8)
  • {
  • //丢点处理,防止屏幕刷新过快
  • DataScope_OutPut_Buffer[0] = '$'; //帧头
  • Float2Byte(&dataArray[5],DataScope_OutPut_Buffer,1);
  • Float2Byte(&dataArray[6],DataScope_OutPut_Buffer,5);
  • Float2Byte(&dataArray[7],DataScope_OutPut_Buffer,9);
  • DataScope_OutPut_Buffer[13] = 13;
  • // for (int i = 0; i < 14; i++) {
  • Serial1.write(DataScope_OutPut_Buffer,14);
  • // }
  • fps_num = 0;
  • }
  • fps_num ++;
  • // if (0 != dataArray[6]) {
  • // // 将浮点数数组转换回字符串,以逗号分隔,并添加回车符
  • // for (int i = 0; i < 10; i++) {
  • // Serial1.print(dataArray[9 - i]);
  • // if (i < 9) {
  • // Serial1.print(",");
  • // } else {
  • // Serial1.println();
  • // }
  • // }
  • // }
  • }
  • }

 

手头没有心电信号模拟仪,只好亲自上阵,电极片贴在胸口,如下图。
期间经过多次调试修改错误,最终实现在PC端显示心电波形。具体效果见开头视频。
数据解析没问题后,下一步就是将这部分整合到主控端,就基本完成本次作品设计了。

最新回复

楼主分享的内容确实值得学习,希望有机会能亲自动手实验一下啊   详情 回复 发表于 2024-9-25 13:29
点赞 关注
 
 

回复
举报

7547

帖子

2

TA的资源

版主

沙发
 
3导联应该只能出一个心电数据吧?

点评

是的,只有单导数据  详情 回复 发表于 2024-9-26 12:20
 
 
 

回复

426

帖子

7

TA的资源

纯净的硅(初级)

板凳
 
别光顾着开发新东西,也要适时锻炼身体,看这肉...........

点评

年纪大了,练不动了  详情 回复 发表于 2024-9-26 12:20
 
 
 

回复

701

帖子

5

TA的资源

纯净的硅(高级)

4
 

楼主分享的内容确实值得学习,希望有机会能亲自动手实验一下啊

点评

那就申请板子动起来  详情 回复 发表于 2024-9-26 12:21
 
 
 

回复

286

帖子

7

TA的资源

一粒金砂(高级)

5
 
wangerxian 发表于 2024-9-23 20:55 3导联应该只能出一个心电数据吧?

是的,只有单导数据

 
 
 

回复

286

帖子

7

TA的资源

一粒金砂(高级)

6
 
lansebuluo 发表于 2024-9-24 08:23 别光顾着开发新东西,也要适时锻炼身体,看这肉...........

年纪大了,练不动了

 
 
 

回复

286

帖子

7

TA的资源

一粒金砂(高级)

7
 
chejm 发表于 2024-9-25 13:29 楼主分享的内容确实值得学习,希望有机会能亲自动手实验一下啊

那就申请板子动起来

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播:当AI遇见仿真,会有什么样的电子行业革新之路?
首场直播:Simcenter AI 赋能电子行业研发创新
直播时间:04月15日14:00-14:50

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

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

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

北京市海淀区中关村大街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
快速回复 返回顶部 返回列表