Fenster auf und zu fahren

Hallo zusammen,

ich versuche mich gerade an einer Gewächshaussteuerung, ich habe dazu einen Haufen Code aus dem Forum zusammen geräubert und es sind auch schon erste erfolge erkennbar. Mein Ziel ist es das 2 Fenster Temperaturgesteuert aud bzw. zu fahren, bzw. bei wind für eine eingestellte Zeit schließen. Die Fenster sollen dann bei über- oder unterschreiten der Temperatur in Intervallen auf und zu fahren.

zb.
Temp soll: 22
Temp ist : 25
Fenster fährt 3 sek. auf und hält dann für 10 sek.
die Zeiten sollen für Fahrzeit und Wartezeit einstellbar sein.

Mit dem Code den ich zusammengeschustert habe, ist es so das die Wartezeit immer kleiner als die Fahrzeit sein muss und ich nicht dahinter komm warum das so ist. Ich würde beide Zeiten gerne unabhängig von einander einstellen können.

Wäre sehr nett wenn mir da jemand unter die Arme greifen könnte...

unsigned long StartZeitFensterAuf = 0;           // Zeitspeicher Fenster auf
unsigned long IntervalFensterAufZu = 3000;       // (*) Interval auf und zu fahrt
unsigned long IntervalFensterPause = 2000;       // (*) Wartezeit (Motoren stop)

void fensterauf() {
  if (WindAlarm == false) {
    if (F1TOGGLE == false && millis() - StartZeitFensterAuf > IntervalFensterPause) {
      StartZeitFensterAuf = millis();
      if (Fenst1Auf == false) Motor1Auf();
      if (Fenst2Auf == false) Motor2Auf();
    }
    
    if (F1TOGGLE == true && millis() - StartZeitFensterAuf > IntervalFensterAufZu) {
      StartZeitFensterAuf = millis();
      Motor1Stop();
      Motor2Stop();
    }
    
  }
  if (WindAlarm == true) {
    Motor1Zu();
    Motor2Zu();
    }  
} // ende fenster auf

Ein weiteres Problem ist das ich auf dem Display, sobald ich ins Menü gehe, immer wieder wirre Zeichen bekomme....

Im Anhang noch der ganze Code falls mir da jemand helfen möchte...

schonmal vielen Dank für die Hilfe

Gruß Lafi

Gewaechshaus_3_3.zip (9.59 KB)

Poste doch mal ein Foto deiner "wirren Zeichen" auf dem Display.

Lafi2004:
Im Anhang noch der ganze Code falls mir da jemand helfen möchte...

Also hast du nicht den ganzen Code reingestellt? Warum nicht?

Hallo,

HotSystems:
Poste doch mal ein Foto deiner "wirren Zeichen" auf dem Display.

Doch, der Code ist einmal nur der snipsel im Post, und der gesamte Code als ZIP-Datei im Anhang...

Hier noch die wirren Zeichen im Anhang...

Vielen Dank das Ihr schon geschaut habt!

Gruß Lafi

Lafi2004:
Hallo,

Doch, der Code ist einmal nur der snipsel im Post, und der gesamte Code als ZIP-Datei im Anhang...

Hier noch die wirren Zeichen im Anhang...

Vielen Dank das Ihr schon geschaut habt!

Gruß Lafi

Mit dem Code-Fragment können wir nix anfangen.
Also poste den kompletten Sketch hier im Forum und nicht als zip-Datei, die kann man mobil nicht lesen.

Und die komischen Zeichen deuten darauf, dass du keine Pullups am I2C-Bus hast.

Hi

Wenn Du sämtliche Zeilen, Die Du eh als Kommentar im Sketch hast (also komplette Blöcke ausgeremmt) entfernst, wirst Du LOCKER unter die 9000 Zeichen-Begrenzung kommen.

Alles in Allem ist der Sketch nicht sonderlich leicht zu Lesen - jetzt hätte ich gerne Kommentare, was welche Funktion wieso macht.

Auch wäre Es für den Helfer einfacher, wenn Du beischreiben könntest, welche Funktion Er in Welcher .ino findet - klar kann ich mir den Kram auch zig Mal durchscrollen - hab dafür aber keine Lust.

Auch könntest Du Dein Problem eingrenzen - Du bist in Deinem Sketch tiefer drin - WO macht Er WAS, und WAS erwartest Du eigentlich statt Dessen?

MfG

HotSystems:
Mit dem Code-Fragment können wir nix anfangen.
Also poste den kompletten Sketch hier im Forum und nicht als zip-Datei, die kann man mobil nicht lesen.

Und die komischen Zeichen deuten darauf, dass du keine Pullups am I2C-Bus hast.

Hallo Dieter,

