rautanand03

Untitled

Apr 21st, 2019
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.08 KB | None | 0 0
  1. #include <OneWire.h>
  2. #include <DallasTemperature.h>
  3.  
  4. // #define NDEBUG
  5.  
  6. #define ONE_WIRE_BUS 2
  7. #define PULSE_PIN A0
  8. #define ECG_PIN A1
  9. #define BLINK_PIN 13
  10.  
  11. #define ECG1 10
  12. #define ECG2 11
  13.  
  14. #define ESP_RESET 12
  15.  
  16. // Volatile Variables, used in the interrupt service routine!
  17. int blinkPin = 13; // pin to blink led at each beat
  18. volatile int BPM; // int that holds raw Analog in 0. updated every 2mS
  19. volatile int Signal; // holds the incoming raw data
  20. volatile int IBI = 600; // int that holds the time interval between beats! Must be seeded!
  21. volatile boolean Pulse = false; // "True" when User's live heartbeat is detected. "False" when not a "live beat".
  22. volatile boolean QS = false; // becomes true when Arduoino finds a beat.
  23.  
  24. static boolean serialVisual = true; // Set to 'false' by Default. Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse
  25.  
  26. volatile int rate[10]; // array to hold last ten IBI values
  27. volatile unsigned long sampleCounter = 0; // used to determine pulse timing
  28. volatile unsigned long lastBeatTime = 0; // used to find IBI
  29. volatile int P = 512; // used to find peak in pulse wave, seeded
  30. volatile int T = 512; // used to find trough in pulse wave, seeded
  31. volatile int thresh = 525; // used to find instant moment of heart beat, seeded
  32. volatile int amp = 100; // used to hold amplitude of pulse waveform, seeded
  33. volatile boolean firstBeat = true; // used to seed rate array so we startup with reasonable BPM
  34. volatile boolean secondBeat = false; // used to seed rate array so we startup with reasonable BPM
  35.  
  36.  
  37. OneWire one_wire( ONE_WIRE_BUS );
  38. DallasTemperature sensors( &one_wire );
  39.  
  40.  
  41.  
  42. typedef enum Mode_
  43. {
  44. MODE_NONE = 0,
  45. MODE_ECG = 1,
  46. MODE_TEMP = 2,
  47. MODE_BPM = 3,
  48. MODE_TEMP_BPM = 4
  49. } Mode_t;
  50. int selected_mode = MODE_NONE;
  51. boolean transmission_mode = true;
  52.  
  53.  
  54.  
  55. /* protos :) */
  56. int getBPM();
  57. void transmit( int bpm, int temperature );
  58. double getECG();
  59. double getTemperature();
  60.  
  61.  
  62. void setup()
  63. {
  64. Serial.begin( 115200 );
  65. Serial1.begin( 115200 );
  66.  
  67. pinMode( ECG1, INPUT );
  68. pinMode( ECG2, INPUT );
  69.  
  70. sensors.begin();
  71.  
  72. Serial.println( "Resetting ESP..." );
  73. pinMode( ESP_RESET, OUTPUT );
  74. digitalWrite( ESP_RESET, 0 );
  75. delay( 2000 );
  76. digitalWrite( ESP_RESET, 1 );
  77.  
  78.  
  79. Serial.println( "Waiting for ESP connectivity..." );
  80. while ( 1 )
  81. {
  82. while ( Serial1.available() > 0 ) Serial1.read();
  83.  
  84. Serial1.print( 'r' );
  85. delay( 50 );
  86. if ( Serial1.read() != 'r' )
  87. {
  88. Serial.print( "." );
  89. delay( 2000 );
  90. continue;
  91. }
  92. else break;
  93. }
  94. Serial.println();
  95. Serial.println( "ESP ready OK." );
  96.  
  97.  
  98. interruptSetup(); // sets up to read Pulse Sensor signal every 2mS
  99. // IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS THAN THE BOARD VOLTAGE,
  100. // UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE TO THE A-REF PIN
  101. // analogReference(EXTERNAL);
  102. }
  103.  
  104. void loop()
  105. {
  106. if ( Serial.available() > 0 )
  107. {
  108. String mode = Serial.readString();
  109. if ( mode.indexOf("temp") != -1 )
  110. selected_mode = MODE_TEMP;
  111. else if ( mode.indexOf("ecg") != -1 )
  112. {
  113. selected_mode = MODE_ECG;
  114. Serial.println( "ECG mode. You can change this mode at any time. " );
  115. Serial.println( "Options: temp, ecg, bpm, temp+bpm, transmission=[true/false], none" );
  116. delay( 2000 );
  117. }
  118. else if ( mode.indexOf("bpm") != -1 )
  119. selected_mode = MODE_BPM;
  120. else if ( mode.indexOf("transmission=true") != -1 )
  121. {
  122. transmission_mode = true;
  123. Serial.println( "Transmission ON." );
  124. }
  125. else if ( mode.indexOf("transmission=false") != -1 )
  126. {
  127. transmission_mode = false;
  128. Serial.println( "Transmission OFF." );
  129. }
  130. else if ( mode.indexOf("temp+bpm") != -1 )
  131. selected_mode = MODE_TEMP_BPM;
  132. else if ( mode.indexOf("none") != -1 )
  133. selected_mode = MODE_NONE;
  134. else
  135. {
  136. Serial.println( "Invalid mode :(! Options: temp, ecg, bpm, temp+bpm, transmission=[true/false], none" );
  137. selected_mode = MODE_NONE;
  138. }
  139. }
  140.  
  141. if ( selected_mode == MODE_NONE )
  142. {
  143. Serial.println( "No mode selected. Options: temp, ecg, bpm, temp+bpm, transmission=[true/false], none" );
  144. while ( Serial.available() <= 0 ){}
  145. return;
  146. }
  147.  
  148. if ( selected_mode == MODE_TEMP )
  149. {
  150. Serial.println( "Reading temperature.." );
  151. int temperature = getTemperature();
  152. Serial.print( "Temperature: " );
  153. Serial.println( temperature );
  154. if ( transmission_mode )
  155. transmit( -1, temperature );
  156. selected_mode = MODE_NONE;
  157. return;
  158. }
  159.  
  160. if ( selected_mode == MODE_ECG )
  161. {
  162. Serial.print( getECG() );
  163. Serial.print( " " );
  164. return;
  165. }
  166.  
  167. if ( selected_mode == MODE_BPM )
  168. {
  169. int bpm = getBPM();
  170. if ( transmission_mode )
  171. transmit( bpm, -1 );
  172. selected_mode = MODE_NONE;
  173. return;
  174. }
  175.  
  176. if ( selected_mode == MODE_TEMP_BPM )
  177. {
  178. Serial.println( "Reading temperature.." );
  179. int temperature = getTemperature();
  180. Serial.print( "Temperature: " );
  181. Serial.println( temperature );
  182.  
  183. int bpm = getBPM();
  184.  
  185. if ( transmission_mode )
  186. transmit( bpm, temperature );
  187.  
  188. selected_mode = MODE_NONE;
  189. return;
  190. }
  191. }
  192.  
  193. void transmit( int bpm, int temperature )
  194. {
  195.  
  196. if ( bpm < 0 && temperature < 0 )
  197. {
  198. Serial.println( "Both BPM and temperature are below 0. Skipping transmission." );
  199. return;
  200. }
  201.  
  202. Serial.print( "Transmitting.." );
  203.  
  204. Serial1.print( 'r' );
  205. while ( Serial1.read() != 'r' )
  206. Serial.print( "." );
  207. Serial.println( "ESP ready OK." );
  208.  
  209. char temp = (char) temperature;
  210. char hrt = (char) bpm;
  211.  
  212. if ( bpm < 0 )
  213. {
  214. String send = "t";
  215. send += temp;
  216. #ifndef NDEBUG
  217. Serial.print( "Sending: " );
  218. Serial.print( send[0] );
  219. Serial.print( (int) send[1] );
  220. #endif /* NDEBUG */
  221. Serial1.print( send );
  222. }
  223. else if ( temperature < 0 )
  224. {
  225. String send = "h";
  226. send += hrt;
  227. #ifndef NDEBUG
  228. Serial.print( "Sending: " );
  229. Serial.print( send[0] );
  230. Serial.print( (int) send[1] );
  231. #endif /* NDEBUG */
  232. Serial1.print( send );
  233. }
  234. else
  235. {
  236. String send = "b";
  237. send += temp;
  238. send += hrt;
  239. #ifndef NDEBUG
  240. Serial.print( "Sending: " );
  241. Serial.print( send[0] );
  242. Serial.print( (int) send[1] );
  243. Serial.print( (int) send[2] );
  244. #endif /* NDEBUG */
  245. Serial1.print( send );
  246. }
  247.  
  248. Serial.print( "Waiting for confirmation from ESP..." );
  249. while ( Serial1.read() != 'd' )
  250. Serial.print( "." );
  251. Serial.println();
  252. Serial.println( "ESP confirmed receipt." );
  253.  
  254. while ( Serial1.available() > 0 ) Serial1.read();
  255. }
  256.  
  257. int getBPM()
  258. {
  259. serialOutput();
  260.  
  261. if (QS == true) // A Heartbeat Was Found
  262. {
  263. // BPM and IBI have been Determined
  264. // Quantified Self "QS" true when arduino finds a heartbeat
  265. serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
  266. QS = false; // reset the Quantified Self flag for next time
  267. }
  268.  
  269. delay(20); // take a break
  270. return BPM;
  271. }
  272.  
  273. void interruptSetup()
  274. {
  275. // Initializes Timer2 to throw an interrupt every 2mS.
  276. TCCR2A = 0x02; // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  277. TCCR2B = 0x06; // DON'T FORCE COMPARE, 256 PRESCALER
  278. OCR2A = 0X7C; // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  279. TIMSK2 = 0x02; // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  280. sei(); // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
  281. }
  282.  
  283. void serialOutput()
  284. { // Decide How To Output Serial.
  285. if (serialVisual == true)
  286. {
  287. arduinoSerialMonitorVisual('-', Signal); // goes to function that makes Serial Monitor Visualizer
  288. }
  289. else
  290. {
  291. sendDataToSerial('S', Signal); // goes to sendDataToSerial function
  292. }
  293. }
  294.  
  295. void serialOutputWhenBeatHappens()
  296. {
  297. if (serialVisual == true) // Code to Make the Serial Monitor Visualizer Work
  298. {
  299. Serial.print(" Heart-Beat Found "); //ASCII Art Madness
  300. Serial.print("BPM: ");
  301. Serial.println(BPM/4);
  302. }
  303. else
  304. {
  305. sendDataToSerial('B',BPM); // send heart rate with a 'B' prefix
  306. sendDataToSerial('Q',IBI); // send time between beats with a 'Q' prefix
  307. }
  308. }
  309.  
  310. void arduinoSerialMonitorVisual(char symbol, int data )
  311. {
  312. const int sensorMin = 0; // sensor minimum, discovered through experiment
  313. const int sensorMax = 1024; // sensor maximum, discovered through experiment
  314. int sensorReading = data; // map the sensor range to a range of 12 options:
  315. int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
  316. // do something different depending on the
  317. // range value:
  318. }
  319.  
  320.  
  321. void sendDataToSerial(char symbol, int data )
  322. {
  323. Serial.print(symbol);
  324. Serial.println(data);
  325. }
  326.  
  327. ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
  328. {
  329. cli(); // disable interrupts while we do this
  330. Signal = analogRead(PULSE_PIN); // read the Pulse Sensor
  331. sampleCounter += 2; // keep track of the time in mS with this variable
  332. int N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid noise
  333. // find the peak and trough of the pulse wave
  334. if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
  335. {
  336. if (Signal < T) // T is the trough
  337. {
  338. T = Signal; // keep track of lowest point in pulse wave
  339. }
  340. }
  341.  
  342. if(Signal > thresh && Signal > P)
  343. { // thresh condition helps avoid noise
  344. P = Signal; // P is the peak
  345. } // keep track of highest point in pulse wave
  346.  
  347. // NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  348. // signal surges up in value every time there is a pulse
  349. if (N > 250)
  350. { // avoid high frequency noise
  351. if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
  352. {
  353. Pulse = true; // set the Pulse flag when we think there is a pulse
  354. digitalWrite(blinkPin,HIGH); // turn on pin 13 LED
  355. IBI = sampleCounter - lastBeatTime; // measure time between beats in mS
  356. lastBeatTime = sampleCounter; // keep track of time for next pulse
  357.  
  358. if(secondBeat)
  359. { // if this is the second beat, if secondBeat == TRUE
  360. secondBeat = false; // clear secondBeat flag
  361. for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
  362. {
  363. rate[i] = IBI;
  364. }
  365. }
  366.  
  367. if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
  368. {
  369. firstBeat = false; // clear firstBeat flag
  370. secondBeat = true; // set the second beat flag
  371. sei(); // enable interrupts again
  372. return; // IBI value is unreliable so discard it
  373. }
  374. // keep a running total of the last 10 IBI values
  375. word runningTotal = 0; // clear the runningTotal variable
  376.  
  377. for(int i=0; i<=8; i++)
  378. { // shift data in the rate array
  379. rate[i] = rate[i+1]; // and drop the oldest IBI value
  380. runningTotal += rate[i]; // add up the 9 oldest IBI values
  381. }
  382.  
  383. rate[9] = IBI; // add the latest IBI to the rate array
  384. runningTotal += rate[9]; // add the latest IBI to runningTotal
  385. runningTotal /= 10; // average the last 10 IBI values
  386. BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM!
  387. QS = true; // set Quantified Self flag
  388. // QS FLAG IS NOT CLEARED INSIDE THIS ISR
  389. }
  390. }
  391.  
  392. if (Signal < thresh && Pulse == true)
  393. { // when the values are going down, the beat is over
  394. digitalWrite(blinkPin,LOW); // turn off pin 13 LED
  395. Pulse = false; // reset the Pulse flag so we can do it again
  396. amp = P - T; // get amplitude of the pulse wave
  397. thresh = amp/2 + T; // set thresh at 50% of the amplitude
  398. P = thresh; // reset these for next time
  399. T = thresh;
  400. }
  401.  
  402. if (N > 2500)
  403. { // if 2.5 seconds go by without a beat
  404. thresh = 512; // set thresh default
  405. P = 512; // set P default
  406. T = 512; // set T default
  407. lastBeatTime = sampleCounter; // bring the lastBeatTime up to date
  408. firstBeat = true; // set these to avoid noise
  409. secondBeat = false; // when we get the heartbeat back
  410. }
  411.  
  412. sei(); // enable interrupts when youre done!
  413. }// end isr
  414.  
  415.  
  416. double getECG()
  417. {
  418. int ecg;
  419.  
  420. if ( (digitalRead(ECG1) == 1 ) || digitalRead(ECG2) == 1 )
  421. Serial.println( "!" );
  422. else
  423. {
  424. ecg = analogRead( ECG_PIN );
  425. Serial.println( ecg );
  426. }
  427.  
  428. delay(1);
  429.  
  430. return ecg;
  431. }
  432.  
  433. double getTemperature()
  434. {
  435. sensors.requestTemperatures();
  436. return sensors.getTempFByIndex( 0 );
  437. }
Add Comment
Please, Sign In to add comment