Heartbeat Sensor

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 13

Heartbeat Sensor is an electronic device that is used to measure the heart rate i.e.

speed of the

heartbeat. Monitoring body temperature, heart rate and blood pressure are the basic things that

we do in order to keep us healthy. In order to measure the body temperature, we use

thermometers and a sphygmomanometer to monitor the Arterial Pressure or Blood Pressure.

Heart Rate can be monitored in two ways: one way is to manually check the pulse either at wrists

or neck and the other way is to use a Heartbeat Sensor. In this project, we have designed a Heart

Rate Monitor System using Arduino and Heartbeat Sensor.

1. Introduction to Heartbeat Sensor

Monitoring heart rate is very important for athletes, patients as it determines the condition of the

heart (just heart rate). There are many ways to measure heart rate and the most precise one is

using an Electrocardiography But the more easy way to monitor the heart rate is to use a

Heartbeat Sensor. It comes in different shapes and sizes and allows an instant way to measure the

heartbeat. Heartbeat Sensors are available in Wrist Watches (Smart Watches), Smart Phones,

chest straps, etc. The heartbeat is measured in beats per minute or bpm, which indicates the

number of times the heart is contracting or expanding in a minute.


Figure 1: A typical Heartbeat Sensor

1.2 Principle of Heartbeat Sensor

The principle behind the working of the Heartbeat Sensor is Photoplethysmograph. According to

this principle, the changes in the volume of blood in an organ is measured by the changes in the

intensity of the light passing through that organ. Usually, the source of light in a heartbeat sensor

would be an IR LED and the detector would be any Photo Detector like a Photo Diode, an LDR

(Light Dependent Resistor) or a Photo Transistor. With these two i.e. a light source and a

detector, we can arrange them in two ways: A Transmission Sensor and a Reflective Sensor.

In a Transmission Sensor, the light source and the detector are place facing each other and the

finger of the person must be placed in between the transmitter and receiver.
Reflective Sensor, on the other hand, has the light source and the detector adjacent to each other

and the finger of the person must be placed in front of the sensor.

1.3 Working of Heartbeat Sensor

The heart beat sensor circuit diagram comprises a light detector and a bright red LED. The LED
needs to be of super bright intensity because maximum light passes and spreads if a finger placed
on the LED is detected by the detector.

Figure 2 Principle of Heartbeat sensor

Now, when the heart pumps blood through the blood vessels, the finger becomes slightly more
opaque; due to this, less amount of light reaches from the LED to the detector. With every heart
pulse generated, the detector signal gets varied. The varied detector signal is converted into an
electrical pulse. This electrical signal gets amplified and triggered through an amplifier which
gives an output of +5V logic level signal. The output signal is also directed by a LED display
which blinks on each heartbeat rate.

A simple Heartbeat Sensor consists of a sensor and a control circuit. The sensor part of the

Heartbeat Sensor consists of an IR LED and a Photo Diode placed in a clip. The Control Circuit
consists of an Op-Amp IC and few other components that help in connecting the signal to a . The

working of the Heartbeat Sensor can be understood better if we take a look at its circuit diagram.

Figure 3: Circuit Diagram of Sensor

The above circuit shows the finger type heartbeat sensor, which works by detecting the pulses.

Every heartbeat will alter the amount of blood in the finger and the light from the IR LED

passing through the finger and thus detected by the Photo Diode will also vary.

The output of the photo diode is given to the non – inverting input of the first op – amp through a

capacitor, which blocks the DC Components of the signal. The first op – amp cats as a non –

inverting amplifier with an amplification factor of 1001.

The output of the first op – amp is given as one of the inputs to the second op – amp, which acts

as a comparator. The output of the second op – amp triggers a transistor, from which, the signal

is given to a like Arduino.


The Op – amp used in this circuit is LM358. It has two op – amps on the same chip. Also, the

transistor used is a BC547. An LED, which is connected to transistor, will blink when the pulse

is detected.

1.4 Circuit of Arduino based Heart Rate Monitor using Heartbeat Sensor

The following image shows the circuit diagram of the Heart Rate Monitor using Heartbeat

Sensor. The sensor has a clip to insert the finger and has three pins coming out of it for

connecting VCC, GND and the Data.


1.5 Components Required

 Atmega Microcontroller

 16 x 2 LCD Display x 1

 10KΩ Potentiometer

 330Ω Resistor (Optional – for LCD backlight)

 Push Button

 Heartbeat Sensor Module with Probe (finger based)

 PCB

 Connecting Wires

1.6 Circuit Design of Interfacing Heartbeat Sensor with Arduino

