Go Down

Topic: Zwei parallele Programme laufen lassen (Read 2047 times) previous topic - next topic

my_xy_projekt

#45
Jul 01, 2020, 07:57 pm Last Edit: Jul 01, 2020, 08:00 pm by my_xy_projekt
Abschließend nochmal der gesamte Code, falls mal jemand etwas ähnliches brauch oder die Geeks ihn tunen wollen :)


Code: [Select]
// Anzahl Kreise
const int Kreise = 2;

// Angabe PIN-Belegung
const int irPin[] = {2, 3};
const int relPin[] = {5, 6};
const int buttonPin[] = {8, 9};

Na bitte! Du hast es mitgenommen.

Code: [Select]

        delay(250);

um es hier wieder zu versauen!
NEIN!!! Kein delay() in produktiven Umgebungen!

Es wurde bereits erwähnt, die Anforderung zu ändern sehe ich ebenfalls kritisch - hier wurde im Einsatz festgestellt, das da was fehlt.
Auch wenn Software "lebt" heisst das nicht, das sowas jederzeit mal eben so "angepasst" werden kann.
Und Nein, BMA, Entrauchung, Türsteuerungen etc. beim BER sind kein Beispiel dafür das es geht.

Zurück zur Sachfrage:
Was mich irritiert, warum Du den ir-PIN sperren willst.
Das halte ich für unsinnig.
Dazu kommt, das Du Deine Bedingungen mehrfach benutzt. Das benötigt unnötige Rechenzeit und Du kannst nicht auschliessen, das sich zwischen if und else der Wert, von dem Du abhängig bist, ändert.

Nebenbei hast Du auch noch ein Problem im Setup mit der Initialisierung deiner Buttons.
Wenn Du auf LOW prüfen willst, musst Du dafür sorgen, das, wenn die Taste NICHT gedrückt ist ein HIGH-Pegel anliegt.
Das geht zum einen mit einem externen Widerstand von +5V nach PIN oder mit der Initialisierung des PULLUP im Chip selbst.
Wenn Du die externe Variante nicht hast, musst Du zwingend INPUT_PULLUP für
Code: [Select]
pinMode(buttonPin[i])
 festlegen!

Und dann würde ich das, was bisher lief nicht anrühren.
Neue Bedingung? Neuer Ablauf!

Ich denk noch drüber nach, ob ich Dir einen Vorschlag mache.

kahmui

Na bitte! Du hast es mitgenommen.

Code: [Select]

        delay(250);

um es hier wieder zu versauen!
NEIN!!! Kein delay() in produktiven Umgebungen!

Es wurde bereits erwähnt, die Anforderung zu ändern sehe ich ebenfalls kritisch - hier wurde im Einsatz festgestellt, das da was fehlt.
Auch wenn Software "lebt" heisst das nicht, das sowas jederzeit mal eben so "angepasst" werden kann.
Und Nein, BMA, Entrauchung, Türsteuerungen etc. beim BER sind kein Beispiel dafür das es geht.

Zurück zur Sachfrage:
Was mich irritiert, warum Du den ir-PIN sperren willst.
Das halte ich für unsinnig.
Dazu kommt, das Du Deine Bedingungen mehrfach benutzt. Das benötigt unnötige Rechenzeit und Du kannst nicht auschliessen, das sich zwischen if und else der Wert, von dem Du abhängig bist, ändert.

Nebenbei hast Du auch noch ein Problem im Setup mit der Initialisierung deiner Buttons.
Wenn Du auf LOW prüfen willst, musst Du dafür sorgen, das, wenn die Taste NICHT gedrückt ist ein HIGH-Pegel anliegt.
Das geht zum einen mit einem externen Widerstand von +5V nach PIN oder mit der Initialisierung des PULLUP im Chip selbst.
Wenn Du die externe Variante nicht hast, musst Du zwingend INPUT_PULLUP für
Code: [Select]
pinMode(buttonPin[i])
 festlegen!

