MicroPython based:TPYBoard heart rate monitor

Showroom for MicroPython related hardware projects.
Target audience: Users wanting to show off their project!
Post Reply
Jackli
Posts: 80
Joined: Thu Apr 29, 2021 9:11 am

MicroPython based:TPYBoard heart rate monitor

Post by Jackli » Wed Jul 14, 2021 9:32 am

A few days ago I was looking at a heart rate monitoring project and I tried to write the simplest one using Micropython.
https://www.instructables.com/LCD-Ardui ... eart-Rate/

I. Methods of heart rate monitoring

1、PPG photoelectric volume method

Because the human skin, bones, muscles, fat, etc. for the light reflection is a fixed value, while capillaries and arteries, veins, as the pulse volume keeps getting bigger and smaller, so the light reflection value is fluctuating value, and this fluctuation value is exactly the same as the heart rate, so the photoelectric volume method is precisely through this fluctuation frequency to determine the user's heart rate data. At present, most of the smart bracelets/watches on the market use this method to monitor heart rate, and the technical solution of this method has been relatively mature, so the price is also relatively low.

2、Heart rate signal measurement method

There is another is the ECG signal measurement method, it is through the smart wearable device equipped with sensors to capture the tiny electrode changes in each heartbeat, and then through the algorithm to restore the frequency of heart rate beating, the principle and ECG similar principle. At present, there are few smart wearable devices using this method.


II. the production process of TPYBoard heart rate monitor

So much has been said above, and then we will enter the main topic. Start the production of heart rate monitor. First, let's introduce the most important device inside - MAX30102 heart rate module.

MAX30102 heart rate module introduction

MAX30102 is an integrated pulse oximeter and heart rate monitor biosensor module. It integrates a red light LEO and an infrared light LEO, photodetectors, optical devices, and low-noise electronic circuitry with ambient light suppression. MAX30102 uses a 1.8V power supply and a separate 5.0V power supply for the internal LEO, and is used in wearable devices for heart rate and blood oxygen collection detection, worn on the finger, earlobe, and wrist. The standard I2C-compatible communication interface can transmit the collected values to microcontrollers such as Arduino, STM32, etc. for heart rate and blood oxygen calculation. In addition, the chip can shut down the module through software, the standby current is close to zero, so that the power supply is always maintained.

Image

A display is also needed for the display, and here I chose to use an OLED display (of course, you can also choose an LCD display). First, refer to the information below to connect the hardware.

Image

After connecting the line, the MAX30102 module of the relevant driver files copied to the TPYBFLASH disk, and then write main.py. Save the finished, use PuTTY software to start running the program to confirm that the program is error-free.

III. Demonstration effect

1. after the program runs, the display will show a heart-shaped pattern, while the MAX30102 module on the red LEDs will light up.

Image

2. placing a finger at the module's red LED and pressing the on-board USR button to initiate the measurement, the display will indicate that the measurement is in progress.

Image

3. Ensure good finger contact, wait about 40 seconds, the display will show the measured heart rate value, then you can remove your hand.

Image

IV. Summary

The heart rate value measured using MAX30102 is close to the heart rate value measured by Honor Bracelet 4 (about 2-3 values difference). The program also has a test of blood oxygen saturation, you can extract from the program to display on the display. You can extract it from the program and show it on the display. However, it should be noted that since the oxygen level is determined based on a lookup table, each oxygen sensor needs to be calibrated with a professional instrument to be accurate. The calibration is accurate. In addition, the wavelength of the RED LED is particularly susceptible to ambient temperature, so the program should take into account the effect of temperature on the accuracy of the blood oxygen, which is the main reason why the MAX30102 itself has a temperature sensor function. Therefore, the oxygen saturation in the program is for reference only and is not accurate.

Here is the main.py code

Code: Select all

import max30102
import hrcalc
from ssd1306_lib import SSD1306

#max30102 module initialization
m = max30102.MAX30102(pin='Y12')
#OLED display initialization
display = SSD1306(pinout={'dc': 'X5',
                          'res': 'X4'},
                  height=64,
                  external_vcc=False)
state = False
#Key press callback function
def f():
    global state
    pyb.delay(10)          #Eliminate shaking
    if sw():
        state = not state
        
#On-board USR button
sw = pyb.Switch()
sw.callback(f)
 
if __name__ == '__main__':
    display.poweron()       #Start Module
    display.init_display()  #Initialize display settings
    display.draw_image()    #Drawing pictures from a font
    display.display()       #Display 
    pyb.delay(3000)
    while True:
        if state:
            display.draw_chinese('测量中',5,1)
            display.display()
            #Samples 250 data in about 10 seconds
            red, ir = m.read_sequential(1000)
            #analysis
            ir_avg = []
            red_avg = []
            for i in range(37):
                d = hrcalc.calc_hr_and_spo2(ir[25*i:25*i+100], red[25*i:25*i+100])
                #print(d)
                if d[1]:
                    ir_avg.append(d[0])
                if d[3]:
                    red_avg.append(d[2])
            ir_D = (sum(ir_avg) - max(ir_avg) - min(ir_avg)) // len(ir_avg)
            red_D = (sum(red_avg) - max(red_avg) - min(red_avg)) // len(red_avg)
            print('ir:',ir_D)
            print('red:',red_D)
            #Clear the set area
            #clear_area(x start,y start,x end,y end) 1 pixel is 1 unit
            display.clear_area(64,16,128,32)
            display.display()
            display.draw_text(85,16,str(ir_D),size=2)
            display.draw_chinese('次',5,2)
            display.draw_text(98,32,'/',size=2)
            display.draw_chinese('分',7,2)
            display.display()
            state = False


# #display.display()
# display.draw_chinese('次分',5,1)
# display.display()


# with open("red.log", "w") as f:
#     for r in red:
#         f.write("{0}\n".format(r))
# with open("ir.log", "w") as f:
#     for r in ir:
#         f.write("{0}\n".format(r))
# m.shutdown()
# red = []
# with open("red.log", "r") as f:
    # for r in f:
        # red.append(int(r))

# ir = []
# with open("ir.log", "r") as f:
    # for r in f:
        # ir.append(int(r))

# print('end')

fdufnews
Posts: 76
Joined: Mon Jul 25, 2016 11:31 am

Re: MicroPython based:TPYBoard heart rate monitor

Post by fdufnews » Mon Jul 26, 2021 12:10 pm

Interesting project but maybe you can add comment at the end of the display.draw_chinese() calls with a translation of the text so non chinese people can adapt the software to their need.

Post Reply