Go Down

Topic: Hilfe bei Schrittkette (Read 828 times) previous topic - next topic

Chippo

#15
Jan 12, 2018, 08:09 pm Last Edit: Jan 12, 2018, 10:21 pm by Chippo
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):

Code: [Select]
// 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 :)

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?


€:
Quote
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.


Quote
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 ;) Das sollte nicht mein Problem sein :)




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 ;)
Soll ja meine eigene Leistung sein und ich möchte es auch verstehen und nicht einfach nur mit copy paste einfügen.

postmaster-ino

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

combie

#17
Jan 12, 2018, 09:51 pm Last Edit: Jan 12, 2018, 10:02 pm by combie
Quote
- Zylinder "Sichern" fährt ein (Bauteile können nachrutschen)
Soll vermutlich
- Zylinder "Sperren" fährt ein (Bauteile können nachrutschen)
heißen.


Quote
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:
Quote
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"?




Kluge Worte zu schreiben, ist schwer.
Schon ein einziger Buchstabendreher, kann alles urinieren.

Chippo

Quote
Soll vermutlich
- Zylinder "Sperren" fährt ein (Bauteile können nachrutschen)
heißen.
ja, habe es geändert


Quote
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 ;)


Quote
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?

combie

#19
Jan 12, 2018, 10:58 pm Last Edit: Jan 12, 2018, 11:07 pm by combie
Quote
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.

Kluge Worte zu schreiben, ist schwer.
Schon ein einziger Buchstabendreher, kann alles urinieren.

agmue

Die Flag setzt du oben einmal auf true, dies wird ja nur einmal zu Beginn ausgeführt, wenn der Arduino Strom bekommt.
Ich habe die Zeile
           einmal = true;
vergessen :smiley-red:

Code: [Select]
// 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))
        {
          einmal = true;
          mState = stateSperren; // der nächste Schritt
        }
      }
      break;

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

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

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

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

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

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

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

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

Wird es nun verständlicher?

Chippo

Quote
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.
hmm, ok. An so etwas habe ich noch gar nicht gedacht, bzw war mir nicht bewusst. Werde mich da auf jeden Fall noch mal genauer informieren.
Werde mir da auf jeden Fall was überlegen, evtl muss ich dann doch andere Relais verwenden.
Was die Sicherheit angeht, habe ich mich noch gar nicht mit beschäftigt, wird aber auf jeden Fall der nächste Schritt. Bauteile verstehen und überprüfen, was kann passieren, wie kann ich es verhindern/absichern.
Mit der VDE Prüfung wollte/muss ich mich eh auch noch mal beschäftigen. Aber gerade was die solche oben genannten Möglichkeiten betrifft habe ich noch zu wenig Erfahrung. Solche Tipps sind auf jeden Fall Gold wert für mich :)


Quote
Ich habe die Zeile
           einmal = true;
vergessen :smiley-red:
Habe es schon fast vermutet, aber jetzt verstehe ich es :) Gefällt mir von der Idee her

combie

#22
Jan 13, 2018, 10:21 am Last Edit: Jan 13, 2018, 10:22 am by combie
Quote
evtl muss ich dann doch andere Relais verwenden.
Warum?
So ein bisschen Timing, ist für deinen UNO, doch ein Klacks.
Ok, für dich vielleicht noch nicht, aber für den UNO schon.
Das kommt.....
Kluge Worte zu schreiben, ist schwer.
Schon ein einziger Buchstabendreher, kann alles urinieren.

Go Up