nu ist es fertig. Meine automatische Kellerfensteraufundzumimik.
Draußen wird die Lufttempertur und Luftfeuchte gemessen und darus der Taupunkt berechnet.
Innen wird die Lufttemperatur knapp über dem Boden gemessen.
Wenn es draußen wärmer ist als drinnen UND der Taupunkt der außenluft unter der Kellerinnentemperatur liegt wird das Fenster geöffnet, sonst geschlossen.
Mit einem Schlüsselschalter lässt sich das Fenster auch manuell öffnen und schliessen.
In diesem Zusammenhang : Die Pollin Endschalter sind absoluter Murks! Wackeliger Stößel und keine Zugentlastung in der Kabeleinführung.
Das Ding hängt jetzt an der Wand und funzt, wenn es 1/2 Jahr zufriedenstellend gelaufen ist, werde ich es nochmal "in schön aufbauen"
Den Stellzylinder (Spindel) hab ich übrigens vom letzten Fingertreffen, leider konnte ich keinen langsameren auftreiben, die 0,6mm/s machen fast schwindelig
Als Gehirn werkelt ein Arduino Leonardo Micro, die Zylindermotoren werden über optogekoppelte SSR mit 230V angesteuert.
Und jetzt Plan, Programm und Bilder :
Code: Alles auswählen
//*************** HW Pinbelegung Leonardo Micro ***************************
//Pin 2 - I2C SDA
//Pin 3 - I2C SCL
//Pin 4 - OneWire Data (mit PullUp 4k7 an Vcc)
//Pin 5 - ZylAus_O Output für Signal Zylinder ausfahren (Relais oder SSR für Ausfahrmotor [oder Drehrichtung 1]
//Pin 6 - ZylEin_O Output für Signal Zylinder einfahren (Relais oder SSR für Einfahrmotor [oder Drehrichtung 2]
//Pin 7 - ZylAus_I Input für Signal Zylinder ausgefahren (Endschalter Endposition belegt)
//Pin 8 - ZylEin_I Input für Signal Zylinder eingefahren (Endschalter Anfangsposition belegt)
//Pin 9 - Hand_Auf Input für Schalter-Signal Fenster manuell öffnen
//Pin10 - Hand_Zu Input für Schalter-Signal Fenster manuell schliessen
// ************* Libraries **************************
#include <OneWire.h> // für Dallas 18B20 Temp.-Chip
#include <DallasTemperature.h> // für Dallas 18B20 Temp.-Chip
#include "Wire.h" // für SHT31 Temp./RH-Chip
#include "SHT31.h" // für SHT31 Temp./RH-Chip
OneWire oneWire(4); // Data Pin von Sensor am Pin 4 angeschlossen (4)
DallasTemperature sensors(&oneWire); // Library starten
SHT31 sht; // Library starten
// ************* Variablen ******************************
float gradC_I; // Innentemperatur in Grad Celsius
float gradC_A; // Aussentemperatur in Grad C
float humid_RH; // Aussenfeuchte in %RH
float tp; // Taupunkt in Grad C
int ZylAus_O = 5; // Output für Signal Zylinder ausfahren
int ZylEin_O = 6; // Output für Signal Zylinder einfahren
int ZylAus_I = 7; // Input für Signal Zylinder ausgefahren (hinter Endschalter Endposition)
int ZylEin_I = 8; // Input für Signal Zylinder eingefahren (hinter Endschalter Anfangsposition)
int Hand_Auf = 9; // Input für Signal Fenster manuell öffnen
int Hand_Zu = 10; // Input für Signal Fenster manuell schliessen
// ************* Setup ******************************
void setup()
{
Serial.begin (9600); // UART Kommunikation initialisieren und auf 9600 Baud
sensors.begin(); // Dallas 18B20 initialisieren
Wire.begin(); // I2C Initialisieren
sht.begin(0x44); // SHT31 initialisieren
Wire.setClock(1000); // I2C Geschwindigkeit auf 1000 setzen
// ************* Pinzuweisungen I/O *****************
pinMode(ZylAus_O, OUTPUT);
pinMode(ZylEin_O, OUTPUT);
pinMode(ZylAus_I, INPUT);
pinMode(ZylEin_I, INPUT);
pinMode(Hand_Auf, INPUT);
pinMode(Hand_Zu, INPUT);
digitalWrite(ZylAus_O,LOW); //Bei Programmstart Ausgänge für Zylindermotoren auf LOW setzen
digitalWrite(ZylEin_O,LOW);
}
// ***************Funktionsroutinen *****************
//void fenster_oeffnen() // Funktion Fenster öffnen
//void fenster_schliessen()// Funktion Fenster schliessen
//float werte_einlesen // Funktion Sensoren ausesen
// ************* Routinen für öffnen und schliessen *****
// ******** öffnen *******************
void fenster_oeffnen() // Starten der Funktion Fenster öffnen
{
digitalWrite(ZylEin_O,LOW); // Sicherstellen, dass nie beide Zylindermotoren gleichzeitig laufen
digitalWrite(ZylAus_O, HIGH); // Zylinder ausfahren über Pin ZylAus_O (5)
while(digitalRead(ZylAus_I) == HIGH) // Solange Endschalter nicht belegt, bleibt ZylAus_O = HIGH, sonst ZylAus_O zurücksetzen
{
digitalWrite(ZylAus_O, HIGH);
}
digitalWrite(ZylAus_O, LOW);
}
// ******** schließen ***************
void fenster_schliessen()
{
digitalWrite(ZylAus_O,LOW);
digitalWrite(ZylEin_O, HIGH);
while(digitalRead(ZylEin_I) == HIGH)
{
digitalWrite(ZylEin_O, HIGH);
}
digitalWrite(ZylEin_O, LOW);
}
// ************* Ende Routinen für öffnen und schliessen *****
// *************Routine Werte aus Sensoren einlesen***********
float werte_einlesen()
{
// --- Messwerte aus Sensoren einlesen ---
// Anfang Messung Innentemperatur ( gradC ) vom Dallas Temperatursensor
sensors.requestTemperatures(); // Temperaturmessung starten
gradC_I=sensors.getTempCByIndex(0); // gemessene Temperatur der Variablen gradC_I zuweisen
//Ende Messung Innentemperatur vom Dallas Temperatursensor. Temperatur nun in der Variable gradC
// Anfang Messung Aussentemperatur (gradC_A) und Feuchte (humid_RH) vom SGT31 Sensor
sht.read(); //SHT31 Messung starten
gradC_A=sht.getTemperature(), 1; //SHT31 Temperaturwert in Variable gradC_A speichern
humid_RH=sht.getHumidity(), 1; //SHT31 Feuchtewertt in Variable humid_RH speichern
// Ende Messung Aussentemperatur (gradC_A) und Feuchte (humid_RH) vom SGT31 Sensor
// --- Messwerte sind eingelesen ---
}
// ************** Routine Taupunktberechnung ****************
float taupunkt_berechnen()
{
// verwendete Variablen :
// float gradC_I; // Innentemperatur in Grad Celsius
// float gradC_A; // Aussentemperatur in Grad C
// float humid_RH; // Aussenfeuchte in %RH
// float tp; // Taupunkt in Grad C
//--- Formel für Taupunktberechnung ---------------------
tp = 243.12*((17.62*gradC_A)/(243.12+gradC_A)+log(humid_RH/100))/((17.62*243.12)/(243.12+gradC_A)-log(humid_RH/100));
// *************Ende Routine Taupunktberechnung***********
// --- Messwerte ausgeben ---
Serial.print("Innentemperatur: ");
Serial.println (gradC_I); // Variable gradC_I auf UART ausgeben
Serial.print("Aussentemperatur: ");
Serial.println(gradC_A); // Variable gradC_A auf UART ausgeben
Serial.print("Aussenfeuchte RH: ");
Serial.println(humid_RH); // Variable humid_RH auf UART ausgeben
Serial.print("Taupunkt: ");
Serial.println(tp);
delay(1000);
// --- Messwerte sind ausgegeben ---
// *************Ende Routine Werte aus Sensoren einlesen***********
}
// ************* Hauptprogramm ***********************
void loop()
{
// --- Prüfung Hand- oder Automatikbetrieb ---
werte_einlesen(); //Sensorwerte einlesen
taupunkt_berechnen(); //Routine taupunkt_berechnen anspringen
if(digitalRead(Hand_Auf) == HIGH)
{ //WENN "Handbetrieb öffnen" dann Routine fenster_oeffnen anspringen
fenster_oeffnen(); //Routine fenster_oeffnen anspringen
Serial.println("Handbetrieb(öffnen)"); //Statusmeldung "Handbetrieb(öffnen)" auf UART ausgeben
}
else if(digitalRead(Hand_Zu) == HIGH)
{ //SONST1, wenn "Handbetrieb schliessen" dann Routine fenster_schliessen anspringen
fenster_schliessen(); //Routine fenster_schliessen anspringen
Serial.println("Handbetrieb(schliessen)"); //Statusmeldung "Handbetrieb(schliessen)" auf UART ausgeben
}
//SONST2, wenn kein Handbetrieb ausgewählt, dann Automatikmodus
else if(gradC_A < gradC_I)
{ //WENN Aussentemperatur kleiner als Innentemperatur, dann Routine fenster_schliessen anspringen
Serial.println("Automatik schliessen A<I"); //Statusmeldung "Automatik schliessen A<I" auf UART ausgeben
fenster_schliessen(); //Routine fenster_schliessen anspringen
while(gradC_A < gradC_I) //So lange hier bleiben wie Aussentempertaut kleiner Innentemperatur
{
werte_einlesen();
Serial.print("Innentemperatur: ");
Serial.println (gradC_I); // Variable gradC_I auf UART ausgeben
Serial.print("Aussentemperatur: ");
Serial.println(gradC_A); // Variable gradC_A auf UART ausgeben
Serial.println("Aussen kälter als Innen");//Statusmeldung "Aussen kälter als Innen" auf UART ausgeben
}
}
else if(tp > gradC_I)
{ //SONST3, wenn Taupunkt über Innentemperatur, dann Routine fenster_schliessen anspringen
Serial.println("Automatik schliessen TP>I");//Statusmeldung "Automatik schliessen TP>I" auf UART ausgeben
fenster_schliessen(); //Routine fenster_schliessen anspringen
}
else if(tp < gradC_I)
{ //SONST4, wenn Taupunkt unter unter Innentemperatur, dann Routine fenster_oeffnen anspringen
Serial.println("Automatik öffnen TP<I"); //Statusmeldung "Automatik öffnen TP<I" auf UART ausgeben
fenster_oeffnen(); //Routine fenster_oeffnen anspringen
}
// Serial.println ("ende"); //Statusmeldung "ende" auf UART ausgeben, bedeutet: Hauptprogrammscvhleife wurde ausgeführt
//delay(1);
}
frischgelüftete Grüße
RK