meinst Du die einzelnen ino Dateien, oder wirklich den ganzen Codetext?

Pullupwiderstände (4,7kOhm) sind eingebaut...

Gruß Lafi

Gewaechshaus_3_3.ino (12.7 KB)

Anzeigen.ino (3.26 KB)

Auswertungen.ino (7.25 KB)

Einstellungen.ino (9.63 KB)

Menue_Einstellungen.ino (2.6 KB)

Sensoren.ino (3.95 KB)

Hallo,

es ist vermutlich schlimm programmiert.... aber ich versuch mal zusammen zu schreiben was mein Ziel ist

Wind messen mit einem Anemometer, Geschwindigkeit einstellbar.
Temperatur Innen Messen
Temperatur Außen Messen
Taupunkt Innen bestimmen
Taupunkt Außen bestimmen
Luftdruck Außen Messen
Uhrzeit

Wenn Wind Größer x Fenster zu fahren und für eine Zeit sperren.
Wenn Wind Kleiner y Fenster wieder freigeben

Wenn Temp Innen > Eingestellten Wert Max dann Fenster für x sek. auf fahren und dann für y sek warten.
Wenn Temp Innen < Eingestellten Wert Max und > Engestellter Wert Min dann Fenster Stop
Wenn Temp Innen < Eingestellter Wert Min dann Fenster für x sek. zu fahren und dann für y sek warten.

Im Menü würde ich gerne alle Werte Einstellen können und gerne im Eprom der Uhr abspeichern.
Im Menü möchte ich auch die Möglichkeit schaffen die Fenster Manuel zu fahren...

Da ich da nun schon seit Wochen dran rum bastel bin ich für jede Hilfe Dankbar...

Hallo zusammen,

ich habe bezüglich der "wirren Zeichen" jetzt verschieden Widerstände als Pullup am I²C Bus zwischen 4,7K und 10K getestet, leider keine Besserung.

Was ich nicht verstehe ist, das die Anzeige im Normalbetrieb einwandfrei geht, und nur sobald ich im Menü bin kommt es zu diesen "wirren Zeichen"....

Gruß Lafi

Lafi2004:
Was ich nicht verstehe ist, das die Anzeige im Normalbetrieb einwandfrei geht, und nur sobald ich im Menü bin kommt es zu diesen "wirren Zeichen"....

Um da jetzt einen Fehler zu finden, muss man sicher am Projekt Messungen vornehmen und dazu das Projekt nachbauen.
Im Sketch habe ich so keinen offensichtlichen Fehler erkennen können.

Du kannst aber an diversen Stellen serielle Ausgaben einbauen, um über diesen Weg deinen Sketch zu debuggen.
Da kommst du sicher an die Fehlerquelle ran.

Alternative wäre ein anderes, fertiges Menü zu verwenden, dass du hier im Forum finden kannst.
Damit könntest du dein Projekt sicher rel. schnell aufbauen.
LCD-Menü

HotSystems:
Alternative wäre ein anderes, fertiges Menü zu verwenden, dass du hier im Forum finden kannst.
Damit könntest du dein Projekt sicher rel. schnell aufbauen.
LCD-Menü

Das habe ich mir schon mal angeschaut, steig aber leider nicht durch. Wenn mir da jemand unter die Arme greifen könnte würde ich mich da gerne nochmal dran versuchen. Ich bekomme die Menüstruktur hin, verstehe aber nicht wie ich meine Funktionen zum laufen bringe. Vor allem bin ich da am Interrupt für die Impulszählung gescheitert...

Gruß Lafi

Das Menü ist doch in der Dokumentation sehr gut beschrieben. Da solltest du mit klar kommen.
Und den Interrupt musst du nur aktivieren, wenn du Messungen vornehmen willst.
In anderen Fällen den Interrupt ausschalten.

HotSystems:
Das Menü ist doch in der Dokumentation sehr gut beschrieben. Da solltest du mit klar kommen.
Und den Interrupt musst du nur aktivieren, wenn du Messungen vornehmen willst.
In anderen Fällen den Interrupt ausschalten.

Ich werde es nochmal probieren mit dem Menü. Aber wie binde ich denn die Windmessung am sinnvollsten ein? aktuell ist es so das ich per Interrupt die Impulse kontinuierlich hochzähle und dann ca. alles 5 sek. in einer Funktion die Geschwindigkeit errechne.

// Allgemeine Variablen

// Anemometer
const int windgeschwindigkeitPin = 2;            //  (*) Reed-Kontakt Windgeschwindigkeit an D2 / INT_0 
volatile byte reedCountSum;                      
volatile unsigned long reedMillisSum;  
int   Radius = 50;                               // (*) Radius in mm (Mitte Schaufel)
int   impulsU = 1;                               // (*) Impulse pro Umdrehung 
int   WindAlarmSpeed[3] = {28, 20, 0};             // (*) Wind Alarm im Kilometer pro Sek. an, Wind Alarm aus, Zwischenspeicher (defaultwerte)
float Vwind, maxwind, minwind;                   // Windgeschwindigkeit (zwischenspeicher)
float Vms = 0;                                   // windgeschwindigkeit in Meter pro Sekunde 
float Vkmh = 0;                                  // windgeschwindigkeit in Kilometer pro Stunde 
int   Bft = 0;                                       
float ProFak = 2.5;                              // Proportionalitätsfaktor -> https://www.meteorologyshop.eu/meteo-blog/grundlagen-der-windmesstechnik


void setup() {
// Serieller Monitor
  Serial.begin(115200);
// Vorbereitung ISR  
  pinMode(windgeschwindigkeitPin, INPUT_PULLUP);
  attachInterrupt(0, reedISR, FALLING);          // Interrupt 0 auf ISR 
  interrupts();                                  // Interrupt einschalten


void reedISR() {
  if (millis() - StartZeitISR >= IntervallISR)   // Entprellzeit
  {
    reedCountSum++;                              // eine Radumdrehung zählen
    reedMillisSum += millis() - StartZeitISR;    // Zeit addieren
    StartZeitISR = millis();                     // Zeit merken
    }
}
void Windgeschwindigkeit() {
  if (millis() - StartZeitWindMessen >= IntervallWindMessen)
  {
  StartZeitWindMessen = millis();
  float Umfang = Radius * 2 * 3.14 / 1000;       // Umfang in Meter
  noInterrupts();                                // Interrupts sperren  
  byte umdrehungen = reedCountSum;               // Zählvariable umkopieren 
  reedCountSum = 0;                              // Zählvariable auf 0 zurücksetzen
  unsigned long zeit = reedMillisSum / 1000;     // Zeitzähler umkopieren in Sekunden
  reedMillisSum = 0;                             // Zeitzähler auf 0 zurücksetzen
  interrupts();                                  // Interrupts wieder zulassen 
  if (zeit > 0) {
  Vms = umdrehungen * Umfang / (zeit * impulsU) * ProFak;
  Vkmh = Vms * 3.6;
  Vwind = Vkmh;                                  // Ausgabe Windgeschwindigkeit in Kilometer pro Stunde
  //Vwind = Vms;                                 // Ausgabe Windgeschwindigkeit in Meter pro Sekunde
  }                                              
  else {                                         
  Vms   = 0;                                     // Null setzen wenn keine Umdrehung gefunden wurde
  Vkmh  = 0;
  Vwind = 0;
  umdrehungen = 0;
  }   
//Ausgabe Beaufort
  if                  (Vms< 0.51)  Bft=0;
  if ((Vms>= 0.51) && (Vms< 2.06)) Bft=1;
  if ((Vms>= 2.06) && (Vms< 3.6))  Bft=2;
  if ((Vms>= 3.6)  && (Vms< 5.66)) Bft=3;
  if ((Vms>= 5.66) && (Vms< 8.23)) Bft=4;
  if ((Vms>= 8.23) && (Vms<11.32)) Bft=5;
  if ((Vms>=11.23) && (Vms<14.4))  Bft=6;
  if ((Vms>=14.4)  && (Vms<17.49)) Bft=7;
  if ((Vms>=17.49) && (Vms<21.09)) Bft=8;
  if ((Vms>=21.09) && (Vms<24.69)) Bft=9;
  if ((Vms>=24.69) && (Vms<28.81)) Bft=10;
  if ((Vms>=28.81) && (Vms<32.92)) Bft=11;
  if  (Vms>=32.92)                 Bft=12;
 }   
}

Gruß Lafi

Hallo zusammen,

Heute habe ich nochmal ewig rumprobiert, und habe folgendes Problem.

Das hier geht:

unsigned long ZeitFensterMotorAn = 2000;       // Zeit die der Motor fährt
unsigned long ZeitFensterMotorAus= 6000;       // Zeit in der der Motor nicht fährt

Das hier nicht! Da stimmt die Auszeit, aber die Anzeit ist nur ein kurzer Impuls!

unsigned long ZeitFensterMotorAn = 6000;       // Zeit die der Motor fährt
unsigned long ZeitFensterMotorAus=2000;       // Zeit in der der Motor nicht fährt

So sieht der Code aus: (bassierend auf dem hier)

unsigned long MemFensterMotorAn = 0;            // Zeitspeicher Fenster auf
unsigned long MemFensterMotorAus = 0;          // Zeitspeicher Fenster auf
unsigned long ZeitFensterMotorAn = 2000;       // Zeit die der Motor fährt
unsigned long ZeitFensterMotorAus= 6000;      // Zeit in der der Motor nicht fährt

boolean M_State = LOW;                                // flag für Intervall Fensterfahren

void fensterauf() {
  if (WindAlarm == false) {
    FensterCurrentMillis = millis();
    if (!M_State && FensterCurrentMillis - MemFensterMotorAus >= ZeitFensterMotorAus) {
    if (Fenst1Auf == false) Motor1Auf();
    if (Fenst2Auf == false) Motor2Auf();
    M_State = true;
    MemFensterMotorAn = FensterCurrentMillis;
    }
    
    
    if (M_State && FensterCurrentMillis - MemFensterMotorAn >= ZeitFensterMotorAn) {
    Motor1Stop();
    Motor2Stop();
    M_State = false;    
    MemFensterMotorAus = FensterCurrentMillis;
    }
  }
  if (WindAlarm == true) {
    Motor1Zu();
    Motor2Zu();
    }  
} // ende fenster auf

mag vielleicht nochmal jemand drüber schauen was ich hier falsch mache?

Lieben Gruß Lafi

Tausche mal diese Zeilen gegeneinander:

    MemFensterMotorAn = FensterCurrentMillis;
...
    MemFensterMotorAus = FensterCurrentMillis;

Hi

Nein, Das wird passen.
Er setzt damit ja die 'Startzeit' des 'letzten Befehl'.
Also wenn die Fenster AUF fahren sollen, muß zuvor der Antrieb x Sekunden gestanden haben - wenn Das der Fall war, wird die AUF-Fahrt gestartet (also die Funktionen aufgerufen - kA, was darin passiert), die aktuelle Zeit gemerkt und das Flag M_State gesetzt.
Nun greift die andere IF-Abfrage, Diese prüft jetzt, ob die Laufzeit ab dem letzten Start-Befehl erreicht wurde.
Wenn Nicht, passiert Nichts (also die Fenster fahren wohl weiter auf - die Funktionen werden NICHT erneut aufgerufen).
Wenn die Zeit um ist, werden die Motoren gestoppt und sich die Zeit für die andere Abfrage wieder gemerkt - wie auch das Flag 'umgedreht'.

Eigentlich müsste Das So passen.

MfG

Eigentlich müßte sogar eine Variable genügen, da der endliche Automat durch M_State gebildet wird. Also in beiden Fällen:

MemFensterMotor = FensterCurrentMillis;

postmaster-ino:
Eigentlich müsste Das So passen.

Natürlich kann der Fehler auch in einer anderen Ecke verborgen sein.

Mir helfen Testausgaben an den seriellen Monitor, logische Knoten in meinem Gehirn zu lösen.

Ertsmal vielen Dank.

postmaster-ino:
....
wenn Das der Fall war, wird die AUF-Fahrt gestartet (also die Funktionen aufgerufen - kA, was darin passiert), die aktuelle Zeit gemerkt und das Flag M_State gesetzt.
...

In den Funktionen Motor1Auf usw. werden nur die Relaisausgänge entsprechend gesetzt. in den Flags "Fenst1Auf" usw. sind nur die Zustände der Endschalter gespeichert, damit die Relais eben nach erreichen von Auf oder Zu nicht mehr weiter klappern...

void Motor1Auf() {
  Serial.println("");
  Serial.println("Fenster Auf (Relais 1 ein");
  Serial.println("-------------------------");

  if (Fenst1Auf    == false) {
    expander1.digitalWrite(0, LOW);  // Relais 1 Fenster 1 auf einschalten
    expander1.digitalWrite(1, HIGH); // Relais 2 Fenster 1 zu  ausschalten
  }
  if (Fenst1Auf    == true) {
    expander1.digitalWrite(0, HIGH); // Relais 1 Fenster 1 auf einschalten
  }
}

agmue:
...
Mir helfen Testausgaben an den seriellen Monitor, logische Knoten in meinem Gehirn zu lösen.

Was soll ich an welcher Stelle denn ausgeben lassen?

Vielen Dank für eure hilfe!

Gruß Lafi

Hast Du meine Ideen aus #14 und #16 ausprobiert, was ist das Ergebnis?

Hallo,

agmue:
Hast Du meine Ideen aus #14 und #16 ausprobiert, was ist das Ergebnis?

ja, hab ich gemacht, leider keine Besserung.

ich habe es jetzt mit diesem Ansatz gelöst, der scheint zu funktionieren :slight_smile:

Aber ich muss den Code dringend aufräumen und verbessern, nur leider keine Ahnung wie :slight_smile: