Relais mit Timer

Guten Morgen
ihr habt hier einen sehr gute Lösung angeboten. Mir erschließt sich nur noch nicht, wo die Pins am Arduino deklariert wurden.

Könnt Ihr hier bitte Licht ins Dunkel bringen.

Anbei der Link - am Ende steht die Lösung und hier wäre hilfreich, wenn man noch die Definition der Pins vom Ardunio einfügt.
https://forum.arduino.cc/t/relais-mit-timer-ansteuern/971436?u=taskforce

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.

Das Lösungsprogramm ist unvollständig, aber in Beitrag #5 findest Du:

const byte relStunde = 2;
const byte relVorStunde = 3;
const byte relS[] = {relStunde, relVorStunde};

Möglicherweise ist es das, was Du suchst?

Ach schick, ist ja eine Lösung von mir :slight_smile:
Ja, in der Lösung #13 steht unten ein Satz, der darauf verweist, dass vorher bereits ein vollständiger Sketch vorhanden war.
Wie @agmue schrieb, ist der vollständige Code in #5 :slight_smile:

Da der Code von mir kam kann ich da ggfls. auch noch was zu sagen, wenn Du Fragen hast. :wink:

Habe den fehlenden Teil nun zusammengeführt. Können Sie, wenn es nicht zu viele Umstände macht, den Code noch mit Kommentaren versehen, zum besseren Verständnis.
Vielen Dank

const byte relStunde = 2;     // Pin Belegung am Arduino
const byte relVorStunde = 3;  // Pin Belegung am Arduino
const byte relS[] = {relStunde, relVorStunde};
enum {an, aus};

const unsigned long stunde = 3600000; // Zeit in ms




void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b = 0; b < sizeof(relS); b++)
  {
    digitalWrite(relS[b], LOW);
    pinMode(relS[b], OUTPUT);
    digitalWrite(relS[b], aus);
  }
  digitalWrite(relStunde, an);
}
void loop()
{
  stundenTick();
  zweiStundenTick();
}

void stundenTick()
{
  const unsigned long laufzeit = 30000;
  static unsigned long lastAusloeser = 0;
  if (millis() - lastAusloeser >= stunde)
  {
    lastAusloeser += stunde;
    digitalWrite(relStunde, an);
  }
  if (digitalRead(relStunde) == an)
    if (millis() - lastAusloeser >= laufzeit)
      digitalWrite(relStunde, aus);
}

void zweiStundenTick()
{
  const unsigned long laufzeit = 300000;  // Zeit in ms
  const unsigned long vorlauf = laufzeit / 2;
  static unsigned long lastAusloeser = 0;
  if (millis() - lastAusloeser >= stunde * 4 - vorlauf)
  {
    digitalWrite(relVorStunde, an);
    lastAusloeser += stunde * 4 - vorlauf;
  }
  if (digitalRead(relVorStunde) == an)
    if (millis() - lastAusloeser >= laufzeit)
    {
      digitalWrite(relStunde, aus);
      lastAusloeser += laufzeit;
    }
}

Mit Sie hat mich auch schon sehr lange keiner mehr angesprochen :laughing:

Wenn Du den Codeteil bitte so formatierst, dass der benutzbar ist. Ja.
-> Mit dem Bleistift nochmal in den Post gehen, den Codeteil markieren -(NUR DEN CODE) und dann oben auf den Button <code> klicken, speichern, fertig.

Beim nächsten Mal in der IDE -> bearbeiten - für Forum kopieren -> dann ersparst Du Dir die Arbeit

const byte relStunde = 2;     // Pin Belegung am Arduino
const byte relVorStunde = 3;  // Pin Belegung am Arduino
const byte relS[] = {relStunde, relVorStunde};
enum {an, aus};               // durch die Enumeration erhält an den Wert 0 / aus -> 1

const unsigned long stunde = 3600000; // Zeit in ms

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b = 0; b < sizeof(relS); b++)   // zählt durch die Elemente von relS
  {
    digitalWrite(relS[b], LOW);             // 
    pinMode(relS[b], OUTPUT);
    digitalWrite(relS[b], aus);
  }
  digitalWrite(relStunde, an);
}

void loop()
{
  stundenTick();
  zweiStundenTick();
}

void stundenTick()
{ 
  const unsigned long laufzeit = 30000;                 // Zeit in ms
  static unsigned long lastAusloeser = 0;               // Merker für letzte Schaltzeit / Variable behält den Inhalt
  if (millis() - lastAusloeser >= stunde)               // Zeit ist um?
  {
    lastAusloeser += stunde;                            // Merker wird um die abgelaufene Zeit erhöht
    digitalWrite(relStunde, an);                        // Aktion
  }
  if (digitalRead(relStunde) == an)                     // Nur wenn aktiv
    if (millis() - lastAusloeser >= laufzeit)           // Prüfung auf abgelaufene Zeit
    { digitalWrite(relStunde, aus); }                   // Aktion
}

void zweiStundenTick()
{
  const unsigned long laufzeit = 300000;                // Zeit in ms (30 sek)
  const unsigned long vorlauf = laufzeit / 2;           // anteilig von laufzeit: -> 15 sek
  static unsigned long lastAusloeser = 0;               // Merker
  if (millis() - lastAusloeser >= stunde * 4 - vorlauf) // -> Hier 3 Stunden 45 Minuten sind um?
  {
    digitalWrite(relVorStunde, an);                     // Aktion
    lastAusloeser += stunde * 4 - vorlauf;              // Schaltzeit setzen
  }
  if (digitalRead(relVorStunde) == an)                  // ist aktiv?
    if (millis() - lastAusloeser >= laufzeit)           // Letzter Schaltpunkt + laufzeit ist um? (hier: -> 4 Stunden 15 Minuten)
    {
      digitalWrite(relStunde, aus);                     // Aktion
      lastAusloeser += laufzeit;                        // Zeit merken
    }
}

Persönliche Anmerkung: Ich würde das heute vermutlich nicht mehr so schreiben.

Danke für die ausführliche Erklärung . Weshalb würden Sie es nun anders machen?
Freundliche Grüße und einen schönen Abend

Ich antworte Dir nicht mer, wenn Du mich weiter siezt :slight_smile:
Ich habe gelernt mit Structuren und Arrays umzugehen und Funktionen kann man Parameteer übergeben was ggfls. dazu führt eine Funktion mehrfach zu verwenden

:innocent: :rofl: okay, kannst du mir bitte noch sagen, wo ich in den Schleifen den Serial.print () einfüge, bzw wäre es hilfreich zu sehen, wie lang es noch dauert, bis die nächste Auslösung des Relais ist.
Im Setup ist bereits Serial Print definiert somit müsste es wahrscheinlich in jeder der beiden Schleifen VoidStundenTick eingefügt werden und hier weis ich nun nicht weiter.
Vielen Dank

Das wird ein Funktionsaufruf, da Du ja nur relativ zur internen Funktion des µC rechnest.
Ich las mir was einfallen. -> Wird zu morgen.

Ich hab mal was ganz verrücktes gemacht und für beide Zweige unterschiedliche Herangehensweisen.

const byte relStunde = 2;     // Pin Belegung am Arduino
const byte relVorStunde = 3;  // Pin Belegung am Arduino
const byte relS[] = {relStunde, relVorStunde};
const uint32_t oneSecond = 1000;
enum {an, aus};               // durch die Enumeration erhält an den Wert 0 / aus -> 1

const unsigned long stunde = 3600000; // Zeit in ms

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b = 0; b < sizeof(relS); b++)   // zählt durch die Elemente von relS
  {
    digitalWrite(relS[b], LOW);             //
    pinMode(relS[b], OUTPUT);
    digitalWrite(relS[b], aus);
  }
  digitalWrite(relStunde, an);
}

void loop()
{
  stundenTick();
  vierStundenTick();
}
//
void stundenTick()
{
  const unsigned long laufzeit = 30000;                 // Zeit in ms -> 30 sekunden
  const unsigned long repeat = stunde - laufzeit;
  static unsigned long lastAusloeser = 0;               // Merker für letzte Schaltzeit / Variable behält den Inhalt
  static unsigned long lastPrintTime = 0;
  static unsigned long tick = digitalRead(relStunde) == an ? laufzeit / oneSecond : repeat / oneSecond; // Initialisierung mit Vorgabewert
  if (digitalRead(relStunde) == an)                     // Nur wenn aktiv
  {
    if (millis() - lastAusloeser >= laufzeit)           // Prüfung auf abgelaufene Zeit
    {
      lastAusloeser += laufzeit;
      digitalWrite(relStunde, aus);                     // Aktion
      tick = repeat / oneSecond;
    }
  }
  else                                                  // inaktiv
  {
    if (millis() - lastAusloeser >= repeat)             // Zeit ist um?
    {
      lastAusloeser += repeat;                          // Merker wird um die abgelaufene Zeit erhöht
      digitalWrite(relStunde, an);                      // Aktion
      tick = laufzeit / oneSecond;
    }
  }
  if (millis() / oneSecond != lastPrintTime / oneSecond)// Sekundentakt
  {
    lastPrintTime = millis();                           // Zeit merken
    Serial.print(F("Nächster Stunden-Schaltpunkt geschätzt in: "));
    {
      restZeit(tick--);
      Serial.println();
    }
  }
}
//
void vierStundenTick()
{
  const unsigned long laufzeit = 300000;               // Zeit in ms (300 sek = 5 Min)
  const unsigned long vorlauf = laufzeit / 2;          // anteilig von laufzeit: -> 150 sek
  const unsigned long repeat = stunde * 4 - vorlauf;   // Hier 3 Stunden 57 Minuten 30 Sekunden
  static unsigned long lastPrintTime = 0;
  static unsigned long tick = digitalRead(relStunde) == an ? laufzeit / oneSecond : repeat / oneSecond; // Initialisierung mit Vorgabewert
  if (tick == 0)
  {
    digitalWrite(relVorStunde, !digitalRead(relVorStunde));
    if (digitalRead(relVorStunde) == an)               // wenn aktiv:
    { tick = repeat / oneSecond; }                     // neue Zeit -> Pause
    else                                               // sonst:
    { tick = laufzeit / oneSecond; }                   // neue Zeit -> pumpzeit
  }
  if (millis() / oneSecond != lastPrintTime / oneSecond)
  {
    lastPrintTime = millis();
    Serial.print(F("Nächster 4Stunden-Schaltpunkt ca. in: "));
    restZeit(tick--);
    Serial.println();
  }
}
//
void restZeit(uint32_t nextSwitch)
{
  uint8_t stunden = nextSwitch / 3600;   // Wieviele Stunden stecken drin?
  nextSwitch -= stunden * 3600;          // Stunden rausrechnen
  uint8_t minuten = nextSwitch / 60;     //
  nextSwitch -= minuten * 60;            //
  vornull(stunden);
  Serial.print(':');
  vornull(minuten);
  Serial.print(':');
  vornull(nextSwitch);
}
//
void vornull(const uint8_t zahl)
{
  if (zahl < 10)
  { Serial.print(0); }
  Serial.print(zahl);
}

Welche gefällt Dir besser?
Und warum ist die Konstelation in StundenTick() Unsinn?

Hallo, danke für die Erstellung von dem Code. Übersichtlicher finde ich den Code im 4 Stunden Tick. Im 1Stunden Tick weiß ich nicht worauf du anspielst. Habe es gerade in den Arduino hochgeladen und lass es laufen. Kann an dem seriellen Monitor erst einmal nichts erkennen. Was jedoch auffällt, ist dass nach dem ersten Durchlauf und anschließendem erneuten Durchlauf der 4StundenTick das Relais länger an ist. .

Die Zeit im 1Stundentick läuft unabhängig von der tatsächlichen Arbeitszeit runter.
Es sind also zwei Funktionen, die das gleiche machen sollen, aber voneinander getrennt sind.
Du bekommst wenn Du Pech hast auf dem SerMon noch mit, dass es angeblich 2 Sekunden bis zum Schaltpunkt sind, Und dann fängt er von vorn an zu zählen, weil die Schaltung schneller war :wink:
Da entscheidet eine ms. Wenn in der letzten Sek. die Zeit abläuft, schaltet er zuerst und kommt dann nicht mehr zur Ausgabe :slight_smile:
Und ja, die erste Schaltung ist kürzer, da wir nicht in der Vergangenheit anfangen.
Kann man ändern...

Guten Morgen, danke für die ausführlichen Antworten. Da ich den Code in seiner gänze verstehen möchte und nicht alles wild zusammenkopieren mag, mit mäßigem Erfolg, hätte ich noch eine Frage zur for Schleife am Anfang die über ein Array der beiden Relais beeinflusst wird.
Wie lange oder wie oft wird mit b++ um eins hoch gezählt, bis die Bedingung erfüllt ist?

const byte relStunde = 2; // Pin Belegung am Arduino
const byte relVorStunde = 3; // Pin Belegung am Arduino
const byte relS[] = {relStunde, relVorStunde};

for (byte b = 0; b < sizeof(relS); b++)

Danke für Antworten.

Ich glaub, das ist die falsche Frage.
Die richtige Antwort:
Es wird solange b aufaddiert, bis die Bedigung nicht mehr erfüllt ist.
In dem Fall wird b nicht größer als 1.
relS enthält 2 Elemente.
Das erste Element beginnt mit 0!!!
relS[0] -> erstes Element
relS[1] -> zweites Element
Beide Elemente werden in der dazugehörigen Funktionsschleife initialisiert .
Wenn b 1 wird, ist die letzte Bedingung erfüllt, danach wird die Funktion verlassen.

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