Und dann würde ich das, was bisher lief nicht anrühren.
Neue Bedingung? Neuer Ablauf!

Ich denk noch drüber nach, ob ich Dir einen Vorschlag mache.
Aua. So dolle verk****? :(

Lass mich morgen früh nochmal daran arbeiten um eine andere Variante zu präsentieren. Wenn die dann auch unzufrieden machen sollte nehme ich gerne nochmal Hilfe an. Aber erstmal versuche ich deine Ratschläge umzusetzen und selbst was auf die Beine zu stellen.

kahmui

#47
Jul 02, 2020, 07:45 am Last Edit: Jul 02, 2020, 12:36 pm by kahmui
So. Also wie du sagtest, einfach erweitern.

Den bestehenden Code habe ich um

Code: [Select]
const int buttonPin[] = {8, 9};

pinMode(buttonPin[i], INPUT_PULLUP);

if (!digitalRead(buttonPin[i]))
{
   digitalWrite(relPin[i], LOW);
}


erweitert.

Damit ist delay() raus (Memo an mich selbst: Streiche delay() aus dem Kopf um my_xy nicht auf die Palme zu bringen). Eine einfache Betätigung des Relais, solange der Taster des jeweiligen Kreises betätigt wird.

Ich muss vorerst mit dem PULLUP arbeiten, da ich hier keine Widerstände vor Ort habe.

noiasca

der INPUT_PULLUP ist per se nichts schlechtes. Ich würde sogar sagen, besser als Widerstände mit ihren langen aber hauchdünnen Beinchen in ein Breadboard gewurstelt.
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

kahmui

der INPUT_PULLUP ist per se nichts schlechtes. Ich würde sogar sagen, besser als Widerstände mit ihren langen aber hauchdünnen Beinchen in ein Breadboard gewurstelt.
Kein Breadboard. Schaltschrank, alles ordentlich :)

kahmui

#50
Jul 07, 2020, 11:35 am Last Edit: Jul 07, 2020, 12:10 pm by kahmui
So. Nach einigen Tagen der Testerei steht noch ein Problem im Raum.

Und zwar muss die Leitung nach der Pumpe entlastet werden, damit der darin stehende Druck abfällt (und nein, die Pumpe kann nicht kurzzeitig in die andere Richtung drehen ;) ). Dazu nutze ich für jeden Kreis ein seperates 2/2 Wegeventil, dass elektrisch für jeweils 200ms über ein weiteres Relais angesteuert werden soll. Hardwareseitig funktioniert alles optimal.

Beim Code hapert es allerdings mal wieder. Wie auch bei den anderen gehe ich davon aus, dass ich erneut mit millis() arbeiten muss. Die Entlastung soll DIREKT nach der Laufzeit der Pumpe stattfinden (Laufzeit vorbei, Wegeventil für 200ms öffnen, Wegeventil schließen).

Dazu habe ich folgendes ergänzt:

Code: [Select]

const int druckPin[] = {10, 11};    // Ausgänge für die Relaissteuerung
 

const unsigned int entlastungszeit[] = {200, 200};    // Entlastungszeit

unsigned long entlastungmillis[] = {0, 0};


void setup() {
pinMode(druckPin[i], OUTPUT);    // Relaisansteuerung natürlich als OUTPUT
}



Die manuelle Entlastung mit Rücklauf am Ende des Codes funktioniert ohne Probleme.


Ich habe nun versucht, die automatische Entlastung an die Laufzeit anzuknüpfen. Wahrscheinlich liegt hier schon der Fehler?

Code: [Select]

void loop()
{
  for (int i = 0; i < Kreise; i++)
  {

    if ((!digitalRead(irPin[i])) && (millis() - pausemillis[i] > pausezeit[i]) && (digitalRead(relPin[i])))           
    { 
      digitalWrite(relPin[i], LOW);                                                                                   
      laufmillis[i] = millis();                                                                                       
    } 
 
    if ((!digitalRead(relPin[i])) && (millis() - laufmillis[i] > laufzeit[i]))                                       
    {     
      digitalWrite(relPin[i], HIGH);                                                                                 
      pausemillis[i] = millis();                                                                                     

      entlastung[i] = 1;
      entlastungmillis[i] = millis();                                                                                 
    }

    if ((millis() > entlastungmillis[i] + entlastungszeit[i]) && (entlastung[i] == 1)) {                                                                                   
      digitalWrite(druckPin[i], LOW);                                                                               
      entlastung[i] = 0;
      }

    if (!digitalRead(buttonPin[i]))                                                                                   
    {                                                                                                                 
      digitalWrite(relPin[i], LOW);                                                                                   
      digitalWrite(druckPin[i], LOW);                                                                                 
    }
  }
}


Funktioniert alles nicht so ganz recht. Wo und wie positioniere ich die Entlastung am optimalsten? Hab schon einige Varianten ausprobiert und komme nie so recht dahin wo ich hin möchte.


Oder muss ich hier zwei  separate if-bedingung schreiben, die zum einen auf das Ende meiner Laufzeit prüfen, die Relais für´s Wegeventil schalten und zum anderen das Ende meiner Entlastung checken (was wiederrum in den Anfang der Zwangspause muss)? Ich bin verwirrt....
Das ganze funktioert ja als gedachter Kreislauf. Aber wie haue ich jetzt eine Zwischenaktion mit hinein, die parallel zu meiner Zwangspause arbeitet? Fragen über Fragen.

Hier mal mein gedachter Code mit zwei separaten if-Bedingungen:


Code: [Select]


const int Kreise = 2;

const int irPin[] = {2, 3};
const int relPin[] = {5, 6};
const int buttonPin[] = {8, 9};
const int druckPin[] = {10, 11};

const unsigned int laufzeit[] = {2500, 2500};
const unsigned int pausezeit[] = {3000, 3000};
const unsigned int entlastungszeit[] = {200, 200};

unsigned long laufmillis[] = {0, 0};
unsigned long pausemillis[] = {0, 0};
unsigned long entlastungmillis[] = {0, 0};

void setup()
{
  for (int i = 0; i < Kreise; i++)
  {
    pinMode(irPin[i], INPUT_PULLUP);
    pinMode(relPin[i], OUTPUT);
    pinMode(buttonPin[i], INPUT_PULLUP);
    pinMode(druckPin[i], OUTPUT);
    digitalWrite(relPin[i], HIGH);
    laufmillis[i] = millis();
  }
}

void loop()
{
  for (int i = 0; i < Kreise; i++)
  {
    // Nach Ablauf der Zwangspause: Pumpe bei Bewegung einschalten
    if ((!digitalRead(irPin[i])) && (millis() - pausemillis[i] > pausezeit[i]) && (digitalRead(relPin[i])))         
    {                                                                                                               
      digitalWrite(relPin[i], LOW);                                                                                 
      laufmillis[i] = millis();                                                                                     
    }   
   
    // Nach Ablauf der Pumpenlaufzeit: Abschalten und Zwangspause starten
    if ((!digitalRead(relPin[i])) && (millis() - laufmillis[i] > laufzeit[i]))                                     
    {                                                                                                 
      digitalWrite(relPin[i], HIGH);                                                                           
      pausemillis[i] = millis();                                                                                                                                                                     
    }

    // Nach Ablauf der Pumpenlaufzeit: Relais für Entlastung schalten
    if (millis() - laufmillis[i] > laufzeit[i])
    {                                                                                                                 
      digitalWrite(druckPin[i], LOW);                                                                                 
      entlastungmillis[i] = millis(); 
    }
   
    // Nach Ablauf der Entlastungszeit: Relais für Wegeventil abschalten
    if ((millis() > entlastungmillis[i] + entlastungszeit[i]))
    {                                                                                                                 
      digitalWrite(druckPin[i], HIGH);                                                                                 
    }

    // Manuelle Betätigung Entlüftungskreislauf
    if (!digitalRead(buttonPin[i]))                                                                                   
    {                                                                                                                 
      digitalWrite(relPin[i], LOW);                                                                                   
      digitalWrite(druckPin[i], LOW);                                                                               
    }
  }
}


