#include
#include
#include
#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));
}
评论