function [QRSwave]=ECGwaveGen(bpm,duration,fs,amp) %[QRSwave]=ECGwaveGen(bpm,dur,fs,amp) generates an artificial ECG/EKG waveform % Heart rate (bpm) sets the qrs event frequency (RR interval). % Duration of the entire waveform (dur) is in units of seconds. % Sample frequency (fs) sets the sample frequency in Hertz. % Amplitude (amp) of the QRS event is measured in micro Volts. % % There are two additional parameters that can be changed from within the function. % They are the parameters that set the QRS width (default 100ms) and the t-wave % amplitude (default 500 uV). %Created January 22, 2001 %Created by Floyd Harriott, primary email (fharriott@stellate.com), secondary email (fsh@po.cwru.edu) %Algorithm is based in part on the journal article: %Ruha, Antti and Seppo Nissila, "A Real-Time Microprocessor QRS Detector System with a 1-ms Timing Accuracy % for the Measurement of Ambulatory HRV", IEEE Trans. Biomed. Eng. Vol. 44, No. 3, 1997 %The artificial ECG signal they describe is based on the recommendations in the Association for the Advancement %of Medical Instrumentation (AAMI) "Standard for Cardiac Monitors, Heart Rate Meters and Alarms (draft), Aug. 1981 %Feel free to make modifications, corrections and or suggestions. if (exist('fs') ~= 1) fs= 200; end %default value, Hz if (exist('bpm') ~= 1) bpm = 72; end %default value, beats per minute if (exist('amp') ~= 1) amp = 1000; end %default value, micro volts if (exist('duration') ~= 1) duration = 60/bpm+1/fs; end %default value gives one cycle, seconds global t_line; %seconds global sample_freq; % always equal to fs %Changeable Parameters d=0.100; %.07 to .120 seconds, QRS width at=500; %amplitude of t-wave, 400 to 1200 uv %Should not have to modify sample_freq=fs; %duplicated simply to make a global version RR=(60/bpm); %RR interval, seconds d1=0.4375*d; d2=0.5*d; d3=d-(d1+d2); dt=0.180; %width of t wave, seconds qt=0.35; %time from beginning of QRS to end of t-wave t_line=0:1/fs:duration; %time line, seconds QRS_wave=zeros( size(t_line) ); %QRS waveform deadspace=RR-qt; %time between t-wave and next QRS if deadspace < 0 err_msg=['Bpm must be equal to or less than ' int2str(60/qt) ' .']; error(err_msg); end t1=deadspace; %Where does the first QRS start? if (t1+60/bpm+1/sample_freq > duration) err_msg=['Need more than ' int2str(t1+60/bpm+1/sample_freq) ' second(s) duration to display one cycle.']; error(err_msg); end while ( t1+60/bpm+1/sample_freq <= duration) %space to insert another qrs pulse in time line %Segment 1 (Q-R) qrs_start=t1; t2=t1+d1; i_t1=time2index(t1); i_t2=time2index(t2); left=0; right=0.875*amp; m1=(right-left)/(t2-t1); QRS1=m1*index2time(i_t1:i_t2)-(m1*t1-left); QRSwave(i_t1:i_t2)=QRS1; %Segment 2 (R-?) t1=t2; t2=t1+d2; i_t1=time2index(t1); i_t2=time2index(t2); left=right; right=-.125*amp; m2=(right-left)/(t2-t1); QRS1=m2*index2time(i_t1:i_t2)-(m2*t1-left); QRSwave(i_t1:i_t2)=QRS1; %Segment 3 bottom_top (?-S) t1=t2; t2=t1+d3; i_t1=time2index(t1); i_t2=time2index(t2); left=right; right=0; if (i_t2-i_t1 >0) %at low sampling freq. there may be no sample for this segment m3=(right-left)/(t2-t1); QRS1=m3*index2time(i_t1:i_t2)-(m3*t1-left); QRS1=QRS1( find(QRS1<=0)); QRSwave(i_t1:i_t1+size(QRS1,2)-1)=QRS1; elseif i_t2-i_t1==0 m3=(right-left)/(t2-t1); QRS1=m3*index2time(i_t1:i_t2)-(m3*t1-left); QRSwave(i_t1)=QRS1(1); end %Segment 4, S-T interval t1=t2; t2=t1+qt+qrs_start-(dt+t2); i_t1=time2index(t1); i_t2=time2index(t2); left=right; right=0; %Segment 5, t-wave t1=t2; t2=t1+dt; i_t1=time2index(t1); i_t2=time2index(t2); t=-1:2/(i_t2-i_t1):1; QRS1=at*sqrt(1-t.^2); QRSwave(i_t1:i_t2)=QRS1; %Segment 6, rest of deadspace t1=t2; t2=t1+deadspace; i_t1=time2index(t1); i_t2=time2index(t2); t1=t2; %end of this segment becomes beginning of next segment %stem(QRSwave); % view ECG waveform end %while loop, appending qrs pulses %_____________________________________% function index=time2index(t) %TIME2INDEX converts time (s) to an index value global t_line; indexArray=find(t_line>=t); index=indexArray(1); %_____________________________________% function time=index2time(i) %INDEX2TIME converts a time line index to a time value (seconds) global sample_freq time=(i-1).*1/sample_freq;