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...
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?
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?
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...
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...
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;
}
}
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?
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'.
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?