Relais schalten nach bestimmter Zeit

Guten Tag,

ich quäle mich mit relativ geringen Arduinokenntnissen ein bisschen durch um ein Script zu erstellen.
Ich würde mich freuen, wenn mir jemand bei meinem aktuellen Problem behilflich sein kann.

Ausgangssituation:
Arduino Nano
Relais 1 (HUBANTRIEBPLUS) am Pin 12
Relais 2 (HUBANTRIEBMINUS) am Pin 13
Relais 3 (TODSCHALTER) am Pin 11
Taster am Pin A1

Gewünschtes Verhalten:
Wenn der Taster 8 Sekunden gedrückt ist, soll Relais 1 und 2 schalten und nach 25 Sekunden, soll Relais 3 schalten.

Aktuelles Verhalten:
Nach 8 Sekunden schalten alle drei Relais.

Code:

#include <Arduino.h>
#include <Wire.h>

// Definierung der Relais 1-12
#define LEDLOGO 2
#define LEDROT 3
#define LEDGRUEN 4
#define LEDBLAU 5
#define MUSIK2 6
#define MUSIK3 7
#define RAUCHLUFT 8
#define RAUCHGENERATOR 9
#define RELAY9 10
#define TODSCHALTER 11
#define HUBANTRIEBPLUS 12
#define HUBANTRIEBMINUS 13

// Definierung der Eingänge
#define TUERZU A1

unsigned long buttonPressTime; // Variable, um die Zeit des Tastendrucks zu speichern  
bool buttonPressed = false;    // Variable, um den Zustand des Tasters zu speichern


void setup() {

  Serial.begin(9600);


  // Definierung der Pins als Ausgang
  pinMode(RAUCHGENERATOR, OUTPUT);
  pinMode(RAUCHLUFT, OUTPUT);
  pinMode(MUSIK2, OUTPUT);
  pinMode(MUSIK3, OUTPUT);
  pinMode(LEDBLAU, OUTPUT);
  pinMode(LEDGRUEN, OUTPUT);
  pinMode(LEDROT, OUTPUT);
  pinMode(LEDLOGO, OUTPUT);
  pinMode(RELAY9, OUTPUT);
  pinMode(TODSCHALTER, OUTPUT);
  pinMode(HUBANTRIEBPLUS, OUTPUT);
  pinMode(HUBANTRIEBMINUS, OUTPUT);
  pinMode(TUERZU, INPUT_PULLUP);
  digitalWrite(TUERZU, HIGH);
  digitalWrite(HUBANTRIEBPLUS, HIGH); // Schublade standartmäßig eingefahren
  digitalWrite(HUBANTRIEBMINUS, HIGH); // Schublade standartmäßig eingefahren
 
}
void loop() {
  // Automatisches Schublade in Grundstellung fahren und Todschalten des Finals, nach Schließen der Tür  
    if (digitalRead(TUERZU) == LOW) { // Prüft, ob der Taster gedrückt ist  
        if (!buttonPressed) {             // Wenn der Taster gerade gedrückt wurde  
            buttonPressed = true;         // Setzt den Zustand auf gedrückt  
            buttonPressTime = millis();   // Speichert die aktuelle Zeit  
        }
        // Prüft, ob der Taster für mindestens 8 Sekunden gedrückt wurde  
        if (millis() - buttonPressTime >= 8000) {
            digitalWrite(HUBANTRIEBPLUS, LOW); // Lässt die Schublade schließen 
            digitalWrite(HUBANTRIEBMINUS, LOW); // Lässt die Schublade schließen
        // Prüft, ob der Taster für mindestens 25 Sekunden gedrückt wurde
        if (millis() - buttonPressTime >= 25000) {
            digitalWrite(TODSCHALTER, HIGH); // Schaltet den Bypass der Stromversorgung aus (Final Stromlos bis zur nächsten Türöffnung)
        }
        }
    } else {
        buttonPressed = false;            // Setzt den Zustand auf nicht gedrückt 
        digitalWrite(HUBANTRIEBPLUS, HIGH); // Lässt die Schublade geöffnet
        digitalWrite(HUBANTRIEBMINUS, HIGH); // Lässt die Schublade geöffnet 
        digitalWrite(TODSCHALTER, LOW);      // Schaltet das Relais aus  
    }

  }

