You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加Firebase上传代码后NodeMCU的MAX30100传感器输出为0问题

问题描述

使用NodeMCU和MAX30100传感器模块,原有代码运行一切正常,但在loop()函数中添加一段Firebase上传代码后,传感器虽仍运行,但心率(BPM)和血氧饱和度(SpO₂)输出均为0,OLED显示屏也仅显示0。

添加的代码片段

if (Firebase.ready() && (millis() - sendDataPrevMillis > 15000 || sendDataPrevMillis == 0))
{
    sendDataPrevMillis = millis();
    Firebase.setFloat(fbdo, "/test/heartrate", pox.getHeartRate());
}

完整代码

#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <ESP8266WiFi.h>
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "OakOLED.h"
 
#define REPORTING_PERIOD_MS 1000
OakOLED oled;
 
// Connections : SCL PIN - D1 , SDA PIN - D2 , INT PIN - D0
PulseOximeter pox;
#define WIFI_SSID "ZainFiber-2.4G-jAMj"
#define WIFI_PASSWORD "0796169690"
float BPM, SpO2;
uint32_t tsLastReport = 0;
 
const unsigned char bitmap [] PROGMEM=
{
0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x18, 0x00, 0x0f, 0xe0, 0x7f, 0x00, 0x3f, 0xf9, 0xff, 0xc0,
0x7f, 0xf9, 0xff, 0xc0, 0x7f, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xf7, 0xff, 0xf0, 0xff, 0xe7, 0xff, 0xf0, 0xff, 0xe7, 0xff, 0xf0, 0x7f, 0xdb, 0xff, 0xe0,
0x7f, 0x9b, 0xff, 0xe0, 0x00, 0x3b, 0xc0, 0x00, 0x3f, 0xf9, 0x9f, 0xc0, 0x3f, 0xfd, 0xbf, 0xc0,
0x1f, 0xfd, 0xbf, 0x80, 0x0f, 0xfd, 0x7f, 0x00, 0x07, 0xfe, 0x7e, 0x00, 0x03, 0xfe, 0xfc, 0x00,
0x01, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x3f, 0xc0, 0x00,
0x00, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
void onBeatDetected()
{
    Serial.println("Beat Detected!");
    oled.drawBitmap( 60, 20, bitmap, 28, 28, 1);
    oled.display();
}
 
void setup()
{
    Serial.begin(9600);
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
    oled.begin();
    oled.clearDisplay();
    oled.setTextSize(1);
    oled.setTextColor(1);
    oled.setCursor(0, 0);
 
    oled.println("Initializing pulse oximeter..");
    oled.display();
    
    pinMode(16, OUTPUT);
 
    Serial.print("Initializing Pulse Oximeter..");
 
    if (!pox.begin())
    {
         Serial.println("FAILED");
         oled.clearDisplay();
         oled.setTextSize(1);
         oled.setTextColor(1);
         oled.setCursor(0, 0);
         oled.println("FAILED");
         oled.display();
         for(;;);
    }
    else
    {
         oled.clearDisplay();
         oled.setTextSize(1);
         oled.setTextColor(1);
         oled.setCursor(0, 0);
         oled.println("SUCCESS");
         oled.display();
         Serial.println("SUCCESS");
         pox.setOnBeatDetectedCallback(onBeatDetected);
    }
 
    // The default current for the IR LED is 50mA and it could be changed by uncommenting the following line.
     //pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
 
}
 
void loop()
{
    pox.update();
 
    BPM = pox.getHeartRate();
    SpO2 = pox.getSpO2();
     if (millis() - tsLastReport > REPORTING_PERIOD_MS)
    {
        Serial.print("Heart rate:");
        Serial.print(BPM);
        Serial.print(" bpm / SpO2:");
        Serial.print(SpO2);
        Serial.println(" %");
 
      
        
        oled.clearDisplay();
        oled.setTextSize(1);
        oled.setTextColor(1);
        oled.setCursor(0,16);
        oled.println(pox.getHeartRate());
 
        oled.setTextSize(1);
        oled.setTextColor(1);
        oled.setCursor(0, 0);
        oled.println("Heart BPM");
 
        oled.setTextSize(1);
        oled.setTextColor(1);
        oled.setCursor(0, 30);
        oled.println("Spo2");
 
        oled.setTextSize(1);
        oled.setTextColor(1);
        oled.setCursor(0,45);
        oled.println(pox.getSpO2());
        oled.display();
 
        tsLastReport = millis();
    }
}

电路连接图

电路连接示意图


问题分析与解决办法

核心原因

  1. Firebase代码缺失关键依赖:添加的代码使用了Firebase.ready()、fbdo对象和sendDataPrevMillis变量,但原代码没有引入Firebase库、声明对应对象和变量,导致运行时隐性错误,干扰了MAX30100的数据计算逻辑。
  2. 主循环优先级混乱:Firebase网络操作可能占用过多时间,导致pox.update()无法被高频调用,MAX30100无法及时采样足够数据,最终输出0值。

解决步骤

  1. 补全Firebase相关代码

    • 引入Firebase库头文件,声明必要的对象和变量:
      #include <FirebaseESP8266.h>
      // 替换为你的Firebase配置
      #define FIREBASE_HOST "你的数据库URL"
      #define FIREBASE_AUTH "你的数据库密钥"
      FirebaseData fbdo;
      unsigned long sendDataPrevMillis = 0;
      
    • 在setup()中初始化Firebase连接:
      Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
      Firebase.reconnectWiFi(true);
      
  2. 优化主循环逻辑
    保证传感器更新优先执行,避免网络操作阻塞采样:

    void loop()
    {
        // 优先执行传感器更新,保证采样频率
        pox.update();
    
        BPM = pox.getHeartRate();
        SpO2 = pox.getSpO2();
    
        // 定时更新串口和OLED显示
        if (millis() - tsLastReport > REPORTING_PERIOD_MS)
        {
            Serial.print("Heart rate:");
            Serial.print(BPM);
            Serial.print(" bpm / SpO2:");
            Serial.print(SpO2);
            Serial.println(" %");
    
            oled.clearDisplay();
            oled.setTextSize(1);
            oled.setTextColor(1);
            oled.setCursor(0,16);
            oled.println(BPM);
    
            oled.setCursor(0, 0);
            oled.println("Heart BPM");
    
            oled.setCursor(0, 30);
            oled.println("Spo2");
    
            oled.setCursor(0,45);
            oled.println(SpO2);
            oled.display();
    
            tsLastReport = millis();
        }
    
        // Firebase上传放在最后,仅在心率有效时上传
        if (Firebase.ready() && (millis() - sendDataPrevMillis > 15000 || sendDataPrevMillis == 0))
        {
            sendDataPrevMillis = millis();
            if(BPM > 0) Firebase.setFloat(fbdo, "/test/heartrate", BPM);
        }
    }
    
  3. 硬件排查
    确认NodeMCU与MAX30100的I2C连接稳定,若WiFi模块工作时传感器数据异常,可尝试给传感器供电端添加100nF滤波电容,减少电源波动影响。


内容的提问来源于stack exchange,提问作者Hamza Ateya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:01:08