Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

ECG recording, storing, filtering and recognition

, 14 Apr 2004
Rate this:
Please Sign up or sign in to vote.
Full open code project for making driver and application software for ECG medical measurements.

Before I start, I would like to excuse myself about my poor English skills, my writing, and bad quality of the published materials. But this is done because writing is a time consuming job, and when it is on English… I think you will understand me.

Introduction

This program is a full ended open code project. It concerns to long time medical ECG single channel record & one additional sensor record - signal from velo test power generator. You can find code for how you can build your drivers without using DMA controller, this is very good for data acquisition systems just like medical ECG recorders. To use this code, you need to compile all 3 DLL files:

  • driver
  • visualization

On the end of this work, compile the application program using just built DLL files. So, use a demo file to see what it can do for you. Application can make DSP on the input signal and can detect ECG QRS-PR-QT segments.

Electro Cardio Graph or simply ECG (EKG) is a very useful medical instrument, its purpose is to help doctors easily diagnose human or animals' heart activity and to detect abnormal functions of the heart muscle.

Today, it is not so difficult to construct such a device, but there are many standards concerned to human safety (direct & indirect) especially for intensive health care usage. So, I don’t mind to talk about them! But there are many other ECG applications, such as rehabilitation holter monitors (long time ECG recorders), remote holter monitors and some sports applications such as veloergometry ECG testers. The last application can be met in many types and varieties from special MEDICAL to ACTIVE TRAINER ECG TESTERS.

"ECG_1" software is concerned to sport ECG veloergometry. Researches that can be made using such a software and non professional ECG instrumentation PC card can help a lot for these people (students) who are interested in these fields: sports, medicine, medical electronics and much more. The main purpose of the project is not to construct and design software and hardware; there is a bigger objective! Creating free, fully opened, database for medical (physiological) chemical, electrical and image records. I know, this is already done in big hospitals and universities, but it is still too hard for beginner students and any others to get this information correct and free! In addition, I think that this one must be corrected! Why? Because making an object oriented medical (sports & physiological) database system containing different long time records and results, such as veloergometry, can be very helpful for research (not only for students). This is my opinion, you may have another, but let's begin!

ECG signal. Before you try to understand the software, I think that it is necessary to explain some of the parameters of the normal ECG signal. This signal contains the main segments: P, Q, R, S, T, c. You can see them on the next picture. Red line fixes the QRS time interval; it was made in software to help to see the time segments in the electrocardiogram.

Sample image

For humans, it is not so difficult to detect them on the paper, and I maintain that is not so difficult to show the PC to recognize them. In standard electrocardiography, we use 12 recording channels, but in veloergometry applications, they are limited to one – this signal is used to detect the heart rate/min. and to detect some rhythm anomalies? – Search in the web for: “ECG time interval variability data”. All these features are included in the ECG_1 main project – class DSP_ECG. Here, I’ll try to explain the first and the main detection technique, QRS segment detection.

Because I suppose that sportiest are normally healthy people, and probably have normal electrocardiograms in this first “ECG_1” version, for fast implementation of the project, I used simplified QRS detecting algorithm, see below:? www.dsp.com?

  1. We will push the raw ECG input signal through a system of filters – see class DSP_Filter.
    1. Use noht filter function to remove 50 or 60 Hz power line signal – see void DSP_Filter::RFilter_Noht and void DSP_Filter::WFilter_Noht functions or use them directly.
    2. Use a low pass filter. If it is necessary, first try to use 100Hz low pass filter – see void DSP_Filter::WFilter_Low100Hz, and if this filtration can’t give the proper quality, use 40Hz low pass filter void DSP_Filter::WFilter_Low40Hz. Using lower filtration length is not recommended because most popular ECG measurements have an interest of the signal spectrum 0.67Hz – 40Hz.
  2. After proper filtration, ECG signal is ready to be detected.
    1. First we will find the first difference of the ECG signal – this is done by next code:

      X contains a filtered ECG signal array. Y contains a first difference of the ECG signal (X & Y are dynamic double precision arrays).

      for( i=0;i<length++;i++){*(Y+i) = *(X+i+1) - *(X+i);}
  3. Therefore, this was the beginning! Now is the main algorithm, QRS detection. As I mentioned before in the picture above and as you can see, the standard QRS complex contains high amplitude (approximately 0.5-3mV) short time deviation impulse (50-200ms). From the main ECG waveform, it is simple to recognize QRS complex. We will make this using first difference of the ECG signal (array Y). This is done by finding the standard deviation of the signal – using double DSP_Filter::StandardDeviation. This function returns the standard deviation of the double array signal. Using this result and going through the Y array, we will mark all points of this array that have values greater than “1.2*deviation”:
    dev = dev*1.2;
        for(i=0;i<lenght-1;i++)
        {    D = arD1[i];
            Delta[i] = D;
            if(D>dev)
            *(AR_MINMAX+i) = 2;
            if(D<-dev)
            *(AR_MINMAX+i) = -2;
        }

    There is a great chance that QRS segments are represented by these bigger differences, but this is not all!

  4. Finally, we have marker array (AR_MINMAX), that show to us points with bigger + & - deference (>1.2*dev). Using the array (AR_MINMAX), we go to the next step of our simplified algorithm, decide what is QRS and what is not. Independent of the low pass filtering (<40hz), in the ECG delta array Y, may be met some disturbances (caused by physiological or physical external sources) that can produce single deviations bigger than standard (“dev”). Moreover, if we suppose that each maximum value in the Y array is QRS, we will fall in a trap. As you can see from the picture above, QRS is not a single pulse of logical “1”, QRS is a composite waveform, containing many bigger than standard deviation values with values + & -. Rest on this supposition, and some statistical information, QRS complex can be any series (at least 3 or 4) containing bigger deviation than standard “dev Y”. (This is a very simplified algorithm, but it really works, and can be used in large varieties of ECG signals after proper filtering).

    This is done in the following lines of code:

    do{ i++;d_count++; } while(*(AR_MINMAX+i)==2); if(d_count>3) //we have QRS

