March 19, 2024, 08:42:46 AM

Sample raw ECG data

Started by Stan12, December 24, 2012, 09:12:58 AM

Previous topic - Next topic

Stan12

If anybody is interested, just want to share some ECG recordings I made with ECG Shield.
This one uses Arduino Duemilanove, shield jumper set to 5V:

Quite a lot of noise.

Next one is Arduino Due, jumper set to 3 V, much less noise:


And that one is Duemilanove again but jumper set to 3V, obviously better:



Ecg images were generated by application I am developing as a hobby project (and, hopefully, more);
rubber-band electrodes location is: L on left hand, R and D on right hand.
Arduino code I used to transmit raw data:
#include <compat/deprecated.h>
#include <FlexiTimer2.h>
#define SAMPFREQ 256                      // ADC sampling rate 256
#define TIMER2VAL (1024/(SAMPFREQ))       // Set 256Hz sampling frequency                   
volatile unsigned char CurrentCh=0;         //Current channel being sampled.
volatile unsigned int ADC_Value = 0;   //ADC current value

void setup() {

noInterrupts();  // Disable all interrupts before initialization

FlexiTimer2::set(TIMER2VAL, Timer2_Overflow_ISR);
FlexiTimer2::start();

// Serial Port
Serial.begin(57600);

interrupts();  // Enable all interrupts after initialization has been completed
}

void Timer2_Overflow_ISR()
{
        ADC_Value = analogRead(CurrentCh);
        Serial.print("D!");    //this is packet header for my application
        Serial.println(ADC_Value);
}

void loop() {
__asm__ __volatile__ ("sleep");
}


This code is for Arduino Duemilanove only. Arduino DUO needs totally different handling of timer.
As you can see it is simplified version of the original ShieldEkgEmgDemo sketch.

It is a nice shield, but I'd like to complain and suggest:
ECG cable that comes with it is... well, it's not the best of them all.
From my experience I may say that good cable and electrodes make 50% of good quality ECG.

First of all, with the leads so short - how on earth can I attach them to both arms and leg??
Second,  these electrodes with rubber band are so called 'rest' electrodes, so  the slightest movement  immediately brings motion artifacts.
Third, I suspect the leads are not shielded and this is why there is a lot of 60hz noise.

I would suggest a simple 3 leads cable with snap connectors, f.e the one for MD100B monitor:


and may be a single pack of 10 foam electrodes, f.e from Protech - as a start-up kit.


I use them for almost a year, them are very reliable, affordable and provide very good skin contact even under the stress-test.

With foam electrodes I'd suggest a chest placement offered by W.A.H.Engelse and C.Zeelenberg (COMPUTERS IN CARDIOLOGY September, 1979). It provides  good amplitude, and allows to use short leads which is critically important for noise reduction; it also minimizes motion artifacts during exercises:


I am just trying to say that poor cable and electrodes spoils the great impression from really good board, so many users might be disappointed with their initial experience. Pls consider this as an improvement suggestion :)


Yet again, very useful shield, I am quite happy with it.


Day later:
yet another proof the cable is catching a lot of noise:
Electrode bands are located on forearms, close to the wrists.
On ECG below left part with less noise is when I keep forearms close to each other, with palms nearly touching. So the leads are close to each others.
Right part with increased noise is when I spread forearms aside, to normal position, ~1 1/2 ft:




alcor

Thank you :) Great advices!
I've ordered the EKG/EMG shield so I'm going to try it in a couple of days (I hope so :P).

I'll write my opinions asap.
- Orlando

Victor

Hello,

Thanks for the above info.  I bought two Mod-EKG boards last December. I am able to test it using a CR2032 battery but once I power it from an external 3.3volt supply from an Arduino board for example, the program does not work anymore, it hangs. It is not able to count and display heartbeat count. This happens on both boards, they both cannot function when connected to another board or supply. I did not even connect any data lines just the power supply.

Any suggestions or what have you suggested to others on how to go around the problem? Thanks in advance,
Victor

Stan12

Quote from: Victor on January 23, 2013, 04:18:12 AM
Hello,

Thanks for the above info.  I bought two Mod-EKG boards last December. I am able to test it using a CR2032 battery but once I power it from an external 3.3volt supply from an Arduino board for example, the program does not work anymore, it hangs. It is not able to count and display heartbeat count. This happens on both boards, they both cannot function when connected to another board or supply. I did not even connect any data lines just the power supply.

Any suggestions or what have you suggested to others on how to go around the problem? Thanks in advance,
Victor
Victor, I'm sort of not quite getting it. What is 'test it using a CR2032 battery'?
AFAIK CR2032 provides 1.5 V DC, this is not enough for any board.
Are we talking about the same board? It does not need external power, you just piggy-back it on your Arduino and voilĂ .
Also, which 'program'?

Hotte

Hey Stan12!
Thanks for posting your ECG recordings - it's an awesome signal for this cheap thing!
I'm wondering how you are reading in the data to display? As far as I can see you are just analogreading one channel:
     
QuoteADC_Value = analogRead(CurrentCh); 
     Serial.print("D!");    //this is packet header for my application
     Serial.println(ADC_Value);

did you use processing to display the graph then?
I tried to use processing (processing.org) to establish a serial connection with my Arduino to then plot the signal (see attachment), but it seems like I'm loosing a lot of data since the refresh rate of the processing sketch is 60Hz. I want to write the "raw" serial data to a txt file as pure as possible - and of course have a live plot. any advice for that?
Your sampling looks far higher than mine - judged from the picture you uploaded.
I am using a mac.
Hope you can answer to this question!


Stan12

#5
Hi,
as I wrote above, I am using my own application developed with DELPHI 7 for dispalying and storing data.
I would not rely on Processing for any serious data handling, it is only good for simpliest demo screens.
From your pictures  ECG looks quite distorted with heavy filtration of higher frequencies, as you can see, noise pattern is very regular. Actually, it is pure 60 Hz.
On Mac you could probably make a simple application with C#, they have Mono open source app, or Lazarus - this is open-source DELPHI-like IDE; or else you may run Windows emulator and use MS Visual studio or something.
Actually, you may also try storing data on Arduino SD card and transfer it for processing later. There will be some data gaps though when  data buffer is flushed to SD. Or else, you may attach RAM board to Arduino for extra-fast data accuisition; using QuadRam board I was able to store  up to 30000 measurement/sec on Arduino-based controller (accelerometer data).

Hotte

Thanks for your quick reply!
You are right about data handling with processing - it would have been the easiest way for me since I don't have programming experience. I will try lazarus ... and post my results, if I get something out of it.
I don't have an Arduino SD card reader (yet).
30kHz data sampling with the QuadRam board sounds awesome. Have to check that out ...

Stan12

30kHz was sort of bragging...very special task. You don't need it for ECG.
Most professional ECG monitors provide 200 samples/sec; for precise and sophisticated ECG analysis (like, HRV, frequency-domain etc.) 500-1000 samples/sec would be absolutely sufficient.

olimex

EKG/EMG board have filers at 50Hz so there is non sense to scan with 30 kHz as you will receive nothing above this frequency, all frequancies above 50Hz are heavy depressed to remove the mains interferences

Stan12

Quote from: olimex on July 02, 2013, 09:46:14 AM
EKG/EMG board have filers at 50Hz so there is non sense to scan with 30 kHz as you will receive nothing above this frequency, all frequancies above 50Hz are heavy depressed to remove the mains interferences
As you might have noticed, I mentioned 30KHz in regard with different application, just as an example of Arduino possibilities. Professional design for registering ECG must have notch filter in 50-60Hz area, otherwise it is nothing more than just a toy.
You board still have enough broadband to pass high frequency noises, as can be seen from my diagrams above.
As per Hotte's data it looks like it has been heavily filtered by the software application.

leitneeb

I have messed around with this for hours to no avail now... I copied your code, Stan12, and tried using the code provided, but all I can get is noise. I also tried inserting a 60Hz bandstop filter (Butterworth first order) into my code and nothing. It seems like a lot of people are having this issue...any suggestions to rectify the output data to actually make an ECG trace? Thanks a lot...any help would be fantastic.

Stan12

Quote from: leitneeb on October 01, 2013, 05:29:30 PM
I have messed around with this for hours to no avail now... I copied your code, Stan12, and tried using the code provided, but all I can get is noise. I also tried inserting a 60Hz bandstop filter (Butterworth first order) into my code and nothing. It seems like a lot of people are having this issue...any suggestions to rectify the output data to actually make an ECG trace? Thanks a lot...any help would be fantastic.
Sorry, I don't see how I can help here.
You see, registering ECG (along with any other biopotentials) takes  a lot of experience, as such it is somewhat closer to art...
To use my code you will probably need some data representation software... actually for very short records you can try even Excel charting... may be.

dzsingisz

Hello,

I'm also using Arduino Due with Olimex ECG shield, can you show me your code? I'm mainly interested in the timer functions, because Flexitime (the manual mentioned) is not working with Due.

Thanks for your help.

Stan12

Here is the code I used for Arduino Due:
//timer based on http://arduino.cc/forum/index.php/topic=130423.15.html
volatile unsigned int ADC_Value = 0;
boolean timer_fired=false;
// Black magic
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk((uint32_t)irq);
  TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
  uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above
  TC_SetRA(tc, channel, rc/2); //50% high, 50% low
  TC_SetRC(tc, channel, rc);
  TC_Start(tc, channel);
  tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
  tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
  NVIC_EnableIRQ(irq);
}

void setup(){
  // Start timer. Parameters are:

  // TC1 : timer counter. Can be TC0, TC1 or TC2
  // 0   : channel. Can be 0, 1 or 2
  // TC3_IRQn: irq number.
  // 250 : frequency (in Hz)
  // The interrupt service routine is TC3_Handler.
Serial.begin(57600);
  startTimer(TC1, 0, TC3_IRQn, 250);
}

void loop(){
  if (timer_fired)
  {
     ADC_Value = analogRead(0);
     Serial.print("D!");
     Serial.println(ADC_Value);
     timer_fired=false;
  }
}

volatile boolean l;

// This function is called every 1/250 sec.
void TC3_Handler()
{
  TC_GetStatus(TC1, 0);
  timer_fired=true;
}

owai

thank you very much, Stan12 !
I was searching for something like this too!