本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

基于Arduino及MAX30102的心率测量仪

发布时间:2021-07-04
分享到:

基于Arduino及MAX30102的心率测量仪

发布时间:2021-07-04
分享到:

本文简单介绍了如何使用Arduino UNO板、MAX30102(脉搏血氧仪和心率监视器模块)、 OLED显示器和蜂鸣器制作一个测量BPM的仪器。

BPM是“每分钟的心跳数”,对于正常人来说,它们在休息时约为65-75次,田径运动可能低于此数,SpO2是氧饱和度水平,对于正常人来说,它在95%以上。

硬件部件:

(Arduino UNO)

(OLED)

(蜂鸣器)

(MAX30102) 

连接图:

代码:(点击下载

/*此代码与MAX30102 + 128x32 OLED i2c +蜂鸣器和Arduino UNO配合使用
*它在屏幕上显示平均BPM,带有动画和蜂鸣器声音
*每次检测到心跳时
*这是心率库示例的修改版本
*/

#include <Adafruit_GFX.h>        //OLED库
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include "MAX30105.h"           //MAX3010x 库
#include "heartRate.h"          //心率计算算法

MAX30105 particleSensor;

const byte RATE_SIZE = 4; //增加此值以获得更多平均值。4是好的。
byte rates[RATE_SIZE]; //心率组数
byte rateSpot = 0;
long lastBeat = 0; //最后一拍发生的时间
float beatsPerMinute;
int beatAvg;

#define SCREEN_WIDTH 128 // OLED 显示宽度,以像素为单位
#define SCREEN_HEIGHT 32 // OLED 显示高度,以像素为单位
#define OLED_RESET    -1 // 复位引脚#(如果共享Arduino复位引脚,则为-1)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //声明显示名称(显示)

static const unsigned char PROGMEM logo2_bmp[] =
{ 0x03, 0xC0, 0xF0, 0x06, 0x71, 0x8C, 0x0C, 0x1B, 0x06, 0x18, 0x0E, 0x02, 0x10, 0x0C, 0x03, 0x10,              //Logo2和Logo3是两个bmp图片,调用时会显示在OLED上
0x04, 0x01, 0x10, 0x04, 0x01, 0x10, 0x40, 0x01, 0x10, 0x40, 0x01, 0x10, 0xC0, 0x03, 0x08, 0x88,
0x02, 0x08, 0xB8, 0x04, 0xFF, 0x37, 0x08, 0x01, 0x30, 0x18, 0x01, 0x90, 0x30, 0x00, 0xC0, 0x60,
0x00, 0x60, 0xC0, 0x00, 0x31, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00,  };

static const unsigned char PROGMEM logo3_bmp[] =
{ 0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08,
0x20, 0x01, 0x80, 0x04, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03,
0x80, 0x00, 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00,
0x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 0x00,
0x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 0x00, 0xA0, 0xA0, 0x08,
0x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0,
0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00,
0x00, 0x08, 0x10, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00  };


void setup() {  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //启动OLED 显示屏
  display.display();
  delay(3000);
  // 初始化传感器
  particleSensor.begin(Wire, I2C_SPEED_FAST); //使用默认I2C端口,400千赫速度
  particleSensor.setup(); //用默认设置配置传感器
  particleSensor.setPulseAmplitudeRed(0x0A); //将红色发光二极管转到低电平,表示传感器正在运行

}

void loop() {
 long irValue = particleSensor.getIR();    //读取红外值可以让我们知道传感器上是否有手指
                                           //同时检测心跳
if(irValue > 7000){                                           //如果检测到手指
    display.clearDisplay();                                   //清除显示
    display.drawBitmap(5, 5, logo2_bmp, 24, 21, WHITE);       //画第一张bmp图(小心脏)
    display.setTextSize(2);                                   //在它附近显示平均BPM,如果需要,可以显示BPM
    display.setTextColor(WHITE); 
    display.setCursor(50,0);                
    display.println("BPM");             
    display.setCursor(50,18);                
    display.println(beatAvg); 
    display.display();
    
  if (checkForBeat(irValue) == true)                        //如果检测到心跳
  {
    display.clearDisplay();                                //清除显示
    display.drawBitmap(0, 0, logo3_bmp, 32, 32, WHITE);    //画第二张图(更大的心)
    display.setTextSize(2);                                //仍然显示平均BPM
    display.setTextColor(WHITE);             
    display.setCursor(50,0);                
    display.println("BPM");             
    display.setCursor(50,18);                
    display.println(beatAvg); 
    display.display();
    tone(3,1000);                                        //蜂鸣器响100毫秒
    delay(100);
    noTone(3);                                          //关闭蜂鸣器,使其具有“哔哔声”的效果
    long delta = millis() - lastBeat;                   //测量两拍之间的持续时间
    lastBeat = millis();

    beatsPerMinute = 60 / (delta / 1000.0);           //计算BPM

    if (beatsPerMinute < 255 && beatsPerMinute > 20)               //为了计算平均值,我们选择一些值(4),然后做一些数学计算平均值
    {
      rates[rateSpot++] = (byte)beatsPerMinute; //将读数储存在数组中
      rateSpot %= RATE_SIZE; //包装变量

      //取读数平均值
      beatAvg = 0;
      for (byte x = 0 ; x < RATE_SIZE ; x++)
        beatAvg += rates[x];
      beatAvg /= RATE_SIZE;
    }
  }

}
  if (irValue < 7000){       //如果没有检测到手指,它会通知用户并将平均BPM设置为0,否则将存储它以备下次测量
     beatAvg=0;
     display.clearDisplay();
     display.setTextSize(1);                    
     display.setTextColor(WHITE);             
     display.setCursor(30,5);                
     display.println("Please Place "); 
     display.setCursor(30,15);
     display.println("your finger ");  
     display.display();
     noTone(3);
    }

}

测试:

未检测到手指:

将手指放在传感器上,一段时间后,听到蜂鸣器的“哔哔声”与心跳同步或OLED动画与之同步,就可以读取正确的BPM。

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论