Steuerung Lüftung einschalten mit Zeitverzögerung

die falschen Kommentierungen stammen daher weil ich das ganze in einem kleineren Programm ausprobieren und verstehen will. Im Keller läuft mein Arduino bereits und regelt Warm / Kalt Wasser / Lüftung / und Musik.
Da will ich nichts ändern bevor ich es verstanden habe.

Darum ist der Lüfter nun eine LED und nicht das Relais für den Lüfter.

Hier ist zumindest mal der Taste 1, Lüfter an, Lüfter nach bestimmter Zeit aus, oder Taste 2 Lüfter aus....

Vielleicht hilft das ja einen Schritt weiter.

Der Lüfter (die LED) geht nach 5 Sekunden von selber aus.

Ich habe hier jetzt folgende Variante:

Taste 1: Schaltet LED/Lüfter sofort ein, nach einer bestimmten Zeit wird die LED automatisch ausgeschaltet.
Taste 2: Schaltet die LED immer aus und unterbricht auch eine Aktion die mit Taste 3 ausgelöst wurde.
Taste 3: Startet einen Timer. Nach einer bestimmten Zeitspanne wird die LED angeschaltet und leuchtet dann für eine bestimmte Zeit. Wird Taste 2 gedrückt, wird der Vorgang abgebrochen ansonsten erlischt die LED nach der vorgegebenen Zeit.

Es wurden drei Timer "gebaut" und die Zeiten immer mit 5 Sekunden definiert.

ach du Alarm mit Klasse und komplexer Fan::XXXSchreibweise
und dann ohne Erklärung was hier was ist und was welche Funktion beim Klasse definieren hat.

@papazonk

Wie oben beschrieben gibt es drei - man könnte sagen "Betriebsmodi"

