[Diao Ye, 프로그래밍 배우기] Arduino 실습(100)---MAX30102 손목 심박수 모듈 4

37개의 센서와 액추에이터에 대한 언급이 인터넷에 널리 퍼졌는데 실제로 Arduino와 호환되는 센서 모듈은 37개 이상이어야 합니다. 어느 정도 센서와 액추에이터 모듈을 수중에 축적했다는 점에서 참지식(손으로 해야 한다)의 개념에 따라 학습과 소통을 목적으로 여기에서 일련의 실험을 하나하나 해보고 성공(프로그램이 통하는) 여부를 기록할 것이다.

[Arduino] 168 센서 모듈 시리즈 실험(데이터 코드 + 시뮬레이션 프로그래밍 + 그래픽 프로그래밍)
실험 100: MAX30102 산소 농도계 손목 심박수 펄스 감지 심장 박동 센서 모듈

여기에 이미지 설명 삽입

여기에 이미지 설명 삽입
실험 배선 회로도
하드웨어 연결(MAX30102에서 Arduino까지):
-5V = 5V(3.3V 허용) -
접지 = 접지
-SDA = A4(또는 SDA)
-SCL = A5(또는 SCL)
-INT = 인터럽트 핀이 연결되지 않음

MAX30102 심박수 및 혈중 산소 센서 모듈 사용 시 주의 사항:
1. 손가락으로 직접 누르면 압력 변화가 발생하여 센서 값에 영향을 미칠 수 있습니다.
2. 착용 부위는 손가락이며, 착용 방향에는 차이가 없습니다.
3. 본 모듈은 전문 의료기기가 아니며 진단 및 치료를 위한 보조 악세서리로 사용할 수 없습니다.

여기에 이미지 설명 삽입


프로그램 5: Arduino 직렬 플로터 Arduino 참조 오픈 소스 코드 에 사용자의 심장 박동 표시

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序五:在 Arduino 的串口绘图器上显示用户的心跳
  下载库: http://librarymanager/All#SparkFun_MAX30105
*/

#include <Wire.h>
#include "MAX30105.h"

MAX30105 particleSensor;

void setup() {
    
    
  Serial.begin(115200);
  Serial.println("正在初始化...");

  // 初始化传感器
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //使用默认 I2C 端口,400kHz 速度
  {
    
    
    Serial.println("没有找到MAX30105,请检查接线/电源。 ");
    while (1);
  }

  //设置以感应串口绘图器上漂亮的曲线
  byte ledBrightness = 0x1F; //亮度选项:0=关 到 255=50mA
  byte sampleAverage = 8; //样本平均值选项:1、2、4、8、16、32
  byte ledMode = 3; //工作方式选项:1 = 仅红色,2 = 红色 + IR,3 = 红色 + IR + 绿色
  int sampleRate = 100; //采样率选项:50、100、200、400、800、1000、1600、3200
  int pulseWidth = 411; //脉宽选项:69、118、215、411
  int adcRange = 4096; //选项:2048、4096、8192、16384

  //使用这些设置来配置传感器
  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);

  //Arduino 绘图仪令人讨厌地自动缩放。为了解决这个问题,预先填充
  //绘图仪的传感器平均读数为 500

  //在通电时取平均 IR 读数
  const byte avgAmount = 64;
  long baseValue = 0;
  for (byte x = 0 ; x < avgAmount ; x++)
  {
    
    
    baseValue += particleSensor.getIR(); //读取IR值
  }
  baseValue /= avgAmount;

  //预填充绘图仪,使 Y 比例接近 IR 值
  for (int x = 0 ; x < 500 ; x++)
    Serial.println(baseValue);
}

void loop() {
    
    
  Serial.println(particleSensor.getIR()); //将原始数据发送到绘图器
  delay(10);
}

Arduino IDE——도구——직렬 포트 플로터를 열고 실험 파형 보기
실험 직렬 포트 플로터의 반환 상태

여기에 이미지 설명 삽입

프로그램 6: 최소 출력 센서에서 읽은 원시 값(IR 및 빨간색 판독값)
Arduino 참조 오픈 소스 코드

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序六:最简输出传感器读取的原始值(IR 和红色读数)
  下载库: http://librarymanager/All#SparkFun_MAX30105
*/

#include <Wire.h>

#include "MAX30105.h"//导入驱动库

MAX30105 particleSensor;

