- 2025-02-21
-
回复了主题帖:
>>征集 | 晒电机控制痛点与难题,一起寻求最优解!
作为一名刚入行的电机控制工程师,我在实际项目开发中深刻体会到这个领域的复杂性和挑战性。以下是我总结的几个典型痛点和难点并结合ADI的TMC9660芯片谈谈它的解决方案: ### 一、算法开发门槛高,调试周期长 刚接触电机控制时,FOC(磁场定向控制)算法让我头疼不已。数学建模、坐标变换、PI参数整定…每一步都需要深厚的理论功底和大量实验验证。传统方案中,工程师需要从零开始编写代码实现这些算法,光是电流环和速度环的调试就可能耗费数周时间。 **TMC9660的突破**: 它直接用硬件实现了FOC算法和伺服控制环路(包括位置/速度/扭矩环),甚至内置了8点加减速轨迹规划器。通过TMCL-IDE软件,只需配置电机参数和勾选预置算法模式,就能跳过底层代码开发,直接进入功能验证阶段。 ### 二、硬件设计复杂度爆炸 设计电机驱动板时,我需要同时考虑栅极驱动、电源管理、信号调理、保护电路等多个模块。光是MOSFET驱动电路的设计就涉及死区时间优化、EMI抑制、短路保护等细节,稍有不慎就会烧毁器件。 **TMC9660的集成优势**: 这颗芯片将70V智能栅极驱动、同步降压电源(支持7.7 - 70V宽压输入)、4通道高精度电流采样(15MHz带宽CSA + 1MSps ADC)、过流/短路/热保护等功能全部集成在9x9mm的封装内。外部只需搭配MOS管和少量被动元件,PCB面积比传统方案减少60%以上。 ### 三、系统稳定性与实时性难以兼顾 在调试伺服电机时,遇到过编码器信号干扰导致位置漂移、PWM频率不足引发转矩脉动等问题。传统MCU方案中,软件处理延迟可能达到微秒级,难以满足高速伺服控制的实时性需求。 **TMC9660的硬核性能**: 其硬件运动控制单元(MCC)支持100kHz的FOC运算和SVPWM输出,时钟分辨率高达120MHz。编码器接口直接支持双路绝对值/增量式反馈,配合硬件实现的实时Ramp动态计算,确保位置控制精度可达±1个脉冲计数。 ### 四、跨学科知识要求高 电机控制涉及电力电子、自动控制、嵌入式软件等多个领域。作为新人,我常因对某一方面理解不足导致设计缺陷——比如未考虑电机电感参数对电流环的影响,或是电源瞬态响应导致控制失稳。 **TMC9660的智能化设计**: 芯片内置AI自学习功能,可自动识别电机电阻/电感参数,匹配负载惯量和控制带宽。甚至能通过机械特性分析优化PID参数,大幅降低了对工程师经验的要求。 ### 五、开发工具链碎片化 以往项目中,我需要同时使用示波器、逻辑分析仪、MATLAB仿真、Keil编译环境等多套工具,数据同步和调试效率低下。 **TMC9660的生态支持**: 配套的TMCL - IDE软件整合了参数配置、实时曲线监控、故障诊断等功能。通过USB连接评估板后,可直接在图形化界面中观察电流环响应曲线,甚至自动生成优化建议,让调试过程像“调游戏画质”一样直观。 ### 总结:TMC9660如何改变新人工程师的体验 这款芯片通过**硬件算法固化**(省去代码开发)、**全栈集成**(减少外围电路设计)、**智能自整定**(降低经验依赖)三大特性,将原本需要数月迭代的电机控制系统开发缩短到几天。例如在BLDC电机控制案例中,从硬件搭建到完成FOC闭环调试仅需3步:连接电机→配置参数→运行自检,真正实现了“让电机控制像点亮LED一样简单”。对于像我这样的新人而言,这种高集成度方案不仅能快速交付项目,更提供了一个理解电机控制原理的“透明沙箱”——通过观察预设算法在真实硬件中的运行效果,加速了理论知识的实践转化。 作为一名刚入行的电机控制工程师,我在实际项目开发中深刻体会到这个领域的复杂性和挑战性。以下是我总结的几个典型痛点和难点并结合ADI的TMC9660芯片谈谈它的解决方案: ### 一、算法开发门槛高,调试周期长 刚接触电机控制时,FOC(磁场定向控制)算法让我头疼不已。数学建模、坐标变换、PI参数整定…每一步都需要深厚的理论功底和大量实验验证。传统方案中,工程师需要从零开始编写代码实现这些算法,光是电流环和速度环的调试就可能耗费数周时间。 **TMC9660的突破**: 它直接用硬件实现了FOC算法和伺服控制环路(包括位置/速度/扭矩环),甚至内置了8点加减速轨迹规划器。通过TMCL-IDE软件,只需配置电机参数和勾选预置算法模式,就能跳过底层代码开发,直接进入功能验证阶段。 ### 二、硬件设计复杂度爆炸 设计电机驱动板时,我需要同时考虑栅极驱动、电源管理、信号调理、保护电路等多个模块。光是MOSFET驱动电路的设计就涉及死区时间优化、EMI抑制、短路保护等细节,稍有不慎就会烧毁器件。 **TMC9660的集成优势**: 这颗芯片将70V智能栅极驱动、同步降压电源(支持7.7 - 70V宽压输入)、4通道高精度电流采样(15MHz带宽CSA + 1MSps ADC)、过流/短路/热保护等功能全部集成在9x9mm的封装内。外部只需搭配MOS管和少量被动元件,PCB面积比传统方案减少60%以上。 ### 三、系统稳定性与实时性难以兼顾 在调试伺服电机时,遇到过编码器信号干扰导致位置漂移、PWM频率不足引发转矩脉动等问题。传统MCU方案中,软件处理延迟可能达到微秒级,难以满足高速伺服控制的实时性需求。 **TMC9660的硬核性能**: 其硬件运动控制单元(MCC)支持100kHz的FOC运算和SVPWM输出,时钟分辨率高达120MHz。编码器接口直接支持双路绝对值/增量式反馈,配合硬件实现的实时Ramp动态计算,确保位置控制精度可达±1个脉冲计数。 ### 四、跨学科知识要求高 电机控制涉及电力电子、自动控制、嵌入式软件等多个领域。作为新人,我常因对某一方面理解不足导致设计缺陷——比如未考虑电机电感参数对电流环的影响,或是电源瞬态响应导致控制失稳。 **TMC9660的智能化设计**: 芯片内置AI自学习功能,可自动识别电机电阻/电感参数,匹配负载惯量和控制带宽。甚至能通过机械特性分析优化PID参数,大幅降低了对工程师经验的要求。 ### 五、开发工具链碎片化 以往项目中,我需要同时使用示波器、逻辑分析仪、MATLAB仿真、Keil编译环境等多套工具,数据同步和调试效率低下。 **TMC9660的生态支持**: 配套的TMCL - IDE软件整合了参数配置、实时曲线监控、故障诊断等功能。通过USB连接评估板后,可直接在图形化界面中观察电流环响应曲线,甚至自动生成优化建议,让调试过程像“调游戏画质”一样直观。 ### 总结:TMC9660如何改变新人工程师的体验 这款芯片通过**硬件算法固化**(省去代码开发)、**全栈集成**(减少外围电路设计)、**智能自整定**(降低经验依赖)三大特性,将原本需要数月迭代的电机控制系统开发缩短到几天。例如在BLDC电机控制案例中,从硬件搭建到完成FOC闭环调试仅需3步:连接电机→配置参数→运行自检,真正实现了“让电机控制像点亮LED一样简单”。对于像我这样的新人而言,这种高集成度方案不仅能快速交付项目,更提供了一个理解电机控制原理的“透明沙箱”——通过观察预设算法在真实硬件中的运行效果,加速了理论知识的实践转化。
作为一名电机控制工程师,我在实际项目开发中深刻体会到这个领域的复杂性和挑战性。以下是我总结的几个典型痛点和难点并结合 ADI 的 TMC9660 芯片谈谈它的解决方案:
一、算法开发门槛高,调试周期长
刚接触电机控制时,FOC(磁场定向控制)算法让我头疼不已。数学建模、坐标变换、PI 参数整定… 每一步都需要深厚的理论功底和大量实验验证。传统方案中,工程师需要从零开始编写代码实现这些算法,光是电流环和速度环的调试就可能耗费数周时间。
TMC9660 的突破:
它直接用硬件实现了 FOC 算法和伺服控制环路(包括位置 / 速度 / 扭矩环),甚至内置了 8 点加减速轨迹规划器。通过 TMCL-IDE 软件,只需配置电机参数和勾选预置算法模式,就能跳过底层代码开发,直接进入功能验证阶段。
二、硬件设计复杂度爆炸
设计电机驱动板时,我需要同时考虑栅极驱动、电源管理、信号调理、保护电路等多个模块。光是 MOSFET 驱动电路的设计就涉及死区时间优化、EMI 抑制、短路保护等细节,稍有不慎就会烧毁器件。
TMC9660 的集成优势:
这颗芯片将 70V 智能栅极驱动、同步降压电源(支持 7.7 - 70V 宽压输入)、4 通道高精度电流采样(15MHz 带宽 CSA + 1MSps ADC)、过流 / 短路 / 热保护等功能全部集成在 9x9mm 的封装内。外部只需搭配 MOS 管和少量被动元件,PCB 面积比传统方案减少 60% 以上。
三、系统稳定性与实时性难以兼顾
在调试伺服电机时,遇到过编码器信号干扰导致位置漂移、PWM 频率不足引发转矩脉动等问题。传统 MCU 方案中,软件处理延迟可能达到微秒级,难以满足高速伺服控制的实时性需求。
TMC9660 的硬核性能:
其硬件运动控制单元(MCC)支持 100kHz 的 FOC 运算和 SVPWM 输出,时钟分辨率高达 120MHz。编码器接口直接支持双路绝对值 / 增量式反馈,配合硬件实现的实时 Ramp 动态计算,确保位置控制精度可达 ±1 个脉冲计数。
四、跨学科知识要求高
电机控制涉及电力电子、自动控制、嵌入式软件等多个领域。作为新人,我常因对某一方面理解不足导致设计缺陷 —— 比如未考虑电机电感参数对电流环的影响,或是电源瞬态响应导致控制失稳。
TMC9660 的智能化设计:
芯片内置 AI 自学习功能,可自动识别电机电阻 / 电感参数,匹配负载惯量和控制带宽。甚至能通过机械特性分析优化 PID 参数,大幅降低了对工程师经验的要求。
五、开发工具链碎片化
以往项目中,我需要同时使用示波器、逻辑分析仪、MATLAB 仿真、Keil 编译环境等多套工具,数据同步和调试效率低下。
TMC9660 的生态支持:
配套的 TMCL - IDE 软件整合了参数配置、实时曲线监控、故障诊断等功能。通过 USB 连接评估板后,可直接在图形化界面中观察电流环响应曲线,甚至自动生成优化建议,让调试过程像 “调游戏画质” 一样直观。
总结:TMC9660 如何改变新人工程师的体验
这款芯片通过硬件算法固化(省去代码开发)、全栈集成(减少外围电路设计)、智能自整定(降低经验依赖)三大特性,将原本需要数月迭代的电机控制系统开发缩短到几天。例如在 BLDC 电机控制案例中,从硬件搭建到完成 FOC 闭环调试仅需 3 步:连接电机→配置参数→运行自检,真正实现了 “让电机控制像点亮 LED 一样简单”。对于像我这样的新人而言,这种高集成度方案不仅能快速交付项目,更提供了一个理解电机控制原理的 “透明沙箱”—— 通过观察预设算法在真实硬件中的运行效果,加速了理论知识的实践转化。
- 2025-01-22
-
回复了主题帖:
祝福2025!回帖即有奖!选取最有心的送5块国产开发板!
期待2025越来越好,开发版越来越多,知识越来越高,技能越来越强!祝大家新的一年里技术更牛,工作一流!!
- 2024-12-05
-
评论了课程:
【2024 DigiKey 应用说】第三期:大模型时代的智能汽车
AI赋能汽车,产品想象力无限。
- 2024-11-17
-
加入了学习《【2024 DigiKey创意大赛】+智慧焊接工作台》,观看 智慧焊接工作台
- 2024-11-02
-
发表了主题帖:
【DigiKey创意大赛】便携生命探测仪07+作品提交
便携生命探测仪
作者:sipower
一、作品简介
现在越来越多业余驴友喜欢户外冒险,但是随之而来的就是遇到危险的情况时有发生,因此我想到做一个便携生命探测仪,在发生危险时,能帮助救援人员方便找到遇险者。此方案主要采用热敏式图像传感器MLX90640ESF-BAB-000-TU检测人体红外信号,采用BME680气体,湿度,压力,温度传感器评估板记录环境信息,配合一个带屏幕的评估板,显示热成像图片。再额外添加一个心电采集模块,当发现遇险者后,能立即给遇险者采集心电图和心率并在屏幕上显示,方便救援人员判断生命体征状态,好制定下一步救援计划。下图是最终的作品照片,我用纸壳做成一个手枪形态的样子。
本次作品从得捷电子采购的器件:
序号
型号
名称
用途
1
MLX90640ESF
热敏式图像传感器
检测人体红外信号
2
3660
BME680评估板
采集气体,湿度,压力,温度参数
3
DFR1075
ESP32-C6评估板
转换心电数据格式
4
JB2835AWT-W
白色发光管
用于探测仪照明
本次作品自备的器件:
序号
型号
名称
用途
1
DFR0975
ESP32-S3评估板
主控板实现数据处理和现实功能
2
MSP3520
3.5英寸480*320分辨率触摸屏
显示热成像图像和心电波形
3
LH001-91
心电评估板
采集心电数据
二、系统框图
整个系统框图如下图。
如上图所示,ESP32-S3评估板作为主控板,通过SPI接口连接一片480*320分辨率的触摸屏,用来显示各个检测数据、图像、心电波形。通过串口连接一片ESP32-C6评估板。ESP32-C6负责通过串口从LH001-91心电评估板接收字符串数据,然后选择心电波形、心率、导联脱落数据转换成浮点数,再从另外一个串口发给主控板。通过I2C接口连接热敏式图像传感器MLX90640ESF-BAB-000-TU检测人体红外信号,转换成热成像实时图片刷新到显示屏。通过I2C接口连接BME680气体,湿度,压力,温度传感器评估板记录环境信息,并显示在屏幕上。
三、各部分功能说明
所有板子,传感器,屏幕等器件焊接好,并打胶加固后的效果如下图。
热成像传感器MLX90640
该传感器分辨率为32H x 24V阵列,封装是TO-39,本次大赛两个必选料之一。焊接好的图片如下。和主控板之间采用I2C接口。该传感器软件驱动我这里参考Adafruit_MLX90640的库,再结合显示屏特点进行了调色板处理,通过差值将32*24点阵放大到320*240点阵,可以在屏幕上均匀显示,祛除颗粒感。
主控板
选的是以前做评测攒下的一块ESP32-S3开发板,由DFRobot设计的FireBeetle-ESP32-S3,如下图。该评估板提供非常丰富的IO接口,可以满足大部分DIY的需求。这个板卡的程序我在VScode+PlatformIO平台开发,使用体验非常好,强烈推荐没用过的同行们尝试一下。
显示屏
选了一块480*320的TFT,如下图,也是以前做评测攒下的。该屏幕采用SPI接口,带电阻式触摸屏,使用该屏幕可以省掉按键,配合开源显示驱动库TFT_eSPI,可以非常方便的实现各种显示功能。这里需要特别说明一下,由于该屏幕使用的驱动IC ILI9488是18bit数据,TFT_eSPI是不支持DMA的,我这使用了一些技巧,最终实现DMA写屏,使得热成像刷新率显著提高,具体的细节可以参考我分享的第三贴。
BME680传感器
该传感器具有SPI和I2C两种接口,由于我用的这个ESP32-S3开发板引出的SPI口接屏了并且SPI占IO口比较多,我择使用I2C接口连接BME680小板,最开始为了省事我把它和MLX90640挂在同一个I2C总线上了。但是我发现一个问题,就是每次读取BME680时候,热成像刷新都会卡顿一下,体验不好,原因就是共用总线造成的。好在ESP32-S3有多个I2C,并且还有一个巨牛掰的GPIO交换矩阵,可以让外设使用任意IO口。于是我从引脚分配表上找了2个闲置的IO口A4和A5配置成了I2C总线,完美解决卡顿问题。采集数据显示如下图。
心电采集部分
本次作品为了实现心电采集,我选用了领慧立芯推出的医疗级模拟前端心电采集方案。具体实现采用的是领慧立芯的心电采集评估板,该评估板基于LH001-91设计。
LH001-91是专门针对心电信号采集而开发的医疗级模拟前端,集成了24位Σ-Δ ADC,可编程增益放大器,右腿驱动,导电脱落监测等功能。更详细资料见如下链接:
http://www.legendsemi.com/hyyy_2/4.html
下图是我申请到的LH001-91的评估板,主要由AFE(LH001-91),通用MCU和两侧的三个电极组成。
为了降低主控端的软件复杂度,我还选用了一块ESP32-C6开发板做心电数据解析,该开发板由DFRobot设计研发,型号是FireBeetle 2 ESP32-C6。如下图所示。
FireBeetle 2 ESP32-C6采用较新的RISC-V内核,在官方VScode+PlatformIO平台还不支持Arduino架构,最后采用ArduinoIDE做的程序开发。详细程序见作品源代码。
在本次作品中主要是用到了ESP32-C6的两个串口做协议转换。原理框图如下图。
我在PC端用了一个能显示串口数据波形的软件,ESP32-C6负责从LH001-91评估板接收字符串数据,然后转换成上位机软件能识别的协议,再从另外一个串口发出去。最后由主控板接收数据并显示在屏幕上。心电显示效果如下图。
照明部分
考虑到这个探测仪会在黑暗环境下工作,我在作品最前端加了2个高亮白光LED发光管。在最终的手枪状扳机处粘了一个按键,可以控制发光管的亮灭。局部照片如下图。
四、作品源码
ESP32-S3程序采用VScode+PlatformIO平台开发。
ESP32-C6程序采用ArduinoIDE开发。
便携生命探测仪源代码
https://download.eeworld.com.cn/detail/sipower/634850
五、作品功能演示视频
[localvideo]ec5c9ffb1ee98e05de790da3423d6055[/localvideo]
六、项目总结
感谢EEWorld和得捷电子提供的这次机会,让我体验了热敏式图像传感器MLX90640和环境检测传感器BME680。然后做出这个有意义的作品。在开发过程中,感觉到ESP32单片机生态系统很完善,不但有非常好用的Arduino平台,还有更强大的VScode+PlatformIO开发平台,让程序开发更加高效稳健。
下面链接是本次作品开发过程中的经验分享贴,本文中没有详细介绍的内容,在下面帖子中都能找到。
https://bbs.eeworld.com.cn/thread-1290207-1-1.html
https://bbs.eeworld.com.cn/thread-1291434-1-1.html
https://bbs.eeworld.com.cn/thread-1292207-1-1.html
https://bbs.eeworld.com.cn/thread-1294411-1-1.html
https://bbs.eeworld.com.cn/thread-1294434-1-1.html
https://bbs.eeworld.com.cn/thread-1296592-1-1.html
七、其他
无。
-
发表了日志:
【DigiKey创意大赛】便携生命探测仪07+作品提交
- 2024-10-30
-
上传了资料:
【DigiKey创意大赛】便携生命探测仪源代码
- 2024-10-28
-
加入了学习《 【2024 DigiKey创意大赛】 《智能起居室环境控制台》任务报告汇总》,观看 【2024 DigiKey创意大赛】 《智能起居室环境控制台》任务报告汇总
-
回复了主题帖:
【DigiKey创意大赛】便携生命探测仪06+各模块整合联调
wangerxian 发表于 2024-10-24 16:13
嗯嗯,单导只能看心率,我以前问过医生,单导其实看不出什么东西。
感觉您也是专业人士哈
- 2024-10-24
-
回复了主题帖:
【DigiKey创意大赛】家庭共享智能药盒05+基于TouchGFX的UI程序设计
界面简洁实用
-
回复了主题帖:
【DigiKey创意大赛】便携生命探测仪06+各模块整合联调
wangerxian 发表于 2024-10-24 09:02
那确实,采样率不够,心电波形就会有点问题。
对于单导的心电,主要还是看心律,计算心律不齐、室早房早啥的,看形态的少些。
-
回复了主题帖:
【DigiKey创意大赛】便携生命探测仪06+各模块整合联调
wangerxian 发表于 2024-10-21 15:32
我感觉那个心电图可以画的频率低一些,要不显示的不是很好看。
是的,这个采样率低,处理的时候还丢点了,心电波就显得比较密集,要是想显示清楚,需要增加采样点和MCU处理能力,目前选的这个板板改起来比较费劲,当前这个波形主要是看心律情况。
- 2024-10-20
-
发表了主题帖:
【DigiKey创意大赛】便携生命探测仪06+各模块整合联调
[localvideo]d3ebd2761ecd76c87286f8e09232ebab[/localvideo]
上一帖介绍了如何获取心电数据并解析协议,最终显示在电脑上,实现了心电采集功能。本帖介绍如何把所有模块整合到一起,实现预期的作品功能。
一、预期功能
做一个便携生命探测仪,在发生危险时,能帮助救援人员方便找到遇险者。此方案主要采用热敏式图像传感器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);
}
代码调试好后,整个系统只需要一个充电宝供电就能独立运行,下图是运行效果图。
实际操作体验效果见开头视频。
截止到此就基本完成了本次作品设计,后续整理材料编写作品文档和制作总结视频。
-
发表了日志:
【DigiKey创意大赛】便携生命探测仪06+各模块整合联调
- 2024-09-26
-
回复了主题帖:
【DigiKey创意大赛】便携生命探测仪05+心电数据解析并在PC显示
chejm 发表于 2024-9-25 13:29
楼主分享的内容确实值得学习,希望有机会能亲自动手实验一下啊
那就申请板子动起来
-
回复了主题帖:
【DigiKey创意大赛】便携生命探测仪05+心电数据解析并在PC显示
lansebuluo 发表于 2024-9-24 08:23
别光顾着开发新东西,也要适时锻炼身体,看这肉...........
年纪大了,练不动了
-
回复了主题帖:
【DigiKey创意大赛】便携生命探测仪05+心电数据解析并在PC显示
wangerxian 发表于 2024-9-23 20:55
3导联应该只能出一个心电数据吧?
是的,只有单导数据
-
回复了主题帖:
【DigiKey创意大赛】便携生命探测仪04+驱动BME680并设计UI
Jacktang 发表于 2024-9-23 07:29
就是每次读取BME680时候,热成像刷新都会卡顿一下,这个看来是确实总线的问题
是滴,换个I2C口就好了,还好ESP32-S3的I2C口多
- 2024-09-21
-
发表了日志:
【DigiKey创意大赛】便携生命探测仪05+心电数据解析并在PC显示
-
发表了主题帖:
【DigiKey创意大赛】便携生命探测仪05+心电数据解析并在PC显示
[localvideo]6d91483f079ec907fa9ab1ad8b63ebaa[/localvideo]
上一帖介绍了驱动BME680并将检测结果显示在屏幕上,然后设计一个操作交互界面,实现用户操作功能。本帖介绍如何获取心电数据并解析协议,最终显示在电脑上。
一、方案和开发板的选择
本次作品为了实现心电采集,我选用了领慧立芯推出的医疗级模拟前端心电采集方案。具体实现采用的是领慧立芯的心电采集评估板,该评估板基于LH001-91设计。
LH001-91是专门针对心电信号采集而开发的医疗级模拟前端,集成了24位Σ-Δ ADC,可编程增益放大器,150Hz带内噪声3μVpp,包括右腿驱动,导电脱落监测等功能的AFE。产品的性能指标优越,其中输入参考噪声2.9 μVpp ,共模抑制比 117dB,内部参考温漂16ppm/℃;静态功耗0.1μW,各项核心指标均达到国际品牌的水平,甚至整体性能优于国际厂商同类型产品,并得到国内医疗客户的专业评测,是目前国内极少能够通过医疗测试的国产芯片。使国内高精度信号链产品有望进入医疗领域,结束被欧美品牌垄断的局面。
更详细资料见如下链接:
http://www.legendsemi.com/hyyy_2/4.html
下图是我申请到的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端子上,并用热熔胶固定好。
心电电极飞线:板子上有留有三个电极的焊盘测试点,我找到一个耳机插头形式的导联线,只需要在板上焊接一个耳机插座即可,这个比较容易,焊好后用热熔胶固定。最终的成品如下图。
软件编写
首先是分析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端显示心电波形。具体效果见开头视频。
数据解析没问题后,下一步就是将这部分整合到主控端,就基本完成本次作品设计了。