Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Arduino
100 min
Share

بناء جهاز لقراءة ورسم معدل نبضات القلب باستخدام الأردوينو

يعد قياس معدل نبضات القلب أحد المؤشرات الحيوية المهمة لصحة الإنسان، حيث يوفر معلومات قيمة عن كفاءة عمل القلب والحالة الصحية العامة. في هذا المشروع، سنقوم بتطوير جهاز مبتكر لقراءة ورسم معدل نبضات القلب باستخدام لوحة أردوينو.

Project Video

Overview

في هذا المشروع، سنقوم ببناء جهاز لقراءة ورسم معدل نبضات القلب باستخدام لوحة أردوينو ومستشعر نبضات القلب لالتقاط الإشارات الحيوية، وسنستخدم شاشة لعرض النتائج بشكل مرئي وأيضاً عرض النتائج خلال رسم بياني على الكمبيوتر.

Getting the Items

Arduino Uno R3 (Voltaat Version)
Get Item
2×16 LCD with I2C Module
Get Item
Pulse Sensor Amped
Get Item
Active Buzzer - 5V
Get Item
Half-size Breadboard
Get Item
Jumper Wires - Male to Male (40 Pack)
Get Item
Jumper Wires – Male to Female (40 Pack)
Get Item

Steps

Wiring it Up

قم بتوصيل الأسلاك بين لوحة الأردوينو ومستشعر ضربات القلب والصفارة والشاشة كما هو موضح بالصورة التالية:

التوصيلات من الاردوينو الى لوحة التجارب  :

•  منفذ ال 5 فولت ← المنافذ الموجبة بلوحة التجارب

•  منفذ الجراوند ← المنافذ السالبة بلوحة التجارب

التوصيلات من الصفارة :

• الطرف الموجب للصفارة ← منفذ رقم 2 فى لوحة الاردوينو

• الطرف السالب للصفارة ← المنافذ السالبة بلوحة التجارب

التوصيلات من حساس نبضات القلب:

• الطرف الموجب للحساس ← المنافذ الموجبة بلوحة التجارب

• الطرف السالب للحساس ← المنافذ السالبة بلوحة التجارب

• طرف الأشارة للحساس ← منفذ رقم A0 فى لوحة الاردوينو

التوصيلات من الشاشة الكريستالية:

• المنفذ الموجب للشاشة الكريستالية ← المنافذ الموجبة بلوحة التجارب

• المنفذ السالب للشاشة الكريستالية ← المنافذ السالبة بلوحة التجارب

• المنفذ SDA للشاشة الكريستالية ← منفذ رقم A4 فى لوحة الاردوينو

• المنفذ SCL للشاشة الكريستالية ← منفذ رقم A5 فى لوحة الاردوينو

Coding

/*

Voltaat learn (http://learn.voltaat.com)

Link for full tutorial:

Tutorial: Building a device to read and graph heart rate using Arduino!

The purpose of this sketch is to build a device to read and chart the heart rate using

an Arduino board and a heart rate sensor to capture vital signs. We will use a screen

to display the results visually and also display the results through a graph on the computer.

Connections from the Arduino to the breadboard:

• Arduino GND pin → Breadboard ground line

• Arduino 5V pin → Breadboard 5V line

Connection from the LCD:

• VCC pin → breadboard 5v line

• GND pin→ breadboard GND line

• SDA pin→ Arduino analog pin A4

• SCL pin → Arduino analog pin A5

Connections from the buzzer:

• The positive terminal of the speaker → Pin 2 on the Arduino board

• The negative terminal of the speaker → Negative terminals on the breadboard

Connections from the Heartbeat Sensor:

• Positive terminal of the sensor → Breadboard 5V line

• Negative terminal of the sensor → Breadboard ground line

• Signal terminal of the sensor → Pin A0 on the Arduino board

*/

#include "LiquidCrystal_I2C.h"

LiquidCrystal_I2C lcd(0x27, 16, 2);

int pulsePin = A0;                 // Pulse Sensor purple wire connected to analog pin A0

int blinkPin = 13;                // pin to blink led at each beat            

int buzzerPin = 2;

// Volatile Variables, used in the interrupt service routine!

volatile int BPM;                   // int that holds raw Analog in 0. updated every 2mS

volatile int Signal;                // holds the incoming raw data

volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!

volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".

volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse

volatile int rate[10];                      // array to hold last ten IBI values

volatile unsigned long sampleCounter = 0;          // used to determine pulse timing

volatile unsigned long lastBeatTime = 0;           // used to find IBI

volatile int P = 512;                      // used to find peak in pulse wave, seeded

volatile int T = 512;                     // used to find trough in pulse wave, seeded

volatile int thresh = 525;                // used to find instant moment of heart beat, seeded

volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded

volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM

volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM

 

void setup()

{

 

  Serial.begin(115200);    

  // we agree to talk fast!

  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS

                                    // IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS THAN THE BOARD VOLTAGE,

                                    // UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE TO THE A-REF PIN

                                    //   analogReference(EXTERNAL);  

  lcd.init();         //--> Initializes the LCD.

  lcd.backlight();    //--> Turns on the backlight of the LCD.

  lcd.begin(16,2);

   pinMode(buzzerPin, OUTPUT);

}

//  Where the Magic Happens

void loop()

{

   serialOutput();  

   

  if (QS == true) // A Heartbeat Was Found

    {    

      // BPM and IBI have been Determined

      // Quantified Self "QS" true when arduino finds a heartbeat

      serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.    

      QS = false; // reset the Quantified Self flag for next time    

    }

     

  delay(20); //  take a break

}

void interruptSetup()

{    

  // Initializes Timer2 to throw an interrupt every 2mS.

  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE

  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER

  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE

  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A

  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED      

}

void serialOutput()

{   // Decide How To Output Serial.

 if (serialVisual == true)

  {  

     arduinoSerialMonitorVisual('-', Signal);   // goes to function that makes Serial Monitor Visualizer

  }

 else

  {

      sendDataToSerial('S', Signal);     // goes to sendDataToSerial function

   }        

}

void serialOutputWhenBeatHappens()

{    

 if (serialVisual == true) //  Code to Make the Serial Monitor Visualizer Work

   { lcd.setCursor(0,0);        

     Serial.println(BPM);

     lcd.print("Heart-Beat Found  ");

     lcd.setCursor(0,1);

     lcd.print("BPM: ");

     lcd.setCursor(4,1);

     lcd.print(BPM);

     if (BPM > 100) {

      lcd.setCursor(12, 1);

      lcd.print("HIGH");

      digitalWrite(buzzerPin, HIGH); // Turn on buzzer

    } else {

      lcd.setCursor(12, 1);

      lcd.print("    "); // Clear line

      digitalWrite(buzzerPin, LOW); // Turn off buzzer

    }

     delay(300);

     

    lcd.clear();

     

   }

 else

   {

     sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix

     sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix

   }  

}

void arduinoSerialMonitorVisual(char symbol, int data )

{    

  const int sensorMin = 0;      // sensor minimum, discovered through experiment

  const int sensorMax = 1024;    // sensor maximum, discovered through experiment

  int sensorReading = data; // map the sensor range to a range of 12 options:

  int range = map(sensorReading, sensorMin, sensorMax, 0, 11);

  // do something different depending on the

  // range value:

}

void sendDataToSerial(char symbol, int data )

{

   Serial.print(symbol);

   Serial.println(data);                

}

ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124

{  

  cli();                                      // disable interrupts while we do this

  Signal = analogRead(pulsePin);              // read the Pulse Sensor

  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

      }

    }

  if(Signal > thresh && Signal > P)

    {          // thresh condition helps avoid noise

      P = Signal;                             // P is the peak

    }                                        // keep track of highest point in pulse wave

  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT

  // signal surges up in value every time there is a pulse

  if (N > 250)

  {                                   // avoid high frequency noise

    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )

      {        

        Pulse = true;                               // set the Pulse flag when we think there is a pulse

        digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED

        IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS

        lastBeatTime = sampleCounter;               // keep track of time for next pulse

 

        if(secondBeat)

        {                        // if this is the second beat, if secondBeat == TRUE

          secondBeat = false;                  // clear secondBeat flag

          for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup

          {            

            rate[i] = IBI;                      

          }

        }

 

        if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE

        {                        

          firstBeat = false;                   // clear firstBeat flag

          secondBeat = true;                   // set the second beat flag

          sei();                               // enable interrupts again

          return;                              // IBI value is unreliable so discard it

        }  

      // keep a running total of the last 10 IBI values

      word runningTotal = 0;                  // clear the runningTotal variable    

      for(int i=0; i<=8; i++)

        {                // shift data in the rate array

          rate[i] = rate[i+1];                  // and drop the oldest IBI value

          runningTotal += rate[i];              // add up the 9 oldest IBI values

        }

      rate[9] = IBI;                          // add the latest IBI to the rate array

      runningTotal += rate[9];                // add the latest IBI to runningTotal

      runningTotal /= 10;                     // average the last 10 IBI values

      BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!

      QS = true;                              // set Quantified Self flag

      // QS FLAG IS NOT CLEARED INSIDE THIS ISR

    }                      

  }

  if (Signal < thresh && Pulse == true)

    {   // when the values are going down, the beat is over

      digitalWrite(blinkPin,LOW);            // turn off pin 13 LED

      Pulse = false;                         // reset the Pulse flag so we can do it again

      amp = P - T;                           // get amplitude of the pulse wave

      thresh = amp/2 + T;                    // set thresh at 50% of the amplitude

      P = thresh;                            // reset these for next time

      T = thresh;

    }

  if (N > 2500)

    {                           // if 2.5 seconds go by without a beat

      thresh = 512;                          // set thresh default

      P = 512;                               // set P default

      T = 512;                               // set T default

      lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date        

      firstBeat = true;                      // set these to avoid noise

      secondBeat = false;                    // when we get the heartbeat back

    }

  sei();                                   // enable interrupts when youre done!

}// end isr

Testing it Out

بعد رفع الكود البرمجي على لوحة الأردوينو، قم بوضع إصبعك على حساس نبضات القلب، ستجد أن لوحة الأردوينو تظهر عدد نبضات القلب على الشاشة الكريستالية، وإذا فتحت الشاشة التسلسلية في حاسوبك ستجد أنه يتم رسم منحنى لنبضات القلب على شاشة حاسوبك.

Resources

No items found.