آردوینو Arduino Uno پروژه های آردوینو

اتصال سنسور Pulse sensor به آردوینو

نوشته شده توسط شهاب کمالی

در این آموزش قصد داریم به وسیله Pulse sensor نبضتان را بگیریم 🙂 این سنسور به راحتی به آردوینو متصل میشود و ضربان قلب را نمایش میدهد برای نمایش نیز میتوانید از خروجی سریال یا ال ای دی چشمک زن استفاده کرد و نتایج را مشاهده نمود. از این پروژه دانش آموزان،‌ سازندگان، ورزشکاران و توسعه دهندگان نرم افزار موبایل و … میتوانند استفاده کنند و به آسانی دیتا خروجی سنسور را در پروژه هایشان استفاده کنند 🙂 در ادامه  آموزش با مرجع تخصصی آردوینو ، دیجی اسپارک همراه باشید.

مانند تصویر زیر روی سنسور یک قلب زیبا وجود دارد، این قسمت را به انگشت یا لاله گوش متصل کنید و آن را توسط سیم های جامپر به آردوینو وصل کنید.

pulse sensor

 

طرف دیگر آن سه عدد سیم خارج شده با رنگ های مختلف ترکیب رنگ آن ممکن است متفاوت باشد اما سمت راست  زمین (GND) است، خروجی وسط برای منبع تغذیه است که بین ۳ تا ۵ ولت متصل میشود و خروجی سمت چپ به پورت آنالوگ.

pulse sensor

 


سخت افزار مورد نیاز


آردوینو Uno
سنسور پالس

 


اتصالات ماژول ضربان قلب


از طرف مخالف تصویر قلب، سنسور را بین انگشتانتان نگه دارید.

سیم سمت راست به GND آردوینو
سیم وسط به ۵ یا ۳ ولت آردوینو
سیم سمت چپ به آنالوگ ۰ A0

arduino to pulse sensor

 


کد نویسی ماژول ضربان قلب


۱- دانلود فایل زیپ. دانلود

۲- فایل PulseSensor_Amped_Arduino-master.zip را در مسیر  Documents/Arduino از حالت فشرده خارج کنید(unzip)

۳-روی فایل PulseSensorAmped_Arduino_1dot2.ino دوبار کلید کنید تا در محیط آردوینو باز شود.

— یا اینکه در مسیر نصب آردوینو فایل های را کپی کنید Sketchbook > PulseSensor_Arduino-Master > PulseSensorAmped_Arduino_1dot2.ino و مانند تصویر زیر آن را باز کنید.

 

 

arduino code

 


فایل AllSerialHandling


 

 

//////////
/////////  All Serial Handling Code,
/////////  It's Changeable with the 'serialVisual' variable
/////////  Set it to 'true' or 'false' when it's declared at start of code.
/////////

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


//  Decides How To OutPut BPM and IBI Data
void serialOutputWhenBeatHappens(){
 if (serialVisual == true){            //  Code to Make the Serial Monitor Visualizer Work
    Serial.print("*** Heart-Beat Happened *** ");  //ASCII Art Madness
    Serial.print("BPM: ");
    Serial.print(BPM);
    Serial.print("  ");
 } else{
        sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix
        sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix
 }
}



//  Sends Data to Pulse Sensor Processing App, Native Mac App, or Third-party Serial Readers.
void sendDataToSerial(char symbol, int data ){
    Serial.print(symbol);

    Serial.println(data);
  }


//  Code to Make the Serial Monitor Visualizer Work
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:
  switch (range) {
  case 0:
    Serial.println("");     /////ASCII Art Madness
    break;
  case 1:
    Serial.println("---");
    break;
  case 2:
    Serial.println("------");
    break;
  case 3:
    Serial.println("---------");
    break;
  case 4:
    Serial.println("------------");
    break;
  case 5:
    Serial.println("--------------|-");
    break;
  case 6:
    Serial.println("--------------|---");
    break;
  case 7:
    Serial.println("--------------|-------");
    break;
  case 8:
    Serial.println("--------------|----------");
    break;
  case 9:
    Serial.println("--------------|----------------");
    break;
  case 10:
    Serial.println("--------------|-------------------");
    break;
  case 11:
    Serial.println("--------------|-----------------------");
    break;

  }
}

 


فایل Interrupt


 

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


// THIS IS THE TIMER 2 INTERRUPT SERVICE ROUTINE.
// Timer 2 makes sure that we take a reading every 2 miliseconds
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




 

فایل PulseSensorAmped_Arduino_1dot4:

/*  Pulse Sensor Amped 1.4    by Joel Murphy and Yury Gitman   http://www.pulsesensor.com

----------------------  Notes ----------------------  ----------------------
This code:
۱) Blinks an LED to User's Live Heartbeat   PIN 13
۲) Fades an LED to User's Live HeartBeat
۳) Determines BPM
۴) Prints All of the Above to Serial

Read Me:
https://github.com/WorldFamousElectronics/PulseSensor_Amped_Arduino/blob/master/README.md
 ----------------------       ----------------------  ----------------------
*/

