KY039 Arduino Heart rate code

OK, this is my first post! 8)

I just got a very similar board, and the discussion here allowed me to confirm how it can be connected since the pinout is not very clearly printed.

I managed to tweak generic ebay code after looking at the output to generate a somewhat responsive heart monitor code. Since there is no amplification, the resolution of the signal is very low, since the dynamic range is small while the finger is on the sensor (960~967), but it is enough to get a coarse heart rate signal (see included graph for about 2 sec of data).

The solution is to do a simple peak detection, done by finding the max, decaying it and resetting it when a new peak is found. The code blips the LED and also outputs to the serial console.

If you rest the sensor without pressing hard, and you don't move, you get a heartbeat display, with some beats missed or duped.

The bottom line is with proper filtering code this thing can work.

I have yet to find a use for it as a sensor to activate fun stuff, but I'm not sure I care to make this a real heart rate monitor. It would not be convenient anyways as it is as cumbersome as an oxymeter.

That said this is an infrared detector with a light source. There must be something I can do with that.

Note: I tried to take a photo of the rig to see the infrared beam, and I could not see it.

int ledPin=13;
int sensorPin=0;

float alpha=0.75;
int period=50;
float change=0.0;

void setup()
{
  // Built-in arduino board pin
  pinMode(ledPin,OUTPUT);

  Serial.begin(9600);
  Serial.print("Heartrate detection.\n");
  delay(100);
}

float max =0.0;

void loop()
{
  static float oldValue=1009;
  static float oldChange=0.2;

  // This is generic code provided with the board.
  int rawValue=analogRead(sensorPin);
  float value= alpha*oldValue +(1-alpha)* rawValue;
  change=value-oldValue;

  // Display data on the LED via a blip:
  // Empirically, if we detect a peak as being X% from
  // absolute max, we find the pulse even when amplitude
  // varies on the low side.
  
  // Reset max every time we find a new peak
  if (change >= max) {
    max= change;
    Serial.println("  |");
    digitalWrite(ledPin,1);
  } else {
    Serial.println("|");
    digitalWrite(ledPin,0);
  }
  // Slowly decay max for when sensor is moved around
  // but decay must be slower than time needed to hit
  // next heartbeat peak.
  max = max * 0.98;
  
  // Display debug data on the console
//  Serial.print(value);
//  Serial.print(", ");
//  Serial.print(change);
//  Serial.print(", ");
//  Serial.println(max);

  oldValue=value;
  oldChange=change;
  delay(period);
}

heartrateRawData.png