Vielen Dank im Voraus!

Könnte man so machen:

constexpr byte TADSCHALTER {A1};

enum class Status : byte { idle, wait8, wait25, waitDone };

void warte() {
  static unsigned long timeStamp {0};
  static Status status {Status::idle};

  if (digitalRead(TADSCHALTER) == LOW) {
    delay(20);   // Entprellen für Arme
    switch (status) {
      case Status::idle:
        timeStamp = millis();
        status = Status::wait8;
        break;
      case Status::wait8:
        if (millis() - timeStamp > 8000) {
          Serial.println("8 Sekunden gewartet");
          status = Status::wait25;
        }
        break;
      case Status::wait25:
        if (millis() - timeStamp > 25000) {
          Serial.println("25 Sekunden gewartet");
          status = Status::waitDone;
        }
        break;
      case Status::waitDone: break;
    }
  } else {
    status = Status::idle;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(TADSCHALTER, INPUT_PULLUP);
}

void loop() { warte(); }

3 Likes

Für was ist das gut: digitalWrite(TUERZU, HIGH); ?
Aber sonst sehe ich keinen Fehler. Kann es ein Verdrahtungsfehler sein?

Bei einem kurzen Test kam das selbe Ergebnis raus.
Werde es morgen aber nochmal genauer testen.

Hatte das irgendwo erlesen, dass ich es machen muss, da ich GND mit dem Taster auf den Pin schalte und den internen Pullup nutze.
Kann es aber auch mal rausnehmen und schauen was passiert.
So langsam glaube ich auch an ein Verdrahtungsfehler und werde dieses nochmal neu machen.

Ja da kannst Du von ausgehen der Sketch haut hin. Nur wie schon erwähnt das digital write auf A1 würde ich rausnehmen.

Das glaube ich nicht... das funktioniert einwandfrei. Dann bleibt eigentlich nur noch ein Verdrahtungsfehler.

Wobei man da eigentlich nicht viel falsch machen kann:

Dein pinMode aktiviert ja schon den Pullup.
Dann ist der digitalWrite nicht nötig/sinnvoll.
Schadet aber auch nicht.

Vielen Dank für alle Antworten!

Es ist wirklich ein Fehler in der Verdrahtung.
Zumindest funktioniert es schon einmal grob wenn ich die Relais alleine und ohne Last angeschlossen habe.

Ich musste erst mal Googlen, was du hier machst mit dem ','.

Nein, alles andere, aber nicht einfach.

Für mich als Laien, definitiv kein einfaches Beispiel.

Da das hier von mir beschriebene auch nur ein kleiner Teil meines eigentlichen Projekts ist, muss ich mich Stück für Stück durch mein Vorhaben durcharbeiten. Da ist es hilfreich, wenn das Script möglichst simpel geschrieben ist.

Für mein komplettes Projekt könnten einige von euch
Bestimmt mal eben ein Script aus dem Handgelenk schütteln, ich brauche dafür sicherlich noch einige Tage/Nächte mit viel googeln und „Try and error“

Aber umso größerer ist das Erfolgserlebnis, wenn es am Ende funktioniert.

Danke für deinen Code :slight_smile:
Dazu die Frage: Wozu brauchst Du das waitDone?

Daraus könnte man doch schön den Status bounce am Anfang der Statemaschine machen?

Das „waitDone“ habe ich eingefügt, damit der Fall „Der Taster wurde auch nach 25 Sekunden noch nicht losgelassen“ behandelt wird. Da passiert halt bis in alle Ewigkeit nichts, solange der nicht wieder losgelassen wird.

Warum?
Wird doch zu Digitalem Pin und kann auch pinMode(A1, INPUT_PULLUP);
Nur wegen dem A ? Dan schreibt der TO eben 15

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.