Verschachtelte Ablaufsteuerung

Hallo zusammen,
ich bin neu, was die programmierung mit dem Arduino betrifft.

Ich bearbeite ein Projekt zur Wasseraufbereitung für meine Bachelorarbeit und möchte den Reaktor gerne automatisieren.
Grundsätzlich funktioniert das bereits. (s. sketch_ZULU10.ino) (ich hoffe das mit den Anhängen klappt hier)

const int Taster = 2;
int Zulaufpumpe = 3;
int Umlaufpumpe = 4;
const int LED = 13;

int TasterStatus = 0;

int w =  60;                          // Dauer Zulauf 60 sec 
int z =  60;                          // Dauer Umlauf 60 sec 
int g = 28236;                        // Dauer Stop 480 min 28800sek.
int p = 28236;                        // Dauer bis Umlauf Stop 480 min 
int h =  101.857143;                  // Intervall Zulauf 1,7min (102,86sek)
int o =  101.857143;                  // Invervall Umlauf 1,7min (102,86sek)
int n =  0;                           // Variable

int LEDState = 0;
                                //benutzte Variablen: b,f,g,h,i,m,n,o,p,x,w 

void setup()  
{
 Serial.begin(9600);
 
 pinMode(Taster, INPUT);
 
 pinMode(Zulaufpumpe, OUTPUT);
 pinMode(Umlaufpumpe, OUTPUT);
 pinMode(LED, OUTPUT);
                
 digitalWrite (Zulaufpumpe, LOW);
 digitalWrite (Umlaufpumpe, LOW);
 digitalWrite (LED, LOW);
 }

 void loop()  {

 TasterStatus = digitalRead(Taster);
 if (TasterStatus == HIGH)
 {
  n=0;
  for (int f=0; f<=p; f++)                // Umlauf für 60 sek
    {
      if (f==n*o)                         // Intervall Umlauf 1,7 min
      {
      n++;
      for (int m=0; m<=z; m++)            // für m=0, <=600min
      {
        digitalWrite (Umlaufpumpe, HIGH);
      
            LEDState = digitalRead(LED);

            if(LEDState == HIGH){
            digitalWrite(LED, LOW);
            }
            else{
            digitalWrite(LED, HIGH);
            }
      delay (1000);
      }
      f=f+z-1;                            // 
      }
     digitalWrite (Umlaufpumpe, LOW);

              digitalWrite (LED, LOW);
    delay (1000);
  }
  n=0;
  for (int i=0; i<g; i++)                 // Zulauf  für 480 min  
                                          // (= Zuweisung) (++ Inkrementierung,
                                          // Zählt zu der Variable 1 dazu) 
    {     
      if (i==n*h)                         // Intervall Zulauf 1,7 min  
                                          // (== prüft auf Gleichheit)
      {
      n++;
      for (int x=0; x<w; x++)             // für x=0, <=60 sek
      {
        digitalWrite (Zulaufpumpe, HIGH);
    
            LEDState = digitalRead(LED);

            if(LEDState == HIGH){
            digitalWrite(LED, LOW);
            }
            else{
            digitalWrite(LED, HIGH);
            }
      delay (1000);                        // +1sek "pause"
      }
      i=i+w-1;
      }
      digitalWrite (Zulaufpumpe, LOW);

              digitalWrite (LED, LOW);
      delay (1000);                        // Pause 1 sek
  }    
  }
  }

Nun zum Problem:

meine Steuerung soll:
für 8h die Umlaufpumpe ein und wieder ausschalten.
diese soll für 60 sekunden, alle 102 sekunden eingeschaltet werden.

im anschluss soll die Zulaufpumpe genauso schalten.

leider passen die Zeiten nie. Ich vermute das es unter anderem am Delay liegt. Daher wollte ich das gerne durch die Verwendung der Funktion millis() ersetzen.

Jedoch gestaltet sich diese schleife in einer Schleife Programmierung für mich doch sehr schwer.
Ich habe damit angefangen. Komme aber leider nicht weiter und habe schon viel zu viele Stunden dafür verwendet. Wenn mir jemand helfen könnte, wäre ich wirklich sehr dankbar.

Der neue Sketch: ZuluMillis.ino

Ich habe mich bereits durch viele Foren und Hilfestellungen gelesen. Leider konnte ich keine Anwendung finden die ich auf mein Problem anpassen kann.
Wichtig ist, dass der Arduino für ein paar Tage nahezu die 8h/8h halten kann. Aktuell läuft er entweder zu schnell oder zu langsam.

Vielen Dank für eure Hilfe!

Gruß
Felix

