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... ;)
So, nachdem heute der 4mm-Schlauchverbinder angekommen ist, konnte ich die Venturidüse fertigstellen. Der Spannungsoffset beträgt bei 5V Versorgung rund 0.2V. Wenn ich durchpuste steigt die Spannung auf ca. 0.5V an. Das ist zwar nicht die Welt aber mit der 5mV-Auflösung vom Arduino geht das schon einigermaßen in Ordnung. Verstärker werde ich daher wohl keinen zusätzlich anschließen...
Das Spirometer ist fertig und hat die Feuertaufe bestanden... 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).
1 | // ============================================================= |
2 | // Programm zur Messung des Lungenvolumen mit dem Sensor MPX5010 |
3 | // ============================================================= |
4 | |
5 | #include <LiquidCrystal_I2C.h> |
6 | #include <Wire.h> |
7 | |
8 | LiquidCrystal_I2C lcd(0x27,16,2); // ACHTUNG: set the LCD address to 0x20 or 0x27 for a 16 chars and 2 line display!!! |
9 | |
10 | // Anschlüsse Display: |
11 | // =================== |
12 | // GND - GND |
13 | // VCC - 5V |
14 | // SDA - ANALOG Pin 4 |
15 | // SCL - ANALOG Pin 5 |
16 | |
17 | // Anschlüsse Drucksensor: |
18 | // ======================= |
19 | // GND - GND |
20 | // VCC - 5V |
21 | // Signal - Analog Pin 0 |
22 | |
23 | |
24 | int sensorPin = A0; |
25 | int pin_start = 12; // Pin für Startknopf |
26 | int i; |
27 | long t_start,t_end; // Variablen zur Bestimmung der Zeitschrittweite dt |
28 | |
29 | float U_sensor, U_offset; |
30 | float v, A, Volumsfluss; |
31 | float Lungenvolumen, dt; |
32 | float k; // Korrekturfaktor |
33 | |
34 | |
35 | // ========================= |
36 | // ======== SETUP ========== |
37 | // ========================= |
38 | |
39 | void setup() |
40 | { |
41 | Serial.begin(9600); |
42 | |
43 | pinMode(pin_start, INPUT); // start-pin für den Beginn der Messung |
44 | |
45 | lcd.begin(); // initialize the lcd |
46 | lcd.backlight(); |
47 | |
48 | // Print a message to the LCD. |
49 | lcd.setCursor(0,0); |
50 | lcd.print("Spirometer"); |
51 | |
52 | delay(4000); |
53 | |
54 | lcd.setCursor(0,0); |
55 | lcd.print(" "); |
56 | lcd.setCursor(0,0); |
57 | lcd.print("press button &"); |
58 | lcd.setCursor(0,1); |
59 | lcd.print("blow then....."); |
60 | |
61 | |
62 | U_offset = (5.0 / 1023) * analogRead(sensorPin); // Bestimmung des sensor-offsets in Volt |
63 | |
64 | A = (0.024*0.024) * 3.141592654; // Querschnittsfläche des Strömungsrohrs in dm² mit Radius r = 0.024 dm |
65 | |
66 | dt = 0.0011605; // zeitliche Schrittweite dt, genau bestimmt mittels millis() |
67 | |
68 | k = 1.4; // Korrekturfaktor |
69 | |
70 | } |
71 | |
72 | |
73 | // ================================= |
74 | // ======== HAUPTSCHLEIFE ========== |
75 | // ================================= |
76 | |
77 | void loop() |
78 | { |
79 | Lungenvolumen = 0.0; |
80 | |
81 | while(digitalRead(pin_start) == HIGH) // Wartet bis Startknopf gedrückt |
82 | |
83 | lcd.setCursor(0,0); |
84 | lcd.print("blow now "); |
85 | lcd.setCursor(0,1); |
86 | lcd.print(" "); |
87 | |
88 | //t_start = millis(); // Startzeit für die Bestimmung von dt |
89 | |
90 | |
91 | for(i = 0; i < 10000; i++) // insgesamt 10000*0.001 = 10 sek Abfrage der Sensorwerte |
92 | { |
93 | // Einlesen des Spannungswerts des Sensors MPX5010 |
94 | |
95 | U_sensor = (5.0 / 1023) * analogRead(sensorPin); // eingelesener Sensorwert in Volt |
96 | |
97 | // Berechnung der Geschwindigkeit in dm/sek |
98 | |
99 | if(U_sensor - U_offset > 0.005) // Abfrage um Werte < Schwelle als 0 zu werten |
100 | { |
101 | v = k * 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 |
102 | } |
103 | else |
104 | { |
105 | v = 0.0; |
106 | } |
107 | |
108 | Volumsfluss = A * v; // Volumsfluss V/t in Liter/sek |
109 | |
110 | Lungenvolumen = Lungenvolumen + Volumsfluss * dt; // Aufsummierung der einzelnen Teilvolumina |
111 | |
112 | delay(1); // 1 ms Verzögerung |
113 | |
114 | } |
115 | |
116 | /* |
117 | t_end = millis(); // Endzeit für die Bestimmung von dt |
118 | |
119 | Serial.println(t_start); |
120 | Serial.println(t_end); |
121 | Serial.print("dt = "); |
122 | Serial.println((t_end - t_start)/10000.0,4); |
123 | */ |
124 | |
125 | lcd.setCursor(0,0); |
126 | lcd.print("V = "); |
127 | lcd.setCursor(4,0); |
128 | lcd.print(Lungenvolumen,2); |
129 | lcd.setCursor(9,0); |
130 | lcd.print("Liter"); |
131 | |
132 | delay(2000); |
133 | |
134 | lcd.setCursor(0,1); |
135 | lcd.print("button to start"); |
136 | |
137 | } |
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.