134195987630404 发表于 2025-5-8 18:05:24

Beetle 树莓派RP2350心率监测系统代码篇,初稿

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SENSOR_PIN 26
#define MIN_VALID_TIME 500// 最小有效计算时间(毫秒)
#define REFRACTORY_PERIOD 150 // 心跳不应期

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

// 心率检测参数
const int sampleWindow = 1000;
unsigned long sampleStart;
int peakCount = 0;
int signalMax = 0;
int signalMin = 4095;
float BPM = 0;
unsigned long lastPeakTime = 0;// 新增:最后心跳时间

void setup() {
Serial.begin(115200);
analogReadResolution(12);

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("OLED init failed");
    while(1);
}
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(SSD1306_WHITE);
}

void loop() {
sampleStart = millis();
peakCount = 0;
signalMax = 0;
signalMin = 4095;

while(millis() - sampleStart < sampleWindow) {
    int rawSignal = analogRead(SENSOR_PIN);

    // 更新信号极值(新增范围限制)
    signalMax = max(signalMax, constrain(rawSignal, 500, 3500)); // 忽略异常信号
    signalMin = min(signalMin, constrain(rawSignal, 500, 3500));

    int threshold = (signalMax + signalMin) / 2;

    static bool lastState = false;
    bool currentState = (rawSignal > threshold);

    if(currentState && !lastState){
      // 新增:不应期检查和时间有效性验证
      if((millis() - lastPeakTime > REFRACTORY_PERIOD) &&
         (millis() - sampleStart > MIN_VALID_TIME)) {
      peakCount++;
      lastPeakTime = millis();

      // 安全计算实时BPM
      unsigned long elapsed = millis() - sampleStart;
      if(elapsed > 100) {// 至少经过100ms才计算
          float tempBPM = peakCount * (60000.0 / elapsed);
          if(tempBPM > 20 && tempBPM < 250) {// 生理范围检查
            updateDisplay(tempBPM);
          }
      }
      }
    }
    lastState = currentState;
}

// 最终计算增加有效性验证
if(signalMax - signalMin > 100) {// 信号波动需大于100单位
    BPM = constrain(peakCount * 60, 30, 200);// 强制限制范围
} else {
    BPM = 0;// 无效信号
}

updateDisplay(BPM);
}

void updateDisplay(float value) {
display.clearDisplay();
display.setCursor(10,20);

if(value >= 30 && value <= 200) {
    display.print(int(value));
    display.print(" BPM");
} else {
    display.print("---");// 无效信号显示
}

display.display();

// 增强调试输出
Serial.print("Peaks:");
Serial.print(peakCount);
Serial.print(" Max:");
Serial.print(signalMax);
Serial.print(" Min:");
Serial.print(signalMin);
Serial.print(" BPM:");
Serial.println(int(value));
}


页: [1]
查看完整版本: Beetle 树莓派RP2350心率监测系统代码篇,初稿