Benötige Hilfe. Wenn Relais 1 geschalten wird soll 2,3,4 die schleife nur einmal durchlaufen danach sollen die Relais ausbleiben. Wo liegt der Fehler?


const int Schalter = 2;
const int RelaisA1 =  5;
const int RelaisA2 =  6;
const int RelaisA3 =  7;
const int RelaisA4 =  8;
int Wert = 0; 
void setup() {
  pinMode(RelaisA1, OUTPUT);
  pinMode(RelaisA2, OUTPUT);
  pinMode(RelaisA3, OUTPUT);
  pinMode(RelaisA4, OUTPUT);
  pinMode(Schalter, INPUT_PULLUP);
}

void loop() {
Wert = digitalRead(Schalter); 

  
  if (Wert == HIGH) {
    digitalWrite(RelaisA1, HIGH);
    delay(500);
    digitalWrite(RelaisA1, LOW);
    
  }
  
else if (Wert == LOW) 
{
  delay(500);
    digitalWrite(RelaisA2, LOW);
    delay(500);
    digitalWrite(RelaisA2, HIGH);
    delay(500);
    digitalWrite(RelaisA3, LOW);
    delay(500);
    digitalWrite(RelaisA3, HIGH);
    delay(500);
    digitalWrite(RelaisA4, LOW);
    delay(500);
    digitalWrite(RelaisA4, HIGH);
    
  }
  }


Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Du kannst doch deinen Sketch ganz einfach mittels seriellem Monitor selbst prüfen. Einfach die Zustände im Monitor anzeigen lassen.

Du solltest Dir eine blockadearme Programmierung ohne delay(500); angewöhnen, dann kann der Arduino verschiedene Aufgaben nahezu gleichzeitig erledigen. Daher habe ich den Herzschlag ergänzt.

Du benötigst:

  • Zeiten messen mit millis()
  • eine Schrittkette (=finite state machine; =endlicher Automat), von mir gerne mittels switch/case realisiert
Programm mit Herzschlag
const byte taster   =  2;
const byte relaisA1 =  5;
const byte relaisA2 =  6;
const byte relaisA3 =  7;
const byte relaisA4 =  8;

void setup()
{
  digitalWrite(relaisA1, HIGH);  // aktiv LOW, also erst "aus"
  digitalWrite(relaisA2, HIGH);
  digitalWrite(relaisA3, HIGH);
  digitalWrite(relaisA4, HIGH);
  pinMode(relaisA1, OUTPUT);
  pinMode(relaisA2, OUTPUT);
  pinMode(relaisA3, OUTPUT);
  pinMode(relaisA4, OUTPUT);
  pinMode(taster, INPUT_PULLUP);  // Taster nach GND schaltend
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  relaisAction();
  herzschlag();
}

void relaisAction()
{
  const uint32_t intervall = 500;
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;
  static byte schritt = 0;

  if (jetzt - vorhin >= intervall)
  {
    switch (schritt)
    {
      case 0:
        if ( !digitalRead(taster) )  // aktiv LOW
        {
          digitalWrite(relaisA1, LOW);
          vorhin = jetzt;
          schritt++;
        }
        break;
      case 1:
        digitalWrite(relaisA1, HIGH);
        vorhin = jetzt;
        schritt++;
        break;
      case 2:
        digitalWrite(relaisA2, LOW);
        vorhin = jetzt;
        schritt++;
        break;
      case 3:
        digitalWrite(relaisA2, HIGH);
        vorhin = jetzt;
        schritt++;
        break;
      case 4:
        digitalWrite(relaisA3, LOW);
        vorhin = jetzt;
        schritt++;
        break;
      case 5:
        digitalWrite(relaisA3, HIGH);
        vorhin = jetzt;
        schritt++;
        break;
      case 6:
        digitalWrite(relaisA4, LOW);
        vorhin = jetzt;
        schritt++;
        break;
      case 7:
        digitalWrite(relaisA4, HIGH);
        vorhin = jetzt;
        schritt = 0;
        break;
    }
  }
}

void   herzschlag()  // funktioniert nur bei blockadearmer Programmierung ohne Rhythmusstörung
{
  const uint32_t intervall = 222;
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;

  if (jetzt - vorhin >= intervall)
  {
    vorhin = jetzt;
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  }
}

