项目背景

心脏运作可以揭露人体许多极具价值的信息,包括其健康状态、生活方式,甚至是情绪状态及心脏疾病的早期发病等。传统的医疗设备中,监测心跳速率和心脏活动是经由测量电生理讯号与心电图 (ECG) 来完成的,需要将电极连接到身体来量测心脏组织中所引发电气活动的信号。

整体方案

本项目系统上位机使用 LabVIEW VI,可以形象的看到6路心电信号,下位机则使用arduino开发板,连接我们的Olimex ECG/EMG扩展板,Arduino ADC 6路读取模拟输入, LabVIEW上位机以图形方式呈现读数, 并可以保存到文件中。

下位机设计

下位机则使用arduino开发板,arduino ARDUINO UNO 中介绍 ADC(模数转换)的概念。Arduino 板有六个 ADC 通道,如下图所示。其中任何一个或全部都可以用作模拟电压的输入。Arduino Uno ADC具有10 位分辨率(因此整数值来自 (0-(2^10) 1023))。这意味着它将 0 到 5 伏之间的输入电压映射为 0 到 1023 之间的整数值。
SHIELD-EKG-EMG是一个扩展模块, 用于ARDUINO兼容电路板, 如OLIMEXINO-328, OLIMEXINO-STM32和PIC32-PINGUINO及其它. 此子板也可兼容ARDUINO电路板, 包括ARDUINO UNO. 电路板配有安装用连接器. 此产品为EKG/EMG子板, 允许Arduino类的电路板捕捉心电图肌电图信号. 此子板添加了进行生物实验反馈的新途径. 此程序可使用户可监视心跳并记录脉搏, 通过监视和分析肌肉动作来识别姿势动作.
可堆叠子板(经针座)
开放硬件,开放软件项目(用户可访问所有的设计文件)
D4/D9数字输出生成校准信号
精确的微调电位器用于校准
输入连接器, 用于无源或有源电极.
可运行3.3V和5V Arduino电路板
从Olimex ECG/EMG心电图/肌电图扩展板读取Arduino模拟输入,以图形方式呈现读数,并保存到“记录的示例”文件夹中的文件。
将工程中的库文件夹中的文件复制到你自己的Arduino库中。一般为“C:\用户\您的名称\文档\Arduino\库”。

