用Arduino Pro Mini和MAX30102 DIY血氧饱和度检测仪

疫情期间,指夹式血氧检测仪全网脱销,好不容易在某多多上买到一个,发现检测值很不靠谱,于是尝试DIY了一个。

一、设计思路

将MAX30102心率血氧传感器采样信息输入到Arduino Pro Mini单片机,把经计算后的心率、血氧数据显示到LCD1602显示屏。

二、软硬件准备

1、硬件:

MAX30102心率血氧传感器

 Arduino Pro Mini单片机

 

 LCD1602显示屏

 USB转TTL-CH340模块

 

2、软件:

GitHub血氧心率检测开源项目

GitHub - sparkfun/MAX30105_Particle_Sensor_Breakout: Breakout to sense smoke, SpO2, Pulse Detection, as well as airborne particles.

 

三、安装CH340串口模块驱动

  1. 首先在网上下载CH340串口驱动程序,下载好以后,点击“SETUP.exe”开始安装。
  2. 在以下界面,点击“安装”控件。

  

     3.安装完成后,点击“确定”。

     4.在“我的电脑”--->“设备管理器”查看COM端口选项(记住这个COM口号,烧写程序时需选择该COM口)。

下载地址:ch340驱动下载_ch340驱动官方下载【绿色版】-华军软件园

四、烧写血氧检测软件

1. 下载开源软件

从GitHub下载开源软件,并解压缩。

 

GitHub血氧心率检测开源项目

GitHub - sparkfun/MAX30105_Particle_Sensor_Breakout: Breakout to sense smoke, SpO2, Pulse Detection, as well as airborne particles.

2. 连接CH340串口模块和Arduino Pro Mini

Arduino Pro Mini

CH340

RX

TX

TX

RX

GND

GND

VCC

5V或3.3V(由Arduino Pro Mini具体型号确定)

注意:如果你的USB转TTL模块有DTR引脚,将板子的DTR连接到USB转TTL模块上的DTR引脚,这样烧录时就不需要按Reset按钮。

3. 配置Arduino IDE环境

启动Arduino IDE,选择之前CH340安装的端口号,将“开发板”型号设置为“Arduino Pro or Pro Mini”。 

4.  打开下载好的开源程序并添加LCD显示部分代码

由于开源项目仅通过串口监测查看检测结果,因此需添加LCD显示输出代码,修改如下:


#include <Wire.h>
#include "MAX30105.h"
#include "spo2_algorithm.h"
#include <LiquidCrystal.h> //LCD

MAX30105 particleSensor;

#define MAX_BRIGHTNESS 255

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
//Arduino Uno doesn't have enough SRAM to store 100 samples of IR led data and red led data in 32-bit format
//To solve this problem, 16-bit MSB of the sampled data will be truncated. Samples become 16-bit data.
uint16_t irBuffer[100]; //infrared LED sensor data
uint16_t redBuffer[100];  //red LED sensor data
#else
uint32_t irBuffer[100]; //infrared LED sensor data
uint32_t redBuffer[100];  //red LED sensor data
#endif

int32_t bufferLength; //data length
int32_t spo2; //SPO2 value
int8_t validSPO2; //indicator to show if the SPO2 calculation is valid
int32_t heartRate; //heart rate value
int8_t validHeartRate; //indicator to show if the heart rate calculation is valid

//byte pulseLED = 11; //Must be on PWM pin
byte readLED = 13; //Blinks with each data read

LiquidCrystal lcd(12,11,5,4,3,2);//init LCD

void setup()
{
  Serial.begin(115200); // initialize serial communication at 115200 bits per second:

  lcd.begin(16,2);//Set line and row
  //lcd.print(" %SpO2    PRbpm");//Print SpO2 and PRbpm Title
  
  //pinMode(pulseLED, OUTPUT);
  pinMode(readLED, OUTPUT);

  // Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
  {
    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) ; //wait until user presses a key
  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); //Configure sensor with these settings
}

void loop()
{
  bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps

  //read the first 100 samples, and determine the signal range
  for (byte i = 0 ; i < bufferLength ; i++)
  {
    while (particleSensor.available() == false) //do we have new data?
      particleSensor.check(); //Check the sensor for new data

    redBuffer[i] = particleSensor.getRed();
    irBuffer[i] = particleSensor.getIR();
    particleSensor.nextSample(); //We're finished with this sample so move to next sample

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

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Push your finger");
    lcd.setCursor(0,1);
    lcd.print("on the sensor");
  }

  //calculate heart rate and SpO2 after first 100 samples (first 4 seconds of samples)
  maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

  //Continuously taking samples from MAX30102.  Heart rate and SpO2 are calculated every 1 second
  while (1)
  {
    //dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top
    for (byte i = 25; i < 100; i++)
    {
      redBuffer[i - 25] = redBuffer[i];
      irBuffer[i - 25] = irBuffer[i];
    }

    //take 25 sets of samples before calculating the heart rate.
    for (byte i = 75; i < 100; i++)
    {
      while (particleSensor.available() == false) //do we have new data?
        particleSensor.check(); //Check the sensor for new data

      digitalWrite(readLED, !digitalRead(readLED)); //Blink onboard LED with every data read

      redBuffer[i] = particleSensor.getRed();
      irBuffer[i] = particleSensor.getIR();
      particleSensor.nextSample(); //We're finished with this sample so move to next sample

      //send samples and calculation result to terminal program through 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);

      lcd.clear();
      
      lcd.setCursor(2,0);
      lcd.print("%SpO2:");
      lcd.setCursor(8,0);
      lcd.print(spo2);
      
      lcd.setCursor(2,1);
      lcd.print("PRbpm:");
      lcd.setCursor(8,1);
      lcd.print(heartRate);
      
    }

    //After gathering 25 new samples recalculate HR and SP02
    maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
  }
}

5. 烧写代码

程序编译没有问题的话,就可以开始上传,但要注意,如USB转TTL模块没有DTR引脚,需要你在IDE开始上传的一瞬间(差不多就行)按下板子上的Reset按钮,这样才能上传成功。

五、连接电路

根据LCD1602的引脚定义如上图,和Arduino Pro mini的连接方法如下:

LCD VSS 接地

LCD VDD 接5V电源

LCD VL 用于调节对比度,通过电位器再接地。

LCD RS pin 链接数字口 pin12

LCD R/W pin 接地

LCD Enable pin 链接数字口 pin11

LCD D4 pin 链接数字口 pin5

LCD D5 pin 链接数字口 pin4

LCD D6 pin 链接数字口 pin3

LCD D7 pin 链接数字口 pin2

LCD BLA 光源正极

LCD BLK 光源负极

MAX30102Arduino Pro mini的连接方法如下:

MAX30102

Arduino Pro mini

GND

GND

SCL

A5

SDA

A4

VIN

5V电源

 

 

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值