ZuluMillis.ino (5.56 KB)

sketch_ZULU10.ino (3.02 KB)

(deleted)

femae81: ich bin neu, was die programmierung mit dem Arduino betrifft. ... meine Steuerung soll: ...

Grundsätzlich solltest Du Dir angewöhnen, „schönen“ Code zu schreiben - d.h. passende Einzüge, nicht zu lange Zeilen, usw. ... siehe z. B. hier. Für Deine Steuerung solltest Du zunächst einen Ablaufplan zeichnen. Evtl. kannst Du dann direkt davon den Code ableiten. Anstatt längere Zeiten mit millis(), delay() u. derlei Zeug zu realisieren, solltest Du eine Real-Time-Clock (RTC) benutzen - z. B. eine DS 3231.

Gruß

Gregor

Hallo,

Setze den bitte in Code-Tags.

Verwende dazu die Schaltfläche </> oben links im Editorfenster.
Dazu den Sketch markieren und die Schaltfläche klicken, oder [code] davor und [/code] dahinter ohne *.

Damit wird dieser für alle besser lesbar, auch für mobile Geräte.

Die Zeitsteuerung des Arduino (ohne RTC) ist sehr ungenau und unstabil.
Du solltest dafür eine RTC (DS3231) vewenden, damit hast du schon mal eine genaue Zeitsteuerung.

Jedoch gestaltet sich diese schleife in einer Schleife Programmierung für mich doch sehr schwer.

Habe ich volles Verständnis für! Kann ich auch nicht leiden, und unterbinde ich, für mich, schon im Ansatz. Auch mehrfach geschachtelte IF kann ich nicht leiden.

Und wenn dann noch die Einrückungnen so irrational sind, wie bei dir, dann ist Ende im Gelände. Für sowas bin ich einfach zu blöd, oder zu faul um da durchblicken zu wollen.

Ansonsten mache ich recht viel mit Zeitsteuerungen und endlichen Automaten.

Wichtig ist, dass der Arduino für ein paar Tage nahezu die 8h/8h halten kann.

Ein paar Sekunden wird es sich pro Stunde ziehen, wenn man keine RTC verwendet. Dem Wasser dürfte das egal sein.

Ablaufsteuerung Meine Standardantwort zu Ablaufsteuerungen:

Eine Stichworte Sammlung für Google Suchen: Endlicher Automat, State Machine, Multitasking, Coroutinen, Ablaufsteuerung, Schrittkette,

BlinkWithoutDelay,

Blink Without Delay

Die Nachtwächter Erklärung

Intervall Macro Multitasking Macros INTERVAL Ersatzstoff CooperativeTask

femae81:
… für meine Bachelorarbeit …

Dann möchte ich mal etwas pingeliger sein, als bei einem, der das wie ich nur zum Spaß macht.

const int Taster = 2;
int Zulaufpumpe = 3;
int Umlaufpumpe = 4;
const int LED = 13;

Taster und LED hängen an festen Pins, die Pumpenanschlüsse sind variabel? Wohl nicht, daher bietet sich const int oder noch besser const byte an. Zweck ist die Fehlervermeidung.

int TasterStatus = 0;
...
int LEDState = 0;

Variablen wird ein Typ zugewiesen, der hat eine Bedeutung. Bei logischen Variablen paßt bool oder const uint8_t gut.

int w =  60;                                        // Dauer Zulauf in Sekunden, in diesem Fall: 60 sec
int z =  60;                                        // Dauer Umlauf in Sekunden, in diesem Fall: 60 sec
int g = 28236;                                      // Dauer bis Zulauf Stop 480 min  480 -->8h 28800sek. abzgl 1 sek je Umlauf (282) und abzgl 1 sek für delay (564)
int p = 28236;                                      // Dauer bis Umlauf Stop 480 min

Dies dürften Konstanten sein, da bietet sich const uint16_t an.

int h =  101.857143;                                // Intervall Zulauf 1,7min (102,86sek)
int o =  101.857143;                                // Invervall Umlauf 1,7min (102,86sek)

Du versuchst, Gleitkommazahlen in einer Variablen für ganze Zahlen zu speichern, das ist falsch! Möglicherweise ergeben sich hierdurch die beobachteten Ungenauigkeiten.

int n =  0;                                         // Variable

Der Kommentar wenig aussagekräftig.

Grundsätzlich kann ich als fauler Mensch verstehen, wenn Du einzelne Buchstaben als Konstanten/Variablen verwendest. Als fremder Betrachter bin ich dann aber auch zu faul, mir die Bedeutung der Konstanten/Variablen zu merken.

+t formatiert in der IDE mit Einrückungen.

Hallo,

was verstehst Du unter "Zeiten passen nicht" ? warum gibst Du deine Variablen keine Namen bei denen man verstehen kann was da passieren soll. ich sehe nur irgendweche intergalagtische Faktoren die man keinem erklären kann. Was willst Du mit den for schleifen ? Bachelor Arbeit ? Sorry 5 setzen.

millis() ist der richtige Ansatz, aber so schwer ist das doch nicht, Schau Dir den Nachtwächter an. Wenn Dir das nicht genau genug wird solltest Du eine RTC verwenden.

Heinz

Danke für die zum Teil mehr, zum Teil weniger Konstruktiven Kommentare. Der Arduino ist nur ein Hilfsgerät welches ich nicht der Arbei nicht betrachte. Daher habe ich auch die Variablen nicht so benannt wie oben gewünscht.

Sorry für die unverständlichkeit.

Es wird eine RTC werden.

Danke für die Mühen.

felix

femae81: Der Arduino ist nur ein Hilfsgerät welches ich nicht der Arbei nicht betrachte. Daher habe ich auch die Variablen nicht so benannt wie oben gewünscht.

Sorry für die unverständlichkeit.

Wenn du es gleich verständlicher schreiben würdest, brauchst dudich nicht zu entschuldigen. Deinen obigen Satz verstehe ich tatsächlich nicht.

Und Variable mit sprechendem Namen helfen auch dem Programmierer, wenn dieser seinen Sketch nach 6 Monaten erneut bearbeiten soll. Das hat nichts mit Arbeit, Hobby oder Privat zu tun.

(deleted)

Hi

Auch, wenn's mir fast zu wider ist, hier zu antworten, da der TO wohl doch was Besseres ist - blöd nur, daß Er alleine nicht auf den Baum rauf kommt.

Wir haben einen Wechselblinker, Der alle 8 Stunden Seinen Zustand ändert. (wirklich alle 8 Stunden? Also nicht irgendwie auf 'volle' 24 Stunden? ... klar ist 24 durch 8 teilbar, aber eben nicht gerade).

Nun denn - wenn wir in einer 'Hell-Phase' sind, soll ein weiterer Blinker an und aus gehen, mit unterschiedlichen Zeiten.

Wo siehst Du hier ein Problem? Ok - habe die Sichtung Deines Sketch dann doch Mal abgebrochen ... wie schon gesagt wurde: schön ist anders. Auch fiel mir '600 Minuten' ins Auge - was nun rein gar nicht zu Deiner Umschreibung passt. Da auch mir die kryptischen Bezeichnungen zu blöd sind, war's Das dann für mich.

Also - 1x per millis() prüfen, ob die Wartezeit von (uint32_t)8*60*60*1000 vorbei ist - wenn ja, Zustand umschalten, neue Startzeit merken. Wenn wir auf AUS gehen, schalten wir die Pumpe auch direkt aus. Somit hätten wir den AUTOMATIK/AUS-Rythmus. Wenn wir nun auf AUTOMATIK sind, - prüfen wir, ob der letzte AUSschalt-Befehl schon 'Aus-Wartezeit' vorbei ist - wenn JA, einschalten, Uhrzeit merken. - prüfen wir, ob der letzte EINschalt-Befehl schon 'An-Wartezeit' vorbei ist - wenn Ja, ausschalten, Uhrzeit merken.

Für welchen Titel muß ich den Kram nun wo abgeben?

MfG

agmue: Dann möchte ich mal etwas pingeliger sein, als bei einem, der das wie ich nur zum Spaß macht.

Das war glaube ich vergebene Liebesmühe. Es klingt sehr danach als wäre der Code an sich keine relevante Leistung sondern viel mehr eine kleine Hilfe um den eigentlichen Versuch durchzuführen. Wasseraufbereitung als Abschlussarbeit klingt nicht gerade nach Informatikstudent.

Mahimus: ... Wasseraufbereitung als Abschlussarbeit klingt nicht gerade nach Informatikstudent.

Dermaßen schlechter Code klingt noch nicht einmal nach Student.

Gruß

Gregor

Mahimus: Das war glaube ich vergebene Liebesmühe.

Da muß ich Dir wohl leider zustimmen :(

gregorss: Dermaßen schlechter Code klingt noch nicht einmal nach Student.

Und wieso sollte beispielsweise der erste Code eines angehenden Bauingenieurs besser aussehen als der erste Code eines gelernten Industriemechanikers?

Fakt ist: beide können sich verbessern, wenn sie wollen. Der TO will aber nicht.