Eines der Hauptprobleme hier ist, dass das Relais für das Wegeventil (druckPin) permanent betätigt bleibt (außer bei der normalen Auslösung durch IR-Sensor) und auf Dauer natürlich heiß wird.

Danke schonmal! :smiley-confuse:

combie

#51
Jul 07, 2020, 12:26 pm Last Edit: Jul 07, 2020, 12:30 pm by combie
Hmm...
Fein, noch eine Salamischeibe...
Ja, so ist das manchmal....


Quote
Ich bin verwirrt....
Wenn du den gewünschten Ablauf schon nicht mit Worten logisch hintereinander bekommst, dann wirds schwierig diesen zu programmieren.
Oder?

Quote
die parallel zu meiner Zwangspause arbeitet?
Du hast jetzt schon 2 Abarbeitungsfäden für die Pumpen.
Was hindert dich, für die Druckentlastungsventile 2 weitere Fäden aufzuspannen?


Mein Tipp:
Denke in Zuständen
Denke nebenläufig
Beachte den Daten und hier auch den Materialfluss
Baue Module und lass die Module miteinander quatschen (Nachrichten austauschen)

Konzentriere dich nicht so sehr auf den Kontrollfluss (if-else usw).
Denn wie du siehst werden die Bedingungen immer komplexer.
Ich bin da schon lange raus! (siehe Posting #24 und #27)
Ein Wunder dass du da noch durchblickst.
Gefährlich, was Theorien aus Menschen machen können.
Schlimmer, was Menschen aus Theorien machen.

kahmui

#52
Jul 07, 2020, 12:27 pm Last Edit: Jul 07, 2020, 01:27 pm by kahmui
Ich denke, dass ich den Fehler gefunden habe.

Vorher:
Code: [Select]

    if (millis() - laufmillis[i] > laufzeit[i])
    {                                                                                                                 
      digitalWrite(druckPin[i], LOW);                                                                                 
      entlastungmillis[i] = millis(); 
    }


Nachher:
Code: [Select]

    if (millis() - laufmillis[i] == laufzeit[i])
    {                                                                                                                 
      digitalWrite(druckPin[i], LOW);                                                                                 
      entlastungmillis[i] = millis();
    }


> in ==
Damit funktioniert es so wie es soll.

@ Combie. Wo genau fehlt der logische Zusammenhang im Text? Vielleicht kann ich es weiter erläutern, um es verständlicher zu machen.

Die Grundfunktion sieht wie folgt aus:
1. Wenn Sensor Bewegung erkennt -> Löse Pumpe aus
2. Wenn Pumpe eine definierte Zeit gelaufen ist -> Pumpe aus
3. Wenn Pumpe aus
     -> Entlastung der Druckleitung und
     -> Beginn einer Zwangspause bis zur erneut möglichen Betätigung
4. Manuelle Betätigung des Pumpenkreislaufes zur Entlüftung / Erstbefüllung

Habt ihr dennoch Verbesserungsvorschläge für mich?
Danke :)

Tommy56

Nimm besser >= anstelle von >

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

combie

Quote
Die Grundfunktion sieht wie folgt aus:
Und die Extrawurst, Handbedienung...?
Ist nicht nach der Handbedienung auch eine Druckentlastung nötig?

Überhaupt, allgemein gefragt:
Wie verhalten sich Handbedienung zu Druckentlastung?
Muss der Haupthandlungsfaden zurückgesetzt werden, bei/vor der Handbedienung?



Quote
Habt ihr dennoch Verbesserungsvorschläge für mich?
Ich habe dir schon in #14 den Vorschlag gemacht, den ich zu dem Zeitpunkt für den bestmöglichen gehalten habe.
Dort deine Druckentlastung unter zu bringen, ist trivial und deine "Grundfunktion" somit dann vollkommen abgedeckt.




