Go Down

Topic: ECG Project (Help needed) (Read 5212 times) previous topic - next topic

jdhamm82

May 16, 2014, 07:59 am Last Edit: May 16, 2014, 10:34 am by jdhamm82 Reason: 1
Hello All!

I am in need of help with an Mobile ECG project that I am working on for my senior project in college. I am fairly new to the Arduino world, however, I have taken programming classes (C++ & Java), so I have a fairly decent understanding of programming (not an expert my any means). My school recently switched to the Arduino platform for our microcontroller courses (previously taught using the Freescale Tower (Assembly and C languages)), so I have a intermediate level understanding of Arduino programming as well.

Here's what I'm looking to accomplish with the Arduino:


  • I will be using an Arduino Due to read an analog voltage from a pulse grip-based ECG circuit. I'm essentially taking the small voltage from the body and amplifying the signal so that it is large enough to be read by an analog input of the Arduino.

    I am looking to do some signal processing via the Arduino for digital filtering. I recently installed the Arduino Filter Library from https://github.com/jeroendoggen/Arduino-signal-filtering-library but I don't know how to implement the filters I want to use.

    I want to detect the peak voltages from the ECG signal, convert it to beats per minute, and also display that to an LCD

    From the beats per minute information, I would like to see if that can be used to determine the # of calories burned?

    I am also looking to use another analog input to read the speed of a bicycle using a sensor and output that to a LCD.

    I am also wondering if there is a way for the Arduino Due to interface with a sensor that monitors battery charging/discharging?

    Lastly, I need to know what the sampling rate of the analog input is and if there is a way to modify it. I've seen the clock speed can be modified in order to adjust the sampling rate, and I've also been told that I can use a timer interrupt to modify the sampling rate also, but I am not sure how to implement these.




I know this is quite a lot of information and coding that is needed however, if there is a certain area listed here that you can provide insight into, I would greatly appreciate it.

Sincerely,

JDH

jdhamm82

Hello All!

I am in need of help with an Mobile ECG project that I am working on for my senior project in college. I am fairly new to the Arduino world, however, I have taken programming classes (C++ & Java), so I have a fairly decent understanding of programming (not an expert my any means). My school recently switched to the Arduino platform for our microcontroller courses (previously taught using the Freescale Tower (Assembly and C languages)), so I have a intermediate level understanding of Arduino programming as well.

Here's what I'm looking to accomplish with the Arduino:

I will be using an Arduino Due to read an analog voltage from a pulse grip-based ECG circuit. I'm essentially taking the small voltage from the body and amplifying the signal so that it is large enough to be read by an analog input of the Arduino.

I am looking to do some signal processing via the Arduino for digital filtering. I recently installed the Arduino Filter Library from https://github.com/jeroendoggen/Arduino-signal-filtering-library but I don't know how to implement the filters I want to use.

I want to detect the peak voltages from the ECG signal, convert it to beats per minute, and also display that to an LCD

From the beats per minute information, I would like to see if that can be used to determine the # of calories burned?

I am also looking to use another analog input to read the speed of a bicycle using a sensor and output that to a LCD.

I am also wondering if there is a way for the Arduino Due to interface with a sensor that monitors battery charging/discharging?

Lastly, I need to know what the sampling rate of the analog input is and if there is a way to modify it. I've seen the clock speed can be modified in order to adjust the sampling rate, and I've also been told that I can use a timer interrupt to modify the sampling rate also, but I am not sure how to implement these.

I know this is quite a lot of information and coding that is needed however, if there is a certain area listed here that you can provide insight into, I would greatly appreciate it.

Sincerely,

JDH

jremington

There are a lot of parts to this project and they all need to be tackled individually. Each component should be thoroughly understood and working to your satisfaction before you start adding the components together.

I would start by learning how to use the ADC on the Arduino, all by itself, perhaps with a simple variable voltage source like a potentiometer as a voltage divider, powered by either +5V or a 1.5 V battery, as the "signal". Google "Arduino ADC" to find tutorials, examples and how to use the ADC library. Learn how to sample at different rates. Try averaging successive samples to reduce noise.

When all that works, connect the ADC input to  your ECG amplifier and see if you can make sense of the signal, perhaps sending the data to the serial monitor and eventually, plotting the points. Then you are set to learn how the signal processing package works, and try peak detection.

With all that under  your belt (the heart of the project) the other bits will be easy.

jdhamm82

Thanks for replying. I've found information on some of the areas I'm working on.

I have one quick question: Can the standard timer libraries be used with the Due (i.e. TimerOne from Uno)? I've heard that those libraries are not compatible with the Due.

Please advise.

Thank you!

jdhamm82

Here's what I have so far do filter the signal digitally, once this is done I am looking to detect the peak of the waveform (the beat of the heart).

Code: [Select]

// sketch_13_04_null_filter_due

const long samplePeriod = 4000L; // microseconds

const int analogInPin = A0;
const int analogOutPin = DAC0;

//Band pass chebyshev filter order=4 alpha1=0.002 alpha2=0.064
//http://www.schwietering.com/jayduino/filtuino/index.php?characteristic=ch&passmode=bp&order=4&chebrip=-3&usesr=usesr&sr=250&frequencyLow=0.5&noteLow=&frequencyHigh=16&noteHigh=&pw=pw&calctype=float&run=Send

