最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

algorithm - Calculating SpO2 with MAX30101 Sensor in Python on Raspberry Pi 4 - Stack Overflow

programmeradmin1浏览0评论

I have recently purchased a MAX30101 breakout board / sensor and have been using it with a Raspberry Pi 4 and Python. I have been using the sparkfun-qwiic-max3010x library provided by Sparkfun to communicate with the sensor and collect data. The GitHub page for the Python sparkfun-qwiic-max3010x library includes an example for calculating heart rate but not SpO2. The Arduino library includes an example for calculating heart rate and SpO2.

I was wondering if there is an algorithm available or if it is possible to calculate SpO2 accurately in Python on the Raspberry Pi 4.

I have seen an algorithm in the user guide of the MAX30101 sensor but have not been able to accurately get an SpO2 reading with it in Python in the following code. The SpO2 value sometimes goes in the negatives and will give extremely different consecutive values.

import time
import numpy as np
import qwiic_max3010x

# Initialize the MAX30101 sensor
sensor = qwiic_max3010x.QwiicMax3010x()

sensor.begin()
sensor.setup()

sensor.setPulseAmplitudeGreen(0)

# Function to read raw values from the sensor
def read_raw_values(num_samples=100):
    red_values = []
    ir_values = []

    for _ in range(num_samples):
            red = sensor.getRed()
            ir = sensor.getIR()
            red_values.append(red)
            ir_values.append(ir)
            time.sleep(0.01) # Adjust the delay as needed
    
    sensor.shutDown()
    
    return np.array(red_values), np.array(ir_values)


# Function to calculate AC and DC components
def calculate_ac_dc(raw_values):
    dc = np.mean(raw_values)  # DC component
    ac = raw_values - dc  # AC component
    return ac, dc


def calculate_spo2(red_ac, red_dc, ir_ac, ir_dc):
    r = (np.mean(red_ac) / red_dc) / (np.mean(ir_ac) / ir_dc)
    spo2 = 104 - (17 * r)
    return spo2


# Main loop
try:
    while True:
        # Read raw values
        red_raw, ir_raw = read_raw_values(num_samples=100)

        # Calculate AC and DC components
        red_ac, red_dc = calculate_ac_dc(red_raw)
        ir_ac, ir_dc = calculate_ac_dc(ir_raw)

        spo2 = calculate_spo2(red_ac, red_dc, ir_ac, ir_dc)

        print("Spo2: ", spo2)

        # Wait for a bit before the next reading
        time.sleep(1)  # Adjust the sleep time as needed

except KeyboardInterrupt:
    print("Program stopped.")

I have recently purchased a MAX30101 breakout board / sensor and have been using it with a Raspberry Pi 4 and Python. I have been using the sparkfun-qwiic-max3010x library provided by Sparkfun to communicate with the sensor and collect data. The GitHub page for the Python sparkfun-qwiic-max3010x library includes an example for calculating heart rate but not SpO2. The Arduino library includes an example for calculating heart rate and SpO2.

I was wondering if there is an algorithm available or if it is possible to calculate SpO2 accurately in Python on the Raspberry Pi 4.

I have seen an algorithm in the user guide of the MAX30101 sensor but have not been able to accurately get an SpO2 reading with it in Python in the following code. The SpO2 value sometimes goes in the negatives and will give extremely different consecutive values.

import time
import numpy as np
import qwiic_max3010x

# Initialize the MAX30101 sensor
sensor = qwiic_max3010x.QwiicMax3010x()

sensor.begin()
sensor.setup()

sensor.setPulseAmplitudeGreen(0)

# Function to read raw values from the sensor
def read_raw_values(num_samples=100):
    red_values = []
    ir_values = []

    for _ in range(num_samples):
            red = sensor.getRed()
            ir = sensor.getIR()
            red_values.append(red)
            ir_values.append(ir)
            time.sleep(0.01) # Adjust the delay as needed
    
    sensor.shutDown()
    
    return np.array(red_values), np.array(ir_values)


# Function to calculate AC and DC components
def calculate_ac_dc(raw_values):
    dc = np.mean(raw_values)  # DC component
    ac = raw_values - dc  # AC component
    return ac, dc


def calculate_spo2(red_ac, red_dc, ir_ac, ir_dc):
    r = (np.mean(red_ac) / red_dc) / (np.mean(ir_ac) / ir_dc)
    spo2 = 104 - (17 * r)
    return spo2


# Main loop
try:
    while True:
        # Read raw values
        red_raw, ir_raw = read_raw_values(num_samples=100)

        # Calculate AC and DC components
        red_ac, red_dc = calculate_ac_dc(red_raw)
        ir_ac, ir_dc = calculate_ac_dc(ir_raw)

        spo2 = calculate_spo2(red_ac, red_dc, ir_ac, ir_dc)

        print("Spo2: ", spo2)

        # Wait for a bit before the next reading
        time.sleep(1)  # Adjust the sleep time as needed

except KeyboardInterrupt:
    print("Program stopped.")
Share Improve this question asked Mar 28 at 2:29 Ish18Ish18 231 silver badge3 bronze badges 1
  • see whether it is related to difference in n-bit arithmetics. numpy arrays use int64 in your code, float64 for mean. While C++ code uses uint32, int32 (and even uint16,int16 sometimes) github/sparkfun/SparkFun_MAX3010x_Sensor_Library/blob/… – jfs Commented Mar 28 at 5:26
Add a comment  | 

1 Answer 1

Reset to default 4

Calculating r the way you do is incorrect. By the very nature of red_ac its mean is almost zero (it is not exactly zero because of rounding errors). Same for ir_ic. Dividing two such values results in a huge meaningless error, precisely what you observe.

Notice that in the Maxim paper you linked they do not divide averages. They divide instant readings, normalized by the averages. So the first thing you shall try is to calculate instant values of r[i] = (red_ac[i]/red_dc) / (ir_ac[i]/ir_dc) and average them over the observation window. In the ideal case you'll get reasonable results.

Then you'd have to deal with the noise. The signals you sample are far from ideal, and it is not coincidental that the Arduino code does not resemble the simple formula. Most of the SpO2 computation is fighting noise.

发布评论

评论列表(0)

  1. 暂无评论