Warte Zeit im Program

solrac3f:
Ich denke an deinen Sketch muss ich in void Förderband die Schritte reinschreiben die ich möchte.
void foerderband()
{
digitalWrite(LED_BUILTIN,millis()/500%2);
switch (Serial.read())
{
case 'l': linkslauf(); break;
case 'r': rechtslauf(); break;
case 's': stopmotor(); break;
}
Danke. Werde es später ausprobieren

Nein,
die Erweiterung dient NUR der Möglichkeit die Funktionen für die Motorsteuerung zu testen, mehr nicht.

Dah ich mit millis() nicht weiter kam, habe ich die TaskMacro Variante ausprobiert. Und war direkt ein Volltreffer. Ich denke deswegen dah ich schon mit einfachen SPS Steuerungen erfahrung habe.

Fein!

Die Task Macros funktionieren übrigens auch mit Millies!
taskPause() ist ein "verbergendes Konstrukt" welches intern nach dem "BlinkWithoutDelay" Prinzip funktioniert.
Der Trick ist einfach, dass taskPause() die Rechenzeit/Kontrolle abgibt und eben nicht das ganze Programm blockiert.

Ja, das ist nicht weit weg von irgendwelchen SPSen.
Alle SPSler kennen den Funktionsbaustein "Schrittkette"

Hallo zusammen,
ich komme mal wieder ihr um Hilfestellung oder Tips bei Euch nachzufragen.
Seit das letze mal hat sich schon a bischen mehr bei meiner Forderbandbaustelle getan.
Die hilfe von paulpaulson bei meinem Sketch “Serial.pintln()s” eizufugen hat mir sehr geholfen die Zustande zu testen. So habe ich auch ein bischen uber “Serial.pintln()s” nachgelesen und gelernt.
Da die Task Macros Funktion sehr sehr hilfreich wahr ( Danke nochmal combie) , wollte ich und will ich haber selber das gleiche machen mit Millies. Das “BlinkWithoutDelay” Prinzip hat mir geholfen die zwei Motorstart Wartezeiten zu erstellen die ich brauche . Den “Debounce” Prinzip habe ich fur die zwei Sensoren benutz die den Motor starten wie auch stoppen mussen. Und genau ihr brauche ich Hilfe.
Ich werde den Sketch zeigen, denn ich bis zu diesen Moment habe und dan versuchen zu erklaren was mein Problem jetzt ist.

const int sensor1           =  2;
const int sensor2           =  3;
const int starten           =  4;
const int stoppen           =  5;
const int relais1           =  6;
const int relais2           =  7;

int relais1State     = LOW;
int relais2State     = LOW;
int sensor1State;
int lastsensor1State = LOW; 
int sensor2State;
int lastsensor2State = LOW; 
int startenState     = 0;
int stoppenState     = 0;

unsigned long lastDebounceTime1 = 0;  
unsigned long debounceDelay1 = 50; 
unsigned long lastDebounceTime2 = 0;  
unsigned long debounceDelay2 = 50; 

unsigned long previous_r_Millis =  0;
unsigned long previous_l_Millis =  0;
const long zeit1 = 6000;
const long zeit2 = 6000;

//////////////////////////////////////////////////////////////////
void setup() 
{
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(starten, INPUT);
  pinMode(stoppen,  INPUT);
  pinMode(relais1, OUTPUT);
  digitalWrite(relais1, relais1State);
  pinMode(relais2, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  Serial.println(F("Taste|[rs]=rechtslauf_start | [ls]=linkslauf_start | [rh]=rechtslauf_halt | [lh]=linkslauf_halt | "));
}

///////////////////////////////////////////////////////////////////
void visualisierung() ///Zustand Beobachten//
{
  digitalWrite(LED_BUILTIN,millis()/500%2);
  switch (Serial.read()){
    case 'rs': rechtslauf_start(); break;
    case 'ls': linkslauf_start(); break;
	case 'rh': rechtslauf_halt(); break;
	case 'lh': linkslauf_halt(); break;}
}

//////////////////////////////////////////////////////////////////
void loop() ///Schleifen Program////
{
  visualisierung();
  foerderband();
}
//////////////////////////////////////////////////////////////////
void foerderband() ///Foerderband Steuern///
{
  wartezeitrechtslauf();
  rechtslauf_start();
  rechtslauf_halt(); 
  //wartezeitlinkslauf();
  //linkslauf_start();
  //linkslauf_halt();
}

////////////////////////////////////////////////////////////////////
//////////////UBERWACHUNG STEUERUNG MOTOR RECHTLAUF/////////////////
////////////////////////////////////////////////////////////////////
void wartezeitrechtslauf() ///Wartezeit Position Rechts///
{
    unsigned long current_r_Millis = millis();
if (current_r_Millis - previous_r_Millis >= zeit1){
	previous_r_Millis = current_r_Millis;
  if (relais1State == LOW){
	  relais1State = HIGH;} 	
     digitalWrite(relais1, relais1State);}
}

void rechtslauf_start() ///Motor Rechtslauf Starten///
{
  Serial.println(F("rechtslauf_start()"));
 int reading = digitalRead(sensor1);
if (reading != lastsensor1State) {
    lastDebounceTime1 = millis();
  }
if ((millis() - lastDebounceTime1) > debounceDelay1) {
  if (reading != sensor1State) {
      sensor1State = reading;
      if (sensor1State == HIGH) {
        relais1State = !relais1State;
      }
    }
  }
digitalWrite(relais1, relais1State);
    //digitalWrite(relais2, LOW);
lastsensor1State = reading;	
}

void rechtslauf_halt() ///Motor Rechtslauf Stoppen///
{
  Serial.println(F("rechtslauf_halt()"));
    int reading = digitalRead(sensor2);
if (reading != lastsensor2State) {
    lastDebounceTime2 = millis();
  }
if ((millis() - lastDebounceTime2) > debounceDelay2) {
  if (reading != sensor2State) {
      sensor2State = reading;
      if (sensor2State == HIGH) {
        relais1State = !relais1State;
      }
    }
  }
digitalWrite(relais1, relais1State);
lastsensor2State = reading;
}

////////////////////////////////////////////////////////////////////
//////////////UBERWACHUNG STEUERUNG MOTOR LINKSLAUF/////////////////
////////////////////////////////////////////////////////////////////
void wartezeitlinkslauf() ///Wartezeit Position Links///
{
    unsigned long current_l_Millis = millis();
if (current_l_Millis - previous_l_Millis >= zeit2){
    previous_l_Millis = current_l_Millis;
  if (relais2State == LOW){
    relais2State = HIGH;} 
    digitalWrite(relais2, relais2State);}
}

void linkslauf_start() ///Motor Linkslauf Starten///
{
  Serial.println(F("linkslauf_start()"));
 int reading = digitalRead(sensor2);
if (reading != lastsensor2State) {
    lastDebounceTime2 = millis();
  }
if ((millis() - lastDebounceTime2) > debounceDelay2) {
  if (reading != sensor2State) {
      sensor2State = reading;
      if (sensor2State == HIGH) {
        relais2State = !relais2State;
      }
    }
  }
digitalWrite(relais2, relais2State);
    //digitalWrite(relais1, LOW);
lastsensor2State = reading;	
}

void linkslauf_halt() ///Motor Linksslauf Stoppen///
{
  Serial.println(F("rechtslauf_halt()"));
    int reading = digitalRead(sensor1);
if (reading != lastsensor1State) {
    lastDebounceTime2 = millis();
  }
if ((millis() - lastDebounceTime1) > debounceDelay1) {
  if (reading != sensor1State) {
      sensor1State = reading;
      if (sensor1State == HIGH) {
        relais2State = !relais2State;
      }
    }
  }
digitalWrite(relais2, relais2State);
lastsensor1State = reading;
}

Lasse ich den Code nur mit “UBERWACHUNG STEUERUNG MOTOR RECHTSLAUF” oder nur mit “UBERWACHUNG STEUERUNG MOTOR LINKSLAUF” laufen, habe ich die Funtionen bedingt erfultt mit einen FEHLER. Das heisst z.B bei Rechtlauf Uberwachung . Sensor1 ist aktiv, nach 6 sek. Motor startet Rechtsdrehend, Sensor1 ist inaktive Motor dreht weiter bis zum erreichen von Sensor2, Sensor2 wird aktiv Motor Stopped, Sensor2 ist aktiv und nach 6 sek startet der Motor wieder Rechtsdrehend anstatt Linksdrehend. Und das ist mein Problem. Der Motor bei Sensor 2 aktiv musste nach 6 sek. Linksdrehend anfahren.

Habe schon mehrmals den Code angesehen und finde nicht raus wo der Fehler ist.
Falls jemand Stimmung und Laune hat schnell uber den Code ein Auge zu werfen wurde ich mich in voraus bedanken

solrac3f:
Sensor1 ist aktiv, nach 6 sek. Motor startet Rechtsdrehend, Sensor1 ist inaktive Motor dreht weiter bis zum erreichen von Sensor2, Sensor2 wird aktiv Motor Stopped, Sensor2 ist aktiv und nach 6 sek startet der Motor wieder Rechtsdrehend anstatt Linksdrehend. Und das ist mein Problem. Der Motor bei Sensor 2 aktiv musste nach 6 sek. Linksdrehend anfahren.

Du musst gegeneinander verriegeln.
Geht u.a. mit einer Statusvariablen

Das ginge auch mit einer Schrittkette. Aber der Code ist für mich zu unübersichtlich.
Hör auf da ein Haufen Schmuckwerk reinzubasteln und drücke einmal STRG-T vor dem veröffentlichen.

Schreib doch mal auf, was Du willst.
So nach - WENN xx DANN xy ODER DANN yy

Falls jemand Stimmung und Laune hat schnell uber den Code ein Auge zu werfen ...

Gemacht!

Sorry, das sind mir zu viele Bedingungen und durchnummerierte Variablen.
Da komme ich nicht mit klar.
Vermutlich bin ich einfach zu blöd dafür....

my_xy_projekt
Foederband:
Start/Stop Taste, DC Motor, Sensor 1 position links, Sensor2 position rechts

Schritt 1: Start-Stop Taste gedruckt. Transition: Fordebandsteuerung an.
Schritt 2 Aktion: Motor lauft rechtslaufend an. Transition: Position rechts angefahren (Sensor2), zahlt 1 zyklus.
Schritt 3 Aktion: Motor halt an. Transition: Wartezeit von 5 Sekunden.
Schritt 4 Aktion: Motor lauft linkslaufend an. Transition: Position links angefahren (Sensor1).
Schritt 5 Aktion: Motor halt an. Transition: Wartezeit von 5 Sekunden.
Schritt 6 Aktion: Motor lauft rechtslaufend an. Transition: Position rechts angefahren (Sensor2), zahlt 2 zyklus.
usw.....
Scrhritt.....Aktion: Zahler erreicht 20 Zyklen. Transition: Fordebandsteuerung aus:

solrac3f:
Schritt 1: Start-Stop Taste gedruckt.
Schritt 2 Aktion:
Schritt 3 Aktion:
usw.....
Scrhritt.....Aktion: Zahler erreicht 20 Zyklen.

Na das ist doch genau #1... - Warum machst Du Dir soviel Umstände?

Eine neue Anforderung:
Eine Taste

Start-Stop Taste

Ich sehe nur eine Starttaste, keine Stopptaste, in der Ablaufbeschreibung.

Eine neue Anforderung:

zahlt 1 zyklus

Irgendwas soll bezahlt oder gezählt werden.

Eine neue Anforderung:

Zahler erreicht 20 Zyklen. Transition: Fordebandsteuerung aus:

Das nenne ich Salamitaktik.

Da schreibt man/ich ein so schönes funktionierendes Programm, und dann ist es nur wieder für die Tonne, weil sich zwischendurch die Anforderungen mal wieder ändern müssen.

Es wirft die natürliche/übliche Frage auf:
Was kommen denn sonst noch alles für Anforderungen?

const byte sensorLinksEnd  =  2;
const byte sensorRechtsEnd =  3;
const byte startPin        =  4;
const byte stopPin         =  5;
const byte relaisLinks     =  6;
const byte relaisRechts    =  7;

enum {relaisAn, relaisAus};
enum {warten, on, rechts, haltrechts, links, haltlinks, off};
byte schritt = warten;
byte zyklus = 20;
const byte maxzyklus = 20;

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));
  pinMode(sensorLinksEnd, INPUT);
  pinMode(sensorRechtsEnd, INPUT);
  pinMode(startPin, INPUT);
  pinMode(stopPin,  INPUT);
  pinMode(relaisLinks, OUTPUT);
  digitalWrite(relaisLinks, relaisAus);
  pinMode(relaisRechts, OUTPUT);
  digitalWrite(relaisRechts, relaisAus);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  schrittkette();
}

void schrittkette()
{
  static unsigned long lastmillis;
  const unsigned long pauseZeit = 5000; // in ms
  if (digitalRead(stopPin))
  {
    schritt = off;
  }
  switch (schritt)
  {
    case warten:
      if (digitalRead(startPin))
      {
        zyklus = 0;
        schritt = on;
      }
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      break;
    case on:
      digitalWrite(LED_BUILTIN, HIGH);
      schritt = rechts;
      break;
    case rechts:
      digitalWrite(relaisRechts, relaisAn);
      if (digitalRead(sensorRechtsEnd))
      {
        digitalWrite(relaisRechts, relaisAus);
        schritt = haltrechts;
        lastmillis = millis();
      }
      break;
    case haltrechts:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        schritt = links;
      }
      break;
    case links:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAn);
      if (digitalRead(sensorLinksEnd))
      {
        digitalWrite(relaisLinks, relaisAus);
        schritt = haltlinks;
        lastmillis = millis();
      }
      break;
    case haltlinks:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        if (zyklus == maxzyklus)
        {
          schritt = off;
        }
        else
        {
          zyklus++; // Die Zeile hat gefehlt
          schritt = rechts;
        }
      }
      break;
    case off:
      digitalWrite(LED_BUILTIN, LOW);
      schritt = warten;
      break;
  }
}