The circuit design of Arduino based Heartrate monitor system using Heart beat Sensor is very

simple. First, in order to display the heartbeat readings in bpm, we have to connect a 16×2 LCD

Display to the Arduino UNO.

The 4 data pins of the LCD Module (D4, D5, D6 and D7) are connected to Pins 1, 1, 1 and 1 of

the Arduino UNO. Also, a 10KΩ Potentiometer is connected to Pin 3 of LCD (contrast adjust

pin). The RS and E (Pins 3 and 5) of the LCD are connected to Pins 1 and 1 of the Arduino
UNO. Next, connect the output of the Heartbeat Sensor Module to the Analog Input Pin (Pin 1)

of Arduino.

1.7 Working of the Circuit

Upload the code to Atmega and Power on the system. The Arduino asks us to place our finger in

the sensor and press the switch. Place any finger (except the Thumb) in the sensor clip and push

the switch (button). Based on the data from the sensor, Arduino calculates the heart rate and

displays the heartbeat in bpm. While the sensor is collecting the data, sit down and relax and do

not shake the wire as it might result in a faulty values. After the result is displayed on the LCD, if

you want to perform another test, just push the rest button on the Arduino and start the procedure

once again.
Program Code:

#include <LiquidCrystal.h>

// Variables
int pulsePin = 0; // Pulse Sensor purple wire connected to analog pin 0
int blinkPin = 13; // pin to blink led at each beat
int fadePin = 8; // pin to do fancy classy fading blink at each beat
int fadeRate = 0; // used to fade LED on with PWM on fadePin

LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

// Volatile Variables, used in the interrupt service routine!


volatile int BPM; // int that holds raw Analog in 0. updated every 2mS
volatile int Signal; // holds the incoming raw data
volatile int IBI = 600; // int that holds the time interval between beats! Must be seeded!
volatile boolean Pulse = false; // "True" when User's live heartbeat is detected. "False" when
not a "live beat".
volatile boolean QS = false; // becomes true when Arduoino finds a beat.

// Regards Serial OutPut -- Set This Up to your needs


static boolean serialVisual = true; // Set to 'false' by Default. Re-set to 'true' to see Arduino
Serial Monitor ASCII Visual Pulse

volatile int rate[10]; // array to hold last ten IBI values


volatile unsigned long sampleCounter = 0; // used to determine pulse timing
volatile unsigned long lastBeatTime = 0; // used to find IBI
volatile int P = 512; // used to find peak in pulse wave, seeded
volatile int T = 512; // used to find trough in pulse wave, seeded
volatile int thresh = 525; // used to find instant moment of heart beat, seeded
volatile int amp = 100; // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true; // used to seed rate array so we startup with reasonable
BPM
volatile boolean secondBeat = false; // used to seed rate array so we startup with reasonable
BPM

void setup()
{
pinMode(blinkPin,OUTPUT); // pin that will blink to your heartbeat!
pinMode(fadePin,OUTPUT); // pin that will fade to your heartbeat!
Serial.begin(9600); // we agree to talk fast!
lcd.begin(16,2);
interruptSetup(); // sets up to read Pulse Sensor signal every 2mS
// IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS
THAN THE BOARD VOLTAGE,
// UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE
TO THE A-REF PIN
// analogReference(EXTERNAL);
}

// Where the Magic Happens


void loop()
{
serialOutput();

if (QS == true) // A Heartbeat Was Found


{
// BPM and IBI have been Determined
// Quantified Self "QS" true when arduino finds a heartbeat
fadeRate = 255; // Makes the LED Fade Effect Happen, Set 'fadeRate' Variable to 255 to fade
LED with pulse
serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
QS = false; // reset the Quantified Self flag for next time
}

ledFadeToBeat(); // Makes the LED Fade Effect Happen


delay(20); // take a break
}

void ledFadeToBeat()
{
fadeRate -= 15; // set LED fade value
fadeRate = constrain(fadeRate,0,255); // keep LED fade value from going into negative
numbers!
analogWrite(fadePin,fadeRate); // fade LED
}

