Układ do pomiaru pułapu tlenowego naszego organizmu

Układ do pomiaru pułapu tlenowego naszego organizmu

Mamy już luty, dla wielu osób czas rezygnacji z siłowni czy uprawiania sportów, podjętego w ramach postanowień noworocznych… jeśli chcemy mieć do tego dobre usprawiedliwienie, zainteresować nas może kwestia tzw. pułapu tlenowego - VO2max. Jest to cecha naszego organizmu, mówiąca o jego zdolności do pochłaniania tlenu z powietrza, a w konsekwencji, mówiąca o tym, jaką mamy kondycję. Typowo do pomiaru VO2max stosuje się dosyć skomplikowany zestaw aparatury medycznej… jednak możemy skonstruować układ typu DIY, który pozwoli nam na estymację tego parametru.

Uwaga! To nie jest urządzenie medyczne i nie jest w stanie w żaden sposób zastąpić prawdziwej diagnostyki medycznej.

Pułap tlenowy - VO2max, to interesująca koncepcja, która sugeruje, że istnieje naturalnie ograniczona zdolność do wydobywania tlenu z powietrza i zużywania go przez nasz organizm. To tak jakby IQ dla zajęć sportowych - jakiś parametr, który określa, jak bardzo jesteś utalentowany w różnych zawodach sportowych. Pracowano nad nim od początku ubiegłego wieku i polegano na zbieraniu wydychanego powietrza do worków, celem dalszej ich analizy. Współcześnie stosuje się skomplikowany sprzęt, co przekłada się na wysoki koszt tego rodzaju badań.

Alternatywnie można użyć prostej aplikacji na smartfona, która korzysta z pomiarów z naszej opaski fitness/smartwatcha i algorytmu - ktoś kiedyś skorelował kosztowny pomiar pułapu tlenowego np. z pomiarem tętna w czasie wysiłku itp. Taki pomiar nie jest z kolei zbyt precyzyjny i niekoniecznie działa dla szerszej populacji w różnym wieku itd. Aby zmierzyć pułap tlenowy, trzeba dokładnie zmierzyć ilość gazu wchodzącego i wychodzącego z płuc, poziom CO2 i tlenu w tym gazie, jego wilgotność i temperaturę oraz użyć sporej liczby wzorów.

W artykule opisujemy, jak zbudować przenośne urządzenie, pozwalające wykonać pomiary z rozsądną dokładnością, pozwalającą na realne zastosowanie np. przy testach sportowców. Jego koszt to około 150 dolarów. Może nie jest to mała kwota, ale w porównaniu do profesjonalnego sprzętu, gdzie tylko pojedyncze badanie może tyle kosztować, jest to metoda pełni osiągalne dla hobbystów i amatorów. System może być podłączony przez Bluetooth lub Wi-Fi i zapewniać bogactwo informacji podczas użytkowania. Komponenty do oddychania można łatwo oddzielić od drogich czujników, aby ograniczyć obawy związane z przenoszeniem wirusów itp. Tego rodzaju urządzenie może być np. tanio oferowane do użytku w klubach fitness czy dla indywidualnych użytkowników w celu oceny postępów treningowych czy też ogólnej diagnostyki kondycji fizycznej.

Moduł bazuje częściowo na innym projekcie - spirometrze z druku 3D (linki na końcu artykułu). Instrukcja jego montażu itp. może być pomocna w zakresie budowy tego układu.

Potrzebne elementy

Układ nie wymaga egzotycznych, czy trudnych do zdobycia elementów, a główny koszt, to bardzo precyzyjne sensory, jakie są wymagane w tych analizach. Istnieją oczywiście tańsze alternatywy na rynku, jednak, jak wskazuje autor, mają liczne wady znacznie utrudniające stosowanie ich w tym układzie. Dotyczy to w szczególności sensorów tlenu - ten wybrany do projektu jest zintegrowany i ma wyjście cyfrowe (interfejs I²C), gdzie inne - tańsze - wymagają dodatkowych przetwornic do zasilania i zewnętrznego przetwornika analogowo-cyfrowego (ADC) do digitalizacji pomiaru.

