Project 16 - An ECG (Heart Rate)Display

<< Click to Display Table of Contents >>

Navigation:  Projects >

Project 16 - An ECG (Heart Rate)Display

This project creates a Heart Rate Sensor using the MikroElectronica Heart Rate Click. CleO is used to display the current heart rate to plot the real-time sensor data and play a wave file on each detected beat. The Heart Rate Click, in turn, uses the MAX30100 Pulse Oximeter sensor. The Heart Rate Click is connected to the CleO IO hardware.

 

 

Component(s)

 

This project uses the following component(s) -

 

Mikroe Heart Rate

CleO IO

56mm, 80hm 0.5W(RMS) / 1W(Peak) Internal CleO speaker

 

 

Wiring Diagram

 

 

Heartrate schematic

 

 

Hardware Setup

 

The pictures below shows a Mikroe heart rate click mounted on the Arduino UNO click shield which is mounted on an Arduino module (in this example it is on a NerO Module). The speaker is connected to the CleO35 module.

 

Project 16A

 

Project 16B

 

 

Code

 

The Setup() routine initializes the CleO display and configures the HR Click for 100 SPS. An image of the heart is loaded into the CleO memory from the onboard flash, shown in the below code snippet.

 

/* Initializes the CleO display and configures the HR Click for 100 SPS. An image of a heart is loaded into CleO memory from the on-board flash. */

void setup()

{

 CleO.begin();

 CleO.Start();

 CleO.Show();

 CleO.DisplayRotate(2, 0);

 Wire.begin();

 Wire.setClock(400000L);

 

  /* Load the heart bitmap */

 heart = CleO.LoadImageFile("@Pictures/heart.jpg", 0);

/* Initialize plot and algorithm internal state */

 Filt.DC(0, true);

 SampleAvg.Update(0, true);

 DispAvg.Update(0, true);

 Filt.Peak(0, 0, NULL, true);

 Filt.Decide(0, 0, true);

 plot_helper(0, true);

 error = (Click.Init() == true)? false : true; /* Set error flag if init fails */

 invalidate = true; /* force update display once (even if sensor is not present) */

}

 

The loop() routine polls the sensor for any new data. Each sample is filtered and passed through a peak detector algorithm. The display is refreshed for every new sample, and if a peak was detected, the heart image is animated, and a wave file is played. The average value of the Heart Rate is also shown on the screen. The size of the display buffer is 64 samples.

 

The signal processing algorithm to detect the new peaks are as follows:

 

1.Filter the DC offset from the signal using a differentiator followed by a leaky integrator.

2.Average over a moving window of 12 samples

3.Find the peak of the resulting waveform

4.Check if the peak is above an adaptive threshold to classify it as a valid peak, else reject it.

 

The usage of loop() routine is given in the following code snippet -

 

void loop() {

 

 /* Read the latest raw samples from the Sensor and check if a new peak is detected */

 process_click();

 /* The display is only updated if a new sample is gathered.*/

 if (!invalidate) return;

 

  /* Normalize the raw samples so that they will fit into the display screen */

 process_graph();

 

  /* Play a sound if a new beat is detected */

 if (Beat == true) CleO.AudioPlay("@Music/beat.wav", PLAY_ONCE);

 invalidate = false;

 CleO.Start(); /* Plot the graph, animate heart and display new HR */

 CleO.LineWidth(3);

 CleO.LineColor(RED);

 for (int i = 0; i < PLOT_SIZ - 1; i++) {

  /* Don't connect the new signal with the old values in the buffer! */

   if (i != (sampleIdx - 1))

     CleO.Line(XTicks[i], dispBuffer[i], XTicks[i + 1], dispBuffer[i + 1]);

 }

/* Get the average heart rate */

 int hr = HRAvg.GetAvg();

 if ((hr < HR_MAX) && (hr > HR_MIN)) HRDisp = hr;

/* Animate the Heart */

 if ((Beat == true) && (ha == LAST)) ha = 0;

 else if (ha != LAST) ha++;

 Beat = false;

 /* Select a factor for this cycle */

 CleO.BitmapTransform(anims[ha] / 8., 0);

 

  /* Change the heart color to white for 2 cycles */

 CleO.BitmapColor((ha < 2) ? WHITE : 0xff2020);

 CleO.BitmapJustification(MM);

 /* Locate the image at (X,Y) = (480 - 162 / 2, 100)*/

 CleO.Bitmap(heart, HEART_X, HEART_Y);

 /* Display the numerical value of the Heart Rate */

 char buf[4];

 sprintf(buf, "%d", HRDisp);

 /* Use the largest font and display string at (X,Y) = (480-162/2, 230) */

 CleO.StringExt(FONT_HUGE, BPM_X, BPM_Y, 0xffffffUL, MM, 0, 0, buf);

 if(error)

 CleO.StringExt(FONT_TINY, 0, 320, RED, BL, 0, 0, "No Heart Rate Click detected");

 CleO.Show(); /* End display update */

}

 

Note: If no hardware is detected, then an appropriate error message is displayed.

 

 

Output

 

 

Project 16 - An ECG Heart Rate Display