readSamplesAndCalculate method

Future<_PulseOxymeterData> readSamplesAndCalculate()

Implementation

Future<_PulseOxymeterData> readSamplesAndCalculate() async {
  _PulseOxymeterData result = _PulseOxymeterData()
    ..pulseDetected = false
    ..heartBPM = .0
    ..irCardiogram = 0.0
    ..irDcValue = 0.0
    ..redDcValue = 0.0
    ..saO2 = currentSaO2Value
    ..lastBeatThreshold = 0
    ..dcFilteredIR = 0.0
    ..dcFilteredRed = 0.0;

  List<_SensorFIFOSample> fifoSampleList = await readFIFO();

  for (int i = 0; i < fifoSampleList.length; i++) {
    _SensorFIFOSample sample = fifoSampleList[i];

    dcFilterIR = dcRemoval(sample.rawIR.toDouble(), dcFilterIR.w, alpha);
    dcFilterRed = dcRemoval(sample.rawRed.toDouble(), dcFilterRed.w, alpha);

    double meanDiffResIR = meanDiff(dcFilterIR.result, meanDiffIR); // &meanDiffIR
    lowPassButterworthFilter(meanDiffResIR /*-dcFilterIR.result*/, lpbFilterIR); // &lpbFilterIR

    irACValueSqSum += dcFilterIR.result * dcFilterIR.result;
    redACValueSqSum += dcFilterRed.result * dcFilterRed.result;
    samplesRecorded++;

    if (detectPulse(lpbFilterIR.result) && samplesRecorded > 0) {
      result.pulseDetected = true;
      pulsesDetected++;

      double ratioRMS = log(sqrt(redACValueSqSum / samplesRecorded)) / log(sqrt(irACValueSqSum / samplesRecorded));

      if (debug == true) {
        printWithTimestamp("RMS Ratio: $ratioRMS");
      }

      // This is probably far from correct, requires proper empirical calibration
      double ratioToApply = ratioRMS;
      if (ratioToApply > 1.0) {
        ratioToApply = 1.0;
      }
      currentSaO2Value = 110.0 - 15.0 * ratioToApply;
      if (currentSaO2Value > 100) {
        currentSaO2Value = 100.0;
      }

      if (pulsesDetected % resetSPO2EveryNPulses == 0) {
        irACValueSqSum = 0;
        redACValueSqSum = 0;
        samplesRecorded = 0;
      }
    }
  }

  balanceIntensities(dcFilterRed.w, dcFilterIR.w);

  result.heartBPM = currentBPM;
  result.irCardiogram = lpbFilterIR.result;
  result.irDcValue = dcFilterIR.w;
  result.redDcValue = dcFilterRed.w;
  result.lastBeatThreshold = lastBeatThreshold;
  result.dcFilteredIR = dcFilterIR.result;
  result.dcFilteredRed = dcFilterRed.result;

  return result;
}