Du hast Sie

  • Modus "OFF" (Das ist Taste S1)
  • Modus "On" (Das ist Taste S2
  • Modus "WAIT" (Das ist Taste S3)
    genannt.

Das sind jetzt in einem switch-case-break-statement drei verschiedene case

Und an der Stelle stelle ich jetzt eine Bedingung bevor ich weitere Erklärungen und evtl. Code liefere:

Jetzt poste mal was auf den Tasten auf deiner Fernbedienung wirklich aufgedruckt ist!
Ist auf den physischen Tasten wirklich "S1", "S2" und "S3" aufgedruckt?
Das glaube ich erst wenn du mir ein Foto von der IR-Fernbedienung gepostest hast.

Diese Kurznamen für Variablen usw. machen das Lesen und Weiterentwickeln des Codes schwerer.
Weil man nämlich immer eine Übersetzungsleistung machen muss "S1" ist Taste mit Aufdruck "7" und das bedeutet ausschalten usw. Das finde ich persönlich bescheuert

Wenn man sowieso nicht so viel Ahnung vom Programmieren hat, dann sollte sich wenigstens der Programtext locker runterlesen lassen. Und - du machst es allen anderen Usern auch leichter dein Programm zu verstehen.

Das Grundprinzip ist jetzt das Programm startet im Modus "OFF"
und in jedem Modus werden die entsprechenden Bedingungen abgefragt die zu einem evtl. Umschalten des Betriebsmodus führen.

Also wie isset? postest du die aufgedruckten Zeichen deiner IR-Fernbedienung?
vgs

Ich weiß gar nicht was Du willst. Kann man doch alles nachschlagen. Außerdem kümmerst Du dich doch um die Prosa. Konkretes Nachfragen und somit konkretes Antworten ginge ja auch.

Ist doch alles gut. :slightly_smiling_face:

2 Likes

Poste mal deinen Sketch hier in Klartext

Ja das stimmt. :slightly_smiling_face: :smile: :grin: :laughing:

Es gibt einen Aspekt wo ich deinen Code in der WOKWI-Simulation mit drei Tasten vereinfachen würde. Es gibt ein switch-case-break für die Tasten und ein switch-case-break für die Betriebsmodi

Das Drücken einer Taste löst doch schon einen Betriebsmodus aus.
Jetzt ist das bei dir mit Initialisieren und Bedingungen prüfen irgendwie zwischen den beiden switch-cases aufgeteilt.

Da würde ich einmal if-bedingungen zum Initialisieren (Timer-Startwert, Betriebsmodi) nehmen und dann nur einmal switch-case-break für die drei Betriebsmodi

vgs

Meinst du den Wokwi Code?

ja, ich meine den Sketch aus der Simulation

Also ihr lieben, ihr fordert mich da gewaltig :slight_smile:
Das wäre die Fernbedienung:
drücken will ich
Feuer für ON = s1
Blatt für OFF = s2
und Gelb für WAIT = s3

daher habe ich die Abkürzungen gewählt!

Hier das Programm das am laufen ist. Es kann alles bis auf das Verzögerte einschalten des Lüfters:

#include <Arduino.h>
#include <IRremote.h>
uint32_t startzeitluft;
uint32_t startzeitwarm;
uint32_t startzeitkalt;
uint32_t wartezeit1h;
uint32_t nachtluft;

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;



//Die Codes Für Die Fernbedienung
//
//  1. 1082097791   Musik alle an 
//  2. 1082081471   Musik alle aus
//  3. 1082099831   Musik ohne Sub
//  4. 1082091671   
//  5. 1082085551   
//  6. 1082083511   Musik nur im Dampf
//  7. 1082067191   Musik -
//  8. 1082101871   Musik +
//  9. 1082089631   Lüfter Piazza an 
//  10.1082110031   Lüfter Dampf an 
//  11.1082093711   Relais Wasser heisser
//  12.1082107991   Umstellen bluetooth / Klingelbrett
//  13.1082122271   Lüfter beginnt in einer Stunde für eine Stunde
//  14.1082069231   Relais Wasser kälter 
//  15.1082077391   Stop Temperatur Mischmotor?
//  16.1082103911   Lüfter Piazza ab
//  17.1082075351   Lüfter Dampf aus


void setup()

{
Serial.begin(9600);
pinMode (13, OUTPUT);    // Lüfter    Pin 13 /12 /8/7/2 als Ausgänge definieren
pinMode (12, OUTPUT);    // Lüfter
pinMode (8,OUTPUT);       //Dampfboxe          
pinMode (7,OUTPUT);       //Piazza,
pinMode (2,OUTPUT);       //Subwoover         
pinMode (4,OUTPUT);       // Wasser wärmer
pinMode (5,OUTPUT);       //Wasser kälter         
irrecv.enableIRIn();
IrSender.enableIROut(38);
IrSender.begin(3); // Start with IR_SEND_PIN as send pin and if NO_LED_FEEDBACK_CODE is NOT defined, enable feedback LED at default feedback LED pin
// ir empfänger = 11 // wird oben bei ir receiv pin definiert

digitalWrite (12, HIGH);
digitalWrite(5, HIGH);
digitalWrite(4, HIGH);

}

void loop()
{
  
    if (irrecv.decode(&results))
    {
      if (results.value == 1082089631)  //Regelung für Lüfter Piazza on
      {digitalWrite (13, LOW);}      
    
      if (results.value == 1082103911)  //Regelung für Lüfter Piazza off
      {digitalWrite (13, HIGH);}        
    
      if (results.value == 1082110031)  // Regelung Lüfter Dampf
      {
      digitalWrite (12, LOW);           // mache Lüfter an
      startzeitluft = millis();         // starte Zeit um Lüfter danach wieder abzustellen
      }                                   
      if (results.value == 1082075351)  // mache Lüfter Dampf aus
      {digitalWrite (12, HIGH);
      }       

//      if (results.value == 1082122271)  //Regelung für nachtlüftung 1 Stunde verspätet für 1 Stunde einschalten
//      {           
//        wartezeit1h = millis(); 
//      }        

    
    
    //Regelung Sound
    
      if (results.value == 1082097791)  //Regelung Sound
      {
      digitalWrite (7, LOW);            // schalte kleine Boxen an
      digitalWrite (8, LOW);
      digitalWrite (2, LOW);
      }      
      if (results.value == 1082081471)
      {
      digitalWrite (7, HIGH);           // schalte kleine Boxen aus
      digitalWrite (8, HIGH);
      digitalWrite (2, HIGH);

      } 


      if (results.value == 1082083511)  // Musik nur in Dampfkabine
      {
      digitalWrite (7, HIGH);           // schalte piazza und Schlafraum und Sub aus
      digitalWrite (8, HIGH);
      digitalWrite (2, LOW);            // schalte Dampfkabine Boxen an
      }      

      if (results.value == 1082099831)  //  Subwoover aus!
      {
      digitalWrite (7, HIGH);      // schalte Sub aus
      digitalWrite (8, LOW);
      digitalWrite (2, LOW);      // andere Boxen bleiben an
      }      
    
      if (results.value == 1082101871)  //  Musik +   4294967295   
      {
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(21);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(21);
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(24);
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(21);
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(200);

      }      
    
      if (results.value == 1082067191)  //  Musik -
      {
      IrSender.sendSony(0x50, 0x13, 8, 15);
      delay(100);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
      IrSender.sendSony(0x50, 0x13, 8, 15);
      delay(100);
      IrSender.sendSony(0x50, 0x13, 8, 15);
      delay(100);
      }      

      if (results.value == 1082107991)  //  bluetooth / Klingel umstellen
      {
      IrSender.sendSony(0xD0, 0x69, 8, 15);
      delay(100);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
      }      
   
      // Regelung Warmwasser


//auf kalt stellen

      if (results.value == 1082069231)  // stelle Wassertemperatur auf kalt 
      {     
      digitalWrite (5, HIGH);       // Schalte Relais "heisser" ab
      digitalWrite (4, LOW);        // Schalte Relais "kälter" an    
      startzeitkalt = millis();        // starte Zeit um Relais "kälter" wieder abzustellen
      }  


        
//auf heiss stellen

      if (results.value == 1082093711)  // stelle Wassertemperatur auf warm
      {
      digitalWrite (4, HIGH);      // schalte Relais "kälter" ab
      digitalWrite (5, LOW);       // Schalte Relais "heisser" an
      startzeitwarm = millis();    // starte Zeit um Relais "heisser" wieder abzustellen
      }      


      if (results.value == 1082077391)  // stoppe Temperatur wo sie ist!//Beide Relais "heisser & kälter " abstellen Funktion ist sinnlos :-)
      {
      digitalWrite (4, HIGH);      // 
      digitalWrite (5, HIGH);       // setzte beide Relais auf OFF
      }          
    
      Serial.print(results.value );   // schreibe Werte der Fernbedienung in den Serial Monitor   
      Serial.print(" ");
    
      irrecv.resume();                // Warte auf nächsten Wert
 } 

 
  if (millis() - startzeitwarm > 8000)  //  Wenn Zeit um schalte Relais "heisser" wieder aus   
   {digitalWrite(5, HIGH);}

  if (millis() - startzeitkalt > 8000)  //  Wenn Zeit um schalte Relais "kälter" wieder aus  1082089631 
  {digitalWrite(4, HIGH);}

//
//  if (millis() - wartezeit1h > 5000) // Wartezeit ist um Lüftungszeit beginnt Variable Wartezeit zurücksetzen
//    {
//     digitalWrite(12, LOW); 
//      nachtluft = millis();
//      wartezeit1h == stop;
//    }
//
//  if (millis() - nachtluft > 5000) // Wenn der Lüfters  dann gelüftet hat soll er wieder abstellen und die Lüftungszeit zurücksetzen.
//    {
//     digitalWrite(12, HIGH);
//     wartezeit1h == stop;
//     nachtluft == 0;
//     }


  
  if (millis() - startzeitluft > 3600000)  //  Wenn Zeit um mache Lüfter wieder aus   
  {digitalWrite(12, HIGH);}


}

Ich habe dies ebenfalls mit einem dritten Timer versucht siehe unten in den kommentierten Zeilen.

Die von euch gepostete Lösung ist sicher super. Leider verstehe ich davon NOCH nix....
Am liebsten wäre mir eine Lösung wie angedacht. Ich müsste einfach meinen dritten Timer dazu bringen nur einmal den Lüfter auf High zu stellen

OK...

#define DECODE_NEC            // DECODE_NEC
#include <IRremote.hpp>       // Do not change header order.

class FanTimer {
  public:
    void start() {
      timeStamp = millis();
    }
    bool operator()(const unsigned long duration) {
      return (millis() - timeStamp >= duration) ? true : false;
    }

  private:
    unsigned long timeStamp{0};
};

FanTimer fanTimerS1;
FanTimer fanTimerS3On;
FanTimer fanTimerS3Off;

constexpr uint32_t S1_ACTIVE_DURATION_MS {5000};  // 5 Sekunden
constexpr uint32_t S3_START_DURATION_MS {5000};  // 5 Sekunden
constexpr uint32_t S3_ACTIVE_DURATION_MS {5000};  // 5 Sekunden
constexpr uint8_t RECV_PIN {2};
constexpr uint8_t FAN_PORT {12};

enum class Fan : uint8_t {OFF, WAIT_S1_OFF, WAIT_S3_ON, WAIT_S3_OFF} state;

//const uint32_t s1 = 1082110031;
const uint16_t s1 = 0x30;  // Taste 1
const uint16_t s2 = 0x18;  // Taste 2
const uint16_t s3 = 0x7A;  // Taste 3

void setup()
{
  Serial.begin(9600);

  pinMode (FAN_PORT, OUTPUT);    // Lüfter

  digitalWrite (FAN_PORT, LOW);

  IrReceiver.begin(RECV_PIN);
  Serial.print(F("Ready to receive IR signals at pin "));
  Serial.println(RECV_PIN);
}

void loop()
{
  static uint16_t irSwitch;

  irSwitch = irReceive();
  switch (irSwitch) {
    case s1:
      if (state == Fan::OFF) {
        digitalWrite (FAN_PORT, HIGH);
        Serial.println(F("Taste 1: gestartet. Warte auf Ablauf"));
        state = Fan::WAIT_S1_OFF;
        fanTimerS1.start();
      }
      break;
    case s2:
      if (state != Fan::OFF) {
        state = Fan::OFF;
        digitalWrite (FAN_PORT, LOW);
        Serial.println(F("Taste 2: Vorgang abgebrochen"));
      }
      break;
    case s3:
      if (state == Fan::OFF) {
        state = Fan::WAIT_S3_ON;
        Serial.println(F("Taste 3: Anlaufzeit gestartet"));
        fanTimerS3On.start();
      }
      break;
  }

  switch (state) {
    case Fan::WAIT_S3_ON:
      if (fanTimerS3On(S3_START_DURATION_MS)) {
        digitalWrite (FAN_PORT, HIGH);
        state = Fan::WAIT_S3_OFF;
        Serial.println(F("Taste 3: Warte auf Ablauf"));
        fanTimerS3Off.start();
      }
      break;
    case Fan::WAIT_S3_OFF:
      if (fanTimerS3Off(S3_ACTIVE_DURATION_MS)) {
        digitalWrite (FAN_PORT, LOW);
        state = Fan::OFF;
        Serial.println(F("Taste 3: Vorgang beendet"));
      }
      break;
    case Fan::WAIT_S1_OFF:
      if (fanTimerS1(S1_ACTIVE_DURATION_MS)) {
        digitalWrite (FAN_PORT, LOW);
        state = Fan::OFF;
        Serial.println(F("Taste 1: Vorgang beendet"));
      }
      break;
  }
}

uint16_t irReceive() {
  uint16_t received{0};

  if (IrReceiver.decode()) {
    //IrReceiver.printIRResultShort(&Serial);
    if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
      // We have an unknown protocol here, print more info
      IrReceiver.printIRResultRawFormatted(&Serial, true);
    }
    if (IrReceiver.decodedIRData.protocol == NEC) {
      received = IrReceiver.decodedIRData.command;
      //Serial.print("Command: 0x");
      //Serial.println(received, HEX);
    }
    IrReceiver.resume();
  }
  return received;
}

Man muss hier aber berücksichtigen, dass der Simulator nur NEC-Codiert kann und IRremote in der aktuellen Version verwendet wird. Darum sind die Tastencodes anders.

Super gemacht und zum Lernen super kommentiert :+1:

1 Like

Danke für die Blumen :slight_smile:

Ich würde zu viel Zeit brauchen Deinen Code zu verstehen und das was Du möchtest, da rein zu frickeln....

Ich habe versucht ein Beispiel zu liefern wie man das machen kann. Den Rest musst Du machen.
Aber vielleicht ist da ja jemand anderes ambitioniert....

Du kannst das ja am Simulator oder mit einem anderen Controller parallel neu aufbauen ...

Habe vielen herzlichen Dank ich werde mich da reindenken!

Schaue dir mal diese Code-Version an:
Kommt dir die irgendwie bekannt vor?

Die hat fast keine Kommentare aber - oh wunder - man versteht sie direkt beim runterlesen!

#include <Arduino.h>
#include <IRremote.h>
uint32_t startzeitluft;
uint32_t startzeitwarm;
uint32_t startzeitkalt;
uint32_t wartezeit1h;
uint32_t nachtluft;

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

const unsigned long ir_Musik_alle_an  = 1082097791;
const unsigned long ir_Musikalle_aus  = 1082081471;
const unsigned long ir_Musik_ohne_Sub = 1082099831;
// const unsigned long ir_ = 1082091671;
// const unsigned long ir_ = 1082085551;
const unsigned long ir_Musik_nur_im_Dampf = 1082083511;
const unsigned long ir_Musik_leiser = 1082067191;
const unsigned long ir_Musik_lauter = 1082101871;
const unsigned long ir_Luefter_Piazza_an = 1082089631;
const unsigned long ir_Luefter_Dampf_an  = 1082110031;
const unsigned long ir_Luefter_Dampf_aus = 1082075351;
const unsigned long ir_Umstellen_bluetooth_Klingelbrett = 1082107991;
const unsigned long ir_Luefter_Start_1h_Dauer_1h = 1082122271;
const unsigned long ir_Relais_Wasser_heisser = 1082093711;
const unsigned long ir_Relais_Wasser_kaelter = 1082069231;
const unsigned long ir_Stop_Temperatur_Mischmotor = 1082077391;
const unsigned long ir_Luefter_Piazza_ab = 1082103911;

