Hilfe bei Schrittkette

Moin,

ich bin Anfänger was den Arduino betrifft und arbeite mich gerade erst in das Thema ein. Habe schon viel gegoogelt und auf Youtube geguckt, komme aber gerade nicht wirklich weiter. Aktuell mache ich gerade eine Ausbildung zum Mechatroniker, in dessen Rahmen ich dieses Projekt auch mache.

Ich möchte gerne eine Schrittkette/Ablaufsteuerung mit dem Arduino programmieren (kenne bislang nur SPS, daher würde ich mich gerne daran orientieren), bin dabei schon auf die Schlagworte FSM, Nachtwächter und so weiter gestoßen, aber so ganz habe ich trotz Suche die Syntax dahinter noch nicht verstanden.

Bei dem Projekt möchte ich mehrere Pneumatikzylinder in bestimmter Reihenfolge und in Abhängigkeit von Reedkontakten steuern.
Ein Sensor erkennt ob ein Bauteil vorhanden ist, ist dies nicht der Fall soll die Schrittkette beginnen. Sobald der erste Zylinder ausgefahren ist, erkennt dies der entsprechende Reedkontakt und es soll in den nächsten Schritt gehen (Reedkontakte sind die Transitionen) und der nächste Zylinder soll ausfahren. Am Ende soll die Grundstellung wieder erreicht sein.

Habe schon versucht was zu programmieren und zu testen. Dafür habe ich einfach die Zylinder mit LEDs auf einem Breadboard ersetzt und die Reedkontakte indem ich die entsprechenden Pins mit Strom versorge.

Hier einmal mein bisheriger Code:

// falls Not Aus rein, millis einfügen, delay raus

int pin1B1 = 0; // kapazitiver Sensor
int pin2B1 = 1; // Magazin oben/unten
int pin3B1 = 2; //Reed "Klemmen" eingefahren
int pin3B2 = 3; //Reed "Klemmen" ausgefahren
int pin1A1 = 4; // Zylinder "Klemmen"
int pin2A1 = 5; // Zylinder "Sperren"
int pin3A1 = 6; // Zylinder "Schieben"
int pin4A2 = 7; // Zylinder "Sichern"
int pin4B1 = 8; // Reed "Sperren" eingefahren
int pin4B2 = 9; // Reed "Sperren" ausgefahren
int pin5B1 = 10; // Reed "Schieben" eingefahren
int pin5B2 = 11; // Reed "Schieben" ausgefahren
int pin6B1 = 12; // Reed "Sichern" eingefahren
int pin6B2 = 13; // Reed "Sichern" susgefahren
int pinS1 = A0; // Schalter EIN/AUS, noch nicht eingefügt, evtl später

enum States {
  stateRuhestellung, stateSperren, stateKlemmen, stateSichernWeg, stateSchieben, stateSchiebenRein, stateSichernHoch, stateKlemmenWeg, stateSperrenWeg
}; // die einzelnen Schritte

//mState = machine State
States mState = stateRuhestellung;              //der Startpunkt der Schrittkette?

void setup() {

  Serial.begin(9600);

  pinMode(pin1A1, OUTPUT);
  pinMode(pin2A1, OUTPUT);
  pinMode(pin3A1, OUTPUT);
  pinMode(pin4A2, OUTPUT);
  pinMode(pin1B1, INPUT);
  pinMode(pin2B1, INPUT);
  pinMode(pin3B1, INPUT);
  pinMode(pin3B2, INPUT);
  pinMode(pin4B1, INPUT);
  pinMode(pin4B2, INPUT);
  pinMode(pin5B1, INPUT);
  pinMode(pin5B2, INPUT);
  pinMode(pin6B1, INPUT);
  pinMode(pin6B2, INPUT);

  digitalWrite(pin1A1, LOW); // bei Neustart Grundstellung
  digitalWrite(pin2A1, LOW);
  digitalWrite(pin3A1, LOW);
  digitalWrite(pin4A2, HIGH);

}

void loop() {

  // mit "when" Schalter abfragen? Switch case nur solange Schalter Ein?

  Serial.println(F("Start"));

  switch (mState)
  {
    case stateRuhestellung:
      {
        if (pin1B1 == HIGH && pin2B1 == HIGH)

        {
          Serial.println(F("Ruhestellung"));
          //delay (3000);
          mState = stateSperren; // der nächste Schritt
        }

        break;

      case stateSperren:
        {
          if (pin1B1 == LOW && pin2B1 == HIGH)    //Bedingung um den Zylinder in diesem Schritt auszufahren

          {
            digitalWrite (pin2A1, HIGH); // Zylinder soll ausfahren
            Serial.println(F("Sperren"));
            //delay (3000);
            mState = stateKlemmen;
          }
        }

        break; // diesen Schritt verlassen

      case stateKlemmen:
        {
          if (pin4B2 == HIGH)

          {
            digitalWrite (pin1A1, HIGH);
            Serial.println(F("Klemmen"));
            //delay (3000);
            mState = stateSichernWeg;
          }
        }

        break;

      case stateSichernWeg:
        {
          if (pin3B2 == HIGH)

          {
            digitalWrite (pin4A2, LOW);
            Serial.println(F("SichernWeg"));
            //delay (3000);
            mState = stateSchieben;
          }
        }

        break;

      case stateSchieben:
        {
          if (pin6B1 == HIGH)

          {
            digitalWrite (pin3A1, HIGH);
            Serial.println(F("Schieben"));
            //delay (3000);
            mState = stateSchiebenRein; //advance to the next state
          }
        }

        break;

      case stateSchiebenRein:
        {
          if (pin5B2 == HIGH)

          {
            digitalWrite (pin3A1, LOW);
            Serial.println(F("SchiebenRein"));
            //delay (3000);
            mState = stateSichernHoch; //advance to the next state
          }
        }

        break;

      case stateSichernHoch:
        {
          if (pin5B1 == HIGH)

          {
            digitalWrite (pin4A2, HIGH);
            Serial.println(F("SichernHoch"));
            //delay (3000);
            mState = stateKlemmenWeg;
          }
        }

        break;

      case stateKlemmenWeg:
        {
          if (pin6B2 == HIGH)

          {
            digitalWrite (pin1A1, LOW);
            Serial.println(F("KlemmenWeg"));
            //delay (3000);
            mState = stateSperrenWeg;
          }
        }

        break;

      case stateSperrenWeg:
        {
          if (pin3B1 == HIGH)

          {
            digitalWrite (pin2A1, LOW);
            Serial.println(F("SperrenWeg"));
            //delay (3000);
            mState = stateRuhestellung;
          }
        }

        break;
      }
  }
}

Habe es so verstanden, dass switch immer die einzelnen case aktiviert. Ich wähle oben den ersten case für den Start aus und dann gehe ich von einem case in den nächsten. Der jeweilige case ist dann aktiv, wird aber erst ausgeführt wenn die entsprechende if Bedingung im Inneren erfüllt ist. Also so lange dann in dem case bleibt.
Oder muss ich das break dann noch noch in die if Schleife packen?

Habe auch mal auf die schnelle versucht mir den aktuellen Schritt auf dem seriellen Monitor anzeigen zu lassen, aber hat auch nicht so ganz funktioniert, habe mich damit allerdings auch noch nicht beschäftigt.