Do zestawienia projektu potrzebne są:

  • różnicowy czujnik ciśnienia SDP816-125PA CMOSens z skalą pomiarową do 125 Pa,
  • płytka deweloperska TTGO T-Display ESP32 z CP2104, obsługą Wi-Fi i Bluetooth zintegrowana z wyświetlaczem LCD o przekątnej 1,14”,
  • sensor tlenu Gravity z interfejsem I²C,
  • detektor gazu SCD30 do detekcji dwutlenku węgla, zakres pomiarowy 40000 ppm, dokładność 3%,
  • bateria litowo-polimerowa 600 mAh,
  • przełącznik,
  • złącza i wtyczki,
  • ustnik od fajki do nurkowania,
  • arkusz wysokotemperaturowej folii do wycinania uszczelek z gumy silikonowej o wymiarach 12×19”, grubość ok. 0,8 mm,
  • komponenty mechaniczne z druku 3D.

Projekt bazuje na wcześniejszym projekcie elementu układu powietrznego, który zawiera zawory zwrotne, aby uniknąć gromadzenia się powietrza w układzie (link na końcu artykułu) - minimalizuje to objętość martwą układu i znacznie poprawia jakość pomiarów.

Wcześniej, układ ten zastosowany został w fajce do nurkowania, wykonanej w technice druku 3D.

W tym przypadku budowany jest aparat oddechowy, który zasysa powietrze z jednej strony i wypuszcza je giętką rurką zapożyczoną z fajki do oddychania pod wodą z drugiej strony. Rurka ta łączy się z miernikiem gazu w systemie. W ten sposób mierzona jest jedynie ilość wydychanego gazu oraz poziom CO2 i O2 w części wydychanej powietrza. Bez zaworu jednokierunkowego następowałoby mieszanie się strumienia dopływającego i wychodzącego powietrza.

Fotografia 1. Zamontowane w urządzeniu zawory jednokierunkowe

Projekt zaworów jednokierunkowych i sposób ich budowy można znaleźć w projekcie wspomnianej fajki do oddychania. Gotowe zawory pokazano na fotografii 1. Zawór zawiera wydrukowaną w 3D ramkę, na której zamontowano silikonowy arkusz w taki sposób, że mógł on się tylko odchylać w jedną stronę. To bardzo prosty mechanizm i jego budowa powinna być zrozumiała dla każdego. Dysza Venturiego ma taką samą konstrukcję jak w spirometrze (link na końcu artykułu) z dodatkowymi obudowami dodanymi dla czujników tlenu i dwutlenku węgla z wbudowanymi osłonami, które zapewniają ich szczelność i nie zakłócają laminarnego przepływu gazów. Jedyną modyfikacją jest zmiana obudowy elektroniki, która zawiera różnicowy czujnik ciśnienia - jest ona nieznacznie powiększona, aby pomieścić dodatkowe miejsce potrzebne na dwa przewody magistrali I²C dla sensorów.

Rysunek 1. Układ zaworów z miejscem na ustnik

Wszystkie pliki STP potrzebne do druku elementów układu można znaleźć na stronie z projektem. Na rysunku 1 pokazano układ zaworów zwrotnych, które zapewniają jednokierunkowy przepływ powietrza. Wylotową stroną tego modułu łączymy go, za pomocą elastycznej rurki z modułem z dyszą Venturiego, pokazanym na rysunku 2.

Rysunek 2. Układ pomiarowy z dyszą Venturiego i miejscami do osadzenia sensorów O2 i CO2

Zwężka w przewodzie powoduje zmianę ciśnienia, która jest proporcjonalna do przepływu. Różnica ciśnień przed i w zwężonym kanale mierzona jest za pomocą specjalnego ciśnieniomierza różnicowego. W module tym osadzone są także sensory mierzące zawartość tlenu i dwutlenku węgla w wydychanym gazie. Wyjścia tych sensorów podłączone są do elektroniki, znajdującej się w obudowie, pokazanej na rysunku 3.

Rysunek 3. Obudowa elektroniki układu

Komponenty elektroniczne

Ma rysunku 4 pokazany jest schemat elektryczny przyrządu. Jest on bardzo prosty i w zasadzie składa się z dwóch sensorów podłączonych do interfejsu I²C modułu z mikrokontrolerem. Jako ten ostatni zastosowano płytkę deweloperska TTGO T-Display z mikrokontrolerem ESP32 i wyświetlaczem OLED. Podłączone moduły mają różne adresy, dzięki czemu można podłączyć je do wspólnego interfejsu (piny 21 i 22 GPIO). Oprócz linii I²C podłączyć należy tylko zasilanie (3,3 V) oraz masę, aby sensor mógł działać.

Rysunek 4. Schemat urządzenia

