Jste zde

Nízkonákladový pulzní oxymetr

Pulzní oxymetr měří saturaci kyslíku (SpO2). Tato hodnota odráží účinnost kardiopulmonálního systému v těle. Sportovci používají měření SpO2 k měření úrovně vykonaného úsilí v tréninku, ale tato měření získala větší význam během pandemie COVID-19. Poskytovatelé zdravotní péče sledují pokles SpO2 jako včasné varovné znamení poškození plicní tkáně způsobené virem SARS-CoV-2.

U postižených jedinců s mírnými příznaky, kteří jsou doma v karanténě mohou získat informaci o průběhu jejich infekce a včas poskytnout varování k eskalaci zdravotní péče pomocí levnému pulznímu oxymetru. Tento článek stručně popisuje příznaky COVID-19 a potřebu monitorování SpO2. Dále ukazuje, jak lze jednoduše sestavit nízkonákladový pulzní oxymetr pomocí digitálního signálového procesoru od Microchip Technology (DSC) a několika dalších součástek.

COVID-19 a potřeba měřit úroveň saturace kyslíku

COVID-19 se projevuje širokým spektrem příznaků. Jedním z příznaků je zhoršení dýchacího systému a snížení absorpce kyslíku kvůli poškození plicní tkáně. Obvykle se používají rentgenové snímky hrudníku a počítačová tomografie (CT), ale daleko rychlejší je použít data z měření SpO2 jako včasný indikátor.

Měření SpO2 je neinvazivní alternativou k měření saturace arteriálního kyslíku (SaO2), která se provádí přímo z tepny pacienta a následné analýzy hladiny krevního plynu. Bylo zjištěno, že SpO2 poskytuje spolehlivý odhad SaO2. Nejdůležitější informací je, že měření SpO2 lze provádět spolehlivě doma a výsledky jsou srovnatelné jako měření v klinických podmínkách pomocí optických pulzních oxymetrů.

Optické pulzní oxynometry využívají rozdíl v absorpci světla, kterou vykazuje neokysličený hemoglobin (Hb) a okysličený hemoglobin (HBO2). Hemoglobin, nesený v červených krvinkách, rychle tvoří reverzibilní vazbu až s čtyřmi molekulami kyslíku v plicích bohatých na kyslík. V tomto stavu HBO2 molekula absorbuje více světla při 940 nm, než při 660 nm (obrázek 1).

Obrázek 1: Pulzní oxymetrie využívá rozdílu v absorpčním spektru mezi okysličeném hemoglobinu (HBO2 ) a neokysličeném (Hb) hemoglobinu. (Zdroj obrázku: Wikipedia)

Hemoglobin HBO2 nesoucí kyslík se na okraji krevního řečiště tohoto kyslíku zbaví a stane se z něj neokysličený hemoglobin Hb. A právě v tomto stavu se spektrum absorpce světla molekuly mění a absorbuje více světla při 660 nm než při 940 nm.

Jelikož HbO2 se stává Hb, když je parciální tlak kyslíku nízký, SpO2 lze určit jednoduchým vzorcem:

