Sunday, May 13, 2018

Arduino IR Heart Rate Monitor - How to measure your heart rate using Arduino and simple electronics

Today I found a simple circuit that uses Arduino and simple electronic components to measure and visualize heart rate.



There are many circuits out there that uses Arduino boards and a special heart rate sensor.

Although I don't yet know the idea behind that heart rate sensor but I think it could be simple.

That's why I searched further until I could find this simple circuit in this post.

This circuit is so simple that it only contains Arduino board and IR transmitter and receiver as the heart rate sensor.

I know this is very simple and primitive, but it's efficient.

You can find many circuits with expensive sensors or larger circuits that use many amplifiers and OP-AMPs.

But this one is fairly simple and enough for the job.


Theory of operation
The IR (infrared) transmitter and receiver are used to measure the blood flow which corresponds to the heart rate.

The Arduino processor then processes the received signal and filters it to get a cleaner indication of the heart rate based on the blood flow in your finger.



Components
Arduino Uno 
IR emitter and detector
100 Ohm resistor
10K Ohm resistor



Connections



Circuit


Code

Arduino Code

#include
#include
#include
#include
#include
#include

float amplifiedSignal;
float filteredSignal;

void setup() {
  Serial.begin(9600);
}


// filter out frequencies below 1 Hz.
float highFilterFrequency = 1;  

// create a highpass filter that only keeps frequencies above highFilterFrequency
FilterOnePole filterOneHighpass( HIGHPASS, highFilterFrequency );  

// filters out frequenceies greater than 3 Hz.
float lowFilterFrequency = 3;  

// create a lowpass filter that only keeps frequencies below lowFilterFrequency
FilterOnePole filterOneLowpass(LOWPASS, lowFilterFrequency);  


void loop() {
  
//The next line applies a band pass filter to the signal

  amplifiedSignal = 100*analogRead(A0);
  filteredSignal = filterOneHighpass.input(filterOneLowpass.input(amplifiedSignal));

  Serial.println(filteredSignal);



}


Processing code

import processing.serial.*;

Serial myPort;        // The serial porthe
int xPos = 1;         // horizontal position of the graph 

//int xPos = millis()/1000;

//Variables to draw a continuous line.
int lastxPos=1;
int lastheight=0;

int screenWidth = 600;
int screenHeight = 400;

int pulseNumber = 0;
boolean pulseHigh = false;
int startTime;
int stopTime;
int heartRate;

void makeGrid(int screenWidth, int screenHeight){
  stroke(0,255,0);
  strokeWeight(0.5);
  line(0, screenHeight/2, screenWidth, screenHeight/2);
  
  for (int i = 0; i <= 10; i = i+1) {
    line(i*screenWidth/10, 0, i*screenWidth/10, screenHeight);
    line(0, i*screenHeight/10, screenWidth, i*screenHeight/10);
  }
}

void setup () {
  // set the window size:
  size(screenWidth, screenHeight);        

  // List all the available serial ports
  println(Serial.list());
  // Check the listed serial ports in your machine
  // and use the correct index number in Serial.list()[].

  myPort = new Serial(this, Serial.list()[0], 9600);  //

  // A serialEvent() is generated when a newline character is received :
  myPort.bufferUntil('\n');
  background(0);      // set inital background:
  
  makeGrid(screenWidth, screenHeight);
   
  
}
void draw () {
  // everything happens in the serialEvent()
}



void serialEvent (Serial myPort) {
  // get the ASCII string:
  String inString = myPort.readStringUntil('\n');
  if (inString != null) {
    inString = trim(inString);                // trim off whitespaces.
    float inByte = float(inString);           // convert to a number.
    
    if (inByte >= 0 && pulseHigh == false){
      if (pulseNumber == 0){
        startTime = millis();
        //println("first");
      }
      else{
        stopTime = millis();
      }
      pulseNumber = pulseNumber + 1;
      //println("next");
      pulseHigh = true;
    }
    
    else if (inByte <= 0 && pulseHigh == true){
      pulseHigh = false;
    }

    
    
    inByte = map(inByte, -1023, 1023, 0, height); //map to the screen height.
    
    //Drawing a line from Last inByte to the new one.
    stroke(255,0,0);     //stroke color
    strokeWeight(4);        //stroke wider
    line(lastxPos, lastheight, xPos, height - inByte); 
    lastxPos= xPos;
    lastheight= int(height-inByte);
    

    // at the edge of the window, go back to the beginning:
    if (xPos >= width) {
      xPos = 0;
      lastxPos= 0;
      background(0);  //Clear the screen.
      makeGrid(screenWidth, screenHeight);
      
      heartRate = 60*1000*(pulseNumber-1)/(stopTime-startTime);
      textSize(16);
      //text("This is your heart beat. Your heart rate is " + str(heartRate) + " bpm.", 10, 30); 
      //fill(0, 102, 153);
      
      pulseNumber = 0;
    } 
    else {
      // increment the horizontal position:
      xPos++;
    }
  }

}



Results






Source: Instructables


















No comments: