Meine Endlosschleife stoppt.

Ich habe eine Kombination aus Tasterbedienung und automatischen Betrieb.

Über zwei Taster kann ich manuell hoch und runter fahren und per millis kann
parallel eine Schleife laufen.

Das tut sie auch einige Durchläufe, aber scheinbar willkürlich bleibt sie
irgendwann stehen. Dabei wird kein Taster bedient.

Habt ihr eine Idee, wo sich da im Code eventuell ein Fehler befindet?

Code:

const int RELAY3=12;                       //Relais zuweisen
const int RELAY2=11;
const int RELAY1=10;
int hoch=2;                                     //Taster Hoch fahren
int runter=3;                                   // Taster Runter fahren
int stat_hoch=0;             
int stat_runter=0;
unsigned long startzeit_1 = 0;
#define        laufzeit_1   10000UL     //Zeit für Zyklus festlegen
void setup()
{
pinMode(hoch, INPUT);                   //Pins als In- oder Output setzen
pinMode(RELAY3, OUTPUT);
pinMode(runter, INPUT);
pinMode(RELAY2, OUTPUT);
pinMode(RELAY1, OUTPUT);
digitalWrite(RELAY2, HIGH);             //Relais zu Beginn ausschalten
digitalWrite(RELAY3, HIGH);
}

void loop()
{
  if (millis() - startzeit_1 >= laufzeit_1) {          //Schleife für die Links/Rechts Bewegung
  startzeit_1 = millis();
  digitalWrite(RELAY1, digitalRead(RELAY1) ^ 1);
  }
stat_hoch=digitalRead(hoch);                         //Taster auswerten
stat_runter=digitalRead(runter);
if (stat_hoch == HIGH)                                  //Die zwei hoch und runter Fahrbewegungen
{                                                                  //mit einem delay gegen Einschalten durch Störfaktoren.
digitalWrite(RELAY3, LOW);
delay(1);
digitalWrite(RELAY3, HIGH);
}
else
{
digitalWrite(RELAY3, HIGH); 
}
if (stat_runter == HIGH)
{
digitalWrite(RELAY2, LOW);
delay(1);
digitalWrite(RELAY2, HIGH);
}
else
{
digitalWrite(RELAY3, HIGH); 
}
}

Marino_needing_help:
Über zwei Taster kann ich manuell hoch und runter fahren und per millis kann
parallel eine Schleife laufen.

sicher?

const int RELAY3=12;                       //Relais zuweisen

int hoch=2;                                     //Taster Hoch fahren
int stat_hoch=0;

pinMode(hoch, INPUT);                   //Pins als In- oder Output setzen
pinMode(RELAY3, OUTPUT);

digitalWrite(RELAY3, HIGH);
}

void loop()
{
stat_hoch=digitalRead(hoch);                         //Taster auswerten

if (stat_hoch == HIGH)                                  //Die zwei hoch und runter Fahrbewegungen
{                                                                  //mit einem delay gegen Einschalten durch Störfaktoren.
digitalWrite(RELAY3, LOW);
delay(1);
digitalWrite(RELAY3, HIGH);
}
else
{
digitalWrite(RELAY3, HIGH);
}
}

Was das delay dazwischen soll, ist mir nicht klar, aber das Ding fährt IMMER hoch.

Was jetzt neu auftritt ist, dass die Relais für hoch und runter manchmal geschaltet werden und auch
an bleiben, sobald ich die 24V Wechselspannung der Last, die über die Relais geschaltet wird, einschalte und die Schleife laufen lasse.

Woher kommen diese Fehler?

Was ist das für eine Last ?
Was für Relais verwendest du ?
Sind da Freilaufdioden drauf ?

Die Relais sind so eine 08/15 China Karte mit Optokopplern und 8 Relais drauf.

Die Last ist etwas besonderes, da es zwei 24V Motoren sind, die an Wechselspannung
laufen, aber man sie wie herkömmliche 230V Steinmetzschaltungen anschließt.
Soll heißen, es gibt 3 Anschlüsse am Motor, einer davon N und die anderen zwei sind
per Kondensator unter einander verbunden. Und je nachdem welchen Anschluss des
Kondensators ich nehme, geht es rechts oder links herum.

Freilaufdioden weiß ich nicht, ob das Board solche drauf hat.

Falls nicht, gibt es die fertig und wenn nein, wie konstruiere ich die?

if (stat_hoch == HIGH) //Die zwei hoch und runter Fahrbewegungen
{ //mit einem delay gegen Einschalten durch Störfaktoren. Das! macht es noch schlimmer
digitalWrite(RELAY3, LOW);
delay(1);
digitalWrite(RELAY3, HIGH);
}
else
{
digitalWrite(RELAY3, HIGH);
}

!!!

Wenn ich deine Antwort verstehe, lösche ich das delay einfach aus dem Code raus, richtig?

Und ich wollte nochmal bezüglich der Freilaufdioden fragen, wie man so etwas konstruiert.

Parallel zur Stule, das weiß ich wohl, aber es wird ja wohl nicht bloß eine einzige Diode
sein, oder doch?

Marino_needing_help:
Wenn ich deine Antwort verstehe, lösche ich das delay einfach aus dem Code raus, richtig?

Nicht nur.
Was soll das LOW für 1ms setzen überhaupt? Das Relay zieht dabei vielleicht nicht mal an.
Hast Du das, was ich ROT markiert habe nicht verstanden?

Ich hab mich sogar mal an den Code gewagt und versucht da ein wenig was lesbares draus zu machen.

Hier mit ein paar Änderungen der obere Teil:

const int RELAY3 = 12;                //Relais zuweisen
const int RELAY2 = 11;
const int RELAY1 = 10;
const int hoch = 2;                   //Taster Hoch fahren
const int runter = 3;                 // Taster Runter fahren
bool stat_hoch = LOW;
bool stat_runter = LOW;
unsigned long startzeit_1 = 0;
unsigned long laufzeit_1 = 10000;      //Zeit für Zyklus festlegen
void setup()
  {
  pinMode(hoch, INPUT);               //Pins als In- oder Output setzen
  pinMode(runter, INPUT);
  pinMode(RELAY3, OUTPUT);
  pinMode(RELAY2, OUTPUT);
  pinMode(RELAY1, OUTPUT);
  digitalWrite(RELAY1, HIGH);         //Relais zu Beginn ausschalten
  digitalWrite(RELAY2, HIGH);
  digitalWrite(RELAY3, HIGH);
  }

void loop()
  {
  if (millis() - startzeit_1 >= laufzeit_1)            //Schleife für die Links/Rechts Bewegung
    {
    startzeit_1 = millis();
    digitalWrite(RELAY1, digitalRead(RELAY1) ^ 1);
    }
  stat_hoch = digitalRead(hoch);                       //Taster auswerten
  stat_runter = digitalRead(runter);

Und ab hier krankt es.
Tasterprellen: nicht berücksichtigt
Wenn die Relay LOW aktiv sind, dann...
Relay3 ist IMMER aus.

Der Kommentar gilt nur für stat_hoch? oder auch für stat_runter?
Was sollen die Bedingungen machen?

  if (stat_hoch == HIGH)                                  //Die zwei hoch und runter Fahrbewegungen
    {
    //mit einem delay gegen Einschalten durch Störfaktoren.
    digitalWrite(RELAY3, LOW);
    delay(1);
    digitalWrite(RELAY3, HIGH);
    }
  else
    {
    digitalWrite(RELAY3, HIGH);
    }
  if (stat_runter == HIGH)
    {
    digitalWrite(RELAY2, LOW);
    delay(1);
    digitalWrite(RELAY2, HIGH);
    }
  else
    {
    digitalWrite(RELAY3, HIGH);
    }
  }

Und dann: Was benutzt Du als Taster?
Wenn Du auf HIGH prüfst, brauchst Du zwingend Widerstände nach GND!
Hast Du einen Aufbau, von dem Du ein Foto machen und hier reinstellen kannst?

... erklärt plötzlich auch, warum Da keine H-Brücke für Links/Rechts benötigt wird - war im anderen Thread wohl unnötig, diese Kleinigkeit zu erwähnen.
Vll. hätte man 'Relay1' bis 'Relay3' auch sinnvolle Namen geben können - Steinmetz ist nun nicht so unbekannt.

Nun denn - für den Rest habe ich derzeit keine Lust - vll. ergibt Sich ja noch was, wenn weitere Details in den Thread finden, Die der Lösung helfen könnten ...

PS: Was spricht GOOGLE zu dem Wörtchen Freilaufdiode?
Potzblitz ... Das ist echt nur eine einzige Diode ... Wer hätte DAS gedacht ...

my_xy_projekt:
Und dann: Was benutzt Du als Taster?
Wenn Du auf HIGH prüfst, brauchst Du zwingend Widerstände nach GND?
Hast Du einen Aufbau, von dem Du ein Foto machen und hier reinstellen kannst?

Naja Taster sind bei mir halt ganz normale Taster.

Ach so, Widerstände habe ich natürlich verbaut. 5 V gehen parallel auf alle taster.
Jeder Tasterpin geht auf einen Widerstand und dann auf gnd. Zwischen Tasterpin
und Widerstand erfolgt der Abgriff des Signals.

Bild kann ich notfalls später mal rein reichen.

postmaster-ino:
... erklärt plötzlich auch, warum Da keine H-Brücke für Links/Rechts benötigt wird - war im anderen Thread wohl unnötig, diese Kleinigkeit zu erwähnen.

Och nö....

Nun denn - für den Rest habe ich derzeit keine Lust -

Ich dachte Du liebst (auch) Herausforderungen. :grin:

Ok, ich habe jetzt den ganzen Taster Krempel soweit funktionierend.

Das delay und nach dem delay sofort HIGH setzen raus löschen hat
tatsächlich die Fehltastungen behoben.

Aber was ich nach wie vor nicht verstehe ist, warum sich meine millis Schleife
nach ein paar Durchläufen aufhängt.

Marino_needing_help:
Ach so, Widerstände habe ich natürlich verbaut. 5 V gehen parallel auf alle taster.
Jeder Tasterpin geht auf einen Widerstand und dann auf gnd. Zwischen Tasterpin
und Widerstand erfolgt der Abgriff des Signals.

Also so?

Taster - Zustand HIGH
         +5V
          |
PIN2 --+--/   
       |        
       _      
      | |
      | | R
      | |
       -
       |
      GND

Alternativ: Zustand LOW
   +5V
    |
-+---
 |

Bild kann ich notfalls später mal rein reichen.

mach das.

Aber ohne Beantwortung meiner Frage gehts hier nicht weiter.

Marino_needing_help:
Ok, ich habe jetzt den ganzen Taster Krempel soweit funktionierend.

glaub ich erst, wenn der Code hier steht.

Aber was ich nach wie vor nicht verstehe ist, warum sich meine millis Schleife
nach ein paar Durchläufen aufhängt.

Hast Du das, was ich im oberen Teil bereits lauffähig hatte bei Dir ersetzt?

Ich will Code sehen.

Am Rande, dieses ist unglücklich gelöst:

  pinMode(RELAY3, OUTPUT);
  pinMode(RELAY2, OUTPUT);
  pinMode(RELAY1, OUTPUT);
  digitalWrite(RELAY1, HIGH);         //Relais zu Beginn ausschalten
  digitalWrite(RELAY2, HIGH);
  digitalWrite(RELAY3, HIGH);

Auf AVR besser:

  digitalWrite(RELAY1, HIGH);
  pinMode(RELAY1, OUTPUT);
      
  digitalWrite(RELAY2, HIGH);
  pinMode(RELAY2, OUTPUT);

  digitalWrite(RELAY3, HIGH);
  pinMode(RELAY3, OUTPUT);

Auf die Begründung verzichte ich an dieser Stelle!
Die überlasse ich dem logischen Denkvermögen.

my_xy_projekt:
ch will Code sehen.

Hier:

const int RELAY3=12;         //Relais zuweisen
const int RELAY2=11;
const int RELAY1=10;
int hoch=2;                  //Taster Hoch fahren
int runter=3;                // Taster Runter fahren
int stat_hoch=0;             
int stat_runter=0;
unsigned long startzeit_1 = 0;
#define        laufzeit_1   10000UL     //Zeit für Zyklus festlegen
void setup()
{
pinMode(hoch, INPUT);                   //Pins als In- oder Output setzen
pinMode(RELAY3, OUTPUT);
pinMode(runter, INPUT);
pinMode(RELAY2, OUTPUT);
pinMode(RELAY1, OUTPUT);
digitalWrite(RELAY2, HIGH);             //Relais zu Beginn ausschalten
digitalWrite(RELAY3, HIGH);
}

void loop()
{
  if (millis() - startzeit_1 >= laufzeit_1) {          //Schleife für die Links/Rechts Bewegung
  startzeit_1 = millis();
  digitalWrite(RELAY1, digitalRead(RELAY1) ^ 1);
  }
stat_hoch=digitalRead(hoch);                           //Taster auswerten
stat_runter=digitalRead(runter);
if (stat_hoch == HIGH)                                 //Die zwei hoch und runter Fahrbewegungen
{                                                      //mit einem delay gegen Einschalten durch Störfaktoren.
digitalWrite(RELAY3, LOW);
}
else
{
digitalWrite(RELAY3, HIGH); 
}
if (stat_runter == HIGH)
{
digitalWrite(RELAY2, LOW);
}
else
{
digitalWrite(RELAY2, HIGH); 
}
}

Das mit dem debounce bekomme ich zwar nicht hin, aber selbst so
habe ich keine Doppelbetätigungen drin.

Also ist jetzt erst mal das mit den Tastern angepasst.

Ansonsten sieht das für jeden Taster so aus, wie es bei dir zeichnerisch dargestellt ist.

Marino_needing_help:
Das mit dem debounce bekomme ich zwar nicht hin, aber selbst so
habe ich keine Doppelbetätigungen drin.

Also ist jetzt erst mal das mit den Tastern angepasst.

Ansonsten sieht das für jeden Taster so aus, wie es bei dir zeichnerisch dargestellt ist.

Das da keine Doppelbestätigungen drin sind, glaubst Du nur.
Ok - las ich erstmal aussen vor.

Ersetze den Code bis zum Ende des Setup durch meinen und arbeite combie seinen Tip noch ein, indem Du einfach ein paar Zeilen umbaust. - Also erst digitalWrite und DANN Setzen des PIN als Output.
Da die Relais LOW-aktiv sind, werden die so nicht mal kurz aktiviert.

Gehe vorher in der IDE oben auf "Werkzeuge" und "Sketch archivieren" - Das legt eine .zip mit dem aktuellen Stand an.

Ok, das sähe dann ja so aus:

const int RELAY3 = 12;                //Relais zuweisen
const int RELAY2 = 11;
const int RELAY1 = 10;
const int hoch = 2;                   //Taster Hoch fahren
const int runter = 3;                 // Taster Runter fahren
bool stat_hoch = LOW;
bool stat_runter = LOW;
unsigned long startzeit_1 = 0;
unsigned long laufzeit_1 = 10000;      //Zeit für Zyklus festlegen
void setup()
  {
  pinMode(hoch, INPUT);               //Pins als In- oder Output setzen
  pinMode(runter, INPUT);
  pinMode(RELAY3, OUTPUT); 
  digitalWrite(RELAY3, HIGH);
  digitalWrite(RELAY2, HIGH);               //Relais zu Beginn ausschalten
  pinMode(RELAY2, OUTPUT);
  digitalWrite(RELAY1, HIGH);
  pinMode(RELAY1, OUTPUT);
  }


void loop()
{
  if (millis() - startzeit_1 >= laufzeit_1) {          //Schleife für die Links/Rechts Bewegung
  startzeit_1 = millis();
  digitalWrite(RELAY1, digitalRead(RELAY1) ^ 1);
  }
stat_hoch=digitalRead(hoch);                           //Taster auswerten
stat_runter=digitalRead(runter);
if (stat_hoch == HIGH)                                 //Die zwei hoch und runter Fahrbewegungen
{                                                      
digitalWrite(RELAY3, LOW);
}
else
{
digitalWrite(RELAY3, HIGH); 
}
if (stat_runter == HIGH)
{
digitalWrite(RELAY2, LOW);
}
else
{
digitalWrite(RELAY2, HIGH); 
}
}

Ich schiebe das mal drauf und schaue, was passiert.

Mal als Verständnisfrage:

Was genau ändert der Zusatz "const" vor dem int und was kann "bool", was die
vorherige Version nicht konnte? (Informatik abgewählt)

const
bool

Ah, ok.

Aber trotz der Hilfe hängt sich die Schleife immer noch auf.

Und ich verstehe nicht, warum.

Die Relais an den Tastern spinnen auch wieder.