Skip to main content
edited tags
Link
Juraj
  • 18.3k
  • 4
  • 32
  • 50
added 2490 characters in body
Source Link
chrisl
  • 16.6k
  • 2
  • 18
  • 27

#include <LiquidCrystal.h>

#include <SoftwareSerial.h>

float pulse = 0;

float temp = 0;

SoftwareSerial ser(9,10);

String apiKey = "U5AGYVQT5JRJPSDR";

// Variables

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

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

int fadePin = 8; // pin to do fancy classy fading blink at each beat

int fadeRate = 0; // used to fade LED on with PWM on fadePin

LiquidCrystal lcd(13, 12, 6, 5, 4, 3);

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

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

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Engineers Garage");

ser.begin(9600);

ser.println("AT");

delay(1000);

ser.println("AT+GMR");

delay(1000);

ser.println("AT+CWMODE=3");

delay(1000);

ser.println("AT+RST");

delay(5000);

ser.println("AT+CIPMUX=1");

delay(1000);

String cmd="AT+CWJAP="EngineersGarage","egP@$$w0rd?"";

ser.println(cmd);

delay(1000);

ser.println("AT+CIFSR");

delay(1000);

}

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

  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

read_temp();

esp_8266();

}

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

}

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 Happened *** ");  //ASCII Art Madness

 Serial.print("BPM: ");

 Serial.println(BPM);

 lcd.clear();

 lcd.print("BPM: ");

 lcd.print(BPM);

}

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:

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;

}

}

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#include noise<LiquidCrystal.h>

  P = Signal;                             // P is the#include peak<SoftwareSerial.h>

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

  {     float pulse = 0;

   float Pulsetemp = true;                               // set the Pulse flag when we think there is a pulse0;

    digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED

    IBI = sampleCounter - lastBeatTime;         // measure time between beats inSoftwareSerial mSser(9,10);

    lastBeatTime = sampleCounter;               // keep track of time for next pulse

String apiKey = "U5AGYVQT5JRJPSDR";


  //  if(secondBeat)Variables

    {    int pulsePin = A0;                 // if thisPulse isSensor thepurple secondwire beat,connected ifto secondBeatanalog ==pin TRUE0

int blinkPin = 7   secondBeat = false;      ;                // clearpin secondBeatto flagblink led at each beat

int fadePin = 8;   for(int i=0; i<=9; i++) // seed the running total       // pin to getdo afancy realisiticclassy BPMfading blink at startupeach beat

int fadeRate = 0;   {              // used to fade LED on with PWM on fadePin

        rate[i] = IBI;                      

LiquidCrystal lcd(13, 12, 6, 5, 4, }3);

    }

// Volatile Variables, used in the interrupt service routine!

volatile int BPM;                   // int that holds raw Analog in 0. updated every 2mS

volatile int Signal;  if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE// holds the incoming raw data

volatile int IBI = {600;             // int that holds the time interval between beats! Must be seeded! 

    volatile boolean firstBeatPulse = false;        // "True" when User's live heartbeat is detected. "False" when not
 //a clear"live firstBeatbeat". flag

    volatile boolean secondBeatQS = true;        false;        // becomes true //when setArduoino thefinds seconda beat flag.

      sei();                               // enable interrupts again

      return;                          // Regards Serial OutPut // IBI-- valueSet isThis unreliableUp soto discardyour itneeds

static boolean serialVisual = }true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino 
Serial Monitor ASCII Visual Pulse 

  // keep a running total of the last 10 IBI values

volatile int wordrate[10]; runningTotal = 0;                   // clear thearray runningTotalto variablehold last ten IBI values

volatile unsigned long sampleCounter = 0;          // used to determine pulse timing

volatile unsigned for(intlong i=0;lastBeatTime i<=8;= i++)0;           // used to find IBI

volatile int P = {512;                      // shiftused datato find peak in thepulse ratewave, arrayseeded

volatile int T = 512;  rate[i] = rate[i+1];                  // andused dropto thefind oldesttrough IBIin valuepulse wave, seeded

volatile int thresh = 525;  runningTotal += rate[i];            // used to find instant moment of heart beat, seeded

volatile int amp = 100;                   // addused 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!

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

  lcd.clear();

  lcd.setCursor(0,0);

  lcd.print("Engineers Garage");


  ser.begin(9600);


  ser.println("AT");

  delay(1000);

  ser.println("AT+GMR");

  delay(1000);

  ser.println("AT+CWMODE=3");

  delay(1000);

  ser.println("AT+RST");

  delay(5000);

  ser.println("AT+CIPMUX=1");

  delay(1000);

  String cmd="AT+CWJAP="EngineersGarage","egP@$$w0rd?"";

  ser.println(cmd);

  delay(1000);

  ser.println("AT+CIFSR");

  delay(1000);

}


//  Where the 9Magic oldestHappens

void loop()

{

   serialOutput();  

   

  if (QS == true) // A Heartbeat Was Found

    {     

      // BPM and IBI valueshave been Determined

      // Quantified Self "QS" true when arduino finds a heartbeat

      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    

    }

     

  rate[9] = IBI;                         ledFadeToBeat(); // addMakes the latest IBILED toFade theEffect rateHappen array

  runningTotal += rate[9];               delay(20); // add the latest IBItake toa runningTotalbreak

  runningTotal /= 10;                     // average the last 10 IBI values 

  BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!read_temp();

  QS = true;                              // set Quantified Self flag 

  // QS FLAG IS NOT CLEARED INSIDE THIS ISResp_8266();

  pulse = BPM;}

}                       

}

if (Signal < thresh && Pulse == true)

{   // when the values are going down, the beat is over

 void digitalWriteledFadeToBeat(blinkPin,LOW);            // turn off pin 13 LED

  Pulse = false;                         // reset the Pulse flag so we can do it again{

  amp = PfadeRate - T; = 15;                         // get amplitude ofset theLED pulsefade wavevalue

  thresh = amp/2 + T;            fadeRate = constrain(fadeRate,0,255);   //  keep //LED setfade threshvalue atfrom 50%going ofinto thenegative amplitudenumbers!

  P = thresh;                  analogWrite(fadePin,fadeRate);          // reset these for nextfade timeLED

  T =}


void thresh;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

   }        

}

if (N > 2500)

{                           // if 2.5 seconds go by without a beat

  thresh = 512;                          // set thresh default

  P = 512;                               // set Pvoid defaultserialOutputWhenBeatHappens()

  T = 512;                              { // set T default

  lastBeatTime = sampleCounter;      if (serialVisual == true) // bring the lastBeatTime upCode to date   Make the Serial Monitor Visualizer Work

  firstBeat = true;           {           // set these to avoid noise

  secondBeat = false; Serial.print("*** Heart-Beat Happened *** ");  //ASCII Art Madness

     Serial.print("BPM: ");

     //Serial.println(BPM);

 when we get the heartbeatlcd.clear();

 back    lcd.print("BPM: ");

     lcd.print(BPM);

   }

 else

   {

     sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix

     sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix

   }   

}

sei(); // enable interrupts when youre done!

}// end isr

void esp_8266()