void setup() {
    
    
  Serial.begin(9600);//初始化串口

  Serial.println("MAX30102准备就绪");

  // 初始化传感器
  if (particleSensor.begin() == false) {
    
    
    Serial.println("没有找到MAX30102,请检查接线/电源。");
    while (1);
  }

  particleSensor.setup(); //配置传感器,使用 6.4mA 进行 LED 驱动
}

void loop() {
    
    
  Serial.print(" R[");//串口打印传感器读取的原始值
  Serial.print(particleSensor.getRed());
  Serial.print("] IR[");
  Serial.print(particleSensor.getIR());
  Serial.println("]");

  delay(1000);
}

실험적인 직렬 포트 반환

여기에 이미지 설명 삽입

프로그램 7: 가장 간단한 심박수 파형 그리기
Arduino 참조 오픈 소스 코드

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序七:最简绘制心率波形
  下载库: http://librarymanager/All#SparkFun_MAX30105
*/

#include <Wire.h>
#include "MAX30105.h"//导入驱动库
MAX30105 particleSensor;

void setup() {
    
    
  Serial.begin(9600);//初始化串口
  Serial.println("MAX30102准备就绪");

  // 初始化传感器
  if (particleSensor.begin() == false) {
    
    
    Serial.println("没有找到MAX30102,请检查接线/电源。");
    while (1);
  }

  particleSensor.setup(); //配置传感器,使用 6.4mA 进行 LED 驱动
}

void loop() {
    
    
  Serial.print(particleSensor.getRed());
  Serial.print(", ");
  Serial.println(particleSensor.getIR());
  delay(6);
}

Arduino IDE——도구——직렬 포트 플로터를 열고 실험 파형 보기
실험 직렬 포트 플로터의 반환 상태

여기에 이미지 설명 삽입
Arduino IDE에서 도구 > 직렬 플로터를 선택합니다. 센서 위로 손을 움직이면 아래 이미지와 유사한 물결 모양이 나타납니다.

여기에 이미지 설명 삽입

프로그램 8: 심박수 지침을 시각적으로 감지하는 시연
: 이 방법은 까다롭고 잘못된 판독값을 제공하는 경향이 있습니다. 따라서 실제 의료 진단에 사용하지 마십시오.
Arduino 참조 오픈 소스 코드

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序八:以光学方式检测心率的演示
  说明:这种方法很棘手,容易给出错误的读数。所以请不要将它用于实际的医疗诊断。
  下载库: http://librarymanager/All#SparkFun_MAX30105
*/

#include <Wire.h>
#include "MAX30105.h"//导入驱动库
#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;

void setup() {
    
    
  Serial.begin(115200);
  Serial.println("Initializing...");

  // 初始化传感器
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
    
    
    Serial.println("MAX30102 was not found. Please check wiring/power. ");
    while (1);
  }
  Serial.println("Place your index finger on the sensor with steady pressure.");

  particleSensor.setup(); //使用默认设置配置传感器
  particleSensor.setPulseAmplitudeRed(0x0A); //将红色LED变为低电平表示传感器正在运行
  particleSensor.setPulseAmplitudeGreen(0); //关闭绿色LED
}

void loop() {
    
    
  long irValue = particleSensor.getIR();

  if (checkForBeat(irValue) == true) {
    
    
    //我们感觉到了节拍!
    long delta = millis() - lastBeat;
    lastBeat = millis();

    beatsPerMinute = 60 / (delta / 1000.0);

    if (beatsPerMinute < 255 && beatsPerMinute > 20) {
    
    
      rates[rateSpot++] = (byte)beatsPerMinute; //将此读数存储在数组中
      rateSpot %= RATE_SIZE; //包装变量

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

  Serial.print("IR=");
  Serial.print(irValue);
  Serial.print(", BPM=");
  Serial.print(beatsPerMinute);
  Serial.print(", Avg BPM=");
  Serial.print(beatAvg);

  if (irValue < 50000)
    Serial.print(" No finger?");

  Serial.println();
}

실험적인 직렬 포트 반환
여기에 이미지 설명 삽입

프로그램 9: 혈중 산소 포화도(SpO2)의 간단한 측정
지침: 가능한 한 안정적으로 센서에 손가락을 대고 판독값이 이해될 때까지 몇 초간 기다리십시오.
Arduino 참조 오픈 소스 코드

/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  程序九:测量血氧饱和度 (SpO2)
  说明:将手指尽可能稳定地放在传感器上,然后等待几秒钟以使读数有意义。
  下载库: http://librarymanager/All#SparkFun_MAX30105
*/

#include <Wire.h>
#include "MAX30105.h"//导入驱动库
#include "spo2_algorithm.h"

MAX30105 particleSensor;

#define MAX_BRIGHTNESS 255

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
//Arduino Uno 没有足够的 SRAM 来存储 100 个 32 位格式的 IR LED 数据和红色 LED 数据样本
//为了解决这个问题,采样数据的16位MSB将被截断。样本变成 16 位数据。
uint16_t irBuffer[100];   //红外LED传感器数据
uint16_t redBuffer[100];  //红色LED传感器数据
#else
uint32_t irBuffer[100];   //红外LED传感器数据
uint32_t redBuffer[100];  //红色LED传感器数据
#endif

int32_t bufferLength; //数据长度
int32_t spo2; //SPO2值
int8_t validSPO2; //用于显示 SPO2 计算是否有效的指标
int32_t heartRate; //心率值
int8_t validHeartRate; //显示心率计算是否有效的指标

byte pulseLED = 11; //必须在PWM引脚上
byte readLED = 13; //每次读取数据时闪烁

void setup() {
    
    
  Serial.begin(115200); // 以每秒 115200 位初始化串行通信

  pinMode(pulseLED, OUTPUT);
  pinMode(readLED, OUTPUT);

  // 初始化传感器
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) // 使用默认 I2C 端口,400kHz 速度
  {
    
    
    Serial.println(F("MAX30105 was not found. Please check wiring/power."));
    while (1);
  }

  Serial.println(F("Attach sensor to finger with rubber band. Press any key to start conversion"));
  while (Serial.available() == 0) ; //等到用户按下一个键
  Serial.read();

  byte ledBrightness = 60; //Options: 0=Off to 255=50mA
  byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
  byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
  byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int pulseWidth = 411; //Options: 69, 118, 215, 411
  int adcRange = 4096; //Options: 2048, 4096, 8192, 16384

  //使用这些设置配置传感器
  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
}

void loop() {
    
    
  bufferLength = 100; // 100 的缓冲区长度存储以 25sps 运行的 4 秒样本

  //读取前100个样本,并确定信号范围
  for (byte i = 0 ; i < bufferLength ; i++)
  {
    
    
    while (particleSensor.available() == false) //我们有新数据吗?
      particleSensor.check(); //检查传感器是否有新数据

    redBuffer[i] = particleSensor.getRed();
    irBuffer[i] = particleSensor.getIR();
    particleSensor.nextSample(); //我们已经完成了这个样本所以移动到下一个样本

    Serial.print(F("red="));
    Serial.print(redBuffer[i], DEC);
    Serial.print(F(", ir="));
    Serial.println(irBuffer[i], DEC);
  }

  //计算前 100 个样本后的心率和 SpO2(前 4 秒样本)
  maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

  //继续从MAX30102采样。每 1 秒计算一次心率和 SpO2
  while (1)
  {
    
    
    //转储内存中的前25组样本并将后75组样本移到顶部
    for (byte i = 25; i < 100; i++)
    {
    
    
      redBuffer[i - 25] = redBuffer[i];
      irBuffer[i - 25] = irBuffer[i];
    }

    //在计算心率之前取25组样本
    for (byte i = 75; i < 100; i++)
    {
    
    
      while (particleSensor.available() == false) //我们有新数据吗?
        particleSensor.check(); //检查传感器是否有新数据

      digitalWrite(readLED, !digitalRead(readLED)); //每次读取数据时板载 LED 闪烁

      redBuffer[i] = particleSensor.getRed();
      irBuffer[i] = particleSensor.getIR();
      particleSensor.nextSample(); // 我们已经完成了这个样本所以移动到下一个样本

      //通过UART发送样本和计算结果到终端程序
      Serial.print(F("red="));
      Serial.print(redBuffer[i], DEC);
      Serial.print(F(", ir="));
      Serial.print(irBuffer[i], DEC);

      Serial.print(F(", HR="));
      Serial.print(heartRate, DEC);

      Serial.print(F(", HRvalid="));
      Serial.print(validHeartRate, DEC);

      Serial.print(F(", SPO2="));
      Serial.print(spo2, DEC);

      Serial.print(F(", SPO2Valid="));
      Serial.println(validSPO2, DEC);
    }

    //收集25个新样本后重新计算HR和SP02
    maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
  }
}

실험적인 직렬 포트 반환

여기에 이미지 설명 삽입

Je suppose que tu aimes

Origine blog.csdn.net/weixin_41659040/article/details/131875794
conseillé
Classement