Eventuell möchtest Du auch ein Feld verwenden:

Programm mit Feld
const byte tasterPin   =  2;
const byte relaisPin[] =  {5, 6, 7, 8};
const byte relaisAnzahl = sizeof(relaisPin);

void setup()
{
  for (byte i = 0; i < relaisAnzahl; i++)
  {
    digitalWrite(relaisPin[i], HIGH);  // aktiv LOW, also erst "aus"
    pinMode(relaisPin[i], OUTPUT);
  }
  pinMode(tasterPin, INPUT_PULLUP);  // Taster nach GND schaltend
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  relaisAction();
  herzschlag();
}

void relaisAction()
{
  const uint32_t intervall = 500;
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;
  static byte relaisIndex = 0;
  static byte schritt = 0;

  if (jetzt - vorhin >= intervall)
  {
    switch (schritt)
    {
      case 0:
        if ( !digitalRead(tasterPin) )  // aktiv LOW
        {
          schritt++;
        }
        break;
      case 1:
        digitalWrite(relaisPin[relaisIndex], LOW);
        vorhin = jetzt;
        schritt++;
        break;
      case 2:
        digitalWrite(relaisPin[relaisIndex], HIGH);
        relaisIndex++;
        if (relaisIndex < relaisAnzahl)
        {
          vorhin = jetzt;
          schritt = 1;
        } else {
          relaisIndex = 0;
          schritt = 0;
        }
        break;
    }
  }
}

void   herzschlag()  // funktioniert nur bei blockadearmer Programmierung ohne Rhythmusstörung
{
  const uint32_t intervall = 222;
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;

  if (jetzt - vorhin >= intervall)
  {
    vorhin = jetzt;
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  }
}

const int Schalter = 2;
const int RelaisA1 =  5;
const int RelaisA2 =  6;
const int RelaisA3 =  7;
const int RelaisA4 =  8;
int Wert = 0; 
void setup() {
  pinMode(RelaisA1, OUTPUT);
  pinMode(RelaisA2, OUTPUT);
  pinMode(RelaisA3, OUTPUT);
  pinMode(RelaisA4, OUTPUT);
  pinMode(Schalter, INPUT_PULLUP);
}

void loop() {
Wert = digitalRead(Schalter); 

  
  if (Wert == HIGH) {
    digitalWrite(RelaisA1, HIGH);
    delay(500);
    digitalWrite(RelaisA1, LOW);
    
  }
  
else if (Wert == LOW) 
{
  delay(500);
    digitalWrite(RelaisA2, LOW);
    delay(500);
    digitalWrite(RelaisA2, HIGH);
    delay(500);
    digitalWrite(RelaisA3, LOW);
    delay(500);
    digitalWrite(RelaisA3, HIGH);
    delay(500);
    digitalWrite(RelaisA4, LOW);
    delay(500);
    digitalWrite(RelaisA4, HIGH);
    
  }
  }


Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Ich werd aus der Beschreibung nicht schlau.

const byte Schalter = 2;
const byte RelaisA1 =  5;
const byte RelaisA2 =  6;
const byte RelaisA3 =  7;
const byte RelaisA4 =  8;
bool Wert;
bool merker = false;
void setup()
{
  pinMode(RelaisA1, OUTPUT);
  pinMode(RelaisA2, OUTPUT);
  pinMode(RelaisA3, OUTPUT);
  pinMode(RelaisA4, OUTPUT);
  pinMode(Schalter, INPUT_PULLUP);
}

void loop()
{
  if (digitalRead(Schalter) == LOW)
  {
    if (merker == false)
    {
      merker = true;
      digitalWrite(RelaisA1, HIGH);
      delay(500);
      digitalWrite(RelaisA2, LOW);
      delay(500);
      digitalWrite(RelaisA2, HIGH);
      delay(500);
      digitalWrite(RelaisA3, LOW);
      delay(500);
      digitalWrite(RelaisA3, HIGH);
      delay(500);
      digitalWrite(RelaisA4, LOW);
      delay(500);
      digitalWrite(RelaisA4, HIGH);
      delay(500);
      digitalWrite(RelaisA1, LOW);
    }
  }
  else
  { merker = false; }
}

Hinweis: Die Taste schaltet nach GND!!!

HIER NICHT ANTWORTEN!
Ist ein Duplikat und die Moderation angefordert!

Ich habe die beiden Diskussionsstränge zusammengeführt.


@s1v2e3n4

Ihre beiden Themen zum gleichen oder ähnlichen Thema wurden zusammengeführt.

Cross-Posting verstößt gegen die Regeln des Arduino-Forums. Der Grund dafür ist, dass doppelte Beiträge die Zeit derjenigen verschwenden können, die helfen möchten. Jemand könnte viel Zeit damit verbringen, eine detaillierte Antwort auf ein Thema zu verfassen, ohne zu wissen, dass jemand anderes dies bereits im anderen Thema getan hat.

Bitte erstellen Sie nur ein Thema für Ihre Frage und wählen Sie die Forumskategorie sorgfältig aus. Wenn Sie mehrere Fragen zu demselben Projekt haben, stellen Sie diese bitte in einem einzigen Thema, da die Antworten auf eine Frage nützlichen Kontext für die anderen bieten. Außerdem müssen Sie Ihr Projekt nicht immer wieder erneut erklären.

Wiederholtes doppeltes Posten könnte zu einer vorübergehenden oder dauerhaften Sperre im Forum führen.

Nehmen Sie sich bitte ein paar Minuten Zeit, um zu lernen, wie man das Forum benutzt. Dies wird Ihnen helfen, in Zukunft das Beste aus dem Forum herauszuholen.

Vielen Dank.

Das Progamm läuft noch nicht wie erwünscht.Hier noch mal eine genaue Beschreibung.

Programmablauf mit Einem Schalter ( kein Taster) soll das 1 te Relais angesteuert werden für 500 ms. Erst wenn der Schalter wieder ausgeschalten Wird ( egal nach wie viel Stunden) soll das 2 te Relais 2 mal kurz an gehen. Danach das 3 te Relais 2 mal kurz und dann zum Schluss das 4 te Relais auch kurz an. Danach wäre der Ablauf fertig. Starten soll es immer mit Einschalten des Schalters.

du willst nicht auf einen bestimmten Status reagieren. Du willst auf einen Statusübergang reagieren. Du könntest dir ein einer Variable "alterStatus" merken was der Status war und diesen nutzen

Wert einlesen
WENN (Wert != alterStatus) 
DANN Logik verarbeiten
SONST nichts tun.
alterStatus = Wert
delay(100); // schmutziges delay zum Debouncen

es gibt in der IDE das Beispiel StateChangeDetection.

es funktioniert einfach nicht

kannst du mir bitte den code so verändern

Hast Du #4 beachtet?

const byte Schalter = 2;
const byte RelaisA1 = 5;
const byte RelaisA2 = 6;
const byte RelaisA3 = 7;
const byte RelaisA4 = 8;

enum class STEP {warten, stepOne, stepTwo, stepThree, stepFour, stepFive, stepSix, stepSeven};
STEP step;

uint32_t startTime;
const uint32_t pausetime = 500;
const uint32_t relaisOneOnTime = 2000;
void setup()
{
  pinMode(RelaisA1, OUTPUT);
  pinMode(RelaisA2, OUTPUT);
  pinMode(RelaisA3, OUTPUT);
  pinMode(RelaisA4, OUTPUT);
  pinMode(Schalter, INPUT_PULLUP);
  ausgangsstellung();
}

void loop()
{
  switch (step)
  {
    case STEP::warten:  // wartet auf Tastendruck
      if (digitalRead(Schalter) == LOW)
      {
        digitalWrite(RelaisA1, LOW); // erstes Relais ein
        startTime = millis();        // Startzeitpunkt merken
        step = STEP::stepOne;               // nächster Schritt
      }
      break;
    case STEP::stepOne:
      if (millis() - startTime > relaisOneOnTime) // Zeit ist abgelaufen
      {
        digitalWrite(RelaisA1, HIGH);             // Relais in Grundstellung
        step = STEP::stepTwo;                           // nächster Schritt
      }
      break;
    case STEP::stepTwo:
      if (digitalRead(Schalter) == HIGH)          // Schalter ist in Grundstellung
      {
        digitalWrite(RelaisA1, LOW);              // Relais einschalten
        startTime = millis();                     // Startzeitpunkt merken
        step = STEP::stepThree;                           // nächster Schritt
      }
      break;
    case STEP::stepThree:
      if (millis() - startTime > pausetime)
      {
        digitalWrite(RelaisA2, HIGH);
        startTime = millis();
        step = STEP::stepFour;
      }
      break;
    case STEP::stepFour:
      if (millis() - startTime > pausetime)
      {
        digitalWrite(RelaisA2, LOW);
        startTime = millis();
        step = STEP::stepFive;
      }
      break;
    case STEP::stepFive:
      if (millis() - startTime > pausetime)
      {
        digitalWrite(RelaisA3, HIGH);
        startTime = millis();
        step = STEP::stepSix;
      }
      break;
    case STEP::stepSix:
      if (millis() - startTime > pausetime)
      {
        digitalWrite(RelaisA4, LOW);
        startTime = millis();
        step = STEP::stepSeven;
      }
      break;
    case STEP::stepSeven:
      if (millis() - startTime > pausetime)
      {
        digitalWrite(RelaisA4, HIGH);
        startTime = millis();
        step = STEP::warten;
      }
      break;
    default:
      if (digitalRead(Schalter) == HIGH)
      {
        ausgangsstellung();
        step = STEP::warten;
      }
      break;
  }
}

void ausgangsstellung()
{
  digitalWrite(RelaisA1, HIGH); // Grundstellung
  digitalWrite(RelaisA2, HIGH);
  digitalWrite(RelaisA3, HIGH);
  digitalWrite(RelaisA4, HIGH);
}

ungetestet und als Vorlage gedacht....

das kannst anpassen

/*

   https://forum.arduino.cc/t/benotige-hilfe-wenn-relais-1-geschalten-wird-soll-2-3-4-die-schleife-nur-einmal-durchlaufen-danach-sollen-die-relais-ausbleiben-wo-liegt-der-fehler/1335642/17

   2024-12-25 by noiasca
   code in thread
*/


const byte Schalter = 2;
const byte RelaisA1 =  5;
const byte RelaisA2 =  6;
const byte RelaisA3 =  7;
const byte RelaisA4 =  8;
int Wert;
int alterStatus = false;

void einschalten() {
  Serial.println("change to ein");
  digitalWrite(RelaisA1, HIGH);
  delay(500);
  digitalWrite(RelaisA1, LOW);
}

void ausschalten() {
  Serial.println("change to aus");
  digitalWrite(RelaisA1, HIGH);
  delay(500);
  digitalWrite(RelaisA2, LOW);
  delay(500);
  digitalWrite(RelaisA2, HIGH);
  delay(500);
  digitalWrite(RelaisA3, LOW);
  delay(500);
  digitalWrite(RelaisA3, HIGH);
  delay(500);
  digitalWrite(RelaisA4, LOW);
  delay(500);
  digitalWrite(RelaisA4, HIGH);
  delay(500);
  digitalWrite(RelaisA1, LOW);
}

void setup() {
  Serial.begin(115200);
  pinMode(RelaisA1, OUTPUT);
  pinMode(RelaisA2, OUTPUT);
  pinMode(RelaisA3, OUTPUT);
  pinMode(RelaisA4, OUTPUT);
  pinMode(Schalter, INPUT_PULLUP);
}

void loop() {
  Wert = digitalRead(Schalter);
  if (Wert != alterStatus) {
    if (Wert == LOW)
      einschalten();
    else
      ausschalten();
  }
  alterStatus = Wert;
  delay(100); // dirty delay
}
//

Tolle Fehlerbeschreibung!

Warum löscht Du Deinen letzten Beitrag?

Du möchtest wenn Du den Taster drückst etwas machen und wenn Du ihn losläßt was anderes.

Du möchtest nicht etwas solange machen wie der Taster gedrückt ist und etwas anderes wenn er losgelassen ist.

Grüße Uwe

Sorry war nicht mit Absicht. Bin neu hier. Es war ein verkehrten Tastendruck. Ich bedanke mich trotzdem für eure Mühe