مستشعر نبضات القلب

 

شرح مبسط عن المستشعر المستخدم في المشروع

مستشعر النبض هو مستشعر معدل ضربات القلب منخفض الطاقة مصمم جيدًا للتوصيل والتشغيل ل Arduino يمكن استخدامه من قبل الطلاب الذين يرغبون في دمج بيانات معدل ضربات القلب الحية في مشاريعهم
وأفضل جزء هو أن هذا المستشعر يتم توصيله مباشرة بـ Arduino ويمكن تثبيته بسهولة على طرف الإصبع أو شحمة الأذن

 

نظره عامه على الحساس
الجزء الأمامي من المستشعر هو الجانب الذي يحمل شعار القلبهذا هو المكان الذي تضع فيه إصبعك سترى على الجانب الأمامي ثقبًا دائريًا صغيرًا حيث يضيء مصباح LED الأخضر من Kingbright الأخضر المثبت على الجانب الخلفي



يوجد أسفل LED مباشرة مستشعر صورة صغير للضوء المحيط لضبط سطوع الشاشة في ظروف الإضاءة المختلفه المستخدم في الهواتف المحمولة والأجهزة اللوحية وأجهزة الكمبيوتر المحمولة

ستجد بقية المكونات بما في ذلك رقاقة المقاومات والمكثفات التي تشكل شبكة مرشح R / C   ومجموعة من MCP6001 Op-Amp ي الجزء الخلفي من المستشعر , يوجد أيضًا صمام ثنائي حماية عكسي لمنع التلف اذا تم عكس أسلاك الطاقة عن طريق الخطأ.



 

يعمل الحساس من 3.3 إلى 5V DC Voltage و إمداد التيار الكهربائي للتيارالتشغيلي <4Ma

 

بعض المواصفات الفنيه للحساس

3.0 - 5.5 فولت

VCC

 

 

 

اقصى تصنيفات

<4mA

IMax (أقصى سحب للتيار)

0.3V vcc

VOut (نطاق الجهد الناتج)

565 نانومتر

خرج LED

         

              الطول الموجي

525 نانومتر

مدخلات الاستشعار

 

 

كيف يعمل مستشعر النبض
عمل مستشعر النبض أو أي مستشعر ضوئي لمعدل ضربات القلب عن طريق تسليط ضوء أخضر (~ 550 نانومتر) على الإصبع وقياس كمية الضوء المنعكس باستخدام مستشعر ضوئي.
تسمى طريقة اكتشاف النبض من خلال الضوء 
بالرسم البياني الضوئي
تميز الهيموغلوبين المؤكسج في الدم الشرياني بامتصاص الضوء الأخضر. كلما زاد احمرار الدم (كلما ارتفع مستوى الهيموجلوبين) ، زاد امتصاص الضوء الأخضر. عندما يتم ضخ الدم من خلال الإصبع مع كل نبضة قلب ، يتغير مقدار الضوء المنعكس ، مما يؤدي إلى تكوين شكل موجة متغير عند إخراج المستشعر الضوئي.

هذه الإشارة من المستشعر الضوئي صغيرة بشكل عام ومشوشه, لذلك يتم تمرير الإشارة عبر شبكة مرشح R / C م يتم تضخيمها باستخدام Op Amp لإنشاء إشارة أكبر بكثير وأنظف وأسهل في الكشف.

 

مداخل ومخرج المستشعر




ا-GND:السلك المتصل بالارضي
2-
VCC:يتصل بمصدر جهد5V او 3,3V
3-
SIGNAL:هو خرج الاشاره يتصل بالدخل التناظري للاردوينو

 

الادوات المطلوبه لانشاء مستشعر نبضات القلب:

1-مستشعر لنبضات القلب
2-شاشه
LCD
3-اوردوينو اونو
4-اسلاك توصيل

 

طريقه توصيل حساس النبضات بالاردوينو

مخرج الحساس

مدخل الاردوينو

Vcc

5v

Gnd

Gnd

SIGNAL

A0

 

نقوم بتوصيل مخرج الحساس vccبمدخل الاردوينو5v لتغذيه الحساس بالجهد
ونوصل مخرج الحساس
gndبمدخل الاردوينوgnd
ونوصل خرج الحساس SIGNAL بدخل الاردوينوا A0

توصيل شاشه الLcd16*4 بالاردوينو

نوصل الطرف الاول للشاشه gnd والطرف الخامس R/W والطرف السادس عشرA بمنفذ الارضي GND في الاردوينو
نوصل الطرف الثاني
VCC والطرف الخامس عشر K ب5V للاردوينو
ونوصل الطرف الثالث للشاشه
VEE بالمقاومه المتغيره
ونوصل الطرف الرابع
RS للشاشه بمنفذ استقبال البيانات رقم 2 للاردوينو
و الطرف السادس
E للشاشه بمنفذ استقبال البيانات رقم 3 للاردوينو
و الطرف الاحدى عشر
D4 للشاشه بالمنفذ رقم 4 للاردوينو
والطرف الثاني عشر
D5 للشاشه بالمنفذ رقم 5 للاردوينو
والطرف الثالث عشر
D6 للشاشه بالمنفذ رقم 6للاردوينو
والطرف الرابع عشر
D7 للشاشه بالمنفذ رقم 7 للاردوينو
 


صوره توضح طريقه التوصيل بين القطع

 

الاكواد المستخدمه لبرمجه الاردوينو:
#include <LiquidCrystal.h>

LiquidCrystal lcd( 2, 3, 4, 5, 6, 7);

 

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

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

 

// 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()

{

  lcd.begin(16,2);

  pinMode(blinkPin,OUTPUT);// pin that will blink to your heartbeat!

  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);   

}

 

 

//  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

   {            

     Serial.print(" Heart Beat Found ");  //ASCII Art Madness

     Serial.print("BPM: ");

     Serial.println(BPM);

     lcd.setCursor(0,0);

     lcd.print("Heart Beat Found ");

     lcd.setCursor(0,1);

     lcd.print("BPM: ");

     lcd.print(BPM);

     lcd.clear();

     delay(300);

   }

 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

تعليقات

المشاركات الشائعة