Advertisement
Guest User

Untitled

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