Generating Live Heartbeat

Building a Heartbeat monitor from ESP32 and pulse sensor


ECG or electrocardiogram is a device that records heartbeat using electrical signals from the body. An ECG device is used to detect anomalies in the heart rate and diagnose diseases like heart attack. It uses electrodes which are placed on the body to catch signals and then plots it on a graph. The data from an ECG sensor looks as shown in the figure 1 below:

Figure 1: Data from ECG Sensor

Each segment and interval refers to a particular position of blood in the heart. For example, the P wave refers to the depolarization(contraction) of the atria. The QRS signal represents the contraction of the ventricles. The T wave is the re-polarization or relaxation of the ventricles. This cycle repeats after every heartbeat.

In this article, I will demonstrate how to capture and plot live data using an ESP32 board and pulse sensor (also known as SPO2 sensor). This data is further used to find out the BPM (beats per minute) and the pulse.

Requisite Hardware and software

For the purpose of this study, an ESP-32S board (an Arduino board can also be used instead of the ESP32 board), a pulse or SPO2 sensor and some female to female jumper wires would be used . These devices are depicted in Fig 2 and 3 .

The necessary softwares needed for this study are python IDE and Arduino IDE.

Collecting Live data from the sensors

The pulse sensor uses the oxygen levels in the blood to record heartbeat. The heart constantly pumps out deoxygenated and oxygenated blood to all parts of the body alternatively. In other words, all parts of the body alternatively receive blood which only contains hemoglobin or deoxygenated blood and blood which contains oxygen and hemoglobin (known as oxyhemoglobin) or oxygenated blood. Deoxygenated blood and oxygenated blood reflect different amounts of light. So when we place a finger on the LED of the pulse sensor, the sensor measures the amount of light reflected by the finger at that instant and records the beat.

An ESP32 board acts like a mini computer which has 16 GPIO (General purpose Input/Output) pins. These pins are used for providing input and output. Some of these GPIO pins are also analog to digital converter(ADC) pins. These ADC pins play a pivotal role since the data being received from the ECG sensors is analog and needs to be digitized. Analog data refers to data that is in a range or interval of several values while digital data means that the data is either 0 or 1 (high or low). Since the computer only understands digital data , it is necessary to convert analog data to digital data.

The steps to capture heartbeat are as follows:

a) Connect SP02 sensor to ESP32 board: The wires in the SPO2 sensor are connected to the ESP32 board using female to female jumper wires. There are three wires on the sensor. The positive wire or the cathode (marked as +) is connected to the output voltage (3.3 V or 5 V) on the ESP32. The backside of the ESP32 board contains markings (3V3 and 5V) indicating these power voltages. The positive wire of the sensor can be connected to either of these two places, although it is preferable to use the 3.3 V. The negative wire or the anode (marked as -) is connected to the ground. The ESP32 board contains 3 pins for the ground. The anode can be connected to any of these pins. Lastly, the S or the signal pin is connected to an ADC pin (P33-P36).

b) Connect ESP32 board to laptop: The ESP32 board has a USB jack at the extreme end. Any USB data cable can be used to connect the ESP32 to the computer through this USB jack. As soon as the USB is connected, a light lights up on the ESP32 board and the pulse sensor indicating that they are correctly attached. If any one of the devices does not light up, it means that the wires have been wrongly connected.

c) Configure and write code in Arduino IDE: First, make sure that the correct board (ESP32 Dev module) is selected in the Tools tab of Arduino IDE. Also, ensure that the correct COM port is selected. The COM port can be checked by navigating to the device manager’s menu and checking which COM port is the outgoing port for Silicon Arts(UART).

Fig 4: Arduino Code

In any Arduino code there are two necessary functions — setup () and loop () as shown above in figure 4. Anything that needs to be executed only once is written in the setup () while anything that needs to be executed in a loop is written in loop (). Serial. begin (115200) initiates the serial monitor where the data will be plotted. The parameter to this function is the baud rate (the rate at which the serial monitor receives the data).