Probieren... Wenn Du das nicht lesen kannst, dann hab ich nen Problem...

Danke my_xy_projekt fur die Hilfe. Werde den code ausprobieren und bescheid sagen. Ob ich es lesen kann? Manche dinge tue ich erkennen andere wiederrum sind mir ein Ratsel. Wie ich vor knapp 6 Tagen gesagt habe, Halles das ist Neuland fuer mich. Besonders C++. Meine methode momentan ist Learning by Doing. Ich mache immer das, was ich nicht kann, damit ich lernen kann, wie es geht. Ich höre und ich vergesse. Ich sehe und ich erinnere mich. Ich tue und ich verstehe.
Nichts ist dazu gekommen was ich nicht schon mal erwähnt habe combie.
"Der Motor mit zwei Sensoren am Forderband ist nur der Anfang. Es kommt noch Start/Stop, NotAus, Cyclenzahler, Display um Cyclenzahlen ablesen zu konnen, Wartezeiten verhandern uber die Steuerung ohne den Arduino direkt am Laptop anschlisen zu mussen, Cyclenzahlen mit hilfe von Rasperry Wireless in eine Excell tabelle einzufugen...... "
Kann mir jemand von euch eine Lecture uber C++ vorschlagen fur jemanden wie mich der Null Ahnung uber die Materie hat.

solrac3f:
Kann mir jemand von euch eine Lecture uber C++ vorschlagen fur jemanden wie mich der Null Ahnung uber die Materie hat.

Ich muss Dich leider wieder an combie abgeben:

Fürs Erste um mal ein wenig zu erfahren, was so alles geht: Nachtlektüre! Einmal durchlesen - dann weisst, was alles geht… Nicht auswendig lernen. Nachschlagen, weil Du weisst, das es sowas gibt.
Der Rest kommt von allein.
PDF Runterladen von :
https://www.arduinoforum.de/code-referenz

Nichts ist dazu gekommen was ich nicht schon mal erwähnt habe combie.

Da habe ich eine andere Wahrnehmung.

Mein Programm (welches mittlerweile für die Tonne ist) findet sich in Posting #5.
Und davor sehe ich keinerlei Erwähnung deiner "neuen" Features/Anforderungen.

C++ Buch

solrac3f:
Werde den code ausprobieren und bescheid sagen.

Ich hab noch eine Zeile eingefügt - sonst läuft der unendlich und hört nicht nach 20 auf.
De Zeile ist kommentiert.
Na dann...

solrac3f:
"

solrac3f:

    digitalWrite(relais2, LOW);

}
}
//////Stoped die Anlage//////
void anlagehalt()
{
}
//////Motor lauft Rechts//////
void rechtslauf()
{
 Serial.println(F("rechtslauf()"));
 sensor1State = digitalRead(sensor1);
 if (sensor1State == HIGH) {
   digitalWrite(relais1, HIGH);
   digitalWrite(relais2, LOW);
 }
}
//////Motor lauft Links//////
void linkslauf() {
  Serial.println(F("linkslauf()"));
 sensor2State = digitalRead(sensor2);
 if (sensor2State == HIGH) {
   digitalWrite(relais1, LOW);
   digitalWrite(relais2, HIGH);
 }
}
//////Motoren stehen still//////
void stopmotor()
{
 Serial.println(F("stopmotor()"));
 stopenState = digitalRead(stopen);
 if (stopenState == HIGH) {
   digitalWrite(relais1, LOW);
   digitalWrite(relais2, LOW);
 }
}
//////Wartezeit des Motors in rechtslauf//////
void wartezeitrechtslauf()
{
 unsigned long currentMillis = millis();
 if (currentMillis - previousMillisrecht >= lesesensor1)
 {
   previousMillisrecht = currentMillis;
   digitalWrite(relais1, LOW);
   digitalWrite(relais2, LOW);
 }
}
//////Wartezeit des Motors in linksslauf//////
void wartezeitlinkslauf()
{
 unsigned long currentMillis = millis();
 if (currentMillis - previousMillislinks >= lesesensor2)
 {
   previousMillislinks = currentMillis;
   digitalWrite(relais1, LOW);
   digitalWrite(relais2, LOW);
 }
}
//////Steuerung Foerderband//////
void




Fur mich ist zu diesen Zeitpunkt auch sehr wichtig zu sehen das mit millis() ich meine Aufgabenstellung auch bewaltigen kann. Weil erstens " Verdamm es muss einen Wegen geben das zum Arbeiten zu bringen" und zweitens ich sichelich in Zukunft aud millis() zuruck greifen werde. 
Der Motor mit zwei Sensoren am Forderband ist nur der Anfang. Es kommt noch Start/Stop, NotAus, Cyclenzahler, Display um Cyclenzahlen ablesen zu konnen, Wartezeiten verhandern uber die Steuerung ohne den Arduino direkt am Laptop anschlisen zu mussen, Cyclenzahlen mit hilfe von Rasperry Wireless in eine Excell tabelle einzufugen...... :) :( :o :confused: 


Ich habe haber dafur noch viel, viel sehr viel zu lernen.

Woooow.......my_xy_projekt. Dein Code Funktioniert. Habe noch einen weiten weiten Weg zu gehen.
Danke my_xy_projekt und combie fur den Vorschlag des Buches. Werde es mir besorgen. 1000 Seiten......."Think before you speak. Read before you think." I have a lot to read.

combie:
Da habe ich eine andere Wahrnehmung.

Mein Programm (welches mittlerweile für die Tonne ist) findet sich in Posting #5.
Und davor sehe ich keinerlei Erwähnung deiner "neuen" Features/Anforderungen.

C++ Buch

Ich denke deine Wahrnehmung ist nicht richtig. Dein Programm ist auf gar keinen Fall fur die Tonne. Es wahr genau dein Vorschlag und Program das mir mehr begeisterung gegeben hat. Wie ich haber gesagt habe, ich wollte die millis() funktion verstehen , behandeln konnen. Danke fue deine hilfe bis jetzt combie.

Ich denke deine Wahrnehmung ist nicht richtig.

Ja?

Mein Programm (welches mittlerweile für die Tonne ist) findet sich in Posting #5.
Und davor sehe ich keinerlei Erwähnung deiner "neuen" Features/Anforderungen.

Das ist überprüfbar.
Und das habe ich sehr sorgfältig getan.

Nichts ist dazu gekommen was ich nicht schon mal erwähnt habe combie.

Das habe ich damit auch überprüft, und die Aussage als falsch wahrgenommen.

Aber, wie schon gesagt:

Vermutlich bin ich einfach zu blöd dafür....

Zumindest sind meine präkognitiven Fähigkeiten für diesen Fall zu beschränkt.


Es wahr genau dein Vorschlag und Program das mir mehr begeisterung gegeben hat.

Das ist ein anderer Aspekt.
Einer, der dich befriedigt!

solrac3f:
Der Motor mit zwei Sensoren am Forderband ist nur der Anfang. Es kommt noch Start/Stop, NotAus, Cyclenzahler, Display um Cyclenzahlen ablesen zu konnen, Wartezeiten verhandern uber die Steuerung ohne den Arduino direkt am Laptop anschlisen zu mussen, Cyclenzahlen mit hilfe von Rasperry Wireless in eine Excell tabelle einzufugen..

Also Zyklenzähler ist nicht das Problem.
ICH! sehe ein Problem mit einem NOT-Aus, wenn Du das über den Arduino abhandeln willst.
DAS geht NICHT!
Ein Not-Aus gehört dahin, wo sichergestellt ist, das es AUS geht.... Die Frage kommt hier immer wieder auf.
Alles verriegeln. AUS - ohne wenn und aber!
Nach dem entriegeln muss dann wieder gestartet werden.
Letzteres passiert in dem Code, aber aus einem unbestimmten Zustand.
Da ist also noch viel Spielraum für Ideen von Dir.

Ganz wichtig. Bevor Du mit dem Display anfängst, mach alles auf dem seriellen Monitor.
Auch mögliche Eingaben lassen sich auf dem SerMon abbilden.

Zum Not Aus. Ich weiß das es immer über Hardware erfolgen muss nie über die Software. Was haber über ein Not Halt oder besser gesagt eine schnelles stoppen. Wo im Programm wäre es am besten unterzubringen? In der Loop über eine Zustandabfrage eines Eingangs?!?!

solrac3f:
besser gesagt eine schnelles stoppen. Wo im Programm wäre es am besten unterzubringen?

Aaaalso. Nehmen wir das NOT mal raus, kannst Du einen Stop einbauen…
Ein solcher Stop soll angelehnt an ein NOT-Halt sein. :wink:
Damit musst Du sicherstellen, das der Stop auch ausgelöst wird, wenn die Leitung kaputt ist.
Die Leitung ist kaputt, wenn es auf der Leitung zum STOP-Schalter einen Kurzschluss gibt oder einen Kabelbruch.

Dazu erst mein Schaltbild.
Ist nen Spannungsteiler der mit einem NC und einem eingebauten Widerstand im Gehäuse bei Kabelbruch oder ausgelöstem Schalter den Pin HIGH zieht.
Bei einem Kurzschluss oder Ausfall der positoiven Spannung wird nach LOW gezogen.
Die Mitte soll irgendwo in der Mitte liegen :wink:

  +5V 
   |
  +-+
  | |
  +-+
   |
A0 o PIN
   |
#######
#  |  #
# +-+ #
# | | # Widerstand
# +-+ #
#  |  #
#  o  #
#  |+ # Schalter (NC)
#  o  #
####### im Gehäuse
   |
  GND

Ich hab den von mir gelieferten Code angepasst.
Abgefragt wird A0 (Spannungsteiler).
Die Abfrage kann zu jeder Zeit erfolgen.
Sie MUSS vor der Auswahl des schritt erfolgen.
Sie SOLL immer dann erfolgen, wenn eine Funktion aufgerufen wird, die ggfls. nen Moment Zeit braucht.
Die Schrittkette ist erweitert. Bitte unbedingt lesen, was einkommentiert ist.

const byte sensorLinksEnd  =  2;
const byte sensorRechtsEnd =  3;
const byte startPin        =  4;
const byte stopPin         =  5;
const byte relaisLinks     =  6;
const byte relaisRechts    =  7;
const byte HaltPin         =  A0;

enum {relaisAn, relaisAus};
enum {warten, on, rechts, haltrechts, links, haltlinks, off, stoppen, stoppenEnde};
byte schritt = warten;
byte zyklus = 20;
const byte maxzyklus = 20;

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));
  pinMode(sensorLinksEnd, INPUT);
  pinMode(sensorRechtsEnd, INPUT);
  pinMode(startPin, INPUT);
  pinMode(stopPin,  INPUT);
  pinMode(relaisLinks, OUTPUT);
  digitalWrite(relaisLinks, relaisAus);
  pinMode(relaisRechts, OUTPUT);
  digitalWrite(relaisRechts, relaisAus);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  schritt = schnellHalt(schritt);
  schrittkette();

}

void schrittkette()
{
  static unsigned long lastmillis;
  const unsigned long pauseZeit = 5000; // in ms
  if (digitalRead(stopPin))
  {
    schritt = off;
  }
  switch (schnellHalt(schritt))
  {
    case warten:
      if (digitalRead(startPin))
      {
        zyklus = 0;
        schritt = on;
      }
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      break;
    case on:
      digitalWrite(LED_BUILTIN, HIGH);
      schritt = rechts;
      break;
    case rechts:
      digitalWrite(relaisRechts, relaisAn);
      if (digitalRead(sensorRechtsEnd))
      {
        digitalWrite(relaisRechts, relaisAus);
        schritt = haltrechts;
        lastmillis = millis();
      }
      break;
    case haltrechts:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        schritt = links;
      }
      break;
    case links:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAn);
      if (digitalRead(sensorLinksEnd))
      {
        digitalWrite(relaisLinks, relaisAus);
        schritt = haltlinks;
        lastmillis = millis();
      }
      break;
    case haltlinks:
      digitalWrite(relaisRechts, relaisAus);
      digitalWrite(relaisLinks, relaisAus);
      if (millis() - lastmillis > pauseZeit)
      {
        if (zyklus == maxzyklus)
        {
          schritt = off;
        }
        else
        {
          zyklus++; // Die Zeile hat gefehlt
          schritt = rechts;
        }
      }
      break;
    case off:
      digitalWrite(LED_BUILTIN, LOW);
      schritt = warten;
      break;
    case stoppen:
      anhalten();
      schritt=stoppen;
      if (schnellHalt(stoppenEnde) != stoppen)  // Es wird geprüft, ob stoppenEnde möglich ist
      { // kommt "stoppen" zurück, geht es nicht weiter
        // Hier muss etwas rein, was nach dem Rückstellen ausgelöst werden kann
        // Und dann einen definierten schritt zurück gibt
        schritt=stoppenEnde;
      }
      break;
    case stoppenEnde: // Wenn der Stopp nicht mehr gilt UND zurück gefahren,
      schritt = off;  // gehe an definierten Zustand off
      break;
  }
}

byte schnellHalt(byte aktuell)  // Diese Funktion bekommt den aktuellen Schritt übergeben
{
  if (analogRead(HaltPin) > 450 && analogRead(HaltPin) < 550) // Spannungsteiler OK?
  {
    return aktuell; // Wenn ja, ist der Kontakt noch geschlossen
  }
  else
  {
    anhalten();// Wenn nein, ist ausgelöst
  }
  return stoppen;
}

void anhalten()
{
  digitalWrite(relaisRechts, relaisAus);
  digitalWrite(relaisLinks, relaisAus);
}

Danke my_xy_projekt....... :slight_smile:
Hab mir das schon angeschaunt. Spannungsteiler Skizze hab verstanden. Neuer analog eingang dazu gekommen um den Kabelbruch zu Kontrollieren......Super Idee. Ich hatte im Kopf bevor ich gefragt habe, sowas wie einen Geschlossenen Kontakt als eingang zu benutzen und im Program irgenwo einfliessen zu lassen.
Haber einen Spannungsteiler und an einem Analog Eingang ist mich nicht durch den Kopf gegangen. :slight_smile:
Das restliche was dazu gekommen ist muss ich mir sehr ruhig anschauen, durchlesen, nachlesen. Hab die situation mit ruhig anschauen, durchlesen und nachlesen bei deinen ersten gelieferten Code noch nicht beendet und ich stellen schon neue Fragen......
Werde spater wieder bescheid sagen.
Danke nochmal