【Esp32】用esp32和max30102制作一个血氧仪

【物资准备】

esp32-wroom

max30102

点灯科技账号or阿里云物联网平台账号

(本来是想用屏幕去显示的,但是我发现我的esp32只有一个iic引出来,而max30102模块正好是iic通讯,我又懒得弄spi的屏幕,所以用手机app或者网页去起到显示数据的一个作用了)

1、阿里云物联网平台

先上代码

#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>



// 这里添加要连的wifi名称和密码
const char* ssid     = "";
const char* password = "";


/* 设备证书信息,根据情况修改*/
#define PRODUCT_KEY       ""
#define DEVICE_NAME       ""
#define DEVICE_SECRET     ""
#define REGION_ID         "cn-shanghai"

#define CLIENT_ID         ""
#define MQTT_PASSWD       ""

#define ALINK_BODY_FORMAT         "{\"params\":%s}"
#define ALINK_TOPIC_PROP_POST     "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"

/* 线上环境域名和端口号,不需要改 */
#define MQTT_SERVER       PRODUCT_KEY ".iot-as-mqtt." REGION_ID ".aliyuncs.com"
#define MQTT_PORT         1883
#define MQTT_USRNAME      DEVICE_NAME "&" PRODUCT_KEY

WiFiClient espClient;
PubSubClient  client(espClient);

void WiFiInit()
{
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  Serial.println("WIFI CONNECTED!");
}

// 连接MQTT,每隔5s自动重连
void mqttCheckConnect()
{
  while(!client.connected())
  {
    Serial.println("Connecting to MQTT Server ...");
    if(client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD))
    {
      Serial.println("MQTT Connected!");
    }
    else
    {
      Serial.print("MQTT Connect err:");
      Serial.println(client.state());
      delay(5000);
    }
  }
}

// publish(ESP32发送,阿里云接收)
void mqttIntervalPost()
{
  char param[32];     // 存放参数数据
  char jsonBuf[128];  // 存放json格式数据

  sprintf(param, "{\"XY\":%d}", 32); //这是测试的发送数据
  sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
  Serial.println(jsonBuf);
  if(client.publish(ALINK_TOPIC_PROP_POST, jsonBuf))
  {
    Serial.println("Publish success!");
  }
  else
  {
    Serial.println("Publish error!");
  }
}



void setup() 
{
  Serial.begin(115200);
  WiFiInit();
  client.setServer(MQTT_SERVER, MQTT_PORT);
  client.setCallback(callback);
    
}

void loop() 
{
  if(!client.connected())
  {
    mqttCheckConnect();

    //mqttIntervalPost();
  }
  mqttIntervalPost();//定期发送血氧数据
  client.loop();

  delay(500);
}

阿里云我用的是物联网平台接收数据+物联网平台内置的lot Studio来实现网页上线显示数据

2、用点灯科技来实现app

先直接上代码,用的是blinker库

#define BLINKER_PRINT Serial
#define BLINKER_WIFI

#include <Blinker.h>

char auth[] = "";
char ssid[] = "";
char pswd[] = "";

// 新建组件对象
BlinkerNumber Number1("num-gwy"); //xueyang
BlinkerNumber Number2("num-xoe"); //xinlv

void setup() {
  // put your setup code here, to run once:
  // 初始化串口
  Serial.begin(115200);
    
    // 初始化有LED的IO
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    // 初始化blinker
    Blinker.begin(auth, ssid, pswd);
}

void loop() {
  Number1.print(93);    //血氧测试数据
  Blinker.run();
}

外面的资料都比较少,只能看官方文档

3、MAX30102

直接上代码

void setup() {
  // put your setup code here, to run once:
  // 初始化串口
    Serial.begin(115200);

    #if defined(BLINKER_PRINT)
        BLINKER_DEBUG.stream(BLINKER_PRINT);
    #endif
    
    // 初始化有LED的IO
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    // 初始化blinker
    Blinker.begin(auth, ssid, pswd);

    // 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);
  }
  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() {
  // put your main code here, to run repeatedly:

  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);
  }

  //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);
    }

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

  Number1.print(spo2);
  Blinker.run();
}

但是不知道是不是模块问题还是我测量方式不对,好难测出准确的血氧数据= =

当然,下面是一个示例代码,用于使用ESP32控制MAX30102进行血氧检测: ```cpp #include <Wire.h> #include "MAX30105.h" // MAX30102的I2C地址 #define MAX30102_ADDRESS 0x57 // 创建一个MAX30102对象 MAX30105 particleSensor; void setup() { // 初始化串口通信 Serial.begin(115200); // 初始化I2C总线 Wire.begin(); // 初始化MAX30102传感器 if (!particleSensor.begin(Wire, I2C_SPEED_FAST, MAX30102_ADDRESS)) { Serial.println("MAX30102未找到,请检查连接!"); while (1); } // 配置MAX30102传感器的参数 particleSensor.setup(); particleSensor.setPulseAmplitudeRed(0x0A); // 设置红色LED的幅度 particleSensor.setPulseAmplitudeGreen(0); // 设置绿色LED的幅度 particleSensor.setIRLedCurrent(MAX30105_LED_CURR_50MA); // 设置红外LED的电流 // 打开测量 particleSensor.enableDIETEMPRDY(); } void loop() { // 检查是否有新的数据可用 if (particleSensor.available()) { // 读取心率血氧度数据 float heartRate = particleSensor.getHeartRate(); float oxygenSaturation = particleSensor.getSpO2(); // 打印数据 Serial.print("心率: "); Serial.print(heartRate); Serial.print(" bpm"); Serial.print("\t血氧度: "); Serial.print(oxygenSaturation); Serial.println(" %"); } } ``` 这段代码使用了MAX30105库,它是针对MAX30102一个开源库。你需要先在Arduino IDE中安装MAX30105库,然后将上述代码粘贴到一个新的项目中。然后,将ESP32开发板连接到计算机上,选择正确的开发板端口,然后编译并上传代码到ESP32开发板。在串口监视器中,你将能够看到心率血氧度数据的输出。 请注意,这只是一个基本的示例代码,你可以根据自己的需求进行修改扩展。同时,在实际操作中可能会遇到其他问题,你可能需要进一步调试优化代码。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值