//  Variables
int pulsePin = 0;                 // Pulse Sensor purple wire connected to analog pin 0
int blinkPin = 13;                // pin to blink led at each beat
int fadePin = 5;                  // pin to do fancy classy fading blink at each beat
int fadeRate = 0;                 // used to fade LED on with PWM on fadePin

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

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


void setup(){
  pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!
  pinMode(fadePin,OUTPUT);          // pin that will fade 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
        digitalWrite(blinkPin,HIGH);     // Blink LED, we got a beat.
        fadeRate = 255;         // Makes the LED Fade Effect Happen
                                // Set 'fadeRate' Variable to 255 to fade LED with pulse
        serialOutputWhenBeatHappens();   // A Beat Happened, Output that to serial.
        QS = false;                      // reset the Quantified Self flag for next time
  }

  ledFadeToBeat();                      // Makes the LED Fade Effect Happen
  delay(20);                             //  take a break
}





void ledFadeToBeat(){
    fadeRate -= 15;                         //  set LED fade value
    fadeRate = constrain(fadeRate,0,255);   //  keep LED fade value from going into negative numbers!
    analogWrite(fadePin,fadeRate);          //  fade LED
  }



http://pulsesensor.com/pages/pulse-sensor-amped-arduino-v1dot1

 

حالا باید کد ها را روی آردوینو کامپایل کنیم، خروجی موقع یافتن ضربان به صورت زیر است.  توجه کنید که هر چهار عدد فایل حتما باید کنار هم در یک مسیر قرار گرفته باشد و بعدا کامپایل شوند.

خروجی سنسور

خروجی سنسور

 

در ادامه به ویدیوی زیر توجه کنید.

 

 

درباره نویسنده

شهاب کمالی

تبادل نظر و رفع عیب با ثبت دیدگاه

