KY-039 Finger Detection Heartbeat Sensor with Arduino - A Beginner's Guide

1) Introduction & Working of KY-039

The KY-039 Finger Detection Heartbeat Measuring Sensor Module detects the pulse of a finger using an infrared (IR) LED and a phototransistor. When you place your finger on the sensor, the IR LED shines light through your finger, and the phototransistor detects the varying intensity of light caused by blood flow. This variation corresponds to heartbeats, which we can analyze using an Arduino.

Key features of KY-039:

2) Wiring Diagram with Arduino

Components Required:

Wiring Connections:

KY-039 Pin

Arduino Pin

VCC

5V

GND

GND

Signal

A0

External LED Pin

Arduino Pin

Cathode (-)

GND

Anode (+)

D7 (via 220Ω resistor)

3) Fully Commented Code for Heartbeat Detection

// KY-039 Heartbeat Sensor with Arduino

const int sensorPin = A0; // KY-039 Signal Pin connected to A0

int sensorValue = 0; // Variable to store sensor readings

void setup() {

    Serial.begin(9600); // Start Serial Monitor

}

void loop() {

    sensorValue = analogRead(sensorPin); // Read the sensor value

    Serial.println(sensorValue); // Print value to Serial Monitor

    delay(10); // Small delay for stable readings

}

4) Improving Readings with Signal Processing

To get more stable and meaningful data, we can use smoothing filters and peak detection algorithms. The following enhanced code calculates heart rate in beats per minute (BPM):

// KY-039 Heartbeat Sensor - Improved BPM Calculation with Smoothing

const int sensorPin = A0;

const int windowSize = 10; // Adjust this for smoother readings

int readings[windowSize];  // Array to store recent sensor values

int index = 0;

int total = 0;

int average = 0;

int threshold = 500;  // Adjustable based on sensor readings

unsigned long lastBeat = 0;

int beatCount = 0;

void setup() {

    Serial.begin(9600);

    for (int i = 0; i < windowSize; i++) readings[i] = 0; // Initialize array

}

void loop() {

    int sensorValue = analogRead(sensorPin);

   

    // Moving average calculation

    total -= readings[index];

    readings[index] = sensorValue;

    total += readings[index];

    index = (index + 1) % windowSize;

    average = total / windowSize;

    // Peak detection for BPM calculation

    if (average > threshold && millis() - lastBeat > 600) {

        beatCount++;

        lastBeat = millis();

        int bpm = (beatCount * 60000) / millis();

        Serial.print("Heartbeat detected! BPM: ");

        Serial.println(bpm);

    }

    Serial.println(average); // For Serial Plotter visualization

    delay(10);

}

5) Adding an LED Indicator for Each Heartbeat

An external LED is connected to D7 to visually indicate heartbeats. The LED will blink each time a heartbeat is detected.

const int sensorPin = A0;

const int ledPin = 7; // External LED for heartbeat indication

int threshold = 500;  

unsigned long lastBeat = 0;

void setup() {

    Serial.begin(9600);

    pinMode(ledPin, OUTPUT);

}

void loop() {

    int sensorValue = analogRead(sensorPin);

    if (sensorValue > threshold && millis() - lastBeat > 600) {

        digitalWrite(ledPin, HIGH); // LED ON when heartbeat detected

        lastBeat = millis();

        Serial.println("Heartbeat detected!");

    } else {

        digitalWrite(ledPin, LOW); // LED OFF

    }

    Serial.println(sensorValue);

    delay(10);

}

6) Viewing Data on Serial Monitor & Serial Plotter

Steps to View Serial Monitor:

  1. Upload the code to your Arduino board.
  2. Open Serial Monitor (Baud Rate: 9600).
  3. Place your finger on the KY-039 sensor and observe the changing values.

Steps to View Serial Plotter:

  1. Open Tools → Serial Plotter.
  2. Observe the graphical waveform corresponding to heartbeat variations.
  3. If the waveform is too noisy, adjust sensor placement and try different resistor values.

Enhanced Serial Plotter Code for Better Visualization

The following code provides a cleaner graph in Serial Plotter:

// KY-039 Heartbeat Sensor - Serial Plotter Visualization

const int sensorPin = A0;

int sensorValue = 0;

void setup() {

    Serial.begin(9600);

}

void loop() {

    sensorValue = analogRead(sensorPin);

    Serial.println(sensorValue); // Send values for real-time plotting

    delay(10);

}

7) Improved Heart Rate Detection with Smoothing & Thresholding

The following alternative approach uses a sample size averaging method to improve heartbeat detection accuracy:

#define samp_siz 4

#define rise_threshold 5

int sensorPin = A0;

void setup() {

    Serial.begin(9600);

}

void loop () {

    float reads[samp_siz], sum = 0;

    int ptr = 0, rise_count = 0;

    float before = 0, first = 0, second = 0, third = 0, print_value = 0;

    long last_beat = 0;

    bool rising = false;

    for (int i = 0; i < samp_siz; i++) reads[i] = 0;

    while (true) {

        int sensorValue = analogRead(sensorPin);

        sum -= reads[ptr];

        sum += sensorValue;

        reads[ptr] = sensorValue;

        float avg = sum / samp_siz;

        if (avg > before) rise_count++;

        if (!rising && rise_count > rise_threshold) {

            rising = true;

            first = millis() - last_beat;

            last_beat = millis();

            print_value = 60000.0 / (0.4 * first + 0.3 * second + 0.3 * third);

            Serial.println(print_value);

            third = second; second = first;

        } else { rising = false; rise_count = 0; }

        before = avg; ptr = (ptr + 1) % samp_siz;

    }

}

8) Final Thoughts

This tutorial provides a beginner-friendly way to use the KY-039 heartbeat sensor with Arduino. However, note that this sensor is not medically accurate and is best used for educational projects. If you want more accurate readings, consider using MAX30102 or Pulse Sensor Amped.

Now you can experiment with heartbeat sensing and even integrate it into bigger projects like fitness trackers or health monitoring systems! ❤️ Happy experimenting!