Help of Systolic and Diastolic Pressure using MPX5100GP MP

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
}

Is your code also controlling the cuff?

The cuff is manually controlled as of right now. We are troubleshooting and are trying to get this part before we add in the cuff part

To check the decisions the code is making, put in Serial.print statements at various place, in order to see the values of important variables.

There is not difference between the return these two generate:

int bufferPos = (bufferIndex + i) % BUFFER_SIZE;
  return pressureBuffer[bufferPos];

int bufferPoses = (bufferIndex + i) % BUFFER_SIZE;
  return pressureBuffer[bufferPoses];

we didn't know if that was an issue so we created two different ints (added es to the second one), bufferPos and bufferPoses

You could put "fake" values as the return on both of bufferPos(es) to track what is getting sent to where... for example...

return (905); // fake value for bufferPos

return (90535); // fake value for bufferPoses