In the next steps of the function int DSP_ECG::QRS_COUNT, we are finding and fixing the maximum of R wave, minimum of S, and minimum of Q. Because the algorithm is not simplified yet, I’m not going to explain it, but it works.

There are many students at technical universities all over the world, and there are many standard projects to do. But the main difficulty for these my mates is how to show their projects working! It is too difficult when all that you study is not concerned about how to make market compatible solutions, even if they are laboratory samples. To make your hardware working on a standard PC is a nasty work. To build sample test hardware is not the same as to write drivers, and further more applications to use them. But in many cases, it is enough to write a simple program to show your concepts on possible customers or colleagues. It is very funny to see a completed project; just ready to fly in space, but using Excel graphs to show its operation /just like my article/.

To complete this point, it is too important to know that writing a test driver for new hardware is a very easy thing, and the main point is that you can write your drivers without sophisticated Windows DDK! You can spare long days and nights doing Windows Driver fully compatible with Windows architecture, and just like my time yours will be totally lost. In some cases, you can use this type of driving for completed version of your program.

When you can use this driving model?

  1. To test your hardware ports and functions, just like typing port driver for sound card in DOS.
  2. To test and to use low speed ADC, DAC modules connected to your LPT port.

Why using LPT for your projects?

Before you start vituperating me, think about the things listed below!

First, there are many easy to program hardware chips, and it is easy to make them do something for you without using expensive PIC or DSP. In many cases, migrating your code from PC to programmable chips is a standard work; so all you beginning “scientists” can avoid this boring work. Many companies prefer to rewrite all your code, do not think that your project will be pat on the market just as you created it! If you use LPT, it is easy to emulate all serial protocols (RS232, 484, SPI, I2C, CAN and much more!). And last but not least, buying an LPT-PCI card is much cheaper (10-12$) than buying multi (10-12) port I/O periphery (50-100$).

Troubleshooting things concerned to “LPT driver”

As I said before, direct “porting” may be impossible when testing high-speed hardware, like video adapters or CCD camera – the data rate must be bigger, standard LPT byte rate is maximum 1MB/s. But even then, you can make a simple “show” application. It is a big mistake to start designing of PC periphery signal converters trying to make your hardware compatible with USB or RS232. Do not shame to say, “I can't drive code for PIC to implement USB routines”, this is a standard procedure, someone can write it for you for less then 10$!

When it is possible, how to use it in real time applications?

Before you start building time dependent applications and hardware, remember one thing:

Using direct porting on Windows is possible when using Windows Multimedia Timers, and maximum speed you can get is 1000 times per second! /Be sure that your driver code can hold within timer events/. Read the source code for drvECG_1.dll, if you have questions I’ll try to answer you. The main driving process is to set multimedia timer (see timeSetEvent() function) to clock on needed time, and to specify attached to it “driver” function – it must be static defined (using _inp(), _outp() statements – see conio.h). It is better to make a private data block to store data coming from your chip. When sampling process is done, you can activate a callback function in your application to remove data in main processing program, or simply to store it in multimedia file or DSP it.