Ich hoffe ihr könnt mir weiter helfen, falls ihr mehr Infos braucht einfach melden :slight_smile:

hi...
Du beschäftigst dich mit meinem Lieblingsthema!

Automaten.

if (pin6B2 == HIGH)

Die Benennung deiner Pins ist gruselig unübersichtlich (für mich)

Der Ausdruck "pin6B2 == HIGH" ist falsch!
Denn "13==HIGH" willst du doch sicherlich nicht....

Du meinst bestimmt:
if (digitalRead(pin6B2) == HIGH)

Was das gleiche ist wie:
if (digitalRead(pin6B2))

Unschön:
int pin6B2 = 13; // Reed "Sichern" susgefahren

Besser:
const byte pin6B2 = 13; // Reed "Sichern" susgefahren

Und das natürlich bei allen Pins.
Das spart dutzende von Byte im Ram ein.
Teste es.

Übrigens: if Schleife


Im Grunde sieht das alles schon ganz gut aus...
Die Funktion kann ich so nicht prüfen, aber der Weg ist richtig!
Zumindest scheint er gangbar zu sein.

Hi,

schon mal vielen Dank :slight_smile: Für elegantere Schreibweisen bin ich immer offen, werde das direkt mal ändern.

Jetzt wo ich die korrekte Schreibweise sehe, erinnere ich mich auch wieder daran. Werde das auch direkt ändern und dann noch mal testen.

Vor allem das ich nicht komplett auf dem Holzweg bin ist mir schon einmal viel wert. Dann kann ich da weiter dran arbeiten :slight_smile:

1 Like

ok, ich habe den Code jetzt mal so angepasst, wie combie es mir gesagt hat:

// falls Not Aus rein, millis einfügen, delay raus

const byte pin1B1 = A5; // kapazitiver Sensor
const byte pin2B1 = A4; // Magazin oben/unten
const byte pin3B1 = 2; //Reed "Klemmen" eingefahren
const byte pin3B2 = 3; //Reed "Klemmen" ausgefahren
const byte pin1A1 = 4; // Zylinder "Klemmen"
const byte pin2A1 = 5; // Zylinder "Sperren"
const byte pin3A1 = 6; // Zylinder "Schieben"
const byte pin4A2 = 7; // Zylinder "Sichern"
const byte pin4B1 = 8; // Reed "Sperren" eingefahren
const byte pin4B2 = 9; // Reed "Sperren" ausgefahren
const byte pin5B1 = 10; // Reed "Schieben" eingefahren
const byte pin5B2 = 11; // Reed "Schieben" ausgefahren
const byte pin6B1 = 12; // Reed "Sichern" eingefahren
const byte pin6B2 = 13; // Reed "Sichern" susgefahren
const byte pinS1 = A0; // Schalter EIN/AUS, noch nicht eingefügt, evtl später

enum States {
  stateRuhestellung, stateSperren, stateKlemmen, stateSichernWeg, stateSchieben, stateSchiebenRein, stateSichernHoch, stateKlemmenWeg, stateSperrenWeg
}; // die einzelnen Schritte

//mState = machine State
States mState = stateRuhestellung;              //der Startpunkt der Schrittkette?

void setup() {

  Serial.begin(9600);

  pinMode(pin1A1, OUTPUT);
  pinMode(pin2A1, OUTPUT);
  pinMode(pin3A1, OUTPUT);
  pinMode(pin4A2, OUTPUT);
  pinMode(pin1B1, INPUT);
  pinMode(pin2B1, INPUT);
  pinMode(pin3B1, INPUT);
  pinMode(pin3B2, INPUT);
  pinMode(pin4B1, INPUT);
  pinMode(pin4B2, INPUT);
  pinMode(pin5B1, INPUT);
  pinMode(pin5B2, INPUT);
  pinMode(pin6B1, INPUT);
  pinMode(pin6B2, INPUT);

  digitalWrite(pin1A1, LOW); // bei Neustart Grundstellung
  digitalWrite(pin2A1, LOW);
  digitalWrite(pin3A1, LOW);
  digitalWrite(pin4A2, HIGH);

  Serial.println(F("Start"));
}

void loop() {

  // mit "when" Schalter abfragen? Switch case nur solange Schalter Ein?



  switch (mState)
  {
    case stateRuhestellung:
      {
        if (digitalRead(pin1B1 && pin2B1) == HIGH)
        {
          Serial.println(F("Ruhestellung"));
          delay (3000);
          mState = stateSperren; // der nächste Schritt
        }
        break; // diesen Schritt verlassen
      }


    case stateSperren:
      {
        if (digitalRead(pin1B1 == LOW && pin2B1 == HIGH))    //Bedingung um den Zylinder in diesem Schritt auszufahren
        {
          digitalWrite (pin2A1, HIGH); // Zylinder soll ausfahren
          Serial.println(F("Sperren"));
          delay (3000);
          mState = stateKlemmen;
        }
        break;
      }



    case stateKlemmen:
      {
        if (digitalRead(pin4B2) == HIGH)
        {
          digitalWrite (pin1A1, HIGH);
          Serial.println(F("Klemmen"));
          delay (3000);
          mState = stateSichernWeg;
        }
        break;
      }



    case stateSichernWeg:
      {
        if (digitalRead(pin3B2) == HIGH)

        {
          digitalWrite (pin4A2, LOW);
          Serial.println(F("SichernWeg"));
          delay (3000);
          mState = stateSchieben;
        }
        break;
      }



    case stateSchieben:
      {
        if (digitalRead(pin6B1) == HIGH)

        {
          digitalWrite (pin3A1, HIGH);
          Serial.println(F("Schieben"));
          delay (3000);
          mState = stateSchiebenRein; //advance to the next state
        }
        break;
      }



    case stateSchiebenRein:
      {
        if (digitalRead(pin5B2) == HIGH)

        {
          digitalWrite (pin3A1, LOW);
          Serial.println(F("SchiebenRein"));
          delay (3000);
          mState = stateSichernHoch; //advance to the next state
        }
        break;
      }



    case stateSichernHoch:
      {
        if (digitalRead(pin5B1) == HIGH)

        {
          digitalWrite (pin4A2, HIGH);
          Serial.println(F("SichernHoch"));
          delay (3000);
          mState = stateKlemmenWeg;
        }
        break;
      }



    case stateKlemmenWeg:
      {
        if (digitalRead(pin6B2) == HIGH)

        {
          digitalWrite (pin1A1, LOW);
          Serial.println(F("KlemmenWeg"));
          delay (3000);
          mState = stateSperrenWeg;
        }
        break;
      }



    case stateSperrenWeg:
      {
        if (digitalRead(pin3B1) == HIGH)

        {
          digitalWrite (pin2A1, LOW);
          Serial.println(F("SperrenWeg"));
          delay (3000);
          mState = stateRuhestellung;
        }
        break;
      }


  }

}

jetzt läuft zumindest schon mal die Schrittkette :slight_smile:

Allerdings werden die if Abfrageb komplett ignoriert, die Schleife läuft die ganze Zeit einfach durch, egal welche Pins (später die Reedkontakte) aktiv sind.
Ich möchte ja, dass so lange in einem case verblieben wird, bis die Transition erfüllt ist. In diesem Fall der entsprechende Pin von mir manuell auf High gesetzt wird.

Ich habe bereits versucht das break in die if Abfrage zu setzen oder komplett auszuklammern, hat leider auch nicht geholfen