{

// TCP connection AT+CIPSTART=4,"TCP","184.106.153.149",80

String cmd = "AT+CIPSTART=4,"TCP","";

cmd += "184.106.153.149"; // api.thingspeak.com

cmdvoid +=arduinoSerialMonitorVisual(char ""symbol,80"; int data )

ser.println(cmd);{    

Serial.println(cmd);  const int sensorMin = 0;      // sensor minimum, discovered through experiment

if(ser.find  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("Error"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;

  } 

}



void sendDataToSerial(char symbol, int data )

{

   Serial.printlnprint("AT+CIPSTART error"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

      pulse = BPM;

    }                       

  }


  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


void esp_8266()

{

   // TCP connection AT+CIPSTART=4,"TCP","184.106.153.149",80 

    String cmd = "AT+CIPSTART=4,"TCP","";

    cmd += "184.106.153.149"; // api.thingspeak.com

    cmd += "",80";

    ser.println(cmd);

    Serial.println(cmd); 

    if(ser.find("Error"))

    {

      Serial.println("AT+CIPSTART error");

      return;

    }

  // prepare GET string GET https://api.thingspeak.com/update?api_key=LHAG4NSIYJ5UWS6U&field1=0rnrn

  String getStr = "GET /update?api_key=";

  getStr += apiKey;

  getStr +="&field1=";

  getStr +=String(temp);

  getStr +="&field2=";

  getStr +=String(pulse);

  getStr += "rnrn";

  // send data length

  cmd = "AT+CIPSEND=4,";

  cmd += String(getStr.length());

  ser.println(cmd);

  Serial.println(cmd);

  delay(1000);

  ser.print(getStr);

  Serial.println(getStr);

 //thingspeak needs 15 sec delay between updates

  delay(3000);

}


void read_temp()

{

  int temp_val =  analogRead(A1);

  float mv = (temp_val/1024.0)*5000; 

  float cel = mv/10;

  temp = (cel*9)/5 + 32;

}

// prepare GET string GET https://api.thingspeak.com/update?api_key=LHAG4NSIYJ5UWS6U&field1=0rnrn

String getStr = "GET /update?api_key=";

getStr += apiKey;

getStr +="&field1=";

getStr +=String(temp);

getStr +="&field2=";

getStr +=String(pulse);

getStr += "rnrn";

// send data length

cmd = "AT+CIPSEND=4,";

cmd += String(getStr.length());

ser.println(cmd);

Serial.println(cmd);

delay(1000);

ser.print(getStr);

Serial.println(getStr);

//thingspeak needs 15 sec delay between updates

delay(3000);

}

void read_temp()

{

int temp_val = analogRead(A1);

float mv = (temp_val/1024.0)*5000;

float cel = mv/10;

temp = (cel*9)/5 + 32;

}

#include <LiquidCrystal.h>

#include <SoftwareSerial.h>

float pulse = 0;

float temp = 0;

SoftwareSerial ser(9,10);

String apiKey = "U5AGYVQT5JRJPSDR";

// Variables

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

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

int fadePin = 8; // pin to do fancy classy fading blink at each beat

int fadeRate = 0; // used to fade LED on with PWM on fadePin

LiquidCrystal lcd(13, 12, 6, 5, 4, 3);

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

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

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Engineers Garage");

ser.begin(9600);

ser.println("AT");

delay(1000);

ser.println("AT+GMR");

delay(1000);

ser.println("AT+CWMODE=3");

delay(1000);

ser.println("AT+RST");

delay(5000);

ser.println("AT+CIPMUX=1");

delay(1000);

String cmd="AT+CWJAP="EngineersGarage","egP@$$w0rd?"";

ser.println(cmd);

delay(1000);

ser.println("AT+CIFSR");

delay(1000);

}

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

  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

read_temp();

esp_8266();

}

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

}

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 Happened *** ");  //ASCII Art Madness

 Serial.print("BPM: ");

 Serial.println(BPM);

 lcd.clear();

 lcd.print("BPM: ");

 lcd.print(BPM);

}

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:

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;

}

}

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

  pulse = BPM;

}                       

}

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

void esp_8266()

{

// TCP connection AT+CIPSTART=4,"TCP","184.106.153.149",80

String cmd = "AT+CIPSTART=4,"TCP","";

cmd += "184.106.153.149"; // api.thingspeak.com

cmd += "",80";

ser.println(cmd);

Serial.println(cmd); 

if(ser.find("Error"))

{

  Serial.println("AT+CIPSTART error");

  return;

}

// prepare GET string GET https://api.thingspeak.com/update?api_key=LHAG4NSIYJ5UWS6U&field1=0rnrn

String getStr = "GET /update?api_key=";

getStr += apiKey;

getStr +="&field1=";

getStr +=String(temp);

getStr +="&field2=";

getStr +=String(pulse);

getStr += "rnrn";

// send data length

cmd = "AT+CIPSEND=4,";

cmd += String(getStr.length());

ser.println(cmd);

Serial.println(cmd);

delay(1000);

ser.print(getStr);

Serial.println(getStr);

//thingspeak needs 15 sec delay between updates

delay(3000);

}

void read_temp()

{

int temp_val = analogRead(A1);

float mv = (temp_val/1024.0)*5000;

float cel = mv/10;

temp = (cel*9)/5 + 32;

}

#include <LiquidCrystal.h>

#include <SoftwareSerial.h>


float pulse = 0;

float temp = 0;


SoftwareSerial ser(9,10);


String apiKey = "U5AGYVQT5JRJPSDR";


//  Variables

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

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

int fadePin = 8;                  // pin to do fancy classy fading blink at each beat

int fadeRate = 0;                 // used to fade LED on with PWM on fadePin


LiquidCrystal lcd(13, 12, 6, 5, 4, 3);


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

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

  lcd.clear();

  lcd.setCursor(0,0);

  lcd.print("Engineers Garage");


  ser.begin(9600);


  ser.println("AT");

  delay(1000);

  ser.println("AT+GMR");

  delay(1000);

  ser.println("AT+CWMODE=3");

  delay(1000);

  ser.println("AT+RST");

  delay(5000);

  ser.println("AT+CIPMUX=1");

  delay(1000);

  String cmd="AT+CWJAP="EngineersGarage","egP@$$w0rd?"";

  ser.println(cmd);

  delay(1000);

  ser.println("AT+CIFSR");

  delay(1000);

}


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

      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


  read_temp();

  

  esp_8266();

}


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

}


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 Happened *** ");  //ASCII Art Madness

     Serial.print("BPM: ");

     Serial.println(BPM);

     lcd.clear();

     lcd.print("BPM: ");

     lcd.print(BPM);

   }

 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:

  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;

  } 

}



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

      pulse = BPM;

    }                       

  }


  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


void esp_8266()

{

   // TCP connection AT+CIPSTART=4,"TCP","184.106.153.149",80 

    String cmd = "AT+CIPSTART=4,"TCP","";

    cmd += "184.106.153.149"; // api.thingspeak.com

    cmd += "",80";

    ser.println(cmd);

    Serial.println(cmd); 

    if(ser.find("Error"))

    {

      Serial.println("AT+CIPSTART error");

      return;

    }

  // prepare GET string GET https://api.thingspeak.com/update?api_key=LHAG4NSIYJ5UWS6U&field1=0rnrn

  String getStr = "GET /update?api_key=";

  getStr += apiKey;

  getStr +="&field1=";

  getStr +=String(temp);

  getStr +="&field2=";

  getStr +=String(pulse);

  getStr += "rnrn";

  // send data length

  cmd = "AT+CIPSEND=4,";

  cmd += String(getStr.length());

  ser.println(cmd);

  Serial.println(cmd);

  delay(1000);

  ser.print(getStr);

  Serial.println(getStr);

 //thingspeak needs 15 sec delay between updates

  delay(3000);

}


void read_temp()

{

  int temp_val =  analogRead(A1);

  float mv = (temp_val/1024.0)*5000; 

  float cel = mv/10;

  temp = (cel*9)/5 + 32;

}
Source Link

no matching function to call for SoftwareSerial::SoftwareSerial(int&,int&)? How to rectify this problem

#include <LiquidCrystal.h>

#include <SoftwareSerial.h>

float pulse = 0;

float temp = 0;

SoftwareSerial ser(9,10);

String apiKey = "U5AGYVQT5JRJPSDR";

// Variables

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

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

int fadePin = 8; // pin to do fancy classy fading blink at each beat

int fadeRate = 0; // used to fade LED on with PWM on fadePin

LiquidCrystal lcd(13, 12, 6, 5, 4, 3);

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

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

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Engineers Garage");

ser.begin(9600);

ser.println("AT");

delay(1000);

ser.println("AT+GMR");

delay(1000);

ser.println("AT+CWMODE=3");

delay(1000);

ser.println("AT+RST");

delay(5000);

ser.println("AT+CIPMUX=1");

delay(1000);

String cmd="AT+CWJAP="EngineersGarage","egP@$$w0rd?"";

ser.println(cmd);

delay(1000);

ser.println("AT+CIFSR");

delay(1000);

}

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

  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

read_temp();

esp_8266();

}

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

}

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 Happened *** ");  //ASCII Art Madness

 Serial.print("BPM: ");

 Serial.println(BPM);

 lcd.clear();

 lcd.print("BPM: ");

 lcd.print(BPM);

}

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:

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;

}

}

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

  pulse = BPM;

}                       

}

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

void esp_8266()

{

// TCP connection AT+CIPSTART=4,"TCP","184.106.153.149",80

String cmd = "AT+CIPSTART=4,"TCP","";

cmd += "184.106.153.149"; // api.thingspeak.com

cmd += "",80";

ser.println(cmd);

Serial.println(cmd); 

if(ser.find("Error"))

{

  Serial.println("AT+CIPSTART error");

  return;

}

// prepare GET string GET https://api.thingspeak.com/update?api_key=LHAG4NSIYJ5UWS6U&field1=0rnrn

String getStr = "GET /update?api_key=";

getStr += apiKey;

getStr +="&field1=";

getStr +=String(temp);

getStr +="&field2=";

getStr +=String(pulse);

getStr += "rnrn";

// send data length

cmd = "AT+CIPSEND=4,";

cmd += String(getStr.length());

ser.println(cmd);

Serial.println(cmd);

delay(1000);

ser.print(getStr);

Serial.println(getStr);

//thingspeak needs 15 sec delay between updates

delay(3000);

}

void read_temp()

{

int temp_val = analogRead(A1);

float mv = (temp_val/1024.0)*5000;

float cel = mv/10;

temp = (cel*9)/5 + 32;

}