SpO 2 = HBO2 / (HBO2 + Hb

Relativní koncentrace Hb a HBO2 v krevním oběhu může být stanovena měřením absorpce světla při 660 nm a 940 nm vlnové délky. Pulzní oximetry využívají vztah mezi parciálním tlakem kyslíku v krvi, kyslíkem v hemoglobinu a rozdíly v absorpci světla.

Klíčové části pulzního oxymetru

Typická konstrukce pulzního oxymetru obsahuje tři hlavní sub-moduly:
  • Sup-modul, který dodává světelný paprsek o vlnové délce 660nm – červená a 950nm pomocí analogových přepínačů, budičů a LED diod. Některé systémy používají také zelené světlo o vlnové délce 530 nm pro ​​metodu fotopletysmografie (PPG), která určuje srdeční frekvenci tím, že sleduje změny objemu v krevních cévách kůže.
  • Sub-modul pro detekci světla pomocí fotodiody, speciálních algoritmů pro vyhodnocení signálu a analogově-digitálního převodníku (ADC).
  • DSC(Digitální signální procesor) nebo mikrokontroler pro koordinaci sub-modulů a pro výpočet SpO2 z naměřených dat.

Implementace jednotlivých sub-modulů se může výrazně lišit. U transmisních pulzních oxymetrů je fotodioda umístěna naproti LED a mezi nimi se nachází prst nebo ušní lalůček uživatele. V reflektorových impulsních oximetrech jsou fotodiody a LED diody umístěny na stejné straně s optickou bariérou mezi nimi, aby nedocházelo ke zkreslení. Například SFR7060 od společnosti OSRAM má měřící aparaturu (LED dioda + fotodioda) umístěnou v pouzdře o velikosti 7,2 x 2,5 x 0,9 mm.

Tato měřící aparatura již nepotřebuje ke své činnosti další komponenty kromě výkonného mikrokontroleru pro zpracování daného signálu. Konstrukce je postavená na signálním procesoru DSPIC33FJ128GP802 DSC od Microchip Technology. Tento procesor má integrované periferie pro řízení LED diod pro osvětlení kůže a obvody pro digitalizaci výstupního signálu fotodiody (obrázek 2).

Obrázek 2: Typická konstrukce pulzního oxymetru obsahuje obvody pro řízení LED a pro zpracování signálu z fotodiody. (Zdroj obrázku: Microchip Technology)

Konstrukce pulzního oxymetru se obvykle spoléhá na jednu fotodiodu se širokou spektrální křivkou, která umožňuje přijímat vyslaný nebo odrazený světelný signál bez ohledu na zdroj osvětlení. Výkonný mikrokontroler velmi rychle přepíná jednotlivé zdroje světla a vyhodnocuje je v daném čase.

Návrh hardware pulzního oxymetru

Představíme si konstrukci oxymetru, kde signálový procesor (DSC) využívá externí digitální převodník MCP4728 (DAC) od Microchip Technology k nastavení samostatných tranzistorů MBT2222 na úroveň potřebnou k řízení každé LED diody na požadovanou intenzitu světla. DSC používá pro přesné řízení LED diod Pulse Width Modulation (PWM) přivedené na analogový přepínač ADG884 od Analog Devices (obrázek 3).
 

Obrázek 3: Analogový přepínač poháněný střídavými signály z digitálního ovladače umožňuje řídit proud na červené a IR LED diodě. (Zdroj obrázku: Microchip Technology)

MCP6002 obsahuje pár operačních zesilovačů potřebných k implementaci základního dvoustupňového řetězce pro zpracování signálu z fotodiody. MCP6002 používá jeden operační zesilovač k převodu proudového výstupu fotodiody na napěťový signál. Dále signál proudí přes vysokofrekvenční filtr, kde dochází ke snížení šumu. Druhý operační zesilovač v MCP6002 slouží k zesílení signálu a kompenzaci DC složky v celém rozsahu ADC integrovaného v DSC (obrázek 4).

Obrázek 4: Dvoustupňový výstup signálu fotodiody pro vstup do integrovaného ADC digitálního kontroléru. (Zdroj obrázku: Microchip Technology)

DSC používá PWM výstupy a ADC vstupy pro synchronizaci LED diod a řízení ADC převodníku pro zpravování signálu z fotodiody. Dochází k rychlému cyklickému přepínání mezi červenou a IR LED diodou a měřením ADC v době kdy jsou obě diody vypnuté. Tato hodnota ADC odpovídá okolnímu osvětlení a slouží k optimalizaci intenzity jednotlivých LED diod a měření SpO2. Výsledkem je přesně řízený sled událostí, které zachycují úroveň světelného signálu pro Hb, úroveň okolního světla, a nakonec úroveň IR světelného signálu pro HBO2 (obrázek 5).

Obrázek 5: Funkce levného pulzního oxymetru se spoléhá na schopnost digitálního signálového procesoru řídit přesné načasování pro LED diody a sběr dat potřebných pro stanovení SpO. (Zdroj obrázku: Microchip Technology)

Softwarové řešení řízení pomocí přerušení

Microchip poskytuje pulsní oxymetrový softwareový balíček s ukázkovým programem, který demonstruje použití DSC k řízení LED diod a konverzi dat. Toto řízení je provedeno pomocí páru DSC časovačů - Timer2 a Timer3. Ty slouží pro časování zapínacích sekvencí pro IR a červenou LED diodu, v tomto pořadí. Každý časovač zase poskytuje časovou základnu pro moduly DSC pro řízení výstupu(OC), OC1 a OC2, který se používá k ovládání analogových spínačů pro IR LED a červené LED diody.
Jak je uvedeno ve Výpisu 1, software nejprve inicializuje Timer2 a Timer3, aby nastavil požadovanou dobu cyklu osvětlení a umožnil přerušení. Jako součást své inicializační sekvence jsou moduly OC1 a OC2 spojeny s výstupními piny pomocí funkce DSC Remapable pins (RP). Inicializační sekvence pak nastaví pracovní cyklus osvětlení a vybere přidružený časovač pro použití jako jeho časovou základnu.
 
    //*********************************************************************************************************
    // Initialize Timer 2 - IR light
    //*********************************************************************************************************
    T2CON = 0x0020;                    // Stop 16-bit Timer2, 1:64(40MhzFosc) Prescale, Internal clock (Fosc/2)
    TMR2 = 0x00;                    // Clear timer register
    PR2 = 1250;                        // Load the period value, OCxRS <= PRx, 4ms period = (1/(Fosc/2))*1000*64*PR2 = (1/(40000000/2))*1000*64*1250
    IPC1bits.T2IP = 2;                // Set Timer2 Interrupt Priority Level
    IFS0bits.T2IF = 0;                // Clear Timer2 Interrupt Flag
    IEC0bits.T2IE = 1;                // Enable Timer2 Interrupt
 
    //*********************************************************************************************************
    // Initialize Timer 3 - Red light
    //*********************************************************************************************************
    T3CON = 0x0020;                    // Stop 16-bit Timer3, 1:64(40MhzFosc) Prescale, Internal clock (Fosc/2)
    TMR3 = 0x00;                    // Clear timer register
    PR3 = 1250;                        // Load the period value, OCxRS <= PRx, 4ms period = (1/(Fosc/2))*1000*64*PR2 = (1/(40000000/2))*1000*64*1250
    IPC2bits.T3IP = 2;                // Set Timer3 Interrupt Priority Level
    IFS0bits.T3IF = 0;                // Clear Timer3 Interrupt Flag
    IEC0bits.T3IE = 1;                // Enable Timer3 Interrupt
 
    //*********************************************************************************************************
    // Initialize Output Compare 1 module in Continuous Pulse mode, OC1 controls IR LED switch
    //*********************************************************************************************************
    RPOR6bits.RP13R = 0b10010;        // RP13/RB13 tied to OC1 (IR)
    OC1CONbits.OCM = 0b000;         // Disable Output Compare 1 Module
    OC1R = 0;                         // Write the duty cycle for the first PWM pulse, 24=8MHzFosc(50us), 30=40MHzFosc(50us), 600=40MHzFosc(1ms)
    OC1RS = duty_cycle;             // Write the duty cycle for the second PWM pulse, OCxRS <= PRx, 499=8MHzFosc(1ms), 623=40MHzFosc(1ms), 1246=40MHzFoc,2msPeriod, 4984=40MHzFoc,8msPeriod, 280=450us D/C@40MHzFoc,2msPeriod,switch
    OC1CONbits.OCTSEL = 0;             // Select Timer 2 as output compare time base
 
    //*********************************************************************************************************
    // Initialize Output Compare 2 module in Continuous Pulse mode, OC2 controls Red LED switch
    //*********************************************************************************************************
    RPOR6bits.RP12R = 0b10011;        // RP12/RB12 tied to OC2 (Red)
    OC2CONbits.OCM = 0b000;         // Disable Output Compare 2 Module
    OC2R = 0;                         // Write the duty cycle for the first PWM pulse, 24=8MHzFosc, 30=40MHzFosc, 600=40MHzFosc(1ms)
    OC2RS = duty_cycle;             // Write the duty cycle for the second PWM pulse, OCxRS <= PRx, 499=8MHzFosc(1ms), 623=40MHzFosc(1ms), 1246=40MHzFoc,2msPeriod, 4984=40MHzFoc,8msPeriod, 280=450us D/C@40MHzFoc,2msPeriod,switch
    OC2CONbits.OCTSEL = 1;             // Select Timer 3 as output compare time base
 
 
Výpis 1: Hlavní rutina z balíčku ukázkového kódu Microchip Technology používá krátkou inicializační sekvenci k nastavení časovačů digitálního signálu. (Zdroj kódu: Microchip Technology)
 

Tato metoda využívá přidružení každého přerušení časovače architektury DSC se vstupním bodem přerušení (ISR). Například když dojde k přerušení Timer3 pro červenou LED diodu, provede DSC funkci ve vstupním bodě _T3Interrupt. Když tedy vyprší Timer3, dojde ke dvěma koordinovaným hardwarovým a softwarovým událostem:

  • OC2 generuje impuls do analogového spínače a rozsvítí červenou LED
  • DSC začne vykonávat _T3Interrupt ISR (Výpis 2)
void __attribute__((__interrupt__, no_auto_psv)) _T3Interrupt(void)        //Read Red DC & AC signals from AN0 & AN1
{
    int delay;
    unsigned char i;
 
    Read_ADC_Red = 1;
    CH0_ADRES_Red_sum = 0;
    CH1_ADRES_Red_sum = 0;
 
    for (delay=0; delay<200; delay++);    //2000=delayed 256us before read ADC
 
//    LATBbits.LATB14 = 1;            // for debugging
 
    for (i=0; i<oversampling_number; i++)
    {
        //Acquires Red-DC from Channel0 (AN0)
        AD1CHS0bits.CH0SA = 0x00;        // Select AN0
        AD1CON1bits.SAMP = 1;            // Begin sampling
        while(!AD1CON1bits.DONE);        // Waiting for ADC completed
        AD1CON1bits.DONE = 0;            // Clear conversion done status bit
        CH0_ADRES_Red_sum = CH0_ADRES_Red_sum + ADC1BUF0;    // Read ADC result
 
        //Acquires Red-AC from Channel1 (AN1)
        AD1CHS0bits.CH0SA = 0x01;        // Select AN1
        AD1CON1bits.SAMP = 1;            // Begin sampling
        while(!AD1CON1bits.DONE);        // Waiting for ADC completed
        AD1CON1bits.DONE = 0;            // Clear conversion done status bit
        CH1_ADRES_Red_sum = CH1_ADRES_Red_sum + ADC1BUF0;    // Read ADC result
    }
 
    CH0_ADRES_Red = CH0_ADRES_Red_sum / oversampling_number;
    FIR_input_Red[0] = CH1_ADRES_Red_sum / oversampling_number;
 
#ifdef Sleep_Enabled
    if (CH0_ADRES_Red<=74 && CH1_ADRES_Red>=4000)    //if spo2 probe is not connected, 74=60mV, 4000=3.2V
    {
        goto_sleep = 1;
    }
    else if (CH0_ADRES_Red > Finger_Present_Threshold)    //if no finger present then goto sleep
    {
        goto_sleep = 1;
    }
    else
#endif
    {
//        LATBbits.LATB14 = 0;            // for debugging
        for (delay=0; delay<500; delay++);    //1000=delayed 256us before read ADC
//        LATBbits.LATB14 = 1;            // for debugging
 
        //Acquires Red-DC baseline from Channel0 (AN0)
        AD1CHS0bits.CH0SA = 0x00;        // Select AN0
        AD1CON1bits.SAMP = 1;            // Begin sampling
        while(!AD1CON1bits.DONE);        // Waiting for ADC completed
        AD1CON1bits.DONE = 0;            // Clear conversion done status bit
        Baseline_ambient = ADC1BUF0;
 
        Baseline_Upper_Limit = Baseline_ambient + DCVppHigh;
        Baseline_Lower_Limit = Baseline_ambient + DCVppLow;
 
        Meter_State = Calibrate_Red();
    }
 
//    LATBbits.LATB14 = 0;            // for debugging
 
    OC2RS = duty_cycle;                // Write Duty Cycle value for next PWM cycle
    IFS0bits.T3IF = 0;                // Clear Timer3 Interrupt Flag
}

Výpis 2: ISR ​​Timer3 slouží pro měření světelného signálu z červené LED diody a měření okolního světla, zatímco ISR Timer2 slouží k měření IR LED osvětlení. (Zdroj kódu: Microchip Technology)

Jak je ukázáno ve Výpisu 2, _T3Interrupt ISR čte DC úroveň z červené LED diody z ADC kanálu 0 (AN0) a dynamickou úroveň červené LED diody z ADC kanálu 1 (AN1). Pokud je aktivována funkce sleep pomocí definice Sleep_Enabled, kód ISR sleduje sběr dat a pokud dojde k odpojení optické sondy nebo odebrání prstu ze snímací sondy, nastaví se proměnná goto_sleep a procesor přejde do úsporného režimu sleep.

Procesor neustále monitoruje úroveň okolního světla a pomocí této aktualizované hodnoty odpovídajícím způsobem posouvá limity funkce Calibrate_Red (), a tím zvyšuje nebo snižuje výstup DAC pro driver červené LED diody, aby byla zachována intenzita mezi Baseline_Lower_Limit a Baseline_Upper_Limit.

Rutina přerušení časovače T2 používá stejný postup, ​​kromě kontroly spánkového režimu a měření okolního světla.

Ukázkový software obsahuje krátkou inicializační sekvenci a spustí Timer2 a Timer3. Pak přechází do hlavní smyčky a čeká se na data zpracovaná ISR. Jakmile jsou data k dispozici, jsou tyto hodnoty zpracovány pomocí FIR filtru, který nakonec volá rutiny pro výpočet SpO2 a srdeční frekvenci (Výpis 3).

    //********** Enable OC1 & OC2 ouputs for IR & Red LED's on/off switch **********
    OC2CONbits.OCM = 0b101;                // Select the Output Compare 2 mode, Turn on Red LED
    T3CONbits.TON = 1;                    // Start Timer3
 
    for (delay=0; delay<2200; delay++);
 
    OC1CONbits.OCM = 0b101;                // Select the Output Compare 1 mode, Turn on IR LED
    T2CONbits.TON = 1;                    // Start Timer2
 
    goto_sleep = 0;
    first_reading = 0;
   
    while (1)
    {
        if (goto_sleep)
        {
[lines clipped]
           Sleep();                    // Put MCU into sleep
           Nop();
            }
        }
        //--------- Main State Machine starts here ---------
        if (RedReady && IRReady)
        {
            RedReady = 0;
            IRReady = 0;
//            LATBbits.LATB14 = 1;            //for debugging
            FIR(1, &FIR_output_IR[0], &FIR_input_IR[0], &BandpassIRFilter);
            FIR(1, &FIR_output_Red[0], &FIR_input_Red[0], &BandpassRedFilter);
            CH1_ADRES_IR = FIR_output_IR[0];
            CH1_ADRES_Red = FIR_output_Red[0];
[lines clipped]
            if (Detection_Done)
            {
                //Max & Min are all found. Calculate SpO2 & Pulse Rate
                SpO2_Calculation();                //calculate SpO2
                Pulse_Rate_Calculation();        //calculate pulse rate
[lines clipped]
    }
/*****************************************************************************
 * Function Name: SpO2_Calculation()
 * Specification: Calculate the %SpO2
 *****************************************************************************/
void SpO2_Calculation (void)
{
    double Ratio_temp;
 
    IR_Vpp1 = fabs(IR_Max - IR_Min);
    Red_Vpp1 = fabs(Red_Max - Red_Min);
    IR_Vpp2 = fabs(IR_Max2 - IR_Min2);
    Red_Vpp2 = fabs(Red_Max2 - Red_Min2);
 
    IR_Vpp = (IR_Vpp1 + IR_Vpp2) / 2;
    Red_Vpp = (Red_Vpp1 + Red_Vpp2) / 2;
 
    IR_Vrms = IR_Vpp / sqrt(8);
    Red_Vrms = Red_Vpp / sqrt(8);
 
//    SpO2 = log10(Red_Vrms) / log10(IR_Vrms) * 100;
//    if (SpO2 > 100)
//    {
//        SpO2 = 100;
//    }
    // Using lookup table to calculate SpO2
    Ratio = (Red_Vrms/CH0_ADRES_Red) / (IR_Vrms/CH0_ADRES_IR);

Výpis 3: Ukázkový kód od Microchip Technology inicializuje moduly časovače a porovnávací moduly výstupů a vstupuje do nekonečné smyčky, vypočítává SpO2 a srdeční frekvenci. Po vyhodnocení může uvést procesor do režimu spánku, pokud není přítomen prst uživatele v sondě. (Zdroj kódu: Microchip Technology)

Pro výpočet SpO2 se používá funkce SpO2_Calculation (). Ta převádí amplitudu pulzu (Vpp) červené a IR LED světla na hodnoty Vrms. Pomocí těchto hodnot funkce vygeneruje poměr a použije tabulku (není součástí výpisu 3) pro převod poměru na specifickou hodnotu SpO2. Tato tabulka je obvykle odvozena z více empirických měření. Pulse_Rate_Calculation () používá pro stanovení srdeční frekvence časování mezi jednotlivými vrcholy měření.

Optimalizace designu SpO2

Ačkoli konstrukce popsaná v tomto článku poskytuje efektivní řešení pro levný pulzní oxymetr, existují i jiné možnosti řešení. Například lze odstranit externí duální operační zesilovač MCP6002 a místo toho použít diskrétní signálový procesor DSPIC33CK64MP102 od Microchip Technology, který má tyto operační zesilovače integrovány přímo v křemíku.

Při implementaci této modifikované konstrukce pulzního oxymetru je nutné přepsat některé klíčové části výše popsaného softwarového balíčku. Například DSPIC33CK64MP102 poskytuje sadu vícenásobných časovačů, kdežto DSPIC33FJ128GP802 funkce Timer2 / Timer3. Proto je nutné část, která se věnuje časovačům, přizpůsobit pro jiný procesor. I přesto však principy zůstávají stejné, a proto je možné používat zmíněný softwarový balíček od Microchip Technology jako vodítko pro vlastní aplikace.

Závěr

Měření hladin saturace kyslíku v krvi poskytuje důležitý ukazatel respiračních funkcí, a tak stal se důležitým nástrojem během pandemie COVID-19. Pomocí přímých optických metod poskytují pulzní oxymetry spolehlivé hodnoty saturace periferního kyslíku (SpO2). Jak jsme si ukázali, k sestavení pulzního oxymetru potřebujeme výkonný procesor a optický modul, který v sobě ukrývá zdroje světla s různý spektrem a jako přijímač fotodiodu. Měření saturace SpO2 lze provádět spolehlivě doma a výsledky jsou srovnatelné s měřením v klinických podmínkách pomocí optických pulzních oxymetrů. Díky tomu si pacient může spolehlivě určit vzestup infekce a včas vyhledat lékařskou pomoc.

 

Článek vyšel v originále na webu DigiKey.com, autorem je Stephen Evanczuk.

Hodnocení článku: