This is our code to create a blood pressure monitor that detects systolic pressure and diastolic pressure. We detect oscillations in pressure, and determine the systolic and diastolic pressure from them. However, everytime we run this code, the output for the diastolic pressure and the systolic pressure is the same. We've tried various diastolic thresholds. Any suggestions for modification or the way we approach this problem?
Thank you!
// Constants for diastolic detection
const float DIASTOLIC_THRESHOLD = 0.7; // 70% of max oscillation for diastolic pressure
const float SensorOffset = 70.0;
// Constants for systolic detection
const int BUFFER_SIZE = 50; // Number of readings to store
const float SYSTOLIC_THRESHOLD = 1; // 50% of max amplitude for systolic detection
const float MEASUREMENT_COMPLETE_THRESHOLD = 20.0; // Threshold to detect end of measurement
const float MIN_VALID_PRESSURE = 30.0; // Minimum valid pressure to start considering measurement
// Circular buffer for pressure readings
float pressureBuffer[BUFFER_SIZE];
int bufferIndex = 0;
bool bufferFilled = false;
// Arrays for oscillation analysis
float oscillationAmplitudes[BUFFER_SIZE];
int oscillationCount = 0;
// State variables for measurement
bool measurementInProgress = false;
float lastDetectedSystolic = -1;
float lastDetectedDiastolic = -1;
bool resultReported = false;
// Pump pattern detection constants
const float PUMP_DROP_THRESHOLD = 5.0; // Threshold for drop between pumps
const float TRUE_DEFLATION_THRESHOLD = 10.0; // Threshold to detect true deflation
const int DEFLATION_CONFIRM_COUNT = 5; // Number of samples to confirm deflation
bool deflationStarted = false;
bool inPumpDrop = false;
unsigned long lastPumpTime = 0;
float maxPressure = 0.0;
float localMaxPressure = 0.0;
int deflationCounter = 0;
float lastPressure = 0.0;
void setup() {
Serial.begin(9600);
}
void loop() {
float analogValue = analogRead(A0) - SensorOffset;
unsigned long currentTime = millis();
// Store the new reading in circular buffer
pressureBuffer[bufferIndex] = analogValue;
bufferIndex = (bufferIndex + 1) % BUFFER_SIZE;
if (bufferIndex == 0) {
bufferFilled = true;
}
// Detect start of measurement
if (!measurementInProgress && analogValue > MIN_VALID_PRESSURE) {
measurementInProgress = true;
deflationStarted = false;
maxPressure = 0.0;
localMaxPressure = 0.0;
resultReported = false;
lastPumpTime = currentTime;
Serial.println("Measurement started");
}
// Process during measurement
if (measurementInProgress) {
// Pump pattern detection logic
if (!deflationStarted) {
// Update maximum pressures
if (analogValue > maxPressure) {
maxPressure = analogValue;
localMaxPressure = analogValue;
lastPumpTime = currentTime;
inPumpDrop = false;
}
// Detect drops between pumps
if (analogValue < localMaxPressure - PUMP_DROP_THRESHOLD) {
if (!inPumpDrop) {
inPumpDrop = true;
}
}
// Detect new pump starting
if (inPumpDrop && analogValue > lastPressure + 2.0) {
inPumpDrop = false;
localMaxPressure = analogValue;
lastPumpTime = currentTime;
}
// Check for true deflation start
if (analogValue < maxPressure - TRUE_DEFLATION_THRESHOLD) {
deflationCounter++;
if (deflationCounter > DEFLATION_CONFIRM_COUNT) {
deflationStarted = true;
Serial.print("True deflation started at pressure: ");
Serial.println(maxPressure);
}
} else {
deflationCounter = 0;
}
}
// Only process oscillations during confirmed deflation phase
if (deflationStarted && bufferFilled) {
detectOscillations();
float currentSystolic = detectSystolicPressure();
float currentDiastolic = detectDiastolicPressure();
if (currentSystolic > 0) {
lastDetectedSystolic = currentSystolic;
}
if (currentDiastolic > 0) {
lastDetectedDiastolic = currentDiastolic;
}
// Check if measurement is complete
if (analogValue < MEASUREMENT_COMPLETE_THRESHOLD && !resultReported) {
if (lastDetectedSystolic > 0) {
Serial.print("Systolic Pressure: ");
Serial.println(lastDetectedSystolic);
Serial.print("Diastolic Pressure: ");
Serial.println(lastDetectedDiastolic);
resultReported = true;
}
measurementInProgress = false;
deflationStarted = false;
}
}
lastPressure = analogValue;
}
delay(500);
}
void detectOscillations() {
oscillationCount = 0;
// Calculate oscillations from the pressure differences
for (int i = 1; i < BUFFER_SIZE - 1; i++) {
float prev = pressureBuffer[i-1];
float curr = pressureBuffer[i];
float next = pressureBuffer[i+1];
// Check for local maxima
if (curr > prev && curr > next) {
oscillationAmplitudes[oscillationCount] = curr - prev; // Store the amplitude
oscillationCount++;
}
}
}
float detectSystolicPressure() {
if (oscillationCount == 0) {
return -1; // No oscillations detected
}
// Find maximum oscillation amplitude
float maxAmplitude = 0;
for (int i = 0; i < oscillationCount; i++) {
if (oscillationAmplitudes[i] > maxAmplitude) {
maxAmplitude = oscillationAmplitudes[i];
}
}
// Calculate threshold
float threshold = maxAmplitude * SYSTOLIC_THRESHOLD;
// Find the point where oscillations exceed threshold
for (int i = oscillationCount - 1; i >= 0; i--) {
if (oscillationAmplitudes[i] >= threshold) {
int bufferPos = (bufferIndex + i) % BUFFER_SIZE;
return pressureBuffer[bufferPos];
}
}
return -1; // No systolic pressure detected
}
float detectDiastolicPressure() {
if (oscillationCount == 0) {
return -1; // No oscillations detected
}
/*
// Find maximum oscillation amplitude
float maxAmplitude = 0;
for (int i = 0; i < oscillationCount; i++) {
if (oscillationAmplitudes[i] > maxAmplitude) {
maxAmplitude = oscillationAmplitudes[i];
}
}
// Calculate threshold for diastolic (70% of max amplitude)
float threshold = maxAmplitude * DIASTOLIC_THRESHOLD;
*/
// Find the point where oscillations exceed threshold
for (int i = oscillationCount - 1; i >= 0; i--) {
if (oscillationAmplitudes[i] >= 0.01) {
int bufferPoses = (bufferIndex + i) % BUFFER_SIZE;
return pressureBuffer[bufferPoses];
}
}
return -1; // No diastolic pressure detected
}