Sensor ciśnienia (czujnik SDP816-125PA) z wyjściem analogowym musi być podłączony do przetwornika ADC w układzie. Należy go podłączyć do wyprowadzenia 33 GPIO (wejście A5) oraz linii zasilania i masy. Ostatnim elementem, podłączanym do modułu z mikrokontrolerem jest przycisk, który należy wpiąć tak, jak pokazano na schemacie - w dodatnią linię zasilania, pomiędzy baterię a moduł. Układ zasilany jest z baterii, może jednak zasilany być przez port USB-C z zasilacza wtyczkowego. W ten sam sposób należy także ładować baterie, pamiętając jednocześnie, że układ musi być włączony w czasie ładowania. W projekcie zastosowano baterie o pojemności 600 mAh, ale jest szansa, że i większa zmieściłaby się w obudowie układu, co jest podstawowym czynnikiem ograniczającym pojemność zastosowanego akumulatora.

Oprogramowanie

Ostatnim etapem budowy, jest instalacja oprogramowania układowego. Zostało ono opracowane w Arduino IDE. Fragmenty szkicu Arduino, kontrolującego działanie urządzenia, pokazane są na listingu 1. Kompletny szkic można pobrać ze strony z projektem. Obliczanie VO2max nie jest trywialną sprawą. Autor projektu podaje w opisie odniesienia do konkretnych opisów algorytmów, jakie wypróbował podczas tworzenia swojej implementacji. Dzięki temu możemy dokładnie przeanalizować naukowe podstawy metodologii wyznaczania pułapu tlenowego, jeśli nas to interesuje.

Listing 1. Najistotniejsze fragmenty szkicu Arduino obsługującego system

void loop() {
 if(totalBreath == 0) minuteTotal = millis();
 // Wyświetlenie wartości maksymalnej na ekranie
 if(!digitalRead(buttonPin2) screenMax();
 // Obliczanie wartości po 30 s pomiaru
 if((millis()- minuteTotal) > 30000){
   minuteTotal = millis();
   totalBreath = 0;
   goFigure();
   volumeMinute = 0;
 }

 // Odczyt wartości analogowej
 sensorValue = analogRead(analogInPin);
 // Mapowanie odczytu ADC na napięcie
 voltage =( 3.3 * (( sensorValue )/4095.0));
 // Wyliczenie ciśnienia z wartości napięcia
 Pa = (190.0 * voltage/3.3) - 31.0;
 if( Pa > 5 ) {
   if (newBreath < 1) {
     timerBreath = millis();
     if(volumeTotal > 300) totalBreath = totalBreath + 1;
     volumeMinute = volumeMinute + volumeTotal;
     volumeTotal = 0;
     newBreath = 1;
   }
   massFlow = 1000*sqrt(
     (abs(Pa)*2*rho)/((1/(pow(area_2,2)))-(1/(pow(area_1,2)))));
   // Objętościowy przepływ powietrza
   volFlow = massFlow/rho;
   volumeTotal = volFlow * (millis() - TimerNow) + volumeTotal;
 } else if(newBreath){
   newBreath = 0;
   secondsBreath = (millis() - timerBreath)/1000;
   if(secondsBreath > 0.1){
     // Pomiar średniej ilości tlenu
     O2dump();
     // Pomiar średniej ilości CO2
     CO2dump();
     // Aktualizacja danych na ekranie
     screen();
   }
 }
 TimerNow = millis();
 delay(20);
}

void CO2dump(){
 if (airSensor.dataAvailable()){
   lastCotwo = airSensor.getCO2();
   lastTemp = airSensor.getTemperature();
   // Odejmij poprzedni pomiar
   coTotal = coTotal - coReadings[coreadIndex];
   // Odczyt z sensora
   coReadings[coreadIndex] = lastCotwo;
   // Dodaj nowy pomiar
   coTotal = coTotal + coReadings[coreadIndex];
   // Inkrementacja indeksu
   coreadIndex = coreadIndex + 1;
   // Jeśli koniec macierzy - reset indeksu
   if (coreadIndex >= numReadings) coreadIndex = 0;
   // Obliczanie średniej
   coAverage = coTotal / numReadings;
   lastCotwo = coAverage;
 }
  delay(500);
}

void O2dump(){
 float oxygenData = Oxygen.ReadOxygenData(COLLECT_NUMBER);
 // Odejmujemy ostatni pomiar
 oTotal = oTotal - oReadings[oreadIndex];
 // Odczyt z sensiras
 oReadings[oreadIndex] = oxygenData;
 // Dodanie nowego pomiaru
 oTotal = oTotal + oReadings[oreadIndex];
 // Inkrementacja indeksu
 oreadIndex = oreadIndex + 1;
 // Jeśli koniec macierzy - reset indeksu
 if (oreadIndex >= numReadings) oreadIndex = 0;
 oAverage = oTotal / numReadings;
 lastOtwo = oAverage;
}

void goFigure(){
 float percentN2exp;
 float co2;
 volumeMinute = volumeMinute * 2.0;
 volumeMinute = volumeMinute/1000.0; //gives liters of air VE
 co2 = lastCotwo/10000.0;
 percentN2exp = (100.0 - (co2 + lastOtwo));
 volumeMinute = volumeMinute * (273/(273 + lastTemp)) * ((760.0 - 25.2)/760);
 vo2Max = volumeMinute * (((percentN2exp/100.0) * 0.265) - (lastOtwo/100.0));
 vo2Max = (vo2Max * 1000.0)/(float(wtTotal)/2.2);
 tft.fillScreen(TFT_RED);
 tft.setTextColor(TFT_GREEN, TFT_RED);
 tft.drawCentreString("VO2Max= ",60,10,4);
 tft.setTextColor(TFT_RED, TFT_RED);
 tft.drawString("888888",70,40,7);
 tft.setTextColor(TFT_WHITE, TFT_RED); // Orange
 tft.setCursor(70, 40, 7);

 if(vo2Max > vo2MaxMax) vo2MaxMax = vo2Max;
  tft.println(vo2MaxMax);
  tft.setCursor(160, 115, 4);
  tft.setTextColor(TFT_GREEN, TFT_RED);
  tft.println("RESET");
}

void wtRead(){
 buttonState1 = digitalRead(buttonPin1);
 // Jeśli zmienił się stan inkrementowany jest licznik (na zboczu)
 if (buttonState1 != lastButtonState1) {
   // Jeśli obecny stan jest niski, to znaczy, że puszczono przycisk
   if (buttonState1 == LOW) {
     buttonPushCounter1++;
     if(buttonPushCounter1 == 10) buttonPushCounter1 = 0;
   }
   // Opóźnienie eliminujące efekty drgania styków przycisku
   delay(50);
 }
 lastButtonState1 = buttonState1;

 buttonState2 = digitalRead(buttonPin2);
 // Analogicznie drugi przycisk, który przełącza pola wagi
 if (buttonState2 != lastButtonState2) {
   if (buttonState2 == LOW) {
     buttonPushCounter2++;
     wtTotal = wtTotal + 1000/pow(10, buttonPushCounter2) * buttonPushCounter1;
     buttonPushCounter1  = 0;
   }
   delay(50);
 }
 lastButtonState2 = buttonState2;
 if(buttonPushCounter2 < 3) {
   int counter = 30 + (40 * buttonPushCounter2);
   tft.drawNumber(buttonPushCounter1,counter,40,7);
 }
}

Kluczową koncepcją przy tym pomiarze jest fakt, że objętość wydychanego powietrza, nie jest taka sama jak objętość, którą do powietrza wciągnęliśmy przy oddechu. Jest modyfikowany przez fizjologię płuc i należy obliczyć wiele czynników, aby ustalić prawdziwą ilość tlenu, którą z powietrza pobierają nasze płuca. Oprogramowanie musi najpierw uwzględnić wagę użytkownika - podaje się ją obsługując interfejs za pomocą dwóch przycisków dołączonych do modułu TTGO. VO2max jest mierzone w cm³/min/kg. Na ekranie modułu pojawiają się trzy pola. Naciskanie dolnego przycisku zwiększa wagę - cyfrę w danym polu, a drugi przycisk pozwala przejść do kolejnego pola. Ta część programu realizowana jest w funkcji wtRead() (listing 1). Jest ona uruchamiana w konfiguracyjnej części skryptu (funkcja void setup()) w pętli czekającej, na naciśniecie drugiego przycisku po raz czwarty:

while(buttonPushCounter2 < 3) wtRead();

Po wprowadzeniu wagi inicjowane jest sprawdzanie cyklu oddechowego w celu pomiaru całkowitej objętości na minutę. Pomiar realizowany jest co 30 sekund. Można go zresetować za pomocą dolnego przycisku w dowolnym momencie podczas całego procesu, aby ponownie uruchomić 30-sekundowe zliczanie oddechów. Pojawi się nowy ekran z zebraną do tej pory objętością w próbce i zegarem odliczającym 30 sekund. Większość komercyjnych maszyn mierzy te parametry przez minutę, ale to dosyć długo, jak na doraźne pomiary np. w czasie ćwiczeń. Pomiędzy oddechami sprawdzane są poziomy tlenu i CO2 w wydychanym powietrzu. Wyniki tych pomiarów umieszczane są w macierzy, która służy do obliczania średniej kroczącej. Temperatura i wilgotność są również próbkowane z czujnika CO2.

Pod koniec czasu próbkowania funkcja goFigure() (listing 1) oblicza VO2max i porównuje je z poprzednimi próbkami i wybiera wartość maksymalną, którą prezentuje na ekranie. Objętość wydychanego gazu jest kompensowana na podstawie skorygowanych objętości wydychanego CO2 i O2 oraz temperatury, ciśnienia i wilgotności wydychanych gazów. W urządzeniu nie ma sensora ciśnienia atmosferycznego - wykorzystane jest ciśnienia na poziomie morza, więc jeśli stosujemy sensor np. wysoko w górach, pomiary mogą nie być dokładne.

Moduł bazuje na układzie ESP32, zatem możliwe jest użycie wbudowanych w niego interfejsów bezprzewodowych do komunikacji. Łatwo jest sobie wyobrazić, że np. z odpowiednią aplikacją na smartfona, układ mógłby łączyć się z telefonem poprzez Bluetooth, aby tam wyświetlać dane z pomiarów i wyliczony pułap tlenowy.

Podsumowanie

Większość komercyjnych urządzeń, takich jak to, jest testowane przy użyciu znormalizowanych mieszanek gazów w celu sprawdzenia dokładności ich czujników. Autorka nie testowała systemu w ten sposób, a bardziej martwiła się o dokładność pomiarów objętości z rurki Venturiego. Podczas konstruowania spirometru sprawdziła ona ten element z dość dużym przepływem (15 l/min) i stwierdziła, że pomiar jest dość dokładny, ale komercyjne laboratoria ustandaryzowały swoje obliczenia objętości na pomiarach objętości ok. 1 litra. Powstał tego rodzaju kalibrator, bazujący na dużej strzykawce i elementach z druku 3D. Zmierzona dokładność takiego pomiaru wynosi ±8%, co jest raczej dobrą dokładnością, jak na hobbystyczną konstrukcję. Niestety, co do wyznaczania samego VO2max autorka nie miała okazji porównać swojej konstrukcji z urządzeniem komercyjnym.

Samo korzystanie z układu jest proste. Wystarczy zrozumieć, co daje nam ten pomiar. Zasada jest prosta - jesteś silnikiem, który spala tlen i chcesz zwiększyć obroty silnika do czerwonej linii, a następnie zmierzyć, ile tlenu spalasz na minutę na kilogram masy swojego ciała. Prostota tego przenośnego urządzenia polega na tym, że można uprawiać swój ulubiony, męczący sport - bieganie, jazdę na rowerze itp. i używać tego instrumentu, gdy zbliża się koniec naszej wydolności. Pozwala to sprawdzać VO2max. Można dodatkowo zamontować to urządzenie na zestawie okularów ochronnych, jak zwykłą fajkę do nurkowania, jeśli to wygodniejsze w danym zastosowaniu.

Jeśli chodzi o samo fizjologiczne znaczenie VO2max, to istnieją ogromne ilości materiałów w Internecie i literaturze fachowej, ale tematyka zdrowia wykracza poza nasz artykuł - skupiamy się na elektronice, a reszty dowiedzieć można się z innych źródeł, skupiających się na tematyce ludzkiej fizjologii.

Nikodem Czechowski, EP

Bibliografia:

  1. http://bit.ly/3XC41w1
  2. https://www.instructables.com/3D-Printed-Spirometer/
  3. https://www.instructables.com/3D-Printed-Snorkel/
  4. https://bit.ly/3HyC9TW
  5. https://www.biopac.com/wp-content/uploads/h19_bsl4.pdf
  6. https://web.cortland.edu/buckenmeyerp/fall2004/labvo2.html
Artykuł ukazał się w
Elektronika Praktyczna
luty 2023
Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik grudzień 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio listopad - grudzień 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje listopad - grudzień 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna grudzień 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich grudzień 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów