Go Down

Topic: Random Funktion (Read 3743 times) previous topic - next topic

uwefed

Da ist eigentlich nichts besonders kompliziertes dran an meinem Sketch.
Grüße Uwe

currymuetze

Hi Gerlitschka,

Uwe hat dir quasi ähnlich wie von mir bereits vorgeschlagen (mit einigen Verbesserungen) den kompletten code programmiert.
Der ist auch nicht schwer zu durchschauen, geh ihn doch einfach mal step by step durch und mal dir auf papier auf, was jeweils passiert.
=> so kannst du den Code nachvollziehen und lernst außerdem dazu.
Auch wenn du lieber ne "lange" VErsion nutzt, weil sie dir einfacher erscheint, fang lieber frühzeitig an, Code so kurz und übersichtlich wie möglich zu gestalten.

EIne Frage an Uwe:
Code: [Select]
for (int j=4; j>NrPumpenEin; j--)
{
 k = random(4);
 if (digitalRead(PumpenAusgang[k]) == HIGH)
 {
 digitalWrite(PumpenAusgang[k], LOW);
 Serial.print (" Pumpe NR "); Serial.print (PumpenAusgang[k],DEC); Serial.print (" AUS; ");
 }
 else
 {
 j++;
 }
}
vorher = millis();
Serial.println ();
}


"Rein Theoretisch" könnte das doch ne Endlosschleife geben, wenn k = random(4); immer den gleichen Wert zurückspielt oder?
Denn zunächst wird j einen runtergesetzt und dann wieder einen hoch.
Ich gehe davon aus, dass das praktisch nie passieren wird, kann man das daher vernachlässigen?
Oder habe ich grad einen Denkfehler?
Gruß

uwefed

#17
Aug 11, 2011, 02:32 pm Last Edit: Aug 14, 2011, 07:56 pm by uwefed Reason: 1
Hallo currymuetze

"Und ewig grüßet das Murmeltier."

Ja, dieser Spagetti-Code mit den switch-case schleife ist nicht die beste Art zu programmieren.

Ja, theoretisch könnte die Schleife durch das ewig gleiche Ergebnis hängen bleiben, aber die Random-Funktion ist ja so programmiert, daß sie zufällige Zahlen gibt die im gesamten gesehen möglichst gleichmäßig auf den gesamten Wertebereich aufgeteilt ist. Um da signifikante Zeiten herauskommen (einige Sekunden bis Minuten) muß schon einige hundert bis 1000 mal die gleiche Zahl hintereinender herauskommen und das ist unwahrscheinlich bis unmöglich.

Falls das wirklich passiert (daß eine Zahl immer wieder herauskommt) bleibt das Programm in dieser Schleife und es gehen konstant 3 Pumpen. Deshalb habe ich auch so programmiert daß zuerst alle pumpen eingeschaltet werden und dann die Zufallsfunktion die Pumpen ausschaltet und nicht zuerst alle ausschalten und dann einige einschalten.

Natürlich kann man einen Zähler einbauen und kontrollieren ob die Schleife zB 10 mal durchläuft ohne zu einen Ergebnis zu kommen und diesem Fall die Schleife abbricht und 2 Pumpen per default setzt.  
Code: [Select]

int wiederholungen =0;
...
wiederholungen =0;
for (int j=4; j>NrPumpenEin; j--)
{
 k = random(4);
 if (digitalRead(PumpenAusgang[k]) == HIGH)
 {
 digitalWrite(PumpenAusgang[k], LOW);
 Serial.print (" Pumpe NR "); Serial.print (PumpenAusgang[k],DEC); Serial.print (" AUS; ");
 }
 else
 {
 j++;
 }
 wiederholungen++;
if(wiederholungen>=10)
{
digitalWrite(PumpenAusgang[0], LOW);
digitalWrite(PumpenAusgang[1], LOW);
}
}
vorher = millis();
Serial.println ();
}


Die Gefahr einer Fehlfunktion ist da sehr wahrscheinlicher im
Falls sich das System blockieren sollte ist es sehr wahrscheilicher daß es am Blockieren des Arduino, am Blockieren der Pumpe, am Fehlen der Netzspannung durch einen Schaden in der Energieverteilung; am Auslösen des FI-schutzes oder Magnetothermischen Sicherung in Verteiler des Hauses/Wohnung durch eine Schaden an einem anderen Gerät ecc. liegen wird.

Viele Grüße Uwe

So Uwe, ich denk ich habe das soweit alles verstanden, das mit den Zeiten läuft, musste nur ein wenig was abändern, allerdings wollte ich ein Schalter für die Fütterung einrichten, aufdem alle Pumpen gleichzeitig für 15 min ausgehen.

Es müsste doch funktionieren, wenn ich durch Taster betätigen meine "Fuetterung" aktiviere. Dann vergleich ich "vorher" mit "Fuetterung". Wenn "Vorher" größer ist, geht der normale random zustand wieder weiter. Vorher setze ich alle 4 Pumpen auf LOW?  richtig?


int Fuetterung = 900000;
// 15 minuten sind 900000 millis

  if(millis() - vorher  > Pumpenwechselzeit)
  {   
    pumpenAuswaehlen ();
  }

uwefed

Soll die Fütterung immer zulässig sein oder nur alle x Stunden möglich sein? Dies um eine Fehlfunktion entgegenzuwirken.
Grüße Uwe

#20
Aug 15, 2011, 06:26 pm Last Edit: Aug 17, 2011, 11:32 am by Gerlitschka Reason: 1
Sie soll bis zu 4x am Tag  funktionieren, also beliebig oft ist ausreichend, da 15 Minuten ohne Pumpe dem Becken nichts aus macht. Falls du wegen der Schalter funktion meinst, also wenn der Schalter haengt oder so, dass kann auser acht gelassen werden!
Hab als Sicherheitsfunktion zb, wenn meinen Relais die 5 V fehlen, die Pumpen als öffner angeschlossen und das licht als schliesser. Wenn die Spannung fehlt und die Relais in den Ruhezustand zurück springen, gehen alle Pumpen und und das Licht aus, so dass es nicht durchbrennt!!

Ne, es will einfach nicht klappen. mit Delay ist es zwar einfach, aber dass soll ich ja nicht, da hauen mir zuviele aus dem Forum auf die Finger :P

uwefed

#22
Aug 17, 2011, 10:45 pm Last Edit: Aug 17, 2011, 10:54 pm by uwefed Reason: 1
Du kontrollierst im loop() den Stop-taster, setzt ein Stop-Flag (boolean Variable), setzt die Ausgänge auf aus und speicherst die millis()-Zeit
Gleichzeitig im loop() kontrollierst falls das Stop-Flag gesetzt ist ob die Zeit abgelaufen ist. Dann einfach Stop-Flag löschen und Funktion für Pumpensteuerung aufrufen.
In der Bedingung die kontrolliert ob die Beleuchtungszeit abgelaufen ist, kontrollierst Du zusätzlich ob das Stop-Flag nicht gesetzt ist.
Grüße Uwe

Wie speichert man die millis()?
Wie lösche ich dann die Stop Flag?
Grüße Timo

uwefed

unsigned long altezeit = millis();
stopflag = 0;
Grüße Uwe

Go Up