const byte Luefter_Pin     = 13;
const byte Luefter_Pin2    = 12;
const byte Dampfboxen_Pin  =  8;
const byte Piazza_Pin      =  7;
const byte Subwoover_Pin   =  2;

const byte Wasser_waermer_Pin = 4;
const byte Wasser_kaelter_Pin = 5;

const byte EIN = LOW;
const byte AUS = HIGH;

void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  pinMode (Luefter_Pin,    OUTPUT);
  pinMode (Luefter_Pin2,   OUTPUT);
  pinMode (Dampfboxen_Pin, OUTPUT);
  pinMode (Piazza_Pin,     OUTPUT);
  pinMode (Subwoover_Pin,  OUTPUT);
  pinMode (Wasser_waermer_Pin, OUTPUT);
  pinMode (Wasser_kaelter_Pin, OUTPUT);
  irrecv.enableIRIn();
  IrSender.enableIROut(38);
  IrSender.begin(3); // Start with IR_SEND_PIN as send pin and if NO_LED_FEEDBACK_CODE is NOT defined, enable feedback LED at default feedback LED pin
  // ir empfänger = 11 // wird oben bei ir receiv pin definiert

  digitalWrite (Luefter_Pin2, AUS);
  digitalWrite(Wasser_kaelter_Pin, AUS);
  digitalWrite(Wasser_waermer_Pin, AUS);
}

void loop() {

  if (irrecv.decode(&results)) {
    if (results.value == ir_Luefter_Piazza_an) {
      digitalWrite (Luefter_Pin, EIN);
    }

    if (results.value == ir_Luefter_Piazza_ab)  {
      digitalWrite (Luefter_Pin, AUS);
    }

    if (results.value == ir_Luefter_Dampf_an)   {
      digitalWrite (Luefter_Pin2, EIN);
      startzeitluft = millis();         // starte Zeit um Lüfter danach wieder abzustellen
    }

    if (results.value == ir_Luefter_Dampf_aus) {
      digitalWrite (Luefter_Pin2, AUS);
    }
    /* Block-Kommentar ANFANG
          if (results.value == ir_Luefter_Start_1h_Dauer_1h)  {
            wartezeit1h = millis();
          }
    */ //Block-Kommentar ENDE

    //Regelung Sound
    if (results.value == ir_Musik_alle_an)   {
      digitalWrite (Piazza_Pin, EIN);            // schalte kleine Boxen an
      digitalWrite (Dampfboxen_Pin, EIN);
      digitalWrite (Subwoover_Pin, EIN);
    }

    if (results.value == ir_Musikalle_aus) {
      digitalWrite (Piazza_Pin, AUS);
      digitalWrite (Dampfboxen_Pin, AUS);
      digitalWrite (Subwoover_Pin, AUS);
    }

    if (results.value == ir_Musik_nur_im_Dampf)  {
      digitalWrite (Piazza_Pin, AUS);
      digitalWrite (Dampfboxen_Pin, AUS);
      digitalWrite (Subwoover_Pin, EIN);
    }

    if (results.value == ir_Musik_ohne_Sub) {
      digitalWrite (Piazza_Pin, AUS);
      digitalWrite (Dampfboxen_Pin, EIN);
      digitalWrite (Subwoover_Pin, EIN);
    }

    if (results.value == ir_Musik_lauter)  {
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(21);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(21);
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(24);
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(21);
      IrSender.sendSony(0x50, 0x12, 0, 15);
      delay(200);
    }

    if (results.value == ir_Musik_leiser) {
      IrSender.sendSony(0x50, 0x13, 8, 15);
      delay(100);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
      IrSender.sendSony(0x50, 0x13, 8, 15);
      delay(100);
      IrSender.sendSony(0x50, 0x13, 8, 15);
      delay(100);
    }

    if (results.value == ir_Umstellen_bluetooth_Klingelbrett) {
      IrSender.sendSony(0xD0, 0x69, 8, 15);
      delay(100);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
    }

    // Regelung Warmwasser
    if (results.value == ir_Relais_Wasser_kaelter)  {
      digitalWrite (Wasser_kaelter_Pin, AUS);
      digitalWrite (Wasser_waermer_Pin, EIN);
      startzeitkalt = millis();        // starte Zeit um Relais "kälter" wieder abzustellen
    }

    if (results.value == ir_Relais_Wasser_heisser) {
      digitalWrite (Wasser_waermer_Pin, AUS);
      digitalWrite (Wasser_kaelter_Pin, EIN);
      startzeitwarm = millis();    // starte Zeit um Relais "heisser" wieder abzustellen
    }

    if (results.value == ir_Stop_Temperatur_Mischmotor)   {
      digitalWrite (Wasser_waermer_Pin, AUS);
      digitalWrite (Wasser_kaelter_Pin, AUS);
    }

    Serial.print(results.value );   // schreibe Werte der Fernbedienung in den Serial Monitor
    Serial.print(" ");

    irrecv.resume();                // Warte auf nächsten Wert
  }

  if (millis() - startzeitwarm > 8000)  //  Wenn Zeit um schalte Relais "heisser" wieder aus
  {
    digitalWrite(Wasser_kaelter_Pin, AUS);
  }

  if (millis() - startzeitkalt > 8000)  //  Wenn Zeit um schalte Relais "kälter" wieder aus  1082089631
  {
    digitalWrite(Wasser_waermer_Pin, AUS);
  }

  /* Block-Kommentar ANFANG
      if (millis() - wartezeit1h > 5000) // Wartezeit ist um Lüftungszeit beginnt Variable Wartezeit zurücksetzen
        {
         digitalWriteLuefter_Pin2, EIN);
          nachtluft = millis();
          wartezeit1h == stop;
        }

      if (millis() - nachtluft > 5000) // Wenn der Lüfters  dann gelüftet hat soll er wieder abstellen und die Lüftungszeit zurücksetzen.
        {
         digitalWriteLuefter_Pin2, AUS);
         wartezeit1h == stop;
         nachtluft == 0;
         }
  */ // Block-Kommentar ENDE

  if (millis() - startzeitluft > 3600000)  //  Wenn Zeit um mache Lüfter wieder aus
  {
    digitalWrite (Luefter_Pin2, AUS);
  }
}