Gefährlich, was Theorien aus Menschen machen können.
Schlimmer, was Menschen aus Theorien machen.

kahmui

#55
Jul 07, 2020, 01:37 pm Last Edit: Jul 07, 2020, 01:39 pm by kahmui
Und die Extrawurst, Handbedienung...?
Ist nicht nach der Handbedienung auch eine Druckentlastung nötig?
Die Druckentlastung ist bei der Handbedienung automatisch mit drin, da der Druck und das Medium in den Vorratsbehälter abgeführt wird. Dies dient gleichzeitig zum Entlasten der Druckleitung sowie zum Entlüften und Erstbefüllen der Schläuche.

Überhaupt, allgemein gefragt:
Wie verhalten sich Handbedienung zu Druckentlastung?
Muss der Haupthandlungsfaden zurückgesetzt werden, bei/vor der Handbedienung?
Da die manuelle Betätigung nur zu Wartungszwecken genutzt wird, ist es nicht nötig den "Haupthandlungsfaden" zurückzusetzen (wobei dies auch kein großes Problem darstellen sollte). Bei Tests gab es dahingehend keinerlei Probleme. Zumal ein Sicherungsschalter (bei geöffneter Wartungsklappe) die beiden Sensoren außer Kraft setzt und somit ein "unbeabsichtigtes" Auslösen durch Bewegungen unterbunden wird.

Ich habe dir schon in #14 den Vorschlag gemacht, den ich zu dem Zeitpunkt für den bestmöglichen gehalten habe.
Dort deine Druckentlastung unter zu bringen, ist trivial und deine "Grundfunktion" somit dann vollkommen abgedeckt.
Danke. Ich greife aber lieber auf Codezeilen zurück, die ich zumindest halbwegs nachvollziehen und mit meinem Kenntnisstand anpassen kann :)

my_xy_projekt

Moin,

ich fang mal da an, wo es weh tut:

(Memo an mich selbst: Streiche delay() aus dem Kopf um my_xy nicht auf die Palme zu bringen).
Wenn ich es nicht schon geahnt hätte, dann. Achso, Denk mal drüber nach ;)

Quote
Vielleicht kann ich es weiter erläutern, um es verständlicher zu machen.

Die Grundfunktion sieht wie folgt aus:
1. Wenn Sensor Bewegung erkennt -> Löse Pumpe aus
2. Wenn Pumpe eine definierte Zeit gelaufen ist -> Pumpe aus
3. Wenn Pumpe aus
     -> Entlastung der Druckleitung und
     -> Beginn einer Zwangspause bis zur erneut möglichen Betätigung
4. Manuelle Betätigung des Pumpenkreislaufes zur Entlüftung / Erstbefüllung
Nana...
Die Grundfunkton hast Du erklärt als:
Quote
Das System an sich ist relativ einfach:
Es gibt zwei unabhängig voneinander arbeitende Kreise.
Jeder Kreis besitzt einen IR-Sensor und eine Pumpe. Sobald der IR-Sensor eine Bewegung erkennt, soll die Pumpe für 2 Sekunden laufen. Beide Kreise sollen jedoch unabhängig voneinander, parallel funktionieren!
Und ja, ich kann combie's Hinweis auf die Wurstscheiben nicht verdenken.

Ich denke, dass ich den Fehler gefunden habe.

Vorher:
Code: [Select]

    if (millis() - laufmillis[i] > laufzeit[i])


Nachher:
Code: [Select]

    if (millis() - laufmillis[i] == laufzeit[i])


> in ==
Damit funktioniert es so wie es soll.

NEIN!
Wenn Du genau hinschaust, ist "Nachher"-Bedingung genau nur zu einer bestimmten Abhängigkeit erfüllt. GENAU 1ms lang. Wenn die sich ergebene Differenz "laufzeit" aus der Subtraktion millis - laufmillis nicht genau dann erfüllt, passiert genau: nichts!


Danke. Ich greife aber lieber auf Codezeilen zurück, die ich zumindest halbwegs nachvollziehen und mit meinem Kenntnisstand anpassen kann :)
Abhängige Bedingungen sind ab einer nicht näher zu bezeichnenden Tiefe für den Leser schwer bzw. nicht nachvollziehbar.
Ich arbeite damit - und kann das "WENN - DANN / WENN NICHT - DANN" ganz gut umsetzen - auch dank gewisser Formarmatierungsregeln ;)

Eigentlich hat combie nicht Unrecht, aber der Weg dahin ist bedingt aufwändig und kann eher nicht am erlernen des kleinen Einmaleins festgemacht werden.

Und zu Guterletzt:

Ich hätte das:
Code: [Select]

if ((millis() > entlastungmillis[i] + entlastungszeit[i]) && (entlastung[i] == 1))

von vornherein anders geschrieben:
Code: [Select]

if ((millis() > (entlastungmillis[i] + entlastungszeit[i])) && (entlastung[i] == 1))



kahmui

#57
Jul 16, 2020, 08:20 am Last Edit: Jul 16, 2020, 08:50 am by kahmui
Danke an alle für die Hinweise und Hilfstellungen.

Ich habe mir jetzt mal Combies #14 Post zur Seite genommen und kann langsam auch einigermaßen nachvollziehen, wie das ganze funktioniert und aufgebaut ist.
Seit seinem Post sind ja noch ein paar Funktionen hinzugekommen, die vorher nicht geplant waren.

Diese sind zum einen eine Entlastung der Druckleitung nach der Laufzeit der Pumpe, sowie eine manuelle Betätigung der Pumpenkreise.

Hier nochmal der combie-Code, damit niemand durch die Seiten springen muss :)

Code: [Select]


#include <CooperativeTask.h>



class Pumpe: public Task
{
  protected:
    const byte inPin;
    const byte outPin;
    const unsigned long laufZeit;
    const unsigned long pauseZeit;
 
  public:
    Pumpe(const byte inPin,const byte outPin,const unsigned long laufZeit,const unsigned long pauseZeit):
       inPin(inPin),
       outPin(outPin),
       laufZeit(laufZeit),
       pauseZeit(pauseZeit)
    {
    }
   
    virtual void init() override
    {
      pinMode(inPin,INPUT);
      pinMode(outPin,OUTPUT);
    }
   
    virtual void run() override
    {
      TaskBlock
      {
        taskWaitFor(digitalRead(inPin));
        digitalWrite(outPin,HIGH);
        taskPause(laufZeit);
        digitalWrite(outPin,LOW);
        taskPause(pauseZeit);
      }
    }
};

Pumpe pumpen[] { // {inPin,outPin,laufZeit,pauseZeit}
                    {2,    8,     2000,    3000},
                    {3,    9,     2000,    3000}
               };




void setup()
{
 Scheduler::instance().init();
}

void loop()
{
  Scheduler::instance().run();
}


Wenn ich das richtig verstehe, müssten meine Entlastungs-Funktion wie folgt mit eingegliedert werden. Zudem müssen meine Sensoren doch als INPUT_PULLUP behandelt werden, richtig? (Ebenso wie meine Taster für die manuelle Betätigung).

Korrigiert mich bitte wenn ich falsch liege. Das hab ich bisher:

Code: [Select]

#include <CooperativeTask.h>

class Pumpe: public Task
{
  protected:
    const byte inPin;
    const byte outPin;
    const byte entlastungPin;
    const unsigned long laufZeit;
    const unsigned long pauseZeit;
    const unsigned long entlastungZeit;
 
  public:
    Pumpe(const byte inPin,const byte outPin,const byte entlastungPin,const unsigned long laufZeit,const unsigned long pauseZeit,const unsigned long entlastungZeit):
       inPin(inPin),
       outPin(outPin),
       entlastungPin(entlastungPin),
       laufZeit(laufZeit),
       pauseZeit(pauseZeit),
       entlastungZeit(entlastungZeit)
    {
    }
   