Eigentlich dürfte der Befehl um in den nächsten case zu kommen erst abgefragt werden, sobald die if Bedingung erfüllt wird. Da dieser ja innerhalb der if Abfrage steht, oder?

Kleine Frage nebenbei:
ich habe jetzt Pin 0 und 1 mit den analogen A4 und A5 getauscht, da ich ja sonst den seriellen Monitor nicht nutzen kann. Kann ich die Pins trotzdem mit digitalRead auslesen?
Habe anfangs analogRead benutzt, da ist die Schrittkette nicht mehr gestartet, erst als ich dort wieder analogRead genutzt habe (habe die Pins jeweils ein und ausgesteckt, also so wie es lauf Ablaufsteuerung sein sollte, hat sich nichts weiter bewegt). Dann läuft es aber wieder einfach nur durch.

Wie lautet der korrekte Syntax wenn ich innerhalb einer if Abfrage zwei Pins auslesen will? Ist dies so korrekt?

if (digitalRead(pin1B1 && pin2B1) == HIGH)

Vielen Dank schon einmal für die Hilfe :slight_smile:

1 Like

pin2B1 == HIGH

Bitte sorgfältig arbeiten.

if (digitalRead(pin1B1 && pin2B1) == HIGH)

Falsch!
Bitte im Schritttempo denken.
C++ lernen

if (digitalRead(pin1B1)  && digitalRead(pin2B1))

Pulldowns vorhanden?

Kann ich die Pins trotzdem mit digitalRead auslesen?

Woher sollte ich deinen Arduino kennen?
Aber ja, vermutlich ja.

Hi

In der Arduino-IDE kannst Du STRG+T benutzen, um den Code entsprechend der Verschachtelung einzurücken.
So siehst Du, wie 'tief' der Code liegt, welche Bedingung Diesen einschließen.

switch case brauchen ein break; - sonst wird ab dem passendem case ALLES abgearbeitet - also nach dem aktuellem case auch die darunter Stehenden.

byte a=2;
switch (a){
case 1:Serial.println("1");
case 2:Serial.println("2");
case 3:Serial.println("3");
default: Serial.print("?");
}
--> "23?"

Wenn die Zeilen so aussähen:
case 2:Serial.println("2");break;
würden nur die Anweisungen zwischen dem ersten passendem case und dem break; ausgeführt.
Dann ergäbe das obige Beispiel (mit jeweils einem break; in jeder case-Zeile am Ende)
--> "2"

MfG

postmaster-ino:
sonst wird ab dem passendem case ALLES abgearbeitet - also nach dem aktuellem case auch die darunter Stehenden.

Manchmal ist das aber auch gewünscht

Hi

Ok - man sollte Das aber vorher wissen - gerade, wenn man Sich Das nicht wünscht :wink:

MfG

Ja, so ein C++ Buch hat schon was...
Das beantwortet Fragen, auf die man von selber gar nicht gekommen wäre.

Vielen Dank schon einmal für die Hilfe, soweit läuft es eigentlich schon mal einigermaßen. Der Anfang klappt gut, jedoch überspringt er ab Schritt 4 immer Schritte. Der Code ist identisch wie oben, wo es funktioniert, die Verkabelung passt auch, Bezeichnungen ebenfalls. Alles jetzt mehrfach überprüft. Jmd eine Idee woran es liegen könnte?

// falls Not Aus rein, millis einfügen, delay raus

const byte pin1B1 = A5; // kapazitiver Sensor
const byte pin2B1 = A4; // Magazin oben/unten
const byte pin3B1 = 2; //Reed "Klemmen" eingefahren
const byte pin3B2 = 3; //Reed "Klemmen" ausgefahren
const byte pin1A1 = 4; // Zylinder "Klemmen"
const byte pin2A1 = 5; // Zylinder "Sperren"
const byte pin3A1 = 6; // Zylinder "Schieben"
const byte pin4A2 = 7; // Zylinder "Sichern"
const byte pin4B1 = 8; // Reed "Sperren" eingefahren
const byte pin4B2 = 9; // Reed "Sperren" ausgefahren
const byte pin5B1 = 10; // Reed "Schieben" eingefahren
const byte pin5B2 = 11; // Reed "Schieben" ausgefahren
const byte pin6B1 = 12; // Reed "Sichern" eingefahren
const byte pin6B2 = 13; // Reed "Sichern" susgefahren
//const byte pinS1 = A0; // Schalter EIN/AUS, noch nicht eingefügt, evtl später

enum States {
  stateRuhestellung, stateSperren, stateKlemmen, stateSichernWeg, stateSchieben, stateSchiebenRein, stateSichernHoch, stateKlemmenWeg, stateSperrenWeg
}; // die einzelnen Schritte

//mState = machine State
States mState = stateRuhestellung;              //der Startpunkt der Schrittkette

void setup() {

  Serial.begin(9600);

  pinMode(pin1A1, OUTPUT);
  pinMode(pin2A1, OUTPUT);
  pinMode(pin3A1, OUTPUT);
  pinMode(pin4A2, OUTPUT);
  pinMode(pin1B1, INPUT);
  pinMode(pin2B1, INPUT);
  pinMode(pin3B1, INPUT);
  pinMode(pin3B2, INPUT);
  pinMode(pin4B1, INPUT);
  pinMode(pin4B2, INPUT);
  pinMode(pin5B1, INPUT);
  pinMode(pin5B2, INPUT);
  pinMode(pin6B1, INPUT);
  pinMode(pin6B2, INPUT);

  digitalWrite(pin1A1, LOW); // bei Neustart Grundstellung
  digitalWrite(pin2A1, LOW);
  digitalWrite(pin3A1, LOW);
  digitalWrite(pin4A2, HIGH);

  Serial.println(F("Start"));
}

void loop() {

  // mit "when" Schalter abfragen? Switch case nur solange Schalter Ein?



  switch (mState)
  {
    case stateRuhestellung:
      {
        if (digitalRead(pin1B1) && digitalRead(pin2B1))
        {
          Serial.println(F("Ruhestellung"));
          //delay (3000);
          mState = stateSperren; // der nächste Schritt
        }
      }
      break;

    case stateSperren:
      {
        if (!digitalRead(pin1B1) && digitalRead(pin2B1))
        {
          digitalWrite (pin2A1, HIGH); // Zylinder soll ausfahren
          Serial.println(F("Sperren"));
          //delay (3000);
          mState = stateKlemmen;
        }
      }
      break;


    case stateKlemmen:
      {
        if (digitalRead(pin4B2) && digitalRead(pin2B1))
        {
          digitalWrite (pin1A1, HIGH);
          Serial.println(F("Klemmen"));
          //delay (3000);
          mState = stateSichernWeg;
        }
      }
      break;


    case stateSichernWeg:
      {
        if (digitalRead(pin3B2) && digitalRead(pin2B1))
        {
          digitalWrite (pin4A2, LOW);
          Serial.println(F("SichernWeg"));
          delay (3000);
          mState = stateSchieben;
        }
      }
      break;


    case stateSchieben:
      {
        if (digitalRead(pin6B1) && digitalRead(pin2B1))
        {
          digitalWrite (pin3A1, HIGH);
          Serial.println(F("Schieben"));
          //delay (3000);
          mState = stateSchiebenRein;
        }
      }
      break;


    case stateSchiebenRein:
      {
        if (digitalRead(pin5B2) && digitalRead(pin2B1))

        {
          digitalWrite (pin3A1, LOW);
          Serial.println(F("SchiebenRein"));
          //delay (3000);
          mState = stateSichernHoch;
        }
      }
      break;


    case stateSichernHoch:
      {
        if (digitalRead(pin5B1) && digitalRead(pin2B1))

        {
          digitalWrite (pin4A2, HIGH);
          Serial.println(F("SichernHoch"));
          //delay (3000);
          mState = stateKlemmenWeg;
        }
      }
      break;


    case stateKlemmenWeg:
      {
        if (digitalRead(pin6B2) && digitalRead(pin2B1))

        {
          digitalWrite (pin1A1, LOW);
          Serial.println(F("KlemmenWeg"));
          //delay (3000);
          mState = stateSperrenWeg;
        }
      }
      break;


    case stateSperrenWeg:
      {
        if (digitalRead(pin3B1) && digitalRead(pin2B1))

        {
          digitalWrite (pin2A1, LOW);
          Serial.println(F("SperrenWeg"));
          //delay (3000);
          mState = stateRuhestellung;
        }
      }
      break;

  }

}

Du meinst bestimmt:
if (digitalRead(pin6B2) == HIGH)

Was das gleiche ist wie:
if (digitalRead(pin6B2))

dachte ich könnte das auch so wie oben schreiben, meintest ja dies sei das gleiche. Fand es für mich anfangs etwas übersichtlicher, wenn ich dahinter sehe ob es gleich HIGH oder LOW sein soll.
Habe es jetzt aber überall angepasst.

Die Benennung deiner Pins ist gruselig unübersichtlich (für mich)

Habe es sogelernt, aber gebe ich dir Recht :smiley:

Pulldowns vorhanden?

das war das Problem :frowning: In meinem Schaltplanskizze für den späteren Aufbau habe ich sie drin, hier habe ich sie vergessen. Sind für mich neu und wollte gucken ob der Code so funktioniert, war etwas zu voreilig.

Woher sollte ich deinen Arduino kennen?
Aber ja, vermutlich ja.

ist ein Arduino Uno, bin davon ausgegangen, dass die Verwendung der Pins (sofern Bezeichnung identisch ist, auch dann für alle Arduinos gilt, vlt etwas naiv

if (digitalRead(pin1B1) && digitalRead(pin2B1))

suppi, vielen Dank. Mir fehlen noch etwas die Schlagworte um das von mir Gesuchte zu finden

In der Arduino-IDE kannst Du STRG+T benutzen, um den Code entsprechend der Verschachtelung einzurücken.
So siehst Du, wie 'tief' der Code liegt, welche Bedingung Diesen einschließen.

Danke für den Tipp, die Autoformatierung nutze ich bereits, glaube wird nur hier im Code nicht angezeigt

switch case brauchen ein break; - sonst wird ab dem passendem case ALLES abgearbeitet - also nach dem aktuellem case auch die darunter Stehenden.

das hilft mir auf jeden Fall schon mal weiter, danke :slight_smile:

Ja, so ein C++ Buch hat schon was...
Das beantwortet Fragen, auf die man von selber gar nicht gekommen wäre.

Da gebe ich dir auf jeden Fall recht, ich habe mir bevor ich angefangen habe bereits viele Grundlagentutorials auf Youtube und auf diversen Seiten angeguckt und durchgelesen.
Ebenfalls eine Arduino Referenz als PDF mit über 100 Seiten durchgelesen, einfach um mal ein Gefühl für C++ und einen Überblick zu bekommen.
Denke das Thema ist zu komplex um sich vor Beginn bereits die komplette Theorie anzueigenen, zumindest für mich. Ich möchte nicht unbedingt erst ein Buch mit hunderten Seiten durcharbeiten (und verstehen), wenn ich am Ende bin habe ich den Anfang bereits wieder vergessen oder die Motivation hat mich verlassen.
Für mich persönlich ist da ein Projekt/ Aufgabe besser geeignet, an dem ich mich lang hangeln kann. Bis ich zu diesem Punkt hier gekommen bin hat es schon etwas gedauert, und ich konnte auch schon viele Ideen der Umsetzung ausschließen :wink: Ich möchte ja auch gar nicht das mir hier jmd den kompletten Code schreibt, lieber Tipps und Schlagworte mit denen ich wieder etwas weiter komme.

Hast du vlt trotzdem einen Tipp für ein Buch? Bevorzugt wo auch das Thema Automaten behandelt wird.

Thema PullUp/Down-Widerstände: Der µC hat PullUp (ca. 50 kOhm)) eingebaut, die man mittels INPUT_PULLUP aktivieren kann. Allerdings dreht sich damit die Logik, weil Taster gedrückt == LOW ist. Das kann man dann mit !digitalRead(pin); (bitte das Ausrufezeichen beachten) wieder korrigieren, wenn man möchte.

Serial.println(F("Ruhestellung")); müßte eigentlich "Ruhestellung verlassen" heißen. Da gibt es ein Problem, weil die Aktivitäten für case 1 in der Bedingung bei case 0 stehen. Das könnte man besser machen, wenn Du Interesse hast, allerdings erst später am Tag.

Hast du vlt trotzdem einen Tipp für ein Buch? Bevorzugt wo auch das Thema Automaten behandelt wird.

Du hast aber auch Ansprüche!

Ich möchte nicht unbedingt erst ein Buch mit hunderten Seiten durcharbeiten (und verstehen), wenn ich am Ende bin habe ich den Anfang bereits wieder vergessen oder die Motivation hat mich verlassen.

Lesen und üben, das festigt.
Lesen und das gelesene üben.
Meine Prognose: 3 Jahre wird es dauern.
Dann bist du Sattelfest.

Ich kenne nur 2 recht gute Bücher....
Das vom C++ Erfinder selber.
und "Der C++ Programmierer"
Beide haben nicht 100 sondern 1000 Seiten.

Automaten kommen da nicht wirklich vor.
Ein weiteres 1/2 Jahr
Für jedes Spezialgebiet, ein weiteres 1/2 Jahr

Natürlich können Vorkenntnisse den Weg deutlich verkürzen, aber auch wie eine Tonne Blei, in den Stiefeln, wirken. Denn umlernen ist doppelt schwierig.

Der Anfang klappt gut, jedoch überspringt er ab Schritt 4 immer Schritte.

Nenne dann doch bitte den Schritt... du hast doch Namen vergeben.. dann nutze sie auch bei der Kommunikation.
So weiß ich nicht ob du bei 0 anfängst zu zählen, wie die Inder, wie die EDV, oder bei 1 wie in Korea üblich und auch Kinder es tun.

Denke das Thema ist zu komplex um sich vor Beginn bereits die komplette Theorie anzueigenen, zumindest für mich. Ich möchte nicht unbedingt ...

Wenn du meinst....

suppi, vielen Dank. Mir fehlen noch etwas die Schlagworte um das von mir Gesuchte zu finden

Schlagworte?
if (digitalRead(pin1B1 && pin2B1) == HIGH)

const byte pin1B1 = A5; // kapazitiver Sensor
const byte pin2B1 = A4; // Magazin oben/unten