void interruptSetup()
{
// Initializes Timer2 to throw an interrupt every 2mS.
TCCR2A = 0x02; // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC
MODE
TCCR2B = 0x06; // DON'T FORCE COMPARE, 256 PRESCALER
OCR2A = 0X7C; // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
TIMSK2 = 0x02; // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND
OCR2A
sei(); // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}

void serialOutput()
{ // Decide How To Output Serial.
if (serialVisual == true)
{
arduinoSerialMonitorVisual('-', Signal); // goes to function that makes Serial Monitor
Visualizer
}
else
{
sendDataToSerial('S', Signal); // goes to sendDataToSerial function
}
}

void serialOutputWhenBeatHappens()
{
if (serialVisual == true) // Code to Make the Serial Monitor Visualizer Work
{
Serial.print("*** Heart-Beat Happened *** "); //ASCII Art Madness
Serial.print("BPM: ");
Serial.println(BPM);
if (BPM<=150 && BPM>=40)
{
lcd.clear();
lcd.print("BPM: ");
lcd.print(BPM-30+10);
}
}
else
{
sendDataToSerial('B',BPM); // send heart rate with a 'B' prefix
sendDataToSerial('Q',IBI); // send time between beats with a 'Q' prefix
}
}

void arduinoSerialMonitorVisual(char symbol, int data )


{
const int sensorMin = 0; // sensor minimum, discovered through experiment
const int sensorMax = 1024; // sensor maximum, discovered through experiment
int sensorReading = data; // map the sensor range to a range of 12 options:
int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
// do something different depending on the
// range value:
switch (range)
{
case 0:
Serial.println(""); /////ASCII Art Madness
break;
case 1:
Serial.println("---");
break;
case 2:
Serial.println("------");
break;
case 3:
Serial.println("---------");
break;
case 4:
Serial.println("------------");
break;
case 5:
Serial.println("--------------|-");
break;
case 6:
Serial.println("--------------|---");
break;
case 7:
Serial.println("--------------|-------");
break;
case 8:
Serial.println("--------------|----------");
break;
case 9:
Serial.println("--------------|----------------");
break;
case 10:
Serial.println("--------------|-------------------");
break;
case 11:
Serial.println("--------------|-----------------------");
break;
}
}

void sendDataToSerial(char symbol, int data )


{
Serial.print(symbol);
Serial.println(data);
}

ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124


{
cli(); // disable interrupts while we do this
Signal = analogRead(pulsePin); // read the Pulse Sensor
sampleCounter += 2; // keep track of the time in mS with this variable
int N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid noise
// find the peak and trough of the pulse wave
if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
{
if (Signal < T) // T is the trough
{
T = Signal; // keep track of lowest point in pulse wave
}
}

if(Signal > thresh && Signal > P)


{ // thresh condition helps avoid noise
P = Signal; // P is the peak
} // keep track of highest point in pulse wave

// NOW IT'S TIME TO LOOK FOR THE HEART BEAT


// signal surges up in value every time there is a pulse
if (N > 250)
{ // avoid high frequency noise
if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
{
Pulse = true; // set the Pulse flag when we think there is a pulse
digitalWrite(blinkPin,HIGH); // turn on pin 13 LED
IBI = sampleCounter - lastBeatTime; // measure time between beats in mS
lastBeatTime = sampleCounter; // keep track of time for next pulse

if(secondBeat)
{ // if this is the second beat, if secondBeat == TRUE
secondBeat = false; // clear secondBeat flag
for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
{
rate[i] = IBI;
}
}

if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE


{
firstBeat = false; // clear firstBeat flag
secondBeat = true; // set the second beat flag
sei(); // enable interrupts again
return; // IBI value is unreliable so discard it
}
// keep a running total of the last 10 IBI values
word runningTotal = 0; // clear the runningTotal variable
for(int i=0; i<=8; i++)
{ // shift data in the rate array
rate[i] = rate[i+1]; // and drop the oldest IBI value
runningTotal += rate[i]; // add up the 9 oldest IBI values
}

rate[9] = IBI; // add the latest IBI to the rate array


runningTotal += rate[9]; // add the latest IBI to runningTotal
runningTotal /= 10; // average the last 10 IBI values
BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM!
QS = true; // set Quantified Self flag
// QS FLAG IS NOT CLEARED INSIDE THIS ISR
}
}

if (Signal < thresh && Pulse == true)


{ // when the values are going down, the beat is over
digitalWrite(blinkPin,LOW); // turn off pin 13 LED
Pulse = false; // reset the Pulse flag so we can do it again
amp = P - T; // get amplitude of the pulse wave
thresh = amp/2 + T; // set thresh at 50% of the amplitude
P = thresh; // reset these for next time
T = thresh;
}

if (N > 2500)
{ // if 2.5 seconds go by without a beat
thresh = 512; // set thresh default
P = 512; // set P default
T = 512; // set T default
lastBeatTime = sampleCounter; // bring the lastBeatTime up to date
firstBeat = true; // set these to avoid noise
secondBeat = false; // when we get the heartbeat back
}

sei(); // enable interrupts when youre done!


}// end isr

You might also like