class filter
{
public:
filter()
{
for(int i=0; i <= 8; i++)
v[i]=0.0;
}
private:
float v[9];
public:
float step(float x) //class II
{
v[0] = v[1];
v[1] = v[2];
v[2] = v[3];
v[3] = v[4];
v[4] = v[5];
v[5] = v[6];
v[6] = v[7];
v[7] = v[8];
v[8] = (1.729391253396e-4 * x)
+ ( -0.7974549555 * v[0])
+ (  6.4181511105 * v[1])
+ (-22.7432921934 * v[2])
+ ( 46.3498777518 * v[3])
+ (-59.4185721023 * v[4])
+ ( 49.0636546473 * v[5])
+ (-25.4813649782 * v[6])
+ (  7.6090007191 * v[7]);
return
(v[0] + v[8])
- 4 * (v[2] + v[6])
+6 * v[4];
}
};

filter f;

void setup()                 
{
  // http://www.djerickson.com/arduino/
  REG_ADC_MR = (REG_ADC_MR & 0xFFF0FFFF) | 0x00020000;
  analogWriteResolution(8);
  analogReadResolution(8);
}

void loop()                   
{
  static long lastSampleTime = 0;
  long timeNow = micros();
  if (timeNow > lastSampleTime + samplePeriod)
  {
    int raw = analogRead(analogInPin);
float filtered = f.step(raw);
    analogWrite(analogOutPin, (int)filtered);
    lastSampleTime = timeNow;
  }
}



Code for determining BPM
Code: [Select]


include <DueTimer.h>

//External Variables
const int heartPin = A0;
const int ledPin = 3;

//Interrupt Variables
volatile int heart_high;
volatile int heart_low;
volatile int rateData[200];
volatile int i;



void setup()
{
Serial.begin(9600);
pinMode(heartPin, INPUT);
pinMode(ledPin, OUTPUT);
Timer1.attachInterrupt(A0,findPulse, HIGH).setFrequency(250).start();

}

int findPulse()
{
heart_high = 0;
heart_low = 1023;

for(i = 199; i > 0; i--)
{
rateData[i] = rateData [i-1];

if(rateData[i] > heart_high)
heart_high = rateData[i];
if(rateData[i] < heart_low)
heart_low = rateData[i];
}

rateData[0] = analogRead(A0);
}

void loop()
{
Serial.println(rateData[0]);
}



I'm a bit lost on figuring out how to take this digitally filtered signal and writing a program to find the peak (beat). I am guessing that I can sample the signal somehow and perhaps take an average of the readings to determine the beats per minute. The only issue is that I want to do this using a timer interrupt (in order to have a more consistent sampling rate). Any suggestions on the best way to do this?

Thanks!

jdhamm82

Here's what I have so far do filter the signal digitally, once this is done I am looking to detect the peak of the waveform (the beat of the heart).

Code: [Select]

// sketch_13_04_null_filter_due

const long samplePeriod = 4000L; // microseconds

const int analogInPin = A0;
const int analogOutPin = DAC0;

//Band pass chebyshev filter order=4 alpha1=0.002 alpha2=0.064
//http://www.schwietering.com/jayduino/filtuino/index.php?characteristic=ch&passmode=bp&order=4&chebrip=-3&usesr=usesr&sr=250&frequencyLow=0.5&noteLow=&frequencyHigh=16&noteHigh=&pw=pw&calctype=float&run=Send

class filter
{
public:
filter()
{
for(int i=0; i <= 8; i++)
v[i]=0.0;
}
private:
float v[9];
public:
float step(float x) //class II
{
v[0] = v[1];
v[1] = v[2];
v[2] = v[3];
v[3] = v[4];
v[4] = v[5];
v[5] = v[6];
v[6] = v[7];
v[7] = v[8];
v[8] = (1.729391253396e-4 * x)
+ ( -0.7974549555 * v[0])
+ (  6.4181511105 * v[1])
+ (-22.7432921934 * v[2])
+ ( 46.3498777518 * v[3])
+ (-59.4185721023 * v[4])
+ ( 49.0636546473 * v[5])
+ (-25.4813649782 * v[6])
+ (  7.6090007191 * v[7]);
return
(v[0] + v[8])
- 4 * (v[2] + v[6])
+6 * v[4];
}
};

filter f;

void setup()                
{
 // http://www.djerickson.com/arduino/
 REG_ADC_MR = (REG_ADC_MR & 0xFFF0FFFF) | 0x00020000;
 analogWriteResolution(8);
 analogReadResolution(8);
}

void loop()                  
{
 static long lastSampleTime = 0;
 long timeNow = micros();
 if (timeNow > lastSampleTime + samplePeriod)
 {
   int raw = analogRead(analogInPin);
float filtered = f.step(raw);
   analogWrite(analogOutPin, (int)filtered);
   lastSampleTime = timeNow;
 }
}



Code for determining BPM
Code: [Select]


include <DueTimer.h>

//External Variables
const int heartPin = A0;
const int ledPin = 3;

//Interrupt Variables
volatile int heart_high;
volatile int heart_low;
volatile int rateData[200];
volatile int i;



void setup()
{
Serial.begin(9600);
pinMode(heartPin, INPUT);
pinMode(ledPin, OUTPUT);
Timer1.attachInterrupt(A0,findPulse, HIGH).setFrequency(250).start();

}

int findPulse()
{
heart_high = 0;
heart_low = 1023;

for(i = 199; i > 0; i--)
{
rateData[i] = rateData [i-1];

if(rateData[i] > heart_high)
heart_high = rateData[i];
if(rateData[i] < heart_low)
heart_low = rateData[i];
}

rateData[0] = analogRead(A0);
}

void loop()
{
Serial.println(rateData[0]);
}



I'm a bit lost on figuring out how to take this digitally filtered signal and writing a program to find the peak (beat). I am guessing that I can sample the signal somehow and perhaps take an average of the readings to determine the beats per minute. The only issue is that I want to do this using a timer interrupt (in order to have a more consistent sampling rate). Any suggestions on the best way to do this?

Thanks!

Go Up