基于ads1292的心率呼吸信号检测解决方案开发阶段总结
前记
在医疗可穿戴领域,ads1292是一个无法绕过去的存在。今年几个项目产品都和这个芯片有关系。 从不了解到熟悉,算是踩了不少坑吧。对每次的项目进行复盘,是我这些年养成的最好的习惯了。
ads1292芯片
特性如下所示:
ADS1291、ADS1292 和 ADS1292R 是多通道同步采 样 24 位 Δ-Σ 模数转换器 (ADC),它们具有内置的可编 程增益放大器 (PGA)、内部基准和板载振荡器。 ADS1291、ADS1292 和 ADS1292R 包含 便携式 低 功耗医疗心电图 (ECG)、体育和健身 应用通常所需的 所有功能。 凭借高集成度和出色的性能,ADS1291、ADS1292 和 ADS1292R 可在显著减少尺寸、功耗和总体成本的前 提下创建可扩展的医疗仪器系统。 ADS1291、ADS1292 和 ADS1292R 每通道具有灵活 的输入多路复用器,此多路复用器可独立连接至内部生 成的信号,实现测试、温度和持续断线检测。此外,可 选择输入通道的任一配置生成右腿驱动 (RLD) 输出信 号。ADS1291、ADS1292 和 ADS1292R 工作时的数 据速率高达 8kSPS。通过器件内部激励灌电流或拉电 流,可在器件内部执行持续断线检测。ADS1292R 版 本包括一个完全集成的呼吸阻抗测量功能。 总结下来,该芯片是一个用来测量心率和呼吸的利器。
接口信息
该芯片的前端需要连接电极片,这部分设计的原则是尽量减少采集干扰。所以信号屏蔽上要做些工作。该芯片采集到的数据使用spi接口连接到了主控设备上。具体示意图如下所示: 可以看出,该芯片是通过SPI接口和其他设备通信的,把spi接口调试好,使用好,是一个不可缺少的环节。笔者在这里遇到了一些问题,根本原因还是因为芯片配置错误导致对设备接口SPI的使用上出了问题。这点非常值得反思。
调试总结
配置信息。
ads1292是否正常工作,芯片配置特别关键。这次在移植的过程中,就是有一个小小的配置错误,导致了spi读不到数据。调试花费了很多时间。 这里的配置一般要注意几个地方: 1 启动配置信息,主要一定要先发送停止读取数据的命令,再复位,否则在数据传输过程中配置参数,极容易导致系统出错。 // ADS_CLKSEL=1;//启用内部时钟 // ADS_START=0; //停止数据输出 // ADS_RESET=0; //复位 // delay_ms(1000); // ADS_RESET=1;//芯片上电,可以使用 // delay_ms(100); //等待稳定
ADS1292_Send_CMD(SDATAC);//发送停止连续读取数据命令
delay_ms(100);
ADS1292_Send_CMD(RESET);//复位
delay_s(1);
ADS1292_Send_CMD(SDATAC);//发送停止连续读取数据命令
delay_ms(100);
2 配置参数很多是默认的即可,可是要配置的时候一要知道每个参数所代表的含义,否则容易出错:
ADS1292_REG[CONFIG1] = 0x00; //0000 0aaa [7] 0连续转换模式 [6:3] 必须为0
ADS1292_REG[CONFIG1] |= Ads1292_Config1.Data_Rate;//[2:0] aaa 采样率设置采样率 ADS1292_REG[CONFIG2] = 0x00; //1abc d0e1 [7] 必须为1 [2] 必须为0 [0] 设置测试信号为1HZ、±1mV方波
ADS1292_REG[CONFIG2] |= Ads1292_Config2.Pdb_Loff_Comp<<6; //[6]a 导联脱落比较器是否掉电
ADS1292_REG[CONFIG2] |= Ads1292_Config2.Pdb_Refbuf<<5; //[5]b 内部参考缓冲器是否掉电
ADS1292_REG[CONFIG2] |= Ads1292_Config2.Vref<<4; //[4]c 内部参考电压设置,默认2.42V
ADS1292_REG[CONFIG2] |= Ads1292_Config2.Clk_EN<<3; //[3]d CLK引脚输出时钟脉冲?
ADS1292_REG[CONFIG2] |= Ads1292_Config2.Int_Test<<1; //[1]e 是否打开内部测试信号,
ADS1292_REG[CONFIG2] |= 0x81;//设置默认位 ADS1292_REG[LOFF] = 0x10;//[7:5] 设置导联脱落比较器阈值 [4] 必须为1 [3:2] 导联脱落电流幅值 [1] 必须为0 [0] 导联脱落检测方式 0 DC 1 AC ADS1292_REG[CH1SET] = 0x00; //abbb cccc
ADS1292_REG[CH1SET] |=Ads1292_Ch1set.PD<<7; //[7] a 通道1断电?
ADS1292_REG[CH1SET] |=Ads1292_Ch1set.GAIN<<4; //[6:4]bbb 设置PGA增益
ADS1292_REG[CH1SET] |=Ads1292_Ch1set.MUX; //[3:0]cccc 设置通道1输入方式 ADS1292_REG[CH2SET] = 0x00; //abbb cccc
ADS1292_REG[CH2SET] |=Ads1292_Ch2set.PD<<7; //[7] a 通道2断电?
ADS1292_REG[CH2SET] |=Ads1292_Ch2set.GAIN<<4; //[6:4]bbb 设置PGA增益
ADS1292_REG[CH2SET] |=Ads1292_Ch2set.MUX; //[3:0]cccc 设置通道2输入方式 ADS1292_REG[RLD_SENS] = 0X00; //11ab cdef [7:6] 11 PGA斩波频率 fMOD/4
ADS1292_REG[RLD_SENS] |=Ads1292_Rld_Sens.Pdb_Rld<<5; //[5]a 该位决定RLD缓冲电源状态
ADS1292_REG[RLD_SENS] |=Ads1292_Rld_Sens.Rld_Loff_Sense<<4; //[4]b 该位使能RLD导联脱落检测功能
ADS1292_REG[RLD_SENS] |=Ads1292_Rld_Sens.Rld2N<<3; //[3]c 这个位控制通道2负输入 用于右腿驱动的输出
ADS1292_REG[RLD_SENS] |=Ads1292_Rld_Sens.Rld2P<<2; //[2]d 该位控制通道2正输入 用于右腿驱动的输出
ADS1292_REG[RLD_SENS] |=Ads1292_Rld_Sens.Rld1N<<1; //[1]e 这个位控制通道1负输入 用于右腿驱动的输出
ADS1292_REG[RLD_SENS] |=Ads1292_Rld_Sens.Rld1P; //[0]f 该位控制通道1正输入 用于右腿驱动的输出
ADS1292_REG[RLD_SENS] |= 0xc0;//设置默认位 ADS1292_REG[LOFF_SENS] = 0X00; //00ab cdef [7:6] 必须为0
ADS1292_REG[LOFF_SENS] |=Ads1292_Loff_Sens.Flip2<<5; //[5]a 这个位用于控制导联脱落检测通道2的电流的方向
ADS1292_REG[LOFF_SENS] |=Ads1292_Loff_Sens.Flip1<<4; //[4]b 这个位控制用于导联脱落检测通道1的电流的方向
ADS1292_REG[LOFF_SENS] |=Ads1292_Loff_Sens.Loff2N<<3; //[3]c 该位控制通道2负输入端的导联脱落检测
ADS1292_REG[LOFF_SENS] |=Ads1292_Loff_Sens.Loff2P<<2; //[2]d 该位控制通道2正输入端的导联脱落检测
ADS1292_REG[LOFF_SENS] |=Ads1292_Loff_Sens.Loff1N<<1; //[1]e 该位控制通道1负输入端的导联脱落检测
ADS1292_REG[LOFF_SENS] |=Ads1292_Loff_Sens.Loff1P; //[0]f 该位控制通道1正输入端的导联脱落检测 ADS1292_REG[LOFF_STAT] = 0x00; //[6]0 设置fCLK和fMOD之间的模分频比 fCLK=fMOD/4 [4:0]只读,导联脱落和电极连接状态 ADS1292_REG[RESP1] = 0X00;//abcc cc1d
ADS1292_REG[RESP1] |=Ads1292_Resp1.RESP_DemodEN<<7;//[7]a 这个位启用和禁用通道1上的解调电路
ADS1292_REG[RESP1] |=Ads1292_Resp1.RESP_modEN<<6; //[6]b 这个位启用和禁用通道1上的调制电路
ADS1292_REG[RESP1] |=Ads1292_Resp1.RESP_ph<<2; //[5:2]c 这些位控制呼吸解调控制信号的相位
ADS1292_REG[RESP1] |=Ads1292_Resp1.RESP_Ctrl; //[0]d 这个位设置呼吸回路的模式
ADS1292_REG[RESP1] |= 0x02;//设置默认位 ADS1292_REG[RESP2] = 0x00; //a000 0bc1 [6:3]必须为0 [0]必须为1
ADS1292_REG[RESP2] |= Ads1292_Resp2.Calib<<7; //[7]a 启动通道偏移校正?
ADS1292_REG[RESP2] |= Ads1292_Resp2.freq<<2; //[2]b 呼吸频率设置
ADS1292_REG[RESP2] |= Ads1292_Resp2.Rldref_Int<<1; //[1]c RLDREF信号源外部馈电?
ADS1292_REG[RESP2] |= 0X01;//设置默认位 ADS1292_REG[GPIO] = 0x0C; //GPIO设为输入 [7:4]必须为0 [3:2]11 GPIO为输入 [1:0] 设置输入时,指示引脚电平,设置输出时控制引脚电平
spi接口 ads129x系列的接口都是SPI的,这里面和普通的spi接口相比,还加了一个ready信号中断。该信号是用来通知host是否有信号输出的。非常关键。笔者在调试过程中,由于配置失误导致ads1292的spi信号一直输出为零,刚开始还以为是审批出错了,这里走了不少弯路。根本原因,还是对系统不熟悉,这点也算是一个教训吧。
总结
这块涉及到的知识比较多。由于是微弱信号采集,所以对硬件adc的设计这块非常关键。不能引入干扰是最基本的原则,也最最大的困难,这点花费时间很长,后续 花一些时间专门做一个专题研究解析。
软件涉及到东西比较多了,几乎用到了所有常用的接口,SPI接口数据传输和存储,串口打印,无线ble传输,本地sdio数据存储等。这些都是非常重要的软件接口和单元, 笔者也花费了不少时间去熟悉和调试,这块后面也会有不少专题要写出来。
随着对可穿戴医疗设备的深入,越来越发现自身团队医疗方面的知识欠缺了。对医疗知识的基本熟悉和理解,这点非常关键,是最好产品的必备路径。今后也要重点做一些专门的 学习和研究。
基于ads1292的心率呼吸信号检测解决方案开发阶段总结的更多相关文章
- #研发解决方案介绍#基于ES的搜索+筛选+排序解决方案
郑昀 基于胡耀华和王超的设计文档 最后更新于2014/12/3 关键词:ElasticSearch.Lucene.solr.搜索.facet.高可用.可伸缩.mongodb.SearchHub.商品中 ...
- 基于K2的集成供应链流程解决方案
基于K2的集成供应链流程解决方案http://www.k2software.cn/zh-hans/scm-solution 一.详细功能模块 需求管理模块多渠道管理.需求计划.需求感知与传递市场营销及 ...
- WCF分布式开发步步为赢(2)自定义托管宿主WCF解决方案开发配置过程详解
上一节<WCF分布式框架基础概念>我们介绍了WCF服务的概念和通信框架模型,并给出了基于自定义托管服务的WCF程序的实现代码.考虑到WCF分布式开发项目中关于托管宿主服务配置和客户端添加引 ...
- 【毕业设计】基于Android的家校互动平台开发(内含完整代码和所有文档)——爱吖校推(你关注的,我们才推)
☆ 写在前面 之前答应大家的毕业答辩之后把所有文档贡献出来,现在答辩已过,LZ信守承诺,把所有文档开源到了GitHub(这个地址包含所有的代码和文档以及PPT,外层为简单的代码).还望喜欢的朋友们,不 ...
- SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。
熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...
- 基于第三方开源库的OPC服务器开发指南(2)——LightOPC的编译及部署
前文已经说过,OPC基于微软的DCOM技术,所以开发OPC服务器我们要做的事情就是开发一个基于DCOM的EXE文件.一个代理/存根文件,然后就是写一个OPC客户端测试一下我们的服务器了.对于第一项工作 ...
- 基于SageMath的数学网站——本科毕业开发项目
1 绪论 1.1研究背景 我国是一个拥有15亿人口的大国.其中,据2017年的统计,全国共有大学生2600万左右.如此数量众多的大学生,都会有着学习基础数理课程的需求.而在高校的数学教学中,教授最多最 ...
- 基于Spring的可扩展Schema进行开发自定义配置标签支持
一.背景 最近和朋友一起想开发一个类似alibaba dubbo的功能的工具,其中就用到了基于Spring的可扩展Schema进行开发自定义配置标签支持,通过上网查资料自己写了一个demo.今天在这里 ...
- 翻译:打造基于Sublime Text 3的全能python开发环境
原文地址:https://realpython.com/blog/python/setting-up-sublime-text-3-for-full-stack-python-development/ ...
- 基于QT的换肤整体解决方案(QSkinStyle)(提供Linux的XP风格)
基于QT的换肤整体解决方案(QSkinStyle) 对QT这个成功的跨平台GUI库,本身内置了对换肤功能的实现,比如cleanlooks.plastique等跨平台风格:还有一些是和平台相关的风格,比 ...
随机推荐
- C#/.NET/.NET Core优秀项目和框架2024年1月简报
前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍.功能特点.使用方式以及部分功能截图 ...
- linux 后台运行进程:& , nohup
目录 后台执行 & nohup 查看后台运行的命令 jobs ps 关闭当前后台运行的程序 kill 前后台进程的切换与控制 ctrl + z 命令 fg 命令 bg 命令 思考 问题1-为什 ...
- 音频处理实用AI工具
最近在做音频处理相关的工作,主要有以下几个好用的工具. 1. 语音转文字--whisper 这是一款由OpenAI开发的语音转文字工具,项目地址位于:openai/whisper. 这个工具是用来生成 ...
- vue 导出多页pdf, window.print()实现
如果你对分页打印没思路,而网上的现成方案又不适合,不妨进来看看,也许会对你有帮助. 由于工作环境是局域网,对于插件的安装有限制,所以排除了jspdf + html2canvas的实现方式:采用wind ...
- NC19885 [AHOI2009]CHESS 中国象棋
题目链接 题目 题目描述 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧.一个炮要能攻击另一个炮他们必须要 ...
- 对称加密算法汇总:AES DES 3DES SM4 java 实现入门
密码的世界 如果你是黑帮老大,平时和手下沟通,如何保证自己的信息安全呢? 在神探夏洛克的第一季中,就讲述了一个如何侦破黑帮的加密交流的故事. 这种密码利用的是密码字典. 密码本身可以是一本书,比如常见 ...
- java 从零开始手写 redis(七)LRU 缓存淘汰策略详解
前言 java从零手写实现redis(一)如何实现固定大小的缓存? java从零手写实现redis(三)redis expire 过期原理 java从零手写实现redis(三)内存数据如何重启不丢失? ...
- Java设计模式-状态模式State
介绍 状态模式(State Pattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题.状态和行为是一一对应的,状态之间可以相互转换. 当一个对象的内在状态改变时,允许改变其行 ...
- Java Base64编码使用介绍
Base64编码介绍 BASE64 编码是一种常用的字符编码,Base64编码本质上是一种将二进制数据转成文本数据的方案. 但base64不是安全领域下的加密解密算法.能起到安全作用的效果很差 ...
- C++ 多线程的错误和如何避免(9)
有时候使用 std::atomic 比使用 mutexes 更高效 问题分析:使用多线程更新一些简单数据时,比如 int 型,bool 型等等,可以使用 std::atomic,这比 mutex 来得 ...