Durch die Klartextnamen fällt auf
du hast ganz oben in setup IO-pin 2 als Subwoofer kommentiert

pinMode (2,OUTPUT);       //Subwoover         

weiter unten im Code passen die Kommentare dann nicht überall
Das ist das Problem mit den Kommentaren. Die werden auf Dauer nicht mit gepflegt
und dann passen Sie nicht mehr. Und der compiler meckert nicht.

Wenn irgendwo ein Variablenname nicht stimmt meckert der Compiler sofort.

vgs

Ah soooo macht man das!
Herzlichen Dank für eure grosse Arbeit.
Viel gelernt, viele Hausaufgaben bekommen :slight_smile:
lieber Gruss

Hallo @papazonk

also die Kommentare die du zu den IO-pins in void setup() bei den pinMode()-aufrufen stehen hast passen an vielen Stellen nicht zu dem wie du die dann später kommentiert hast
wasser kaelter ist weiter unten wasser wärmer usw.

Kannst du mal eine aktuelle Liste posten welcher physischen IO-pin-nummern schaltet jetzt in der Realität was

Du schaltest in verschiedenen Kombinationen Lautsprecher an/aus
Musik lauter / leiser

Du schaltest Zeitgesteuert eine Warmwasserheizung ein/aus
Du schaltest Zeitgesteuert eine Wasserkühlung ein/aus

Du schaltest bei einem Signal das sich "Stop_Temperatur_Mischmotor" nennt
deine Wasserheizung und die Wasserkühlung aus
Was steckt denn da in der Wirklichkeit dahinter? Wie macht das Sinn?
Ist das Wasser wärmer/kälter ein motorgesteuertes Dreiwegeventil das du auf/zu fährst?

Es mag ja schon sein dass es da ein Relais gibt das, wenn es geschaltet wird "Wasser wärmer"
und
ein zweites Relais gibt das, wenn es geschaltet wird "Wasser kälter"
macht.
Für Aussenstehende wäre das viel leichter nachvollziehbar wenn die Variablennamen das auch direkt sagen würden.

const byte Mischer_Motor_heisser_Pin
const byte Mischer_Motor_kaelter_Pin

Du schaltest zwei Lüfter ein/aus

Diese Schaltvorgänge sind unabhängig von den Lüftern

const byte Luefter_Pin2    = 12;

IO-pin 12 scheint der zu sein den du mit Verzögerung einschalten willst.

Also programmiert man dafür eine eigene function um den Code besser zu strukturieren.
Diese function hat dann die drei Betriebsmodi "OFF", "On", und "WAIT"

Über ein switch-case-break erreicht man, dass entweder nur der
im Betriebsmodus "OFF" nur der Code für "OFF"ausgeführt wird
oder
im Betriebsmodus "On" nur der Code für "On"ausgeführt wird
oder
im Betriebsmodus "WAIT" nur der Code für "WAIT"ausgeführt wird

das sind die drei Betriebsmodi oder man könnte auch sagen Betriebszustände

Zustand in diesem Sinne wird im englischen "state" genannt. Und so ein Programm
in dem das switch-case-break dazu dient verschiedene Betriebszustände zu realisieren
wird state-machine genannt.

Die function für Lüfter "Dampf" (wat is'n det? en Dampfbad? oder een Vaporisateur?)
wird also eine switch-case-break state-machine
so etwas in der Art

#include <Arduino.h>
#include <IRremote.h>
int RECV_PIN = 11;


IRrecv irrecv(RECV_PIN);
decode_results results;

const uint8_t led = 12;

const uint32_t s1_On   = 1082110031;
const uint32_t s2_OFF  = 1082075351;
const uint32_t s3_WAIT = 1082122271;

const byte sm_On   = 1;
const byte sm_OFF  = 2;
const byte sm_WAIT = 3;

byte betriebsModus = sm_OFF;

unsigned long ausschaltTimer = 0;
unsigned long luefterLaufZeit = 5 * 60 * 1000;;

unsigned long verzoegerungsTimer = 0;
unsigned long verzoegerungsZeit = 60 * 60 * 1000;


void setup() {
  Serial.begin(115200); // baudrate auf moderne 115200 umstellen!
  Serial.println("Setup-Start");
  pinMode (led, OUTPUT);    // Lüfter
  irrecv.enableIRIn();
}

void loop() {
  irrecv.decode(&results);
  myLuefterStateMachine();
  irrecv.resume();                // Warte auf nächsten Wert
}


void myLuefterStateMachine() {
  
  if (results.value == s1_On) {
    verzoegerungsTimer = 0;    // Verzögerung DE-aktivieren
    ausschaltTimer = millis(); // Startzeit des Einschaltens speichern
    betriebsModus = sm_On;
  }

  if (results.value == s2_OFF) {
    ausschaltTimer = 0;        // Aus-Schalt-Timer  DE-aktivieren
    verzoegerungsTimer = 0;    // Verzögerung-Timer DE-aktivieren
    betriebsModus = sm_OFF;
    digitalWrite(led, LOW);
  }

  if (results.value == sm_WAIT) {
    ausschaltTimer = 0;          // Aus-Schalt-Timer DE-aktivieren
    verzoegerungsTimer = millis(); // Startzeit des verzögerten Einschaltens speichern
    betriebsModus = sm_WAIT;
  }

  switch (betriebsModus) {
    case sm_On:
      digitalWrite(led, HIGH);
      if ( TimePeriodIsOver(ausschaltTimer, luefterLaufZeit) ) {
        ausschaltTimer = 0;
        betriebsModus = sm_OFF;
      }
      break; // springe SOFORT zu END-OF-SWITCH

    case sm_OFF:
      digitalWrite(led, LOW);
      break; // springe SOFORT zu END-OF-SWITCH

    case sm_WAIT:
      if ( TimePeriodIsOver(verzoegerungsTimer, verzoegerungsZeit) ) {
        ausschaltTimer = 0;        // Aus-Schalt-Timer  DE-aktivieren
        verzoegerungsTimer = 0;    // Verzögerung-Timer DE-aktivieren
        betriebsModus = sm_OFF;
      }
      break; // springe SOFORT zu END-OF-SWITCH
  } // END-OF-SWITCH
}


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

vgs

Genau das ist ein Motor am Mischventil.
Ist halt alles aus der Tonne zusammengebastelt. Aber funktioniert.

Die Musik sind zum einen Relais die die Boxenkabel unterbrechen, zum anderen versuche ich den Verstärker mit IR im Technikraum zu steuern.

Es ist genau wie du sagst: die Kommentare wurden nicht mitgepflegt.
Werde mich da jetzt reinarbeiten und das ganze aufräumen.

Mein Sohn (8) hat mir schlussendlich geholfen und folgendes gebastelt. Es macht genau das selbe und ist für mich verständlich.

#include <Arduino.h>
#include <IRremote.h>


uint32_t startzeitluefter;             // Timer zum Ausschalten des Lüfters
uint32_t wartezeit;                   // Timer für die Verzögerung

int verzogerung = 0;                  // zusätzliche Variable für die Verzögerung

const uint8_t led = 12;

const uint32_t s1 = 1082110031;       //Schalte Lüftung ein
const uint32_t s2 = 1082075351;       //Schalte Lüftung aus
const uint32_t s3 = 1082122271;       //Schalte Lüftung Verzögert ein


int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);

decode_results results;




void setup()

{
Serial.begin(9600);
pinMode (led, OUTPUT);    // Lüfter oder eben zum testen eine LED
      
irrecv.enableIRIn();


digitalWrite (led, LOW);


}

void loop()
{
  
    if (irrecv.decode(&results))
    {
     
      if (results.value == s1)  // Regelung Lüfter Dampf
      {
      digitalWrite (led, HIGH);           // mache Lüfter an
      startzeitluefter = millis();       // starte Zeit um Lüfter danach wieder abzustellen
      verzogerung = 1;                  // stelle Variable Verzögerung auf 1 damit ist die zweite Voraussetzung für die IF Abfrage gegeben
      }                                   
     
      if (results.value == s2)          // mache Lüfter Dampf aus
      {digitalWrite (led, LOW);
      verzogerung = 2;                 // stelle Variable Verzögerung auf 2 damit ist die zweite Voraussetzung für die IF Abfrage NICHT mehr gegeben
      }       

           
      if (results.value == s3)          //Schalte Lüftung Verzögert ein
      { 
          digitalWrite (led,LOW);        // Schalte Lüftung erstmal aus
          wartezeit = millis();         // Schalte Timer für die Verzögerung an

      }        
   
      Serial.print(results.value );   // schreibe Werte der Fernbedienung in den Serial Monitor   
      Serial.print(" ");
    
      irrecv.resume();                // Warte auf nächsten Wert
 } 

 


  if (millis() - wartezeit == 5000)        // prüfe ob Zeit schon abgelaufen
    {
     if (verzogerung == 1)                  // prüfe ob die Variable im Richtigen Zustand ist
     {digitalWrite(led, HIGH);             // Schalte Lüfter / Led ein
     startzeitluefter == millis();          // starte Zeit um Lüfter danach wieder abzustellen
    }
    }


   
  if (millis() - startzeitluefter > 10000)  //  Wenn Zeit um mache Lüfter wieder aus   
  {
    digitalWrite(led, LOW);
    verzogerung == 2;                   // setze Variable für die Verzögerung auf 2, so dass nicht erneut ausgelöst wird

  }


}

Um den Lüfter mit Zeitverzögerung einzuschalten muss man zuerst s1 und danach s2 drücken.

Vielen lieben Dank Stefan!
Mit deinen tollen Erklärungen kriege ich das nun hin.