(BPM) Pulse Rate Monitoring over Internet using ThingSpeak & ESP8266

Pulse Rate Monitoring over Internet using ThingSpeak (Last Updated On: December 1, 2018)

Pulse Rate Monitoring over Internet using ThingSpeak & ESP8266:

In this project we are going to make Pulse Rate Monitoring over Internet using ThingSpeak & ESP8266 with Arduino that will detect the pulse rate using the Pulse Sensor and will show the readings in BPM (Beats Per Minute) on the LCD display as well as on Internet. It will send the readings to ThingSpeak server via Wi-Fi module ESP8266, which can help to monitor the heart beat via Internet at any part of the world.

ThingSpeak is an open source Internet of Things (IoT) application and API to store and retrieve data from things using the HTTP protocol over the Internet or via a Local Area Network.





You can check our previous project, i.e Heartbeat/Pulse/BPM Rate Monitor using Arduino & Pulse Sensor. This is basic pulse rate monitoring system if you are a beginner.


Components Required:

1. Arduino UNO Board
2. ESP8266 Wi-Fi Module -  (Buy Online from Amazone)
3. Pulse Sensor -  (Buy Online from Amazone)
4. 16*2 LCD Display
5. Resistor 2K
6. Resistor 1K
8. LED
9. Breadboard
10. Connecting Wires

Pulse Sensor:

Pulse Rate Monitoring over Internet using ThingSpeak & ESP8266

The Pulse Sensor is a plug-and-play heart-rate sensor for Arduino. It can be used by students, artists, athletes, makers, and game & mobile developers who want to easily incorporate live heart-rate data into their projects.Essence it is an integrated optical amplifying circuit and noise eliminating circuit sensor. Clip the Pulse Sensor to your earlobe or finger tip and plug it into your Arduino ,you can ready to read heart rate. Also it have an Arduino demo code that make it easy to use.

The pulse sensor has three pins: VCC, GND & Analog Pin.

Pulse Rate Monitoring over Internet using ThingSpeak & ESP8266

There is also a LED in the center of this sensor module which helps in detecting the heartbeat. Below the LED, there is a noise elimination circuitry which is supposed to keep away the noise from affecting the readings.




ESP8266:

The ESP8266 is a very user friendly and low cost device to provide internet connectivity to your projects. The module can work both as a Access point (can create hotspot) and as a station (can connect to Wi-Fi), hence it can easily fetch data and upload it to the internet making Internet of Things as easy as possible. It can also fetch data from internet using API’s hence your project could access any information that is available in the internet, thus making it smarter. Another exciting feature of this module is that it can be programmed using the Arduino IDE which makes it a lot more user friendly.

Pulse Rate Monitoring over Internet using ThingSpeak

The ESP8266 module works with 3.3V only, anything more than 3.7V would kill the module hence be cautions with your circuits. Here are its pins description.

Pin 1 : Ground : Connected to the ground of the circuit
Pin 2 : Tx/GPIO – 1 : Connected to Rx pin of programmer/uC to upload program
Pin 3 : GPIO – 2 : General purpose Input/output pin
Pin 4 : CH_EN : Chip Enable/Active high
Pin 5 : Flash/GPIO – 0 : General purpose Input/output pin
Pin 6 : Reset : Resets the module
Pin 7 : RX/GPIO – 3 : General purpose Input/output pin
Pin 8 : Vcc : Connect to +3.3V only


Circuit Diagram & Connections:

For designing Pulse Rate Monitoring over Internet using ThingSpeak & ESP8266, assemble the circuit as shown in the figure below.

Pulse Rate Monitoring over Internet using ThingSpeak

1. Connect Pulse Sensor output pin to A0 of Arduino and other two pins to VCC & GND.
2. Connect the LED to Digital Pin 7 of Arduino via 220 ohm resistor.
3. Connect Pin 1,3,5,16 of LCD to GND.
4. Connect Pin 2,15 of LCD to VCC.
5. Connect Pin 4,6,11,12,13,14 of LCD to Digital Pin12,11,5,4,3,2 of Arduino.
6. The RX pin of ESP8266 works on 3.3V and it will not communicate with the Arduino when we will connect it directly to the Arduino. So, we will have to make a voltage divider for it which will convert the 5V into 3.3V. This can be done by connecting 2.2K & 1K resistor. Thus the RX pin of the ESP8266 is connected to the pin 10 of Arduino through the resistors.
7. Connect the TX pin of the ESP8266 to the pin 9 of the Arduino.


Setting the ThingSpeak:

ThingSpeak provides very good tool for IoT based projects. By using ThingSpeak site, we can monitor our data and control our system over the Internet, using the Channels and web pages provided by ThingSpeak. So first you need to sign up for ThingSpeak. So visit https://thingspeak.com and create an account.
Pulse Rate Monitoring over Internet using ThingSpeak

Then create a new channel and set up what you want. The tutorial in the video below. Follow the video for more clearifications.



Then create the API keys. This key is required for programming modifications and setting your data.
Pulse Rate Monitoring over Internet using ThingSpeak

Then upload the code to the Arduino UNO by assembling the circuit shown above. Open serial monitor and it will automatically connect to Wi-Fi and set up everything.

Now cick on channels so that you can see the online data streaming, i.e Pulse Rate Monitoring over Internet using ThingSpeak & ESP8266 with Arduino as shown in figure here.
Pulse Rate Monitoring over Internet using ThingSpeak


Source Code/Program:

The source code for the project Pulse Rate Monitoring over Internet using ThingSpeak & ESP8266 with Arduino is given below. Simply copy the code and paste it to your Arduino IDE, then compile it and upload to your Arduino UNO Board.

#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(9,10);
#include <LiquidCrystal.h>
#include <stdlib.h>
LiquidCrystal lcd(12,11,5,4,3,2);

#define SSID "Alexahome" // "SSID-WiFiname"
#define PASS "98765432" // "password"
#define IP "184.106.153.149"// thingspeak.com ip
String msg = "GET /update?key=W86OQNB83XEQIMN4"; //change it with your api key

//Variables
float temp;
int hum;
String tempC;
int error;
int pulsePin = 0; // Pulse Sensor connected to analog pin
int blinkPin = 7; // pin to blink led at each beat
int fadePin = 5;
int fadeRate = 0;

// 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 heartbeat is detected. "False" when not a "live beat".
volatile boolean QS = false; // becomes true when Arduino finds a beat.

// Regards Serial OutPut -- Set This Up to your needs
static boolean serialVisual = true; // Set to 'false' by Default.
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
volatile int T = 512; // used to find trough in pulse wave
volatile int thresh = 525; // used to find instant moment of heart beat
volatile int amp = 100; // used to hold amplitude of pulse waveform
volatile boolean firstBeat = true; // used to seed rate array
volatile boolean secondBeat = false; // used to seed rate array

void setup()
{
lcd.begin(16, 2);
lcd.print("Connecting...");
Serial.begin(9600);
esp8266.begin(9600);
Serial.println("AT");
esp8266.println("AT");
delay(5000);
if(esp8266.find("OK")){
connectWiFi();
}
interruptSetup();
}

void loop(){
lcd.clear();
start:
error=0;
lcd.setCursor(0, 0);
lcd.print("BPM = ");
lcd.print(BPM);
delay (100);
lcd.setCursor(0, 1); // set the cursor to column 0, line 2
delay(1000);
updatebeat();
if (error==1){
goto start; //go to label "start"
}

delay(1000);
}

void updatebeat(){
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
esp8266.println(cmd);
delay(2000);
if(esp8266.find("Error")){
return;
}
cmd = msg ;
cmd += "&field1=";
cmd += BPM;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
esp8266.print("AT+CIPSEND=");
Serial.println(cmd.length());
esp8266.println(cmd.length());
if(esp8266.find(">")){
Serial.print(cmd);
esp8266.print(cmd);
}
else{
Serial.println("AT+CIPCLOSE");
esp8266.println("AT+CIPCLOSE");
error=1;
}
}

boolean connectWiFi(){
Serial.println("AT+CWMODE=1");
esp8266.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.println(cmd);
esp8266.println(cmd);
delay(5000);
if(esp8266.find("OK")){
Serial.println("OK");
return true;
}else{
return false;
}
}

void interruptSetup(){
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
}

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

if (N > 250){ // avoid high frequency noise
if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){
Pulse = true; // set the Pulse flag when there is a pulse
digitalWrite(blinkPin,HIGH); // turn on pin 13 LED
IBI = sampleCounter - lastBeatTime; // time between beats in mS
lastBeatTime = sampleCounter; // keep track of time for next pulse

if(secondBeat){ // if this is the second beat
secondBeat = false; // clear secondBeat flag
for(int i=0; i<=9; i++){ // seed the running total to get a realistic BPM at startup
rate[i] = IBI;
}
}

if(firstBeat){ // if it's the first time beat is found
firstBeat = false; // clear firstBeat flag
secondBeat = true; // set the second beat flag
sei(); // enable interrupts again
return; // IBI value is unreliable so discard it
}
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
}
}

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

Video Tutorial & Explanation:

Watch this full video for full understanding and setting up things.





Leave a Reply

Your email address will not be published. Required fields are marked *