This experiment aims to measure the heartbeat using a photodiode-based heartbeat sensor and a Raspberry Pi Pico microcontroller. The photodiode detects changes in light intensity caused by blood flow in the fingertip, converting these changes into an electrical signal that the microcontroller processes to count heartbeats.
Scope:
The scope of this experiment includes:
Understanding how a photodiode works in the context of a heartbeat sensor.
Connecting the sensor to a Raspberry Pi Pico and programming it to count and display heartbeats.
Exploring applications of heartbeat monitoring in health and fitness
Prerequisite:
3.1. Hardware:
Pico microcontroller
Heart beat module
Breadboard
Jumper wires
USB cable (to connect the computer)
3 .2. Software:
Thonny Software(For micro python)
MicroPython firmware installed on Raspberry Pi Pico
ubuntu Terminal(For embedded C)
CMake,Pico SDK,GNU Arm Embedded Toolchain,WSL.
Connection Details:
Heartbeat Module Connections:
Connect the VCC pin of the heartbeat module to the 3.3V pin on the Pico.
Connect the GND pin of the heartbeat module to the GND pin on the Pico.
Connect the O/P (Output) pin of the heartbeat module to ADC GPIO 26 (or any other analog pin).
UART Serial Console: Use a micro-USB cable to connect the Pico to the PC, then open PuTTY and select the correct COM port and baud rate (115200).
Working Principle:
The heartbeat sensor utilizes a photodiode to measure the light reflected by the blood in the fingertip. As the heart beats, blood flow in the fingertip varies, causing changes in light absorption and reflection. The photodiode converts these variations into an electrical signal, which is read by the Raspberry Pi Pico's analog-to-digital converter (ADC). By setting a threshold, the microcontroller counts the number of beats over a defined period (e.g., one minute).
Application code:
MicroPython:
import machine
import time
# Define ADC pin (GPIO 26)
adc = machine.ADC(26)
# Threshold to detect heartbeats
threshold = 2000
# Variables to count heartbeats
beat_count = 0
start_time = time.time()
while True:
# Read analog value from heartbeat sensor
adc_value = adc.read_u16() # 16-bit value (0-65535)
if adc_value > threshold:
beat_count += 1
time.sleep(0.3) # Small delay to avoid counting the same beat multiple times
# Calculate beats per minute (BPM) every 60 seconds
elapsed_time = time.time() - start_time
if elapsed_time >= 60:
print("Heartbeats per minute (BPM):", beat_count)
beat_count = 0 # Reset the beat count for the next minute
start_time = time.time() # Reset start time
Embedded C:
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"
#define THRESHOLD 2000
#define ADC_PIN 26
int main() {
stdio_init_all();
adc_init();
adc_gpio_init(ADC_PIN);
adc_select_input(ADC_PIN);
uint32_t beat_count = 0;
absolute_time_t start_time = get_absolute_time();
while (true) {
uint16_t adc_value = adc_read(); // Read the ADC value
if (adc_value > THRESHOLD) {
beat_count++;
sleep_ms(300); // Delay to avoid multiple counts
}
// Check if 60 seconds have passed
if (absolute_time_diff_us(start_time, get_absolute_time()) >= 60000000) {
printf("Heartbeats per minute (BPM): %lu\n", beat_count);
beat_count = 0; // Reset for the next minute
start_time = get_absolute_time(); // Reset start time
}
}
return 0;
}
Hardware Image:

Output:
The expected output will be a continuous printout of the heartbeats per minute (BPM) on the console of Thonny or via the serial monitor when running the embedded C program. The output will look like this:

Video Demonstration:
Appendix:
Common CMakeLists:
cmake_minimum_required(VERSION 3.12)
# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)
project(pico_experiments C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
if (PICO_SDK_VERSION_STRING VERSION_LESS "1.3.0")
message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.3.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
endif()
# Initialize the SDK
pico_sdk_init()
add_compile_options(-Wall
-Wno-format # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int
-Wno-unused-function # we have some for the docs that arent called
)
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wno-maybe-uninitialized)
endif()
# Hardware-specific examples in subdirectories:
add_subdirectory(expt_10_LCD)
CMakeLists:
cmake_minimum_required(VERSION 3.13)
# Include the Pico SDK
include(pico_sdk_import.cmake)
project(heartbeat_monitor)
# Initialize the Pico SDK
pico_sdk_init()
add_executable(heartbeat_monitor main.c)
# Create map/bin/hex/uf2 file
pico_add_extra_outputs(heartbeat_monitor)
# Link to the required libraries
target_link_libraries(heartbeat_monitor pico_stdlib)
References:
| # | Topic | Date & time | Action |
|---|
0% Completed (0/1)