1622浏览
查看: 1622|回复: 0

[项目] 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));
}


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail