Spirometer mit Arduino und MPX5010

Für alle anderen Basteleien, Messgeräte und physikalische Experimente.

Moderatoren: ebastler, SeriousD, MaxZ

Antworten
Nachricht
Autor
Benutzeravatar

Thread-Ersteller
stoppi
Beiträge: 1427
Registriert: Mo 29. Mär 2010, 21:39
Danksagung erhalten: 271 Mal
Kontaktdaten:

Spirometer mit Arduino und MPX5010

#1 Beitrag von stoppi »

Hallo!

Ein Projekt habe ich noch in der Warteschleife und zwar ein Strömungsmessgerät, welches dann als Spirometer zur Bestimmung des Lungenvolumens dienen soll. Als Sensor kommt der MPX5010 zum Einsatz. Dieser besitzt zwei Druckeingänge, um den Differenzdruck messen zu können. Die Empfindlichkeit beträgt 0.45V/kPa. Ein erster Funktionstest verlief erfolgreich. Konnte durch Einsaugen schön Spannungen bis 4.5V erzielen bei 5V Versorgungsspannung.

Zur Messung des Lungenvolumens muss natürlich der aktuelle Volumsfluss dV/dt bekannt sein. Diesen könnte ich mit einem gewöhnlichen Strömungsmessgerät basierend auf einem Schaufelrad bestimmen nur ist dies mMn viel zu ungenau, da sich zum Beispiel das Schaufelrad aufgrund der Trägheit noch weiterdreht, auch wenn keine Strömung mehr vorliegt. Deshalb habe ich mich für die Druckmessung entschieden. Der Gesamtdruck besteht ja aus statischen, dynamischen und Schweredruck (Bernoulligleichung). Die Summe der drei Drücke ist entlang eines Strömungspfades konstant. Gehe ich von einer Höhendifferenz h = 0 aus, so fällt der Schweredruck weg. Übrig bleibt die Summe aus statischen und dynamischen Druck, also die Gleichung

p_stat_1 + 0.5 * ro * v_1² = p_stat_2 + 0.5 * ro * v_2²

Nun messe ich einen statischen Druck außerhalb des Spirometerrohres, wo v_1 = 0 gilt. Daraus folgt für die Gleichung:

p_stat_1 = p_stat_2 + 0.5 * ro * v_2²

Umgeformt nach v_2 ergibt sich der Ausdruck:

v_2 = Wurzel[2 * (p_stat_1 - p_stat_2) / ro]

Die Druckdifferent p_stat_1 - p_stat_2 wird eben mit dem MPX5010 gemessen. Dessen Ausgangsspannung hat einen geringen (ca. 0.2V) offset, welcher von der ausgegebenen Spannung abgezogen werden muss. Die Empfindlichkeit beträgt wie oben erwähnt 0.45V/kPa.

Daraus folgt die Beziehung:

p_stat_1 - p_stat_2 = 1000 * [(U_out - U_offset) / 0.45]

Eingesetzt in die obige Gleichung für v_2 ergibt sich der finale Ausdruck

v_2 = Wurzel[(2000 / (0.45 * ro)) * (U_out - U_offset)]

mit ro = Luftdiche = ca. 1.25 kg/m³

Aus v_2 und dem Strömungsquerschnitt A_2 ergibt sich der momentane Volumsfluss dV/dt = A_2 * v_2.

Für das innerhalb der Zeit dt durchströmende Volumen dV gilt dann:

dV = A_2 * v_2 * dt

Diese Volumselemente müssen im Arduinoprogramm nur noch aufsummiert werden, um das Lungenvolumen V zu erhalten. Als Zeitschrittweite werde ich dt = ca. 1ms wählen.

Der Sensor um ca. 14 Euro ist bereits aus China eingetroffen. Als nächstes werde ich mich um den Bau der Venturidüse kümmern... ;)
Dateianhänge
Spirometer_Arduino_01.jpg
Spirometer_Arduino_14.jpg
Spirometer_Arduino_14.jpg (55.3 KiB) 1988 mal betrachtet
Spirometer_Arduino_05.jpg
Spirometer_Arduino_05.jpg (108.63 KiB) 1988 mal betrachtet
Spirometer_Arduino_08.jpg
Spirometer_Arduino_06.jpg
Spirometer_Arduino_06.jpg (114.88 KiB) 1988 mal betrachtet
Spirometer_Arduino_13.jpg

Benutzeravatar

VDX
Beiträge: 979
Registriert: Fr 13. Jul 2018, 18:23
Spezialgebiet: Laser und Mikro-/Nanotechnik
Danksagung erhalten: 130 Mal

Re: Spirometer mit Arduino und MPX5010

#2 Beitrag von VDX »

Hi Stoppi,

... auch wieder ein interessantes Projekt! ;)

Hab' mir vor Jahren auch mal überlegt, ob ich mir für was anderes eigene Drucksensoren aufbauen sollte ... wenn du mal was "superempfindliches" (Auflösung bis runter zu "Femto-Pascal" bzw, "Pico-bar") brauchst, könntest mal anfragen ... evtl. wärme ich das dann wieder auf :trollface:

Viktor
Aufruf zum Projekt "Müll-freie Meere" - https://reprap.org/forum/list.php?426 -- Facebook-Gruppe - https://www.facebook.com/groups/383822522290730
Call for the project "garbage-free seas" - https://reprap.org/forum/list.php?425

Benutzeravatar

Thread-Ersteller
stoppi
Beiträge: 1427
Registriert: Mo 29. Mär 2010, 21:39
Danksagung erhalten: 271 Mal
Kontaktdaten:

Re: Spirometer mit Arduino und MPX5010

#3 Beitrag von stoppi »

So, das Arduinoprogramm ist soweit fertig. Zu Beginn muss man einmalig die echte zeitliche Schrittweite dt bestimmen. Die liegt bei mir zum Beispiel bei 1.1605 ms pro Durchlauf. Dieser Wert geht ja als dt ins numerische Integrieren ein und sollte schon recht genau stimmen...

Die Venturidüse habe ich auch fast fertig. Fehlt nur noch der 4mm Schlauchverbinder, der heute oder morgen eintreffen müsste. Die Düse erhält natürlich noch Verstrebungen zur Steigerung der Stabilität.

Code: Alles auswählen

// =============================================================
// Programm zur Messung des Lungenvolumen mit dem Sensor MPX5010
// =============================================================

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // ACHTUNG: set the LCD address to 0x20 or 0x27 for a 16 chars and 2 line display!!!

// Anschlüsse Display:
// ===================
// GND - GND
// VCC - 5V
// SDA - ANALOG Pin 4
// SCL - ANALOG Pin 5

// Anschlüsse Drucksensor:
// =======================
// GND - GND
// VCC - 5V
// Signal - Analog Pin 0


int sensorPin = A0;
int pin_start = 8;      // Pin für Startknopf
int i;
long t_start,t_end;     // Variablen zur Bestimmung der Zeitschrittweite dt

float U_sensor, U_offset;
float v, A, Volumsfluss;
float Lungenvolumen, dt;


// =========================
// ======== SETUP ==========
// =========================

void setup()
   {
    Serial.begin(9600);

    pinMode(pin_start, INPUT);           // start-pin für den Beginn der Messung

    lcd.begin();        // initialize the lcd
    lcd.backlight();

    // Print a message to the LCD.
    lcd.setCursor(0,0);
    lcd.print("Spirometer");

    delay(4000);

    lcd.setCursor(0,0);
    lcd.print("          ");
    lcd.setCursor(0,0);
    lcd.print("press button &");
    lcd.setCursor(0,1);
    lcd.print("blow then.....");
        
    
    U_offset = (5.0 / 1023) * analogRead(sensorPin);   // Bestimmung des sensor-offsets in Volt
    
    A = (0.03*0.03) * 3.141592654;      // Querschnittsfläche des Strömungsrohrs in dm² mit dem Radius r = 0.03 dm

    dt = 0.0011605;                     // zeitliche Schrittweite dt, genau bestimmt mittels millis()

   }


// =================================
// ======== HAUPTSCHLEIFE ==========
// =================================

void loop()
   {
    Lungenvolumen = 0.0;
    
    while(digitalRead(pin_start) == HIGH)    // Wartet bis Startknopf gedrückt

    lcd.setCursor(0,0);
    lcd.print("blow now        ");
    lcd.setCursor(0,1);
    lcd.print("                ");

    //t_start = millis();           // Startzeit für die Bestimmung von dt


    for(i = 0; i < 10000; i++)      // insgesamt 10000*0.001 = 10 sek Abfrage der Sensorwerte
       {
        // Einlesen des Spannungswerts des Sensors MPX5010
        
        U_sensor = (5.0 / 1023) * analogRead(sensorPin);   // eingelesener Sensorwert in Volt

        // Berechnung der Geschwindigkeit in dm/sek

        if(U_sensor - U_offset > 0.015)      // Abfrage um Werte < Schwelle als 0 zu werten
           {      
            v = 10.0 * sqrt((2000/(0.45 * 1.25))*(U_sensor - U_offset));     // Berechnung der Strömungsgeschwindigkeit in dm/sek; 0.45 V/kPa = Sensibilität des Sensors; 1.25 kg/m³ = Luftdichte
           }
        else
           {
            v = 0.0;
           }

        Volumsfluss = A * v;     // Volumsfluss V/t in Liter/sek

        Lungenvolumen = Lungenvolumen + Volumsfluss * dt;   // Aufsummierung der einzelnen Teilvolumina

        delay(1);     // 1 ms Verzögerung
       
       }

    /*
    t_end = millis();     // Endzeit für die Bestimmung von dt

    Serial.println(t_start);
    Serial.println(t_end);
    Serial.print("dt = ");
    Serial.println((t_end - t_start)/10000.0,4);
    */
     
    lcd.setCursor(0,0);
    lcd.print("V =             ");
    lcd.setCursor(4,0);
    lcd.print(Lungenvolumen,2);
    lcd.setCursor(9,0);
    lcd.print("Liter");

    delay(2000);

    lcd.setCursor(0,1);
    lcd.print("button to start");
      
   }
Dateianhänge
Spirometer_Arduino_41.jpg
Spirometer_Arduino_43.jpg

Benutzeravatar

Thread-Ersteller
stoppi
Beiträge: 1427
Registriert: Mo 29. Mär 2010, 21:39
Danksagung erhalten: 271 Mal
Kontaktdaten:

Re: Spirometer mit Arduino und MPX5010

#4 Beitrag von stoppi »

Das Spirometer ist fertig und hat die Feuertaufe bestanden... :awesome:

Weil ich nicht genau weiß, wie sich die Strömungsgeschwindigkeit im Rohr radial verteilt (Stichwort Gesetz von Hagen-Poiseuille) und wohl zum Rand hin wo gemessen wird abnimmt, habe ich noch einen Korrekturfaktor k in die Berechnung der Geschwindigkeit eingebaut. Bekomme aber eigentlich sehr vernünftige Messwerte (um die 2 Liter ohne in der Lunge verbleibendes Restvolumen).
Dateianhänge
Spirometer_Arduino_45.jpg
Spirometer_Arduino_51.jpg
Spirometer_Arduino_59.jpg
Spirometer_Arduino_64.jpg
Spirometer_Arduino_61.jpg
Spirometer_Arduino_63.jpg

Antworten