1 | //*******************************************************
|
2 | //* Ein Arduino Wochenendprojekt von Csaba Klacek *
|
3 | //* Thema: Taupunktberechnung und Steuerung mit Arduino *
|
4 | //* Version 3ok *
|
5 | //*******************************************************
|
6 | // Eine Steuerung ist im Moment noch nicht implementiert.
|
7 | // Eine LCD Anzeige wird noch in der Nächster Version verfügbar sein
|
8 | /*
|
9 | Berechnung erfolgt hier mit festen Temp un relHum, um die Formelrichtigkeit testen zu können.
|
10 | Als Grundlage dienen die Berechnungen wie in der excel Tabelle
|
11 | Temperatur : Temp 35 C (Celsius)
|
12 | Rel.Feuchte: relHum 55 % ( % )
|
13 | (17,1*Temp)
|
14 | Sättigungsdruck: Sdru (Pa) = 610,8*EXP( --------------) ->(EXP(1)= 2,7183)
|
15 | (234,2+Temp)
|
16 |
|
17 | Sättigungsdruckin mbar --> Sdru/100 (hPa(=mbar)
|
18 | Tatsächliche Dampfdruck : TaDa=(Sdru/100)*(relHum/100)
|
19 | Taupunkt: 241,2* (LN(TaDa)-LN(6,112)) / (17,5043- (LN(TaDa)-LN(6,112)) ) ...natürlicher Logaritmus
|
20 | --> 241,2* (LN(TaDa)-1,8103) / (17,5043- (LN(TaDa)-1,8103))
|
21 | ACHTUNG Punkt statt Dezimalkomma verwenden!!!
|
22 |
|
23 | Version 2: stammt von hier www.wetterochs.de (Author ist Dipl-Phys-Stefan Ochs)--------------
|
24 | Beschreibung:
|
25 | Die Luft ist ein Gemisch verschiedener Gase. Eines dieser Gase ist der Wasserdampf.
|
26 | Die Menge an Wasserdampf, die in der Luft enthalten sein kann, ist allerdings begrenzt.
|
27 | Je wärmer die Luft ist, desto mehr Wasserdampf kann in ihr enthalten sein.
|
28 | Die relative Luftfeuchtigkeit gibt an, wie viel Prozent des maximalen Wasserdampfgehaltes die Luft
|
29 | im Augenblick enthält.Da der maximale Wasserdampfgehalt mit steigender Temperatur ansteigt,
|
30 | fällt die relative Luftfeuchtigkeit mit steigender Temperatur (und umgekehrt).
|
31 | Die Taupunkttemperatur ist definiert als die Temperatur, bei der der aktuelle Wasserdampfgehalt in der Luft
|
32 | der maximale (100% relative Luftfeuchtigkeit) ist. Die Taupunkttemperatur ist damit eine von der aktuellen
|
33 | Temperatur unabhängige Größe.
|
34 | Eine Möglichkeit die Taupunkttemperatur zu messen ist das Abkühlen von Metall bis sich die Oberfläche
|
35 | mit Wasserdampf beschlägt. Dann ist die Temperatur des Metalls die Taupunkttemperatur.
|
36 | Es gibt keine exakten Formel zur Umrechnung der Taupunkttemperatur in die relative Luftfeuchtigkeit.
|
37 | Zur Erstellung meines Taupunktrechners habe ich eine einfache Näherungsformel benutzt.
|
38 | Eine exakte Umrechnung ist nur mit experimentell ermittelten Tabellen möglich.
|
39 |
|
40 | Aus Temperatur und relativer Luftfeuchte bzw. Temperatur und Taupunkt lässt sich auch der absolute Feuchtegehalt
|
41 | der Luft in Gramm Wasserdampf pro Kubikmeter ausrechnen.
|
42 | Formeln:
|
43 | Die Grundlage der Berechnungen ist die Näherungsformel für den Sättigungsdampfdruck
|
44 | ( Gleichung 1 ), die sogenannte Magnusformel. Die relative Luftfeuchtigkeit ist definiert
|
45 | als das Verhältnis vom augenblicklichen Dampfdruck zum Sättigungsdampfdruck (umgeformte Gleichung 2).
|
46 | Bei der Taupunkttemperatur ist definitionsgemäß der Sättigungsdampfdruck gleich dem aktuellen Dampfdruck.
|
47 | Aus diesen beiden Definitionen folgt unmittelbar Gleichung 3, die Formel zur Berechnung der relativen
|
48 | Luftfeuchtigkeit aus der Taupunkttemperatur. Die 4. Gleichung beschreibt umgekehrt die Berechnung
|
49 | der Taupunkttemperatur aus der relativen Luftfeuchtigkeit und der aktuellen Temperatur. Diese 4.
|
50 | Gleichung ist im Grunde nichts anderes als die nach T aufgelöste 1. Gleichung , wobei für
|
51 | den Sättigungsdampfdruck der aktuelle Dampfdruck (und nicht der aktuelle Sättigungsdampfdruck) eingesetzt wird,
|
52 | so dass die Taupunkttemperatur und nicht die normale Temperatur als Ergebnis herauskommt.
|
53 | Aus der allgemeinen Gasgleichung ergibt sich die 5. Gleichung .
|
54 | Bezeichnungen:
|
55 | relHum = relative Luftfeuchte
|
56 | Temp = Temperatur in °C
|
57 | TK = Temperatur in Kelvin (TK = Temp + 273.15)
|
58 | TD = Taupunkttemperatur in °C
|
59 | DD = Dampfdruck in hPa
|
60 | SDD = Sättigungsdampfdruck in hPa
|
61 |
|
62 | Parameter:
|
63 | a = 7.5, b = 237.3 für Temp >= 0
|
64 | a = 7.6, b = 240.7 für Temp < 0 über Wasser (Taupunkt)
|
65 | a = 9.5, b = 265.5 für Temp < 0 über Eis (Frostpunkt)
|
66 |
|
67 | R* = 8314.3 J/(kmol*K) (universelle Gaskonstante)
|
68 | mw = 18.016 kg/kmol (Molekulargewicht des Wasserdampfes)
|
69 | AF = absolute Feuchte in g Wasserdampf pro m3 Luft
|
70 | Formeln:
|
71 | 1-Sättigungsdampfdruck in hPa SDD(Temp) = 6.1078 * 10^((a*Temp)/(b+Temp))
|
72 | 2-Tatsächliche Dampfdruck DD(relHum,Temp) = relHum/100 * SDD(Temp)
|
73 | 3-relativen Luftfeuchtigkeit aus der Taupunkttemperatur: relHum(Temp,TD) = 100 * SDD(TD) / SDD(Temp)
|
74 | 4-Taupunkttemperatur TD(relHum,Temp) = b*v/(a-v) mit v(relHum,Temp) = log10(DD(relHum,Temp)/6.1078)
|
75 | 5-Aus der allgemeinen Gasgleichung ergibt sich:
|
76 | AF(relHum,TK) = 10^5 * mw/R* * DD(relHum,Temp)/TK; AF(TD,TK) = 10^5 * mw/R* * SDD(TD)/TK
|
77 |
|
78 | Anmerkungdes Verfassers (Stefan Ochs): Leider kann ich zu den Formeln aus Zeitgründen keinen Support leisten!
|
79 | Die Formeln sind vollständig und richtig. Falls Sie Probleme mit der Mathematik haben,
|
80 | suchen Sie bitte anderweitig Hilfe. Wenn Sie unsicher sind, ob die Näherungen in ihrem
|
81 | Spezialfall zulässig sind, dann kann ich das nicht für Sie entscheiden
|
82 | */
|
83 | // ACHTUNG: DHT Sensor Pinbelegung beachten!!!!!! Ucc-GND-DATA oder Ucc-DATA-GND. Die Versorgung geschiet durch
|
84 | // HIGH und LOW Signallevel an den Arduino Ausgängen
|
85 | #include <Streaming.h> // Serial.print kompakte Schreibweise
|
86 | #include <Metro.h> //Include Metro library, für zeitgesteuerte Schleife,Intervallbildung
|
87 | #include <math.h>
|
88 | #include "DHT.h"
|
89 | #include <OneWire.h>
|
90 | #include <DallasTemperature.h> // Dallas DS18B20 Temperatursensor als Oberflaechentemperaturfuehler
|
91 | #define DHTPIN 8 // DHT Signal Pin an Arduino Eingang
|
92 | //#define DHTTYPE DHT11 // DHT 11
|
93 | #define DHTTYPE DHT22 // DHT 22 (AM2302)
|
94 |
|
95 | #define LED 13 // LED an Pin 13
|
96 | #define GND 10 // GND für DHT als LOW Level
|
97 | #define Vcc 9 // DHT Ucc+5V Pin als HIGH Level
|
98 | // Data wire is plugged into port 2 on the Arduino
|
99 | #define ONE_WIRE_BUS 2
|
100 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
|
101 | OneWire oneWire(ONE_WIRE_BUS);
|
102 | // Pass our oneWire reference to Dallas Temperature.
|
103 | DallasTemperature sensors(&oneWire);
|
104 | // arrays to hold device address
|
105 | DeviceAddress insideThermometer;
|
106 |
|
107 | int state = HIGH;
|
108 | float Temp_DS18;
|
109 | float f; // DHT temp in Fahrenheit
|
110 | float hi; // DHT heat Index für Fahrenheit
|
111 | float DHT_Heatindex; // in Celsius die empfundene Temperatur für die momentane Luftfeuchte
|
112 | float Taupunkt; // berechneter Taupunkt Temperatur in C
|
113 | float TaDa; // Tatsächlicher Dampfdruck
|
114 | float Temp_DHT ; // DHT gemessene Temperatur ---> temp in C
|
115 | float relHum ; // gemessene relative Feuchtigkeit ---> rF in %
|
116 | float THum; // Tatsaechliche Feuchte in g Wasserdampf pro m3 Luft ,wird berechnet
|
117 | float Sdru; //Saettigungsdruck in Pa
|
118 | float Sdru_mbar; //Saettigungsdruck geteilt durch 100, in hPa
|
119 | float absF; //absolute Feuchte in g Wasserdampf pro m3 Luft für V1 Berechnung
|
120 | byte merker = 0;
|
121 | //---------------Parameter Version 2 ----------------------------------------------
|
122 | float TK ; // = Temperatur in Kelvin (TK = T + 273.15)
|
123 | float TD ; // = Taupunkttemperatur in °C
|
124 | float DD ; // = Dampfdruck in hPa
|
125 | float SDD ; // = Sättigungsdampfdruck in hPa
|
126 | // Parameter:
|
127 | float v ; // (relHum,Temp), Methode2
|
128 | float a = 7.5 ; //für T >= 0
|
129 | float b = 237.3 ; //für T >= 0
|
130 | // a = 7.6, b = 240.7 für T < 0 über Wasser (Taupunkt)
|
131 | // a = 9.5, b = 265.5 für T < 0 über Eis (Frostpunkt)
|
132 | float R_konst = 8314.3 ; // R* = 8314.3 J/(kmol*K) (universelle Gaskonstante)
|
133 | float mw = 18.016 ; // mw = 18.016 kg/kmol (Molekulargewicht des Wasserdampfes)
|
134 | float AF ; // = absolute Feuchte in g Wasserdampf pro m3 Luft
|
135 | float TF ; // = tatsächliche Feuchte in g Wasserdampf pro m3 Luft
|
136 | float Anzeige_Taupunkt; // Mittelwert aus der 2 Berechnungsmethoden.
|
137 | float Alarm_Temp; // Temperaturwert-Abstand Taupunkt-Oberflächentemperatur
|
138 | Metro AnzeigeMetro = Metro(3000); // Alle 3 sec neue Werte berechnen,
|
139 | DHT dht(DHTPIN, DHTTYPE);
|
140 | //----------------------------------------------------------------------------------
|
141 | void setup() {
|
142 | pinMode(GND,OUTPUT);
|
143 | pinMode(Vcc,OUTPUT);
|
144 | pinMode(LED,OUTPUT);
|
145 | digitalWrite(GND,LOW);
|
146 | digitalWrite(Vcc,HIGH);
|
147 | digitalWrite(LED,state);
|
148 | Serial.begin(9600);
|
149 | Serial.println(" Taupunktberechnung ;");
|
150 | dht.begin();
|
151 | delay(100);
|
152 | //Serial.println(" Temperatur : 35 C ");
|
153 | //Serial.println(" relHum : 55 % ");
|
154 | // locate devices on the bus
|
155 | Serial.print("Locating devices...");
|
156 | sensors.begin();
|
157 | Serial.print("Found ");
|
158 | Serial.print(sensors.getDeviceCount(), DEC);
|
159 | Serial.println(" Dallas DS18B20.");
|
160 | // report parasite power requirements
|
161 | Serial.print("Parasite power is: ");
|
162 | if (sensors.isParasitePowerMode()) Serial.println("ON");
|
163 | else Serial.println("OFF");
|
164 | if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
|
165 | // show the addresses we found on the bus
|
166 | Serial.print("Dallas DS18B20 0 Address: ");
|
167 | printAddress(insideThermometer);
|
168 | Serial.println();
|
169 |
|
170 | // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
|
171 | sensors.setResolution(insideThermometer, 12);
|
172 | Serial.print("Dallas DS18B20 0 Resolution: ");
|
173 | Serial.print(sensors.getResolution(insideThermometer), DEC);
|
174 | Serial.println();
|
175 | }
|
176 |
|
177 | void loop() {
|
178 |
|
179 | if (AnzeigeMetro.check() == 1) { // check if the metro has passed its interval .
|
180 | if (state==HIGH) state=LOW; // LED13 Blinken lassen, falls merker gesetzt ist
|
181 | else state=HIGH;
|
182 | if (merker==1) digitalWrite(LED,state);
|
183 | else digitalWrite(LED,LOW);
|
184 |
|
185 | THD22(); // Sensordaten anzeigen
|
186 |
|
187 | Serial.println(F(" Temperatur an der Materialoberflaeche wo sich Tauwasser bilden kann"));
|
188 | Serial.print(F(" Sensordaten von Dallas DS18B20: "));
|
189 | sensors.requestTemperatures(); // Send the command to get temperatures
|
190 | // It responds almost immediately. Let's print out the data
|
191 | printTemperature(insideThermometer);
|
192 | Serial.println();
|
193 |
|
194 | Serial.println(F(" THD Data reading - Sensordaten vom DHT22 ---------------------------"));
|
195 | Serial.print(" Luftfeuchtigkeit: "); // THD Humidity
|
196 | Serial.print(relHum);
|
197 | Serial.println(" %\t");
|
198 | Serial.print(" Luft-Temperatur: ");
|
199 | Serial.print(Temp_DHT);
|
200 | Serial.print(" *C (");
|
201 | Serial.print(f);
|
202 | Serial.println("*F)\t");
|
203 | Serial.print(" Heat index(gefuehlte Temperatur): ");
|
204 | Serial.print(hi);
|
205 | Serial.print("*F ");
|
206 | Serial.print(DHT_Heatindex);
|
207 | Serial.println("*C ");
|
208 | Serial.println();
|
209 |
|
210 | Taupunktberechnung_V2();
|
211 | Serial.println();
|
212 | Serial.println(F(" Taupunktberechnung nach Methode 2; --------------------------------"));
|
213 | Serial.print(F(" Saettigungsdampfdruck in hPa : "));
|
214 | Serial.println(SDD);
|
215 | Serial.print(" Dampfdruck in hPa : ");
|
216 | Serial.println(DD);
|
217 | Serial.print(" Taupunkt : ");
|
218 | Serial.print(TD);
|
219 | Serial.println(" *C ");
|
220 | Serial.print(F(" absolute Feuchte in g Wasserdampf pro m3 Luft : "));
|
221 | Serial.println(AF);
|
222 | Serial.print(F(" IST Feuchte in g Wasserdampf pro m3 Luft : "));
|
223 | Serial.println(TF);
|
224 | Serial.println();
|
225 |
|
226 | Taupunktberechnung_V1();
|
227 | Serial.println(F(" Taupunktberechnung nach Methode 1; ------------------------------"));
|
228 | Serial.print(" Saettigungsdruck mbar : ");
|
229 | Serial.println(Sdru);
|
230 | Serial.print(" Dampfdruck in hPa : ");
|
231 | Serial.println(DD);
|
232 | Serial.print(" Tatsaechliche Dampdruck in hPa : ");
|
233 | Serial.println(TaDa);
|
234 | Serial.print(" Taupunkt : ");
|
235 | Serial.print(Taupunkt);
|
236 | Serial.println(" *C ");
|
237 | Serial.print(F(" absolute Feuchte in g Wasserdampf pro m3 Luft : "));
|
238 | Serial.println(absF);
|
239 | Serial.print(F(" Tatsaechliche Feuchte in g Wasserdampf pro m3 Luft : "));
|
240 | Serial.println(THum);
|
241 | Serial.println();
|
242 |
|
243 | Serial.println("--------------Datenanzeige----------------");
|
244 | Anzeige_Taupunkt = (Taupunkt + TD)/2;
|
245 | Alarm_Temp = Temp_DS18-Anzeige_Taupunkt;
|
246 | Serial <<" Tauwasser bildet sich bei "<< Temp_DHT<<" *C Luftfeuchtigkeit "<< endl;
|
247 | Serial <<" auf eine Oberflaechentemperatur mit "<<Anzeige_Taupunkt<<" Grad Celsius"<< endl;
|
248 | Serial.println();
|
249 | Serial <<" Achtung! Bis zu Tauwasserbildung fehlen "<<Alarm_Temp<<" Grad Celsius Temperaturabfall "<< endl;
|
250 | if (Alarm_Temp < 10) {
|
251 | Serial <<" Es wird kritisch, bitte LUEFTUNG einschalten"<< endl;
|
252 | merker = 1; // LED 13 blinkt
|
253 | }
|
254 | else {
|
255 | Serial<<" Tauwasserbildung ist noch nicht zu erwarten. "<< endl;
|
256 | merker = 0; // LED 13 ist aus
|
257 | }
|
258 | Serial.println();
|
259 | }
|
260 | //hier könnten weitere Codezeilen stehen, zB. für Relaissteuerung oder Änliches.....
|
261 |
|
262 | }
|
263 | //----LOOP ENDE-----
|
264 | //------------------------Taupunktberechnung_V1 nach Methode1---------------------------------
|
265 | void Taupunktberechnung_V1() {
|
266 | Sdru = 610.8 * exp((17.1*Temp_DHT)/(234.2+Temp_DHT));
|
267 | Sdru_mbar=Sdru/100;
|
268 | TaDa=(Sdru_mbar*relHum)/100;
|
269 | Taupunkt= 241.2 * ((log(TaDa)-1.8103) / (17.5043- (log(TaDa)-1.8103)));
|
270 | absF = ((Sdru *0.002165022853) / (Temp_DHT+273.15))*1000; //absolute Feuchte in g Wasserdampf pro m3 Luft
|
271 | THum = (absF/100)*relHum ; // Tatsaechliche Feuchte in g Wasserdampf pro m3 Luft
|
272 | }
|
273 | //------------------------Taupunktberechnung_V2 nach Methode2---------------------------------
|
274 | void Taupunktberechnung_V2() {
|
275 | SDD = 6.1078 * pow(10,((a*Temp_DHT)/(b+Temp_DHT))); // Saettigungsdampfdruck in hPa
|
276 | DD = (relHum/100) * SDD; // Dampfdruck in hPa
|
277 | v = log10((DD/6.1078)); // ACHTUNG log 10 verwenden!!!
|
278 | TD = (b*v)/(a-v); // Taupunkt
|
279 | AF = 216.686912909 * (SDD/(Temp_DHT + 273.15)); //absolute Feuchte in g Wasserdampf pro m3 Luft
|
280 | TF = (AF/100) * relHum ; // Tatsaechliche Feuchte in g Wasserdampf pro m3 Luft
|
281 | }
|
282 | //------------------------THD22 Messwerte für Taupunktberechnung---------------------------------
|
283 | void THD22() {
|
284 | relHum = dht.readHumidity();
|
285 | Temp_DHT = dht.readTemperature();
|
286 | f = dht.readTemperature(true);
|
287 | // Check if any reads failed and exit early (to try again).
|
288 | if (isnan(relHum) || isnan(Temp_DHT) || isnan(f)) {
|
289 | Serial.println("Failed to read from DHT sensor!");
|
290 | return;
|
291 | }
|
292 | // Compute heat index, Must send in temp in Fahrenheit!
|
293 | hi = dht.computeHeatIndex(f, relHum);
|
294 | DHT_Heatindex = (hi-32)/1.8; // Fahrenhein in Celsius umrechnen
|
295 | }
|
296 | //------------------------------------------------------------------------------
|
297 | // function to print a device address
|
298 | void printAddress(DeviceAddress deviceAddress){
|
299 | for (uint8_t i = 0; i < 8; i++)
|
300 | {
|
301 | if (deviceAddress[i] < 16) Serial.print("0");
|
302 | Serial.print(deviceAddress[i], HEX);
|
303 | }
|
304 | }
|
305 | // ------------------function to print the temperature for a device----------------
|
306 | void printTemperature(DeviceAddress deviceAddress){
|
307 | Temp_DS18 = sensors.getTempC(deviceAddress);
|
308 | Serial.print("Temp C: ");
|
309 | Serial.print(Temp_DS18);
|
310 | Serial.print(" Temp F: ");
|
311 | Serial.println(DallasTemperature::toFahrenheit(Temp_DS18)); // Converts tempC to Fahrenheit
|
312 | }
|