Next, in the loop function the data is read from the SPO2 sensor using the analogRead function (34 is the ADC pin being used here, you can use any ADC pin and mention the pin number here). This is stored in an integer variable val which is then plotted using the Serial.println() command. The delay function takes data after every 10 milliseconds. This delay function is an important step because otherwise the data will arrive too fast and we will not be able to analyze it.

d) Upload the code on ESP32 board: After the Arduino code is compiled, it can be uploaded by clicking the arrow button next to the verify option. This uploads the code onto the ESP32.

e) Plotting Live Data: Once the code is successfully uploaded, gently place your finger on the LED of the pulse sensor. A graph of the data can be seen by opening the serial plotter under the Tools Tab. This graph will look something as shown below in fig 5.

Fig 5: Serial Plotter Output

Sometimes the graph might not look like as expected. The possible cause for this can be power interference (The power voltage can interfere with actual data in case there is a AC power source nearby and create noise in the data). In such case, the laptop should be kept away from any power source.

f) Sending data through the Bluetooth: The data plotted on the serial plotter of Arduino IDE cannot be manipulated in any way and so it is also not very easy to remove noise on the Arduino IDE. Hence to solve such issues, the data received on the Arduino IDE is sent to Python IDE through the Bluetooth. The code to send data from Arduino to python through the Bluetooth is shown below in Fig 6.

Fig 6: Bluetooth communication using Arduino

Here in the setup function, a serial Bluetooth function is initialized along with the serial monitor. The outgoing Bluetooth port can be checked from the Bluetooth settings of the system. In our case COM 6 belonged to “Vani_Bluetooth outgoing”. This port is selected in Arduino IDE in the Tools tab and the code is uploaded hereafter.

g) Receiving data in Python through Bluetooth: The code to capture data through Bluetooth is shown below in Fig. 7.

First, the serial library is imported which lets us connect and access the Bluetooth com port. The data is then read and printed. This data however also contains a lot of other characters apart from integers , which is the data that we require here. The data from the Bluetooth is therefore casted into an integer and again stored in another variable which is then printed.

Figure 7: Code to receive data on Python

Once the data is received on python, we can manipulate it in any way and plot it using the library Matplotlib.

Calculating the BPM and the pulse

The BPM or the beats per minute, as the name suggests, is the speed of the heart beat measured by the number of cycles per minute. A normal heart rate differs from person to person, however, the average rate of a healthy human adult is 60–100 bpm. It is important to find out the BPM so that one can identify any changes or irregularities in the heart that could point to a possible disease. The pulse, here, refers to digitized bpm. This means that bpm can range over a number of values(analog) but the pulse can only take two values — high and low(digital). Therefore, the bpm represents the numerical heart rate while the pulse represents the rhythmic beating of the heart and not the actual number of beats.

A sample code in fig 8 shows how we can measure the heart rate of the data received using the pulse sensor. In this code we first set a threshold. If the signal is above the threshold , the pulse value is high (here we have taken the high value as 40). Now once the signal comes back down the threshold, a Boolean variable ‘pd’ is turned true and the pulse value becomes low. Once the signal goes up the threshold again, the counter increases. So every time the signal is above the threshold the counter is increased. This way the number of beats in 5 seconds is counted and then this number is multiplied by 12 to get the BPM. This method of finding the number of beats every 5 seconds, although reduces accuracy, lessens the computation required.

Figure 8: Sample code for BPM calculation


To summarize this article, we use the SPO2 sensor and ESP32 board to gather live data. This data is read using Arduino IDE and then also sent to Python through the Bluetooth. The BPM and the pulse of the data received are also calculated to find any irregularities in the data

This study can further be extended to include Machine learning . A machine learning model can be applied to the data received by the SPO2 sensor and can be used to detect anomalies in the heart. Machine learning can also be used to quickly differentiate between noise and actual data. Furthermore, since it is quite easy to setup and get the data, other diseases related to the lungs or the blood flow may also be detected using this method.