auf dem UNO das gleiche wie:
const byte pin1B1 = 19; // kapazitiver Sensor
const byte pin2B1 = 18; // Magazin oben/unten

Damit wird "pin1B1 && pin2B1" zu "19 && 18"
Da && ein Boolean Operator ist werden beide implizit zu einem bool gecastet.
Aus "19 && 18" wird also "true && true" und das ist somit immer "true"

"digitalRead(pin1B1 && pin2B1)" wird dadurch zu "digitalRead(true)"
DigitakRead erwartet allerdings ein Byte (und kein bool) als Parameter
Also wird unser "true" implizit zu einer 1 gecastet

Aus "digitalRead(pin1B1 && pin2B1)" wird am Ende dann "digitalRead(1)"
Und genau das willst du ja nicht.

Du verstehen:
Mit "Schlagworte um das von mir Gesuchte zu finden" kommst du da nicht weiter.
Mit Videos schauen auch nicht!
Da hilft nur die Kenntnis der Sprache, und Gehirn einschalten.

Wenn du bei solchen Böcken keinen Frust empfindest, aber beim Lesen eines Buches, dann bist du irgendwie schief gewickelt.
(aus meiner Sicht, welche nicht das Maß der Dinge sein muss)

Stichwort um was wichtiges zu lernen: Entprellen.
Denn evtl spielt dir das Prellen einen Streich.

Ich kann noch nicht so ganz vollziehen, wie so ein case durchlaufen wird.

durch States mState = stateRuhestellung; gebe ich zu Beginn an in welchem case er starten soll,
dann prüft er die if Abfrage. Bleibt er dann so lange innerhalb der Klammer vor der if Abfrage bis diese erfüllt ist?

Ist diese erfüllt führt er den Code innerhalb der if Abfrage aus, geht weiter bis er zum break kommt. Dadurch das ich in der if Abfrage den nächsten case benannt habe, und durch das break, bleibt er dann innerhalb des nächsten case bis diese if Abfrage erfüllt ist. Oder? Hoffe ich konnte mich einigermaßen verständlich ausdrücken.
Ziel ist ja, dass er die Schritte in einer festgelegten Reihenfolge durchgeht und erst in den nächsten Schritt geht, wenn die Tranisition dafür erfüllt ist.

case stateRuhestellung:
      {
        if (digitalRead(pin1B1) && digitalRead(pin2B1))
        {
          Serial.println(F("Ruhestellung"));
          //delay (3000);
          mState = stateSperren; // der nächste Schritt
        }
      }
      break;

Thema PullUp/Down-Widerstände: Der µC hat PullUp (ca. 50 kOhm)) eingebaut, die man mittels INPUT_PULLUP aktivieren kann. Allerdings dreht sich damit die Logik, weil Taster gedrückt == LOW ist. Das kann man dann mit !digitalRead(pin); (bitte das Ausrufezeichen beachten) wieder korrigieren, wenn man möchte.

Ja, habe ich mal gelesen das man es auch so machen kann, werde mich damit noch mal genauer beschäftigen. Kann ich das an jedem Pin machen?
Ansonsten sollte es auch kein Problem sein Widerstände zu nutzen, muss später eh noch Optokoppler und Co löten.

Serial.println(F("Ruhestellung")); müßte eigentlich "Ruhestellung verlassen" heißen. Da gibt es ein Problem, weil die Aktivitäten für case 1 in der Bedingung bei case 0 stehen. Das könnte man besser machen, wenn Du Interesse hast, allerdings erst später am Tag.

Ja, ist mir auch schon aufgefallen das es irgendwie noch nicht richtig passt. Hatte es vorher anders, aber auch da hat es nicht so ganz gepasst. War eher eine schnelle Lösung, damit ich am seriellen Monitor erkennen kann wann er in den nächsten Schritt geht. Für später ist keine Anzeige geplant, deswegen habe ich es erst mal so gelassen.

Nenne dann doch bitte den Schritt... du hast doch Namen vergeben.. dann nutze sie auch bei der Kommunikation.

war mir nicht mehr ganz sicher bei welchem Schritt es genau war, vermute aber ebenfalls das es am Aufbau der Schaltung (fehlendes entprellen) liegt.
Dachte vlt übersehe ich eine Kleinigkeit die ein geübtes Auge sieht :wink: Werde es aber zeitnah mal richtig aufbauen und dann sehen ob der Fehler immer noch vorkommt.

if (digitalRead(pin1B1 && pin2B1) == HIGH)

const byte pin1B1 = A5; // kapazitiver Sensor
const byte pin2B1 = A4; // Magazin oben/unten

auf dem UNO das gleiche wie:
const byte pin1B1 = 19; // kapazitiver Sensor
const byte pin2B1 = 18; // Magazin oben/unten

Damit wird "pin1B1 && pin2B1" zu "19 && 18"
Da && ein Boolean Operator ist werden beide implizit zu einem bool gecastet.
Aus "19 && 18" wird also "true && true" und das ist somit immer "true"

"digitalRead(pin1B1 && pin2B1)" wird dadurch zu "digitalRead(true)"
DigitakRead erwartet allerdings ein Byte (und kein bool) als Parameter
Also wird unser "true" implizit zu einer 1 gecastet

Aus "digitalRead(pin1B1 && pin2B1)" wird am Ende dann "digitalRead(1)"
Und genau das willst du ja nicht.

sowas hilft mir doch schon mal weiter, da kann ich zB noch mal genauer einsteigen um es zu verstehen

Wenn du bei solchen Böcken keinen Frust empfindest, aber beim Lesen eines Buches, dann bist du irgendwie schief gewickelt.

Wenn du der Meinung bist bist das es nur einen richtigen Weg gibt, ok. Ich denke das es didaktisch sinnvoller ist sich an die individuellen Bedürfnisse anzupassen.
Ich gebe dir aber recht, dass nur lesen und üben hilft. Genau das versuche ich ja. Fand es eigentlich gut das man gerade am Anfang schnell Erfolge erzielen kann. Inwiefern diese sinnvoll und richtig sind sei mal dahin gestellt. Es hilft auf jeden Fall bei der Stange zu bleiben, ich muss ja schließlich nicht den Arduino nutzen, kann auch einfach eine SPS oder LOGO nutzen. Allerdings interessiert mich das Thema und macht mir Spaß.
Vielleicht bin ich etwas naiv an das Thema rangegangen, aber warum sollte ich es nicht versuchen?Ich denke ich bin auf einem guten Weg und bin optimistisch das es funktioniert.
Mein Ziel ist es auch nicht C++ direkt perfekt zu beherrschen, sondern nach und nach :wink: Und da bin ich froh das ich hier von euch Hilfe erhalte. Und natürlich bin ich Printmedien nicht abgeneigt, gefrustet war ich von einem guten Buch noch nie :smiley:

Da hilft nur die Kenntnis der Sprache, und Gehirn einschalten.

aber um die Kenntnisse zu erlangen greife ich halt auch gerne auf digitale Medien zurück. Warum diese schlechter sein sollen, kann ich nicht erkennen. Natürlich hinterfrage ich das Gelesene auch und kopiere es nicht einfach blind raus.

Wie in #10 angekündigt, nun eine Variante mit einem Fähnchen (Flag) für das, was einmalig im Schritt ausgeführt werden soll (ungetestet):

// falls Not Aus rein, millis einfügen, delay raus