۴۱ دیدگاه

  • سلام
    ممنونم از آموزش خوبتون، یه سوالی داشتم، میشه راجع به فایل Interrupt توضیحات بیشتری بدین؟
    ممنون

    • درود، دوست عزیز این فایل ها توسط سازندگان سنسور یا افرادی که تسلط کامل به سخت افزار سنسور دارند تهیه شده اند و در حالت کلی بهتر است تغییری در کد ها بجز متغییر هایی که در مقاله توضیح داده شده به وجود نیاورید. اما این فایل کارهایی مانند تنظیمات سنسور و ایجاد وقفه برای پاک کردن مقدار های قبلی و خواندن از پورت آنالوگ را انجام میدهد.

    • درود دوست عزیز، خیر نیازی به کتابخانه نداره شما چهار تا فایل دریافتی رو کنار هم قرار دهید و کامپایل کنید

  • باسلام

    این اردوینو که به سنسور ضربان قلب متصل شد کجا ضربان قلب رو نشون میده… ایا باید بهشش یه LCDوصل بشه اگه LCD باید بهش وصل بشه چه جوری وصلش کنیم..منبع تغذیه این اردوینو رو چه جوری به اردوینو وصل کنیم.. چند ولت باشه؟و من میخوام به این اردوینو یه سنسور دما هم اضافه کنم ایا میشه؟ من این چیزارو واسه ربات میخوام..یه سوالم داشتم ایا نرم افزاری سراغ دارید که بتونم باهاش تو لب تاب یا کامپیوتر یا تبلت ربات رو کنترل کنم ؟ لطفا و خواهشا توضیح بدید لازم دارم…. باتشکر

  • سلام دوست عزیز برای مشاهده ضربان قلب باید به یک کنسول مانند کنسول خود آردوینو متصل بشید، تو عکس آخر نمایش دادیم، شما درباره خود آردوینو بیشتر مطالعه کنید و این پست رو دوباره دنبال کنید موفق خواهید شد.

  • راستی میشه خواهشا اموزش کامل اینارو و طریقه نصب اون کنسولو تو جیمیلم بزارید ممنون دستتون درد نکنه

  • منظور ما از کنسول محیط هایی هستند که میتوانند خروجی سریال را نمایش دهند مانند کنسول خود آردوینو از مسیر tools–>serial monitor

  • من اینو میخوام بزارم تو ربات امدادگر میخوام واسشLCD بزارم میشه بهم بگید چه جوری وصلش کنم…LEDشو از کجا بخرم … ایا برای این نیازی به کتابخانه هست یاخیر؟؟؟ و ایا میشه یه کاری بکنم که توی کنسول خود اردوینو نشون بده اگه میشه چه جوری( منظورم اینکه به صورت بیسیم بفرسته اطلاعاتو) واگه میشه میشه توضیح بدید…و قطعاتشو میشه بگید تهیه کنم… ممنون به شما هم ظحمت دادیما ممنون اگه شد و اگه طولانی بود بفرستید جیمیلم

    باتشکر

  • دوست خوب، طبق دستورالعمل اول خروجی رو سنسور را وصل کنید به آردوینو و ۴تا فایل را کنار هم قرار بدید و کامپایل کنید سنسور هم اتصالاتش رو چک کنید که درست باشه بعد وقتی سنسور وصل بود دستتون رو طبق ویدیو بگذارید تو اون کنسول شروع میکنه نمایش دادن، برای نمایش روی ال سی دی هم باید متغییر BPM روی ال سی دی بفرستید

    • سلام عرض ادب
      اگر در تحلیل کد ها یا ایجاد وقفه ها در زیرساخت Rasbian مشکل دارید می توانید به راحتی از آردوینو و کد فعلی استفاده کنید و خروجی نهایی را به سمت رزپبری ارسال نمایید.
      موفق باشید

  • سلام
    ممنونم از مطالب خوبتون بخصوص سنسور پالس با آردوینو
    یک سوال داشتم !؟
    من اگه خواسته باشم میزان نبض روی LCD 2*16 به نمایش بگذارم باید از چه کدی استفاده بکنم در آردوینو ؟؟
    ممنون میشم پاسخگو باشید چون توی کد LCD و فرمول نبض گیر کردم
    سپاس فراوان

  • سلام من میخاهم کدک رو تغییر بدم مثلا وقتی ضربان قلب به “n” رسید از پورت ۱۱ خروجی داشته باشم لطفا راهنماییم کنید

  • ممنون از آموزش خوبتون
    لطفا اگر نحوه ی نمایش ضربان روی یک LCD رو هم پیدا کردین توی سایت بذارین

  • سلام
    همه این مراحلو انجام دادم فقط نا منظم چشمک میزنه و خروجی در سریال مانیتور نوشهت های عجیب غریب میاد :/
    مشکل از کجا میتونه باشه

    • سلام عرض ادب
      در مورد نامنظم چشمک زدن:
      در صورت امکان با چسب کاغذی سنسور رو به سر انگشت خودتون متصل کنید. نکته ی مهم اینجاست که نباید دست شما به پشت مدار برخورد کند. بعضی از دوستان به اشتباه، به انگشت اشاره و شست سنسور را نگه میدارند که اشتباه است و باعث ایجاد خطا میشود.

      در مورد نادرست بودن نوشته ها:
      در قسمت پایین سمت راست پنجره Serial Monitor مقدار را بر روی “۱۱۵۲۰۰” قرار دهید.
      موفق باشید

  • سلام
    میشه روی این بردبورد یه lcd برای نشان دادن میزان ضربان قلب و یه بلندگو برای به صدا در اومدن بوق با هر بار خاموش شدن led نصب کنید و کدها شو بزارید یا برام بفرستید.
    دو روز بیشتر وقت ندارم برای دادن این پروژه و حسابی درگیر کارم.
    با تشکر از شما و خانم پوربلورچیان

    • با سلام
      کاربر گرامی همه‌ی این کارها قابل اجراست. دقت داشته باشید که دیجی اسپارک مرجع آموزش‌های رایگان است. نه اینکه جنابعالی یک پروژه صفر تا صد را تقاضا دهید و اینجا به راحتی برای شما منتشر شود. شما می‌بایست دانش فنی و کافی داشته باشید. سپس در صورت برخورد با مشکل به هنگام اجرا از این طریق موارد را مطرح بفرمایید.

  • سلام
    ممنونم از اموزش خوبتون
    این ۴ کد رو باید بصورت جداگانه اپلود کنم ؟
    اینکارو که انجام میدم تو نمایشگر خود اردوینو یه سری عدد و حروف عجیب نشون داده میشه !
    ممنون میشم راهنماییم کنید

  • سلام خسته نباشد برای کامپایل کردن برنامه روی برد نرم افزار ما قسمت tools که میریم برای انتخاب برد .برد Arduino UNO SMD را ندارد اگه میشه راهنمایی کنین که رو چه بردی قرار دهیم

    • سلام
      باید Arduino/ Genuino UNO را انتخاب کنید.
      تفاوتی بین دو برد آردوینو UNO SMD و UNO DIP وجود ندارد. اگر همچنان شناسایی نشد، از همین طریق اطلاع رسانی بفرمایید.

  • سلام
    من سایت شما عضو شدم…. حق عضویت دادم…. الان نمیتونم بهش دسترسی داشته باشم.
    کمک کنید…

    • با سلام
      اشتراک شما فعال می‌باشد و در خصوص دسترسی مشکلی ندارید. ولی دقت کنید که برای پست هایی با سطح دسترسی اسپارکر پلاس، میبایست اشتراک ماهیانه، سه ماهه و یا سالیانه را تهیه کنید.

  • سلام ممنون از اموزش های خوبتون
    میخواستم به جای اینکه با هر ضربان LEDروشن بشه وقتی ضربان از حدی بیشتر شد روشن بشه میشه بگید چه تغییری باید ایجاد کنم