Heart beat pulse sensor interfacing with pic microcontroller

Heart beat pulse sensor

Heart Beat rate is most important parameter in monitoring any person’s health. In the modern era of wearable devices, there are lot of devices which can measure heartbeat, blood pressure, footsteps, calories burnt and lot of other things. These devices has pulse sensor inside them to sense the pulse rate. Today, we will also use a pulse sensor with PIC Microcontroller to count heart beat per minute and the Inter-Beat Interval, these values will be further displayed on 16×2 character LCD. We will use PIC16F877A PIC microcontroller in this project. We already interfaced pulse sensor with Arduino for Patient Monitoring System.Heart beat pulse sensor

Required Components

  1. PIC16F877A microcontroller
  2. 20 Mhz Crystal
  3. 33pF capacitor 2 pcs
  4. 4.7k resistor 1 pcs
  5. 16×2 Character LCD
  6. 10K pot for contrast control of the LCD
  7. SEN-11574 Pulse sensor
  8. Velcro strap
  9. 5V Power adapter
  10. Breadboard and hookup wire

Pulse Sensor SEN-11574

To measure the heartbeat we need a pulse sensor. Here we have selected SEN-11574 pulse sensor which is easily available on online or offline stores. We used this sensor as there are sample codes provided from the manufacturer, but that is an Arduino code. We converted that code for our PIC microcontroller.Pulse Sensor SEN 11574

The sensor is really small and perfect for reading heartbeat across earlobe or on the fingertip. It is 0.625” in diameter and 0.125” thick from the round PCB side.

This sensor provides an analog signal and the sensor can be driven with 3V or 5V, the current consumption of the sensor is 4 mA, which is great for mobile applications. The sensor comes with three wire with 24” long hookup cable and berg male header at the end. Also, the sensor comes with Velcro Finger Strap to wear it across fingertip.Pulse Sensor schematic

The sensor schematic consists of optical heart-rate sensor, noise cancellation RC circuitry or filters, which can be seen in the schematic diagram. R2, C2, C1, C3 and an operational amplifier MCP6001 are used for reliable amplified analog output.

There are few other sensors for Heart Beat Monitoring but SEN-11574 pulse sensor is widely used in Electronics projects.

Circuit Diagram for Pulse Sensor interfacing with PIC MicrocontrollerCircuit Diagram

Here we have connected the pulse sensor across a 2nd pin of the microcontroller unit. As the sensor provides analog data, we need to convert the analog data into digital signal by doing necessary calculations.

The Crystal oscillator of 20Mhz is connected across two OSC pins of the microcontroller unit with two ceramic 33pF capacitors. The LCD is connected across the RB port of the microcontroller.Heart Beat Monitoring

Code Explanation

The code is a little bit complex for beginners. The manufacturer provided sample codes for the SEN-11574 sensor, but it was written for the Arduino platform. We need to convert the calculation for our microchip, PIC16F877A. Complete code is given at the end of this project with a Demonstration Video. And the supporting C files can be downloaded from here.

Our code flow is relatively simple and we made the steps using a switch case. As per the manufacturer, we need to get the data from the sensor in every 2 milliseconds. So, we used a timer interrupt service routine which will fire a function in every 2 milliseconds.

Our code flow in switch statement will go like this:

Case 1: Read the ADC

Case 2: Calculate the Heart Beat and IBI

Case 3: Show the heartbeat and IBI on LCD

Case 4: IDLE (Do nothing)

Inside the timer interrupt function, we change the state of the program to Case 1: Read the ADC on every 2 milliseconds.

So, in the main function, we defined the program state and all the switch cases.

void main() {
    system_init();
    main_state = READ_ADC;      
    while (1) {
        switch (main_state) {
            case READ_ADC:
            {                
                adc_value = ADC_Read(0); // 0 is the channel number
                main_state = CALCULATE_HEART_BEAT;                
                break;
            }
            case CALCULATE_HEART_BEAT:
            {
                calculate_heart_beat(adc_value);
                main_state = SHOW_HEART_BEAT;
                break;
            }
            case SHOW_HEART_BEAT:
            {
                if (QS == true) { // A Heartbeat Was Found
                    // BPM and IBI have been Determined
                    // Quantified Self "QS" true when Arduino finds a heartbeat                    
                    QS = false; // reset the Quantified Self flag for next time

                    // 0.9 used for getting better data. actually should not be used
                    BPM = BPM * 0.9;
                    IBI = IBI / 0.9;
                    lcd_com(0x80);
                    lcd_puts("BPM:-     ");
                    lcd_print_number(BPM);
                    lcd_com(0xC0);
                    lcd_puts("I.B.I:-   ");
                    lcd_print_number(IBI);                    
                }
            }
                main_state = IDLE;
                break;
       
        case IDLE:
        {            
            break;
        }
        default:
        {

        }
    }
}
}

We are using two hardware peripherals of the PIC16F877A: Timer0 and ADC.

Inside the timer0.c file,

TMR0 = (uint8_t)(tmr0_mask & (256-(((2 *_XTAL_FREQ)/(256*4))/1000)));

This calculation is providing the 2 milliseconds timer interrupt.  The calculation formula is

// TimerCountMax - (((delay(ms) * Focs(hz)) / (PreScale_Val * 4)) / 1000)

If we see the timer_isr function, it is-

void timer_isr() {
    main_state = READ_ADC;    
}

In this function the program state is changed to READ_ADC in every 2ms.

Then the CALCULATE_HEART_BEAT function is taken from the Arduino example code.

void calculate_heart_beat(int adc_value) {
    Signal = adc_value;
    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
        }
    }
………….
………………………..

Further, the complete code is given below and well explained by the comments. This heart beat sensor data can be further uploaded to the cloud and monitored over the internet from anywhere, which thus makes it IoT based Heart Beat Monitoring system, follow the link to learn more.

Video:

Leave a Comment

Your email address will not be published. Required fields are marked *