const byte pin1B1 = A5; // kapazitiver Sensor
const byte pin2B1 = A4; // Magazin oben/unten
const byte pin3B1 = 2; //Reed "Klemmen" eingefahren
const byte pin3B2 = 3; //Reed "Klemmen" ausgefahren
const byte pin1A1 = 4; // Zylinder "Klemmen"
const byte pin2A1 = 5; // Zylinder "Sperren"
const byte pin3A1 = 6; // Zylinder "Schieben"
const byte pin4A2 = 7; // Zylinder "Sichern"
const byte pin4B1 = 8; // Reed "Sperren" eingefahren
const byte pin4B2 = 9; // Reed "Sperren" ausgefahren
const byte pin5B1 = 10; // Reed "Schieben" eingefahren
const byte pin5B2 = 11; // Reed "Schieben" ausgefahren
const byte pin6B1 = 12; // Reed "Sichern" eingefahren
const byte pin6B2 = 13; // Reed "Sichern" susgefahren
//const byte pinS1 = A0; // Schalter EIN/AUS, noch nicht eingefügt, evtl später

enum States {
  stateRuhestellung, stateSperren, stateKlemmen, stateSichernWeg, stateSchieben, stateSchiebenRein, stateSichernHoch, stateKlemmenWeg, stateSperrenWeg
}; // die einzelnen Schritte

//mState = machine State
States mState = stateRuhestellung;              //der Startpunkt der Schrittkette
bool einmal = true;

void setup() {

  Serial.begin(9600);

  pinMode(pin1A1, OUTPUT);
  pinMode(pin2A1, OUTPUT);
  pinMode(pin3A1, OUTPUT);
  pinMode(pin4A2, OUTPUT);
  pinMode(pin1B1, INPUT);
  pinMode(pin2B1, INPUT);
  pinMode(pin3B1, INPUT);
  pinMode(pin3B2, INPUT);
  pinMode(pin4B1, INPUT);
  pinMode(pin4B2, INPUT);
  pinMode(pin5B1, INPUT);
  pinMode(pin5B2, INPUT);
  pinMode(pin6B1, INPUT);
  pinMode(pin6B2, INPUT);

  digitalWrite(pin1A1, LOW); // bei Neustart Grundstellung
  digitalWrite(pin2A1, LOW);
  digitalWrite(pin3A1, LOW);
  digitalWrite(pin4A2, HIGH);

  Serial.println(F("Start"));
}

void loop() {
  // mit "when" Schalter abfragen? Switch case nur solange Schalter Ein?
  switch (mState)
  {
    case stateRuhestellung:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin2A1, LOW);
          Serial.println(F("Ruhestellung"));
        }
        if (digitalRead(pin1B1) && digitalRead(pin2B1))
        {
          mState = stateSperren; // der nächste Schritt
        }
      }
      break;

    case stateSperren:
      {
        if (einmal)
        {
          einmal = false;
          Serial.println(F("Sperren"));
        }
        if (!digitalRead(pin1B1) && digitalRead(pin2B1))
        {
          mState = stateKlemmen;
        }
      }
      break;

    case stateKlemmen:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin2A1, HIGH); // Zylinder soll ausfahren
          Serial.println(F("Klemmen"));
        }
        if (digitalRead(pin4B2) && digitalRead(pin2B1))
        {
          mState = stateSichernWeg;
        }
      }
      break;

    case stateSichernWeg:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin1A1, HIGH);
          Serial.println(F("SichernWeg"));
        }
        if (digitalRead(pin3B2) && digitalRead(pin2B1))
        {
          mState = stateSchieben;
        }
      }
      break;

    case stateSchieben:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin4A2, LOW);
          Serial.println(F("Schieben"));
        }
        if (digitalRead(pin6B1) && digitalRead(pin2B1))
        {
          mState = stateSchiebenRein;
        }
      }
      break;

    case stateSchiebenRein:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin3A1, HIGH);
          Serial.println(F("SchiebenRein"));
        }
        if (digitalRead(pin5B2) && digitalRead(pin2B1))
        {
          mState = stateSichernHoch;
        }
      }
      break;

    case stateSichernHoch:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin3A1, LOW);
          Serial.println(F("SichernHoch"));
        }
        if (digitalRead(pin5B1) && digitalRead(pin2B1))
        {
          mState = stateKlemmenWeg;
        }
      }
      break;

    case stateKlemmenWeg:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin4A2, HIGH);
          Serial.println(F("KlemmenWeg"));
        }
        if (digitalRead(pin6B2) && digitalRead(pin2B1))
        {
          mState = stateSperrenWeg;
        }
      }
      break;

    case stateSperrenWeg:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin1A1, LOW);
          Serial.println(F("SperrenWeg"));
        }
        if (digitalRead(pin3B1) && digitalRead(pin2B1))
        {
          mState = stateRuhestellung;
        }
      }
      break;
  }
}

Ist das einfacher oder schwieriger zu verstehen?

aber um die Kenntnisse zu erlangen greife ich halt auch gerne auf digitale Medien zurück.

Kein Problem!
Nutze auch zum größten Teil digitale Medien.

Warum diese schlechter sein sollen, kann ich nicht erkennen.

Das habe ich weder gesagt noch gedacht, oder gar gemeint.
Nutze auch zum größten Teil digitale Medien.

Aber Video Tutorials....
Die sind bei mir in der Müll Schublade gelandet.

Oder nenne mir nur ein einziges gutes C++ Video Tutorial..
Bin gerne bereit, meine Meinung zu ändern.
Eins würde mir reichen..... nur ein einziges...

Wenn du der Meinung bist bist das es nur einen richtigen Weg gibt, ok.

Habe ich das gesagt?
Ich denke nur, dass es unglaublich viele positive Effekte hat, wenn man das Werkzeug, welches man nutzt auch kennt und um dessen Möglichkeiten/Grenzen weiß.

Ich denke das es didaktisch sinnvoller ist sich an die individuellen Bedürfnisse anzupassen.

Hmmm...
Video Tutorials passen sich nicht deinen Bedürfnissen an, würde ich mal sagen.
Da gilt eher das Motto: Friss, oder stirb.
Da ist kein Raum für Details.
Keine "Breite".


Ich habe schon viele Menschen dabei unterstützt, Computersprachen zu lernen.
ca 50 Tausend Postings in irgendwelchen Computer Foren,
In praktischer Arbeit, in Betrieben, privat, Entwickler Teams, usw.
Konnte den Prozess also schon mehrfach beobachten.

Manchmal war das von Erfolg gekrönt.
Manchmal auch nicht.
Und meine Erfahrung sagt, Leute welche sich ein Buch leisten und auch lesen, kommen viel schneller viel weiter.
Leute, welche man überreden muss, ein Buch zu erwerben, oder das gar ganz verweigern, scheitern oft. Werfen das Zeugs in die Ecke und suchen sich ein anderes Hobby.
Warum das so ist, weiß ich nicht.

Ein bisschen ist es wie in der Fahrschule...
Ganz ohne Theorie geht es nicht!
Erst die grundlegenden Verkehrsregeln lernen, dann die ersten Fahrstunden.
Nicht anders rum.
Die Genialität, die kommt viel später.


OK, anderes Thema... ist genug damit...
Denn, wie du lernst ist im Grunde dein Problem.


Erkläre mir doch mal, was die Maschine tun soll. (wenn du möchtest)
Den zeitlichen Ablauf.
Aus deinem Code kann ich das leider nicht vollständig entnehmen.

Darum kann ich dir auch keinen konkreten Vorschlag machen, wie man/ich es abhandeln könnte.

Aber eins kann ich dir jetzt schon sagen....
Da jeder Zylinder offensichtlich 2 Endlagenschalter und ein Ventil hat, würde ich das zu einer Gruppe/Struktur zusammenfassen. Denn da gibts ja einen mechanischen räumlichen und funktionalen Zusammenhang. Den würde ich genau so im Programm abbilden.
Die Realität in Software gegossen.
Der Zwecke: Das Programm liest sich dann wie eine Geschichte.

agmue:
Wie in #10 angekündigt, nun eine Variante mit einem Fähnchen (Flag) für das, was einmalig im Schritt ausgeführt werden soll (ungetestet):

// falls Not Aus rein, millis einfügen, delay raus

const byte pin1B1 = A5; // kapazitiver Sensor
const byte pin2B1 = A4; // Magazin oben/unten
const byte pin3B1 = 2; //Reed "Klemmen" eingefahren
const byte pin3B2 = 3; //Reed "Klemmen" ausgefahren
const byte pin1A1 = 4; // Zylinder "Klemmen"
const byte pin2A1 = 5; // Zylinder "Sperren"
const byte pin3A1 = 6; // Zylinder "Schieben"
const byte pin4A2 = 7; // Zylinder "Sichern"
const byte pin4B1 = 8; // Reed "Sperren" eingefahren
const byte pin4B2 = 9; // Reed "Sperren" ausgefahren
const byte pin5B1 = 10; // Reed "Schieben" eingefahren
const byte pin5B2 = 11; // Reed "Schieben" ausgefahren
const byte pin6B1 = 12; // Reed "Sichern" eingefahren
const byte pin6B2 = 13; // Reed "Sichern" susgefahren
//const byte pinS1 = A0; // Schalter EIN/AUS, noch nicht eingefügt, evtl später

enum States {
  stateRuhestellung, stateSperren, stateKlemmen, stateSichernWeg, stateSchieben, stateSchiebenRein, stateSichernHoch, stateKlemmenWeg, stateSperrenWeg
}; // die einzelnen Schritte

//mState = machine State
States mState = stateRuhestellung;              //der Startpunkt der Schrittkette
bool einmal = true;

void setup() {

Serial.begin(9600);

pinMode(pin1A1, OUTPUT);
  pinMode(pin2A1, OUTPUT);
  pinMode(pin3A1, OUTPUT);
  pinMode(pin4A2, OUTPUT);
  pinMode(pin1B1, INPUT);
  pinMode(pin2B1, INPUT);
  pinMode(pin3B1, INPUT);
  pinMode(pin3B2, INPUT);
  pinMode(pin4B1, INPUT);
  pinMode(pin4B2, INPUT);
  pinMode(pin5B1, INPUT);
  pinMode(pin5B2, INPUT);
  pinMode(pin6B1, INPUT);
  pinMode(pin6B2, INPUT);

digitalWrite(pin1A1, LOW); // bei Neustart Grundstellung
  digitalWrite(pin2A1, LOW);
  digitalWrite(pin3A1, LOW);
  digitalWrite(pin4A2, HIGH);

Serial.println(F("Start"));
}

void loop() {
  // mit "when" Schalter abfragen? Switch case nur solange Schalter Ein?
  switch (mState)
  {
    case stateRuhestellung:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin2A1, LOW);
          Serial.println(F("Ruhestellung"));
        }
        if (digitalRead(pin1B1) && digitalRead(pin2B1))
        {
          mState = stateSperren; // der nächste Schritt
        }
      }
      break;

case stateSperren:
      {
        if (einmal)
        {
          einmal = false;
          Serial.println(F("Sperren"));
        }
        if (!digitalRead(pin1B1) && digitalRead(pin2B1))
        {
          mState = stateKlemmen;
        }
      }
      break;

case stateKlemmen:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin2A1, HIGH); // Zylinder soll ausfahren
          Serial.println(F("Klemmen"));
        }
        if (digitalRead(pin4B2) && digitalRead(pin2B1))
        {
          mState = stateSichernWeg;
        }
      }
      break;

case stateSichernWeg:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin1A1, HIGH);
          Serial.println(F("SichernWeg"));
        }
        if (digitalRead(pin3B2) && digitalRead(pin2B1))
        {
          mState = stateSchieben;
        }
      }
      break;

case stateSchieben:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin4A2, LOW);
          Serial.println(F("Schieben"));
        }
        if (digitalRead(pin6B1) && digitalRead(pin2B1))
        {
          mState = stateSchiebenRein;
        }
      }
      break;

case stateSchiebenRein:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin3A1, HIGH);
          Serial.println(F("SchiebenRein"));
        }
        if (digitalRead(pin5B2) && digitalRead(pin2B1))
        {
          mState = stateSichernHoch;
        }
      }
      break;

case stateSichernHoch:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin3A1, LOW);
          Serial.println(F("SichernHoch"));
        }
        if (digitalRead(pin5B1) && digitalRead(pin2B1))
        {
          mState = stateKlemmenWeg;
        }
      }
      break;

case stateKlemmenWeg:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin4A2, HIGH);
          Serial.println(F("KlemmenWeg"));
        }
        if (digitalRead(pin6B2) && digitalRead(pin2B1))
        {
          mState = stateSperrenWeg;
        }
      }
      break;

case stateSperrenWeg:
      {
        if (einmal)
        {
          einmal = false;
          digitalWrite (pin1A1, LOW);
          Serial.println(F("SperrenWeg"));
        }
        if (digitalRead(pin3B1) && digitalRead(pin2B1))
        {
          mState = stateRuhestellung;
        }
      }
      break;
  }
}



Ist das einfacher oder schwieriger zu verstehen?

hmm, jein :slight_smile:

Die Intension kann ich nachvollziehen, aber nicht genau wie es funktioniert.

Die Flag setzt du oben einmal auf true, dies wird ja nur einmal zu Beginn ausgeführt, wenn der Arduino Strom bekommt.

Die erste if-Abfrage wird im ersten Fall erfüllt, dann wird die Flag auf false gesetzt. Aber wann wird sie wieder true damit sie im nächsten case wieder die if-Abfrage erfüllt?
Oder ist sie nur innerhalb der if-Abfrage false und sobald diese erfüllt/verlassen wird wieder true?

Die zweite if-Abfrage dient ja der Transition um in den nächsten case zu gelangen?

€:

Aber Video Tutorials....
Die sind bei mir in der Müll Schublade gelandet.

Oder nenne mir nur ein einziges gutes C++ Video Tutorial..
Bin gerne bereit, meine Meinung zu ändern.
Eins würde mir reichen..... nur ein einziges...

Finde die für einen ersten, groben, Überblick nicht schlecht. Geht es dann tiefer in die Materie finde ich sie ebenfalls nicht mehr als ausreichend.

Und meine Erfahrung sagt, Leute welche sich ein Buch leisten und auch lesen, kommen viel schneller viel weiter.
Leute, welche man überreden muss, ein Buch zu erwerben, oder das gar ganz verweigern, scheitern oft. Werfen das Zeugs in die Ecke und suchen sich ein anderes Hobby.
Warum das so ist, weiß ich nicht

Ich informiere mich halt gerne bevor ich mir etwas hole. Bin Azubi, da muss ich schon etwas gucken was ich mir kaufe. Da diese Materie neu für mich ich, kann ich die Qualität nicht beurteilen, bzw ob es überhaupt das Richtige für mich ist. Zumal es online sehr viele Infos zunächst kostenlos gibt, dann brauche ich es nicht doppelt.
Ich bin guten Büchern nicht abgeneigt, besitze deutlich mehr Bücher als digitale Medien, und nicht nur Trivialliteratur :wink: Das sollte nicht mein Problem sein :slight_smile:

Die Bauteile befinden sich in einem Behälter, welcher vorne offen ist und die Bauteile rausrutschen können. Ziel ist es mehrere Behälter zu stapeln und sobald der unterste leer ist, dieser automatisch ausgeworfen werden soll.
Ablauf:

  • kapazitiver Sensor erkennt Bauteile --> High Signal; keine Bauteile --> low Signal
  • Zylinder "Sperren" fährt aus (verhindert zu frühes nachrutschen neuer Bauteile)
  • Zylinder "Klemmen" fährt aus (klemmt die oberen Behälter damit der untere herausgedrückt werden kann)
  • Zylinder "Sichern" fährt ein (sichert untersten Behälter seitlich gegen herausfallen)
  • Zylinder "Schieben" fährt aus (schiebt leeren Behälter raus)
  • Zylinder "Schieben" fährt ein
  • Zylinder "Sichern" fährt aus
  • Zylinder "Klemmen" fährt ein (volle Behälter können nachrutschen)
  • Zylinder "Sperren" fährt ein (Bauteile können nachrutschen)

Die Zylinder werden mit Relais gesteuert, pro Zylinder (bistabil) reicht ein Signal (High ausfahren, low einfahren). Mit den Reedkontakten wird die Position der Zylinder erfasst, sodass zB wirklich nur rausgeschoben wird, wenn die Sicherung weg ist.

Wichtig wäre es mir auch eher nur Denkanstöße, Tipps zu bekommen, keinen komplett fertigen neuen Code :wink:
Soll ja meine eigene Leistung sein und ich möchte es auch verstehen und nicht einfach nur mit copy paste einfügen.

Hi

Da hast Du doch genau den Ablauf, Den Du programmieren möchtest - sogar mit den Rückfahrten!

Diese einzelnen Aktionen nummerierst Du jetzt durch.
Solange Bauteile erkannt werden, verbleibst Du bei '1', da dort die Bauteile erkannt werden sollen.
Wenn dort nach der Maximal-Zeit kein Bauteil erkannt wird, springst Du von 1->2
Ab hier hast Du eine reine Steuerung mit eigenständigen Takten.
In 2 fährt der Zylinder 'Sperren' aus, wenn der Kontak für 'ganz draußen' auslöst 2->3
und so weiter.

Eventuell machst Du Dir Zwischen-Schritte, also Zylinder
1: Zylinder Sperren ausfahren; Schritt++;
2: Ist Zylinder Sperren ganz ausgefahren? Ja -> Schritt++;
3: Zylinder Klemmen ausfahren; Schritt++;
..... to be continue

In Status 2 machst Du Nichts weiter, als laufend nur zu Prüfen, ob der Reed-Kontakt angeschlagen hat - wenn nicht, dann halt in der nächsten Runde erneut.
Das hat den Vorteil, daß der Arduino 'nebenher' auch noch anderes Zeug machen kann - eine LED blinken lassen, auf einen NotStop reagieren ... die Angaben auf einem Display aktualisieren ... wie viele Sekunden der gerade leere Behälter 'gehalten' hat ...
Diese Dinge dann in einem zweiten (x.ten) Switch-Case Block.
So kannst Du (beliebig) viele Abläufe parallel fahren, Jeder braucht halt den eigenen 'Zähler', wo Er Sich Selber gerade befindet.

MfG

  • Zylinder "Sichern" fährt ein (Bauteile können nachrutschen)

Soll vermutlich

  • Zylinder "Sperren" fährt ein (Bauteile können nachrutschen)
    heißen.

Wichtig wäre es mir auch eher nur Denkanstöße, Tipps zu bekommen, keinen komplett fertigen neuen Code

Natürlich! Glaube ich dir.

Aber dennoch, muss ich erst das Problem verstehen, damit ich überhaupt eine Chance habe.
Allgemeine Hilfe, z.B. wie man zu einem tieferen C++ Verständnis kommt, habe ich ja schon genug gegeben. (denke ich mal).

Beispiel:

pro Zylinder (bistabil) reicht ein Signal (High ausfahren, low einfahren).

Denn (High ausfahren, low einfahren) sind 2 Pulse/Signale
Bistabile Relais/Ventile möchten gerne definierte Pulse.

Dafür ist ein eigener kleiner endlicher Automat pro Zylinder nötig.
Denn der Puls darf nicht zu kurz sein (puls reicht nicht damit das Relais umschaltet), und nicht zu lang(pause reicht nicht, um die nächste Umschaltung vorzubereiten)

Stimmt das soweit?

Oder meinst du nicht "Signale", sondern stabile "Pegel"?

Soll vermutlich

  • Zylinder "Sperren" fährt ein (Bauteile können nachrutschen)
    heißen.

ja, habe es geändert

Allgemeine Hilfe, z.B. wie man zu einem tieferen C++ Verständnis kommt, habe ich ja schon genug gegeben. (denke ich mal).

jupp, werde morgen mal nach einem geeigneten Buch suchen :wink:

Denn (High ausfahren, low einfahren) sind 2 Pulse/Signale
Bistabile Relais/Ventile möchten gerne definierte Pulse.

Habe angedacht pro Ventil ein Relais zu nutzen. Das Relais verfügt über Wechselschalter (NO/NC), wodurch ich beide Seiten des Ventils ansteuern kann. Ist sicherlich nicht optimal, aber habe derzeit nur vier Relais zur Verfügung, sollte aber klappen. Habe einen Zylinder so bereits über den Arduino ein- und ausfahren lassen können, in Abhängigkeit des kapazitiven Sensors.

Wie lange genau der Puls sein muss damit das Relais schaltet kann ich gerade nicht genau sagen, muss ich noch mal nachlesen/testen.
Aber da ich die Pins ja erst wieder auf LOW/HIGH setze wenn der entsprechende Reedkontakt das Signal gibt (High Pegel / Low Pegel), sollte es klappen. Der Zylinder wird eher langsam verfahren, also den Reedkontakt erst nach 1-2 sec erreichen.

Werde mich mal mit weiteren, parallelen switch case Blöcken beschäftigen und gucken ob und wie ich diese implementieren kann.
So ein eigener Automat pro Zylinder ist nur nötig, wenn die Zeit zum schalten der Relais nicht reicht, oder?

So ein eigener Automat pro Zylinder ist nur nötig, wenn die Zeit zum schalten der Relais nicht reicht, oder?

Dann auf jeden Fall.

Meist haben bistabile Relais keine 100% ED
Warum auch... sind ja auch nur StromStoßRelais....

Darum:
Wenn ein Endschalter nicht funktioniert, erreicht wird, bleibt dein Automat stehen und das Relais kann durchbrennen.