rautanand03

Untitled

Apr 21st, 2019
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.94 KB | None | 0 0
  1. int pulsePin = A0;                 // Pulse Sensor purple wire connected to analog pin A0
  2. int blinkPin = 13;                // pin to blink led at each beat
  3.  
  4. // Volatile Variables, used in the interrupt service routine!
  5. volatile int BPM;                   // int that holds raw Analog in 0. updated every 2mS
  6. volatile int Signal;                // holds the incoming raw data
  7. volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!
  8. volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".
  9. volatile boolean QS = false;        // becomes true when Arduoino finds a beat.
  10.  
  11. static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse
  12.  
  13. volatile int rate[10];                      // array to hold last ten IBI values
  14. volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
  15. volatile unsigned long lastBeatTime = 0;           // used to find IBI
  16. volatile int P = 512;                      // used to find peak in pulse wave, seeded
  17. volatile int T = 512;                     // used to find trough in pulse wave, seeded
  18. volatile int thresh = 525;                // used to find instant moment of heart beat, seeded
  19. volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
  20. volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
  21. volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM
  22.  
  23. void setup()
  24. {
  25.   pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!
  26.   Serial.begin(115200);             // we agree to talk fast!
  27.   interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS
  28.                                     // IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS THAN THE BOARD VOLTAGE,
  29.                                     // UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE TO THE A-REF PIN
  30.                                     //   analogReference(EXTERNAL);  
  31. }
  32.  
  33. void loop()
  34. {
  35.   int BPM = getBPM();
  36.   Serial.println("BPM");
  37.   Serial.println(BPM);
  38.  
  39. }
  40.  
  41.  
  42. //  Where the Magic Happens
  43. int getBPM()
  44. {
  45.    serialOutput();  
  46.    
  47.   if (QS == true) // A Heartbeat Was Found
  48.     {    
  49.       // BPM and IBI have been Determined
  50.       // Quantified Self "QS" true when arduino finds a heartbeat
  51.       serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.    
  52.       QS = false; // reset the Quantified Self flag for next time    
  53.     }
  54.      
  55.   delay(20); //  take a break
  56.   return getBPM;
  57. }
  58.  
  59.  
  60. void interruptSetup()
  61. {    
  62.   // Initializes Timer2 to throw an interrupt every 2mS.
  63.   TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  64.   TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
  65.   OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  66.   TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  67.   sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED      
  68. }
  69.  
  70. void serialOutput()
  71. {   // Decide How To Output Serial.
  72.  if (serialVisual == true)
  73.   {  
  74.      arduinoSerialMonitorVisual('-', Signal);   // goes to function that makes Serial Monitor Visualizer
  75.   }
  76.  else
  77.   {
  78.       sendDataToSerial('S', Signal);     // goes to sendDataToSerial function
  79.    }        
  80. }
  81.  
  82. void serialOutputWhenBeatHappens()
  83. {    
  84.  if (serialVisual == true) //  Code to Make the Serial Monitor Visualizer Work
  85.    {            
  86.      //Serial.print(" Heart-Beat Found ");  //ASCII Art Madness
  87.      //Serial.print("BPM: ");
  88.      //Serial.println(BPM);
  89.    }
  90.  else
  91.    {
  92.      sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix
  93.      sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix
  94.    }  
  95. }
  96.  
  97. void arduinoSerialMonitorVisual(char symbol, int data )
  98. {    
  99.   const int sensorMin = 0;      // sensor minimum, discovered through experiment
  100.   const int sensorMax = 1024;    // sensor maximum, discovered through experiment
  101.   int sensorReading = data; // map the sensor range to a range of 12 options:
  102.   int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
  103.   // do something different depending on the
  104.   // range value:
  105. }
  106.  
  107.  
  108. void sendDataToSerial(char symbol, int data )
  109. {
  110.    Serial.print(symbol);
  111.    Serial.println(data);                
  112. }
  113.  
  114. ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
  115. {  
  116.   cli();                                      // disable interrupts while we do this
  117.   Signal = analogRead(pulsePin);              // read the Pulse Sensor
  118.   sampleCounter += 2;                         // keep track of the time in mS with this variable
  119.   int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise
  120.                                               //  find the peak and trough of the pulse wave
  121.   if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
  122.     {      
  123.       if (Signal < T) // T is the trough
  124.       {                        
  125.         T = Signal; // keep track of lowest point in pulse wave
  126.       }
  127.     }
  128.  
  129.   if(Signal > thresh && Signal > P)
  130.     {          // thresh condition helps avoid noise
  131.       P = Signal;                             // P is the peak
  132.     }                                        // keep track of highest point in pulse wave
  133.  
  134.   //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  135.   // signal surges up in value every time there is a pulse
  136.   if (N > 250)
  137.   {                                   // avoid high frequency noise
  138.     if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
  139.       {        
  140.         Pulse = true;                               // set the Pulse flag when we think there is a pulse
  141.         digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
  142.         IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
  143.         lastBeatTime = sampleCounter;               // keep track of time for next pulse
  144.  
  145.         if(secondBeat)
  146.         {                        // if this is the second beat, if secondBeat == TRUE
  147.           secondBeat = false;                  // clear secondBeat flag
  148.           for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
  149.           {            
  150.             rate[i] = IBI;                      
  151.           }
  152.         }
  153.  
  154.         if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
  155.         {                        
  156.           firstBeat = false;                   // clear firstBeat flag
  157.           secondBeat = true;                   // set the second beat flag
  158.           sei();                               // enable interrupts again
  159.           return;                              // IBI value is unreliable so discard it
  160.         }  
  161.       // keep a running total of the last 10 IBI values
  162.       word runningTotal = 0;                  // clear the runningTotal variable    
  163.  
  164.       for(int i=0; i<=8; i++)
  165.         {                // shift data in the rate array
  166.           rate[i] = rate[i+1];                  // and drop the oldest IBI value
  167.           runningTotal += rate[i];              // add up the 9 oldest IBI values
  168.         }
  169.  
  170.       rate[9] = IBI;                          // add the latest IBI to the rate array
  171.       runningTotal += rate[9];                // add the latest IBI to runningTotal
  172.       runningTotal /= 10;                     // average the last 10 IBI values
  173.       BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
  174.       QS = true;                              // set Quantified Self flag
  175.       // QS FLAG IS NOT CLEARED INSIDE THIS ISR
  176.     }                      
  177.   }
  178.  
  179.   if (Signal < thresh && Pulse == true)
  180.     {   // when the values are going down, the beat is over
  181.       digitalWrite(blinkPin,LOW);            // turn off pin 13 LED
  182.       Pulse = false;                         // reset the Pulse flag so we can do it again
  183.       amp = P - T;                           // get amplitude of the pulse wave
  184.       thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
  185.       P = thresh;                            // reset these for next time
  186.       T = thresh;
  187.     }
  188.  
  189.   if (N > 2500)
  190.     {                           // if 2.5 seconds go by without a beat
  191.       thresh = 512;                          // set thresh default
  192.       P = 512;                               // set P default
  193.       T = 512;                               // set T default
  194.       lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date        
  195.       firstBeat = true;                      // set these to avoid noise
  196.       secondBeat = false;                    // when we get the heartbeat back
  197.     }
  198.  
  199.   sei();                                   // enable interrupts when youre done!
  200. }// end isr
Add Comment
Please, Sign In to add comment