糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 多通道ECG心率监测系统

多通道ECG心率监测系统

时间:2022-04-24 19:29:19

相关推荐

多通道ECG心率监测系统

项目背景

心脏运作可以揭露人体许多极具价值的信息,包括其健康状态、生活方式,甚至是情绪状态及心脏疾病的早期发病等。传统的医疗设备中,监测心跳速率和心脏活动是经由测量电生理讯号与心电图 (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>///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 variablesvolatile unsigned char TXBuf[PACKETLEN]; //The transmission packetvolatile 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_SIGvolatile 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心率监测系统》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。