#include <compat/deprecated.h>
#include <FlexiTimer2.h>
//http://www.arduino.cc/playground/Main/FlexiTimer2// All definitions
#define NUMCHANNELS 6
#define HEADERLEN 4
#define PACKETLEN (NUMCHANNELS * 2 + HEADERLEN + 1)
#define SAMPFREQ 256                      // ADC sampling rate 256
#define TIMER2VAL (1024/(SAMPFREQ))       // Set 256Hz sampling frequency
#define LED1  13
#define CAL_SIG 9// Global constants and variables
volatile unsigned char TXBuf[PACKETLEN];  //The transmission packet
volatile unsigned char TXIndex;           //Next byte to write in the transmission packet.
volatile unsigned char CurrentCh;         //Current channel being sampled.
volatile unsigned char counter = 0;      //Additional divider used to generate CAL_SIG
volatile unsigned int ADC_Value = 0;     //ADC current value//~~~~~~~~~~
// Functions
//~~~~~~~~~~/****************************************************/
/*  Function name: Toggle_LED1                      */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Switches-over LED1.                   */
/****************************************************/
void Toggle_LED1(void){if((digitalRead(LED1))==HIGH){ digitalWrite(LED1,LOW); }else{ digitalWrite(LED1,HIGH); }}/****************************************************/
/*  Function name: toggle_GAL_SIG                   */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Switches-over GAL_SIG.                */
/****************************************************/
void toggle_GAL_SIG(void){if(digitalRead(CAL_SIG) == HIGH){ digitalWrite(CAL_SIG, LOW); }else{ digitalWrite(CAL_SIG, HIGH); }}/****************************************************/
/*  Function name: setup                            */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Initializes all peripherals           */
/****************************************************/
void setup() {noInterrupts();  // Disable all interrupts before initialization// LED1pinMode(LED1, OUTPUT);  //Setup LED1 directiondigitalWrite(LED1,LOW); //Setup LED1 statepinMode(CAL_SIG, OUTPUT);//Write packet header and footerTXBuf[0] = 0xa5;    //Sync 0TXBuf[1] = 0x5a;    //Sync 1TXBuf[2] = 2;       //Protocol versionTXBuf[3] = 0;       //Packet counterTXBuf[4] = 0x02;    //CH1 High ByteTXBuf[5] = 0x00;    //CH1 Low ByteTXBuf[6] = 0x02;    //CH2 High ByteTXBuf[7] = 0x00;    //CH2 Low ByteTXBuf[8] = 0x02;    //CH3 High ByteTXBuf[9] = 0x00;    //CH3 Low ByteTXBuf[10] = 0x02;   //CH4 High ByteTXBuf[11] = 0x00;   //CH4 Low ByteTXBuf[12] = 0x02;   //CH5 High ByteTXBuf[13] = 0x00;   //CH5 Low ByteTXBuf[14] = 0x02;   //CH6 High ByteTXBuf[15] = 0x00;   //CH6 Low Byte TXBuf[2 * NUMCHANNELS + HEADERLEN] =  0x01;    // Switches state// Timer2// Timer2 is used to setup the analag channels sampling frequency and packet update.// Whenever interrupt occures, the current read packet is sent to the PC// In addition the CAL_SIG is generated as well, so Timer1 is not required in this case!FlexiTimer2::set(TIMER2VAL, Timer2_Overflow_ISR);FlexiTimer2::start();// Serial PortSerial.begin(57600);//Set speed to 57600 bps// MCU sleep mode = idle.//outb(MCUCR,(inp(MCUCR) | (1<<SE)) & (~(1<<SM0) | ~(1<<SM1) | ~(1<<SM2)));interrupts();  // Enable all interrupts after initialization has been completed
}/****************************************************/
/*  Function name: Timer2_Overflow_ISR              */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Determines ADC sampling frequency.    */
/****************************************************/
void Timer2_Overflow_ISR()
{// Toggle LED1 with ADC sampling frequency /2Toggle_LED1();//Read the 6 ADC inputs and store current values in Packetfor(CurrentCh=0;CurrentCh<6;CurrentCh++){ADC_Value = analogRead(CurrentCh);TXBuf[((2*CurrentCh) + HEADERLEN)] = ((unsigned char)((ADC_Value & 0xFF00) >> 8));  // Write High ByteTXBuf[((2*CurrentCh) + HEADERLEN + 1)] = ((unsigned char)(ADC_Value & 0x00FF));    // Write Low Byte}// Send Packetfor(TXIndex=0;TXIndex<17;TXIndex++){Serial.write(TXBuf[TXIndex]);}// Increment the packet counterTXBuf[3]++;            // Generate the CAL_SIGnalcounter++;      // increment the devider counterif(counter == 12){    // 250/12/2 = 10.4Hz ->Toggle frequencycounter = 0;toggle_GAL_SIG();   // Generate CAL signal with frequ ~10Hz}
}/****************************************************/
/*  Function name: loop                             */
/*  Parameters                                      */
/*    Input   :  No                             */
/*    Output  :  No                                 */
/*    Action: Puts MCU into sleep mode.             */
/****************************************************/
void loop() {__asm__ __volatile__ ("sleep");}`

上位机设计

设计一个 LabVIEW VI,
VI需要一些时间才能开始工作, 直到 LabVIEW 与 Arduino的串口输出同步。此时“当前状态”将从“初始状态”更改为“已校正偏移”。可以更改保存文件的名称。如果您想加入自己的信号处理算法,可以在“消费者循环”中执行此操作。


最后效果图:

总结

下位机程序已经在文章中了,需要下位机库文件和上位机labview程序的可以在评论区留下邮箱,如果这篇文章帮助了你,请好评三连呀!

多通道ECG心率监测系统相关推荐

  1. 【项目设计】基于OneNet平台的心率监测系统 -嵌入式 -物联网

    基于OneNET云平台心率监测系统 一.引言 随着我国人口老龄化程度的加深和慢性病人群数量的增加,健康管理愈发重要.心率的监测和心率异常及时报警具有重要的意义. 二.整体方案 该设计分为本地设备端,云 ...

  2. stm32心率监测系统(心率监测,wifi上传,APP显示,上位机显示)

    一.硬件材料清单: 1.STM32核心板 2.OLED显示屏 3.心率传感器 4.ESP8266 二.实现的功能 1:STM32采集心率传感器数据 2:OLED实时显示心率数据和心率曲线 3:wifi ...

  3. 基于人脸视频的实时心率监测系统 DAY 15

    欧拉放大已经实现 在网上查找了主流的心率特征提取方式 1.对脉搏跳动视频帧的像素点亮度值在时域上进行亮度方差统计,同时在Yc吒b颜色空间中分割出皮肤区域:其次,根据亮度方差统计和皮肤分割结果,结合图像 ...

  4. 基于面部视频的心率监测系统 day 10

    欧拉放大的5个步骤 1.转换为YIQ 2.空间滤波.将视频序列进行金字塔多分辨率分解: 3.时域滤波.对每个尺度的图像进行时域带通滤波,得到感兴趣的若干频带: 4.放大滤波结果.对每个频带的信号用泰勒 ...

  5. [RISC-V MCU 应用开发]基于CH32V307和TtencentOS Tiny的物联网心率监测

    这里利用CH32V307和TtencentOS Tiny设计了一款物联网心率监测系统.先来看一下实物图 概要就是实现CH32V307和AD8232实现心率的测量,并将该数据发送到腾讯云上,然后有腾讯云 ...

  6. 分布式光纤温度监测系统在通信动力楼的应用案例

    分布式光纤温度监测系统在通信动力楼的应用 针对通信机房及设备温度监测难题,基于拉曼散射与时域反射相结合的分布式光纤测温方法,有效提高系统测温空间分辨与降低系统敷设难度,实现温度实时监测,趋势分析,事故 ...

  7. voip 音频采集时间_蓝牙音频续航监测系统展会现场演示

    |点击[美格信]关注☝ 大家好,我是美格信公众号主编:小M, 今天的2020(秋季)亚洲蓝牙耳机展上,我们美格信现场展示了发布的新品-MAGNUM麦金纳蓝牙音频续航监测系统. 不过有很多小伙伴因为时间 ...

  8. labview串口数据采集并显示_一种NB-IoT冶金节点温度采集与远程监测系统的设计...

    大型高炉出铁量大,冶金生产环境恶劣,导致铁水沟侵蚀日益严重,需人工定期对冶金沟道部分进行温测,其准确度不高,生产成本高,安全保障低[1].为了能够对高炉冶金沟道进行全方位测温,掌握铁水沟道的温度和腐蚀 ...

  9. 基于 STM32 和 NB-IoT 的可穿戴式老人防摔监测系统

    这是我本科毕设搞得一个小任务,现在稍微整理了其中一点内容,下面有相应的程序代码. 程序参考: 采用STM32作为主控,通过串口与ME3616通信,控制ME3616对接OneNET,将采集到的温度数据上 ...

  10. 预防猝死,8个心率监测方案随时监测的身体状况

    近年来,随着生活节奏加快,工作压力加大,不健康的作息等原因,导致猝死的事件频发,心率情况是身体状态的直接表现,所以做好心率监测可以大大避免一些突发情况的发生.整理了电路城上8个心率监测的电路方案,工程 ...

最新文章

  1. Sql Server数据库连接Oracle数据库
  2. 遍历百万级Redis的键值的大结局
  3. 解析TOMCAT框架 .
  4. 【WC2016】挑战NPC 【带花树】【建图】
  5. mysql--------四种索引类型
  6. 【飞秋】OR层代码组织介绍
  7. apache部署多个项目
  8. Uva 10817 校长的烦恼
  9. C++ STL list的成员函数splice的使用
  10. 6月7日 PowerPoint 版本支持的媒体格式(跨office版本演示需要了解)
  11. python生成wifi字典_用Python自带的itertools生成穷举字典
  12. 学习笔记 利用反射 手写一个简单的实体类 转json 的方法
  13. latex中输入matlab代码,Latex插入matlab代码
  14. HDoj 1862
  15. android 带刻度的滑动条_Android滚动刻度尺实现
  16. springcloud整合Gateway
  17. JavaScript 进阶 - 第2天
  18. Java零基础学习Java编程语言基础知…
  19. Unity5.1 新的网络引擎UNET(十五) Networking 引用--中
  20. java集合 — — lterator迭代器

热门文章

  1. java导出excel设置行高列宽_Java 设置Excel自适应行高或列宽
  2. Micrium 开放了µC/OS-III源代码
  3. rl滤波器原理_滤波器基本知识
  4. 什么是 NAS? 为什么要用 NAS?有什么好玩的功能?
  5. java坦克大战爆炸效果_用java做坦克大战--主要类和基本功能实现
  6. 在CATIA中实现道路缓和曲线的方法
  7. Error querying database. Cause: java.sql.SQLException: ORA-01008: 并非所有变量都已绑定
  8. c语言命令行贪吃蛇,C语言实现贪吃蛇游戏(命令行)
  9. server 2008 r2中无法启用“网络发现”
  10. 3小时GIS入门教程(一):为什么要学GIS