    virtual void init() override
    {
      pinMode(inPin,INPUT_PULLUP);
      pinMode(outPin,OUTPUT);
      pinMode(entlastungPin,OUTPUT);
    }
   
    virtual void run() override
    {
      TaskBlock
      {
        taskWaitFor(digitalRead(inPin));
        digitalWrite(outPin,HIGH);
        taskPause(laufZeit);
        digitalWrite(outPin,LOW);
        digitalWrite(entlastungPin,HIGH);
        taskPause(entlastungZeit);
        taskPause(pauseZeit-entlastungZeit);
      }
    }
};

Pumpe pumpen[] { // {inPin, outPin, entlastungPin,  laufZeit, pauseZeit,  entlastungZeit}
                    {2,     7,      6,              2000,     3000,       300},
                    {3,     5,      4,              2000,     3000,       300}
               };

void setup()
{
 Scheduler::instance().init();
}

void loop()
{
  Scheduler::instance().run();
}


Was combie mit "marginal" meinte, wenn es darum geht eine weitere zeitliche Komponente einzufügen kann ich nun nachvollziehen :)

Meine Fragen:
- WIE baue ich eine manuelle Betätigung meiner Pumpenkreise ein?
- WO baue ich sie ein?
- Sind "Klassen (class)" als eine Art Baustein zu verstehen, die ich später im Loop nur noch abrufe?
- Müsste ich für die manuelle Betätigung eine weitere Klasse hinzufügen oder kann ich die Funktion mit in die bestehende mit einbauen?

Danke :)

agmue

Auf die Gefahr hin, den C++ Freaks kräuseln sich die Fußnägel, versuche ich eine Antwort:

- WIE baue ich eine manuelle Betätigung meiner Pumpenkreise ein?
Ich würde das als Schrittkette (= endlicher Automat, = finite state machine) realisieren, wo man zwischen Manuell und Automatik umschalten kann.

- WO baue ich sie ein?
Beispielsweise in die Methode run.

- Sind "Klassen (class)" als eine Art Baustein zu verstehen, die ich später im Loop nur noch abrufe?
Die "Bausteine" nennt man Objekte, die sowas wie der Typ einer Variablen sind, nur mit verschiedenen Variablenypen und Methoden. Beispiel: Taster tasten[] { ... };

Das Feld tasten enthält Elemente entsprechend das Klasse Taster.

- Müsste ich für die manuelle Betätigung eine weitere Klasse hinzufügen oder kann ich die Funktion mit in die bestehende mit einbauen?
Die "Funktion" wird Methode genannt. Packt man zu viele Methoden in eine Klasse, baut man eine Monsterklasse. Bei vielen Klassen muß man die selben Informationen mehrfach eintragen. Da können dann Vererbungen helfen.

Mal abwarten, wer gekräuselte Fußnägel bekommt ;D
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

kahmui

#59
Jul 16, 2020, 10:16 am Last Edit: Jul 16, 2020, 10:16 am by kahmui
Also wenn ich dich richtig verstehe, entwerfe ich eine zweite Klasse die nur die manuelle Betätigung enthält.

In etwa so?

Code: [Select]

class Manuell: public Task
{
  protected:
    const byte manuellPin;
    const byte outPin;
    const byte entlastungPin;
 
  public:
    Manuell(const byte manuellPin,const byte outPin,const byte entlastungPin):
       manuellPin(manuellPin),
       outPin(outPin),
       entlastungPin(entlastungPin)
    {
    }
   
    virtual void init() override
    {
      pinMode(manuellPin,INPUT_PULLUP);
      pinMode(outPin,OUTPUT);
      pinMode(entlastungPin,OUTPUT);
    }
   
    virtual void run() override
    {
      TaskBlock
      {
        taskWaitFor(digitalRead(manuellPin));
        digitalWrite(outPin,HIGH);
        digitalWrite(entlastungPin,HIGH);
      }
    }
};

Go Up