Concrete, driver attached to ECG project source files have some evil features at this moment, it makes memory lay out after closing the program – 1MB! It is important to know this before using, but it works. This is because in drvECG_1.dll file, there is static declared function; soon I’ll try to correct it. All ECG driver code must work on Windows 95/98; for NT, XP you may need to use special I/O DLL files, search in the web for “DriverLINX”. I think that Windows 98 is better for research projects like mine.

QRS segment detection

Sample image

QT segment detection

Sample image

PR segment detection

Sample image

You can recalculate all records for better detecting. If you want, it is possible to add more recalculating properties in this dialog.

Sample image

Program can store measurements in single files, all information is so-so compatible with ECG-SPC standard for medical records.

Sample image

Sample image

You can review all statistical information concerned to your records - tests. First and main, you can see the heart-rate in time-black line. Second, you can see the veloergometer power sensor-red line.

Sample image

After long time recording, there may be errors in your automatic report, so you can confirm your diagnosis, and this confirmation will be stored in your file.

Sample image

It is too long to explain how it works, read about this soon, just see! If you have problems with compiling & if you need more test files, write to me just now, I'll try to send you some records.

For this moment, I have a problem with saving BMP graphs, so if you can help, I'll be very thankful. Additional problem is that I cant understand FFT, so the DSP functions are a little slow, but they work good for this time. Finally, the ECG program was done for 20 days, including drivers and application. When you use it on Win95/98, you will see that it use much memory...

You can use this code in your applications, however you want! But I can't take any responsibility for its use!

So, get it and test it...

Because this is an open code project, the hardware construction is too open. And now here it is...

Sample image

And this is scanned PCB with mounted elements. Sorry about the picture quality, but it was scanned after mounting in a box.

Sample image

This is my isolation, it is cheap 1chp 6N137 ~ 0.5$

Sample image

This is 6N137 chip inside.

Sample image

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Georgi Petrov
Instructor / Trainer
Bulgaria Bulgaria
PhD, Cum Laude in digital automation systems
M.S. in Telemommunication management
B.S. in Telecommunication systems engineering
Programming: CUDA, C/C++, VHDL
Software and Hardware development and consulting:
data acquisition, image processing, medical instrumentation

Comments and Discussions

 
QuestionHow to use the isolation PinmemberMember 468562029-Sep-10 23:18 
GeneralMIT-BIH Arrhythmia Database PinmemberM.Siyamalan4-Jun-10 7:39 
QuestionMath. formula(s) for ECG emulation? PinmemberWilfredoWilly14-Oct-09 8:37 
AnswerRe: Math. formula(s) for ECG emulation? PinmemberNick Alexeev27-Feb-10 15:46 
Generalinfo about driver Pinmemberhadlerz16-Aug-09 0:59 
GeneralDifferent sampling rate Pinmembernicomaco16-Jun-09 23:29 
GeneralMuscle flutter filter Pinmemberlgsaq11-Apr-09 21:11 
GeneralAtoD Resolution Pinmembertorcomp11-Dec-08 6:37 
QuestionKnow about circuit Pinmemberanikash200320-Jul-08 20:27 
AnswerRe: Know about circuit Pinmemberdisokgone13-Jun-09 23:58 
Generalyou are for hire PinmemberMember 403393623-Apr-08 22:19 
GeneralRe: you are for hire PinmemberGeorgi Petrov23-Apr-08 22:31 
GeneralChange from LTP to RS232 PinmemberMember 403393622-Apr-08 12:18 
GeneralRe: Change from LTP to RS232 PinmemberGeorgi Petrov23-Apr-08 1:29 
Questionbluetooth and wi-fi PinmemberMember 46135579-Apr-08 5:52 
GeneralRe: bluetooth and wi-fi PinmemberGeorgi Petrov9-Apr-08 20:47 
Generalhai georgi petrov Pinmembernor haryanti20-Jan-08 3:48 
GeneralNeed more help for compiling Pinmemberaa_esa23-Nov-07 17:43 
GeneralSchematic PinmemberNick Alexeev6-Nov-07 11:48 
GeneralCompiling Pinmemberjayesch28-Oct-07 18:15 
GeneralRequire more ECG Test File Pinmembershtoh4-Oct-07 16:35 
Generalneed for help Pinmemberapabaelah15-May-07 16:18 
GeneralRe: need for help PinmemberGeorgi Petrov15-May-07 21:52 
Generalquery Pinmembersuruchiwriter18-Apr-07 22:47 
Questionwincore.cpp Pinmembervarunbeckons11-Mar-07 23:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140922.1 | Last Updated 15 Apr 2004
Article Copyright 2003 by Georgi Petrov
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid