Bibliothek für Ein-/Ausschaltverzögerung gesucht

MobaTools.h funktionieren leider nicht auf meinem ESP32.
Kennt ihr Alternativen?

Hier gibt’s doch viele Beispiele für Verzögerung

Was ist Deine Itention?

Ich muss ein paar Verzögerungen im Setzen einer bool-Variablen im Code einbauen, will aber nicht die Übersicht verlieren.

Schrittkette ist keine Option?

Hallo,
ich hab da mal was gemacht , nutze ich schon mal für sowas. Schau dir das mal an.

keywords.txt (86 Bytes)
timer.cpp (1.3 KB)
timer.h (819 Bytes)
testtimer.ino (743 Bytes)

alle Dateien in ein Verzeichniss Timer und das dann den in Adruino/ Lib. Ordner Der Skech testtimer ist ein Beispiel.

/*
 * Beispiel zu Timer Lib
*/
#include "timer.h"

Timer timer1;// Instanzen von Timer ertellen
Timer timer2;
const byte led = 13;
const byte btn = 3;// Taster
bool bn;// Hilfsflag für Taster

void setup() {
  // put your setup code here, to run once:
  pinMode (led, OUTPUT);
  pinMode(btn, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  bn = !digitalRead(btn);// Taster lesen

  //  digitalWrite(led, timer1.pulsOn(bn, 3000));
  // digitalWrite(led, timer1.delayOn(bn, 4000));
  // digitalWrite(led,timer1.delayOff(bn,2000));
  digitalWrite(led, timer1.blink(true, 1000));

// Zyklischer Aufruf
  if (timer2.cycle(true, 2000)) {
    Serial.print("Cycle abgelaufen:"); Serial.println(millis());
  }
}

Heinz

Kann ich 4 Timer erstellen?

Könntest Du mir bitte ein Beispiel geben, das würde ich gerne gegentesten. Sollte es reproduzierbar sein, werde ich mich vertrauensvoll an den Autor wenden.

Ich hatte das hier auf dem ESP8266nodemcu getestet: Funktioniert.

Dann auf meinem Lilygo T5 ESP32: Dann meckert er über Einträge in der Lib.

#include <MobaTools.h>
int sensor = 4;
int relais = 5;

MoToTimer verzoegerungAn;
MoToTimer verzoegerungAus;
bool sensorState;           // zur Flankenerkennung

void setup() {

  pinMode (sensor, INPUT_PULLUP);
  pinMode (relais, OUTPUT);

  digitalWrite(relais, HIGH);

}

void loop() {
  delay(20);  // nur zur Entprellung, kann bei prellfreiem Sensorsignal entfallen
  if ( !digitalRead(sensor) && !sensorState ) {
    sensorState = true;
    // Einschaltverzögerung starten
    verzoegerungAn.setTime( 3000 );
  }

  if (digitalRead(sensor) && sensorState) {
    //Ausschaltverzögerung
    sensorState = false;
    verzoegerungAus.setTime( 5000 );
  }

  if ( verzoegerungAn.expired() ) {
    //Einschaltverzoegerung abgelaufen
    digitalWrite(relais, LOW);
  }

  if ( verzoegerungAus.expired() ) {
    //Ausschaltverzoegerung abgelaufen
    digitalWrite(relais, HIGH);
  }

}

Schon wenn ich nur

#include <MobaTools.h>
MoToTimer verzoegerungAn;
MoToTimer verzoegerungAus;

einfüge, meckert der Compiler mit mir.

In file included from /home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_reg.h:20,
                 from /home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:29:
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c: In function 'spiStartBusMoTo':
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:333:57: error: 'DPORT_SPI_CLK_EN' undeclared (first use in this function); did you mean 'DPORT_SPI3_CLK_EN'?
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN);
                                                         ^~~~~~~~~~~~~~~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:154:88: note: in definition of macro '_DPORT_WRITE_PERI_REG'
 #define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
                                                                                        ^~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:183:46: note: in expansion of macro 'DPORT_WRITE_PERI_REG'
 #define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
                                              ^~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:333:9: note: in expansion of macro 'DPORT_SET_PERI_REG_MASK'
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN);
         ^~~~~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:333:57: note: each undeclared identifier is reported only once for each function it appears in
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN);
                                                         ^~~~~~~~~~~~~~~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:154:88: note: in definition of macro '_DPORT_WRITE_PERI_REG'
 #define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
                                                                                        ^~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:183:46: note: in expansion of macro 'DPORT_WRITE_PERI_REG'
 #define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
                                              ^~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:333:9: note: in expansion of macro 'DPORT_SET_PERI_REG_MASK'
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN);
         ^~~~~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:334:59: error: 'DPORT_SPI_RST' undeclared (first use in this function); did you mean 'DPORT_SPI2_RST'?
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST);
                                                           ^~~~~~~~~~~~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:154:88: note: in definition of macro '_DPORT_WRITE_PERI_REG'
 #define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
                                                                                        ^~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:180:46: note: in expansion of macro 'DPORT_WRITE_PERI_REG'
 #define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
                                              ^~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:334:9: note: in expansion of macro 'DPORT_CLEAR_PERI_REG_MASK'
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST);
         ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:336:57: error: 'DPORT_SPI_CLK_EN_2' undeclared (first use in this function); did you mean 'DPORT_SPI3_CLK_EN'?
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_2);
                                                         ^~~~~~~~~~~~~~~~~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:154:88: note: in definition of macro '_DPORT_WRITE_PERI_REG'
 #define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
                                                                                        ^~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:183:46: note: in expansion of macro 'DPORT_WRITE_PERI_REG'
 #define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
                                              ^~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:336:9: note: in expansion of macro 'DPORT_SET_PERI_REG_MASK'
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_2);
         ^~~~~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:337:59: error: 'DPORT_SPI_RST_2' undeclared (first use in this function); did you mean 'DPORT_SPI2_RST'?
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_2);
                                                           ^~~~~~~~~~~~~~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:154:88: note: in definition of macro '_DPORT_WRITE_PERI_REG'
 #define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
                                                                                        ^~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:180:46: note: in expansion of macro 'DPORT_WRITE_PERI_REG'
 #define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
                                              ^~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:337:9: note: in expansion of macro 'DPORT_CLEAR_PERI_REG_MASK'
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_2);
         ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:339:57: error: 'DPORT_SPI_CLK_EN_1' undeclared (first use in this function); did you mean 'DPORT_SPI3_CLK_EN'?
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_1);
                                                         ^~~~~~~~~~~~~~~~~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:154:88: note: in definition of macro '_DPORT_WRITE_PERI_REG'
 #define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
                                                                                        ^~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:183:46: note: in expansion of macro 'DPORT_WRITE_PERI_REG'
 #define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
                                              ^~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:339:9: note: in expansion of macro 'DPORT_SET_PERI_REG_MASK'
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_1);
         ^~~~~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:340:59: error: 'DPORT_SPI_RST_1' undeclared (first use in this function); did you mean 'DPORT_SPI2_RST'?
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_1);
                                                           ^~~~~~~~~~~~~~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:154:88: note: in definition of macro '_DPORT_WRITE_PERI_REG'
 #define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
                                                                                        ^~~
/home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/tools/sdk/esp32/include/soc/esp32/include/soc/dport_access.h:180:46: note: in expansion of macro 'DPORT_WRITE_PERI_REG'
 #define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
                                              ^~~~~~~~~~~~~~~~~~~~
/home/Carsten/Arduino/libraries/MobaTools-master/src/esp32/esp32-mt-spi.c:340:9: note: in expansion of macro 'DPORT_CLEAR_PERI_REG_MASK'
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_1);
         ^~~~~~~~~~~~~~~~~~~~~~~~~
Mehrere Bibliotheken wurden für "SD.h" gefunden
 Benutzt: /home/Carsten/.arduino15/packages/esp32/hardware/esp32/2.0.6/libraries/SD
 Nicht benutzt: /home/Carsten/Dokumente/arduino-1.8.19/libraries/SD
exit status 1
Fehler beim Kompilieren für das Board ESP32 Dev Module.

wie oft genau. Sprich wie viele Sensoren/Ausgänge?
wenn >= 2 dann würde ich da aber gleich eine schöne Klasse machen mit Sensor-Pin und Ausgangs-Pin und der Klasse das Zeitmanagement zu überlassen.

Bisher 8. Warscheinlich so im Bereich 20 bis 90 Sekunden.

... ich probier mal.

Lies mal nur die zwei Teile der "Ausschaltverzögerung".
Bis du das alles ausprobiert hast - sollte ein Ein/Aus auch fertig sein.

https://werner.rothschopf.net/202003_arduino_retriggerbares_nachlaufrelais.htm

und dann

https://werner.rothschopf.net/202003_arduino_retriggerbares_nachlaufrelais_oop.htm

Win10, IDE 1.8.19, ESP32-Core 2.0.6, aber Board "ESP32 Dev Module":

Der Sketch verwendet 235429 Bytes (17%) des Programmspeicherplatzes. Das Maximum sind 1310720 Bytes.
Globale Variablen verwenden 21824 Bytes (6%) des dynamischen Speichers, 305856 Bytes für lokale Variablen verbleiben. Das Maximum sind 327680 Bytes.

Welches Board hast Du ausgewählt und könntest Du umsteigen?

Den Ansatz von @noiasca finde ich besser, ich frage im Interesse der MobaTools :slightly_smiling_face:

Oha, harter Toback! Da blicke ich noch nicht so recht durch. Ich brauche was einfaches.

Ich habe "ESP32 Dev Module" gewählt. Ich weiss nicht ob ich mit dem Lilygo T5 auch anderes wählen könnte. Einen anderen ESP32 habe ich nicht. Nur den M5Stack.

Wo ist dann die Abweichung zu meiner Einstellung?

MobaTools Version 2.4.3

Ach soooo, du hast deine Einstellung gepostet! Kleines Missverständniss!

Ich nutze auch MobaTools 2.4.3, allerdings unter Linux mx.

fang noch mal mit Teil 1 an.
Gib bescheid wo genau du aussteigst.

Eine einfache Ein/Ausschaltverzögerung hat 4 Status:

enum State {
  OFF,           // Sensor aus/Ausgang aus
  ON_DELAY,      // Sensor hat ausgelöst wir warten ab
  ON,            // es ist eingeschaltet
  OFF_DELAY      // Sensor hat unterschritten, wir warten noch ab 
} state;

In jedem Status passiert halt entweder die Abfrage auf den Sensor oder eine Zeitabfrage.
Das ist nur in diesem Beispiel so. Natürlich kann man die Aktionen auch kombinieren.
Oder z.B. auf einen "Notaus" reagieren und sofort abschalten.

Das ist die Systematik einer "Finite State Machine" wie bereits angesprochen. daher der switch/case.

Der Rest ist "Blink Without Delay".

Jede weitere Sensor/Ausgang kombination ist EINE EINZIGE ZEILE - du musst nur das Array erweitern.
Daher als Klasse mit mehreren Objekten.

zum Spielen:

Das Anwenden der millis ist mir einigermassen geläufig. Nutze ich auch aktuell um einen Impuls auszugeben.

if (ImpulsStateOan == HIGH) 
  {
    triggerOan = true;
    previousMillis = millis();
    mcp.digitalWrite(8, HIGH);        // Ausgang AN schalten
    ImpulsStateOan = LOW;
  }
  if (triggerOan && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(8, LOW);        // Ausgang AUS schalten
    triggerOan = false;
    AnzeigeSprengerOstAn = true;      // Symbol Sprenger für Anzeige freigeben
    AnzeigeSprengerOstAus = false;
    Anzeige = true;                   // Anzeige freischalten
  }

Eigentlich hakt es an der Integration in meinen bestehenden Code. Bisherige Versuche ergaben einen Wirrwar welcher auch nur halb funktionierte.

Bei Kapitel " Viele Buttons - viele LEDs: Der einfache Umgang mit Arrays" wird es schwierig...

Meinen ganzen Code zu posten wird zu unübersichtlich. Ich versuche mal mein Problem zu erklären:

Ich habe zwecks langsamen EPaper die Anzeigen der Display-Änderungen im Unterprogramm ausgelagert. Wird erst aufgerufen wenn restlicher Code durch ist.

Auch die Ausgabe der Impulse habe ich so ausgelagert, damit sie nicht zeitlich beeinflusst werden. Aufruf durch Änderung einer Variablen. Das funktioniert auch recht gut.

Jetzt kommt es aber vor daß ich die Ausgabe der Impulse auch mal z.B. um 40s verzögern muss. Oder anders gesagt: Die Änderung der Variablen zeitlich verzögern muss.

Aus dem Keypad wird der Impuls mit "ImpulsStateOan = HIGH;" quasi "freigegeben".

void ReadKeypad()
{
  // Get the currently touched pads
  currtouched = cap.touched();
  
  for (uint8_t i=0; i<12; i++) 
  {
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) 
    {
      Serial.print(i); Serial.println(" released");         // Taste gelöst
      // Taste 0 *******************************************************************************************************
      if (i == 0) 
      {
        StateTasteSprO = !StateTasteSprO;
        if (StateTasteSprO == LOW) //AUS *************
        {
          //Sprenger ausschalten
          ImpulsStateOaus = HIGH;             //Impulsstatus Sprenger Ost soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
          if ((StateTasteSprS == LOW) && (StateTasteSprW == LOW) && (StateTasteSprN == LOW))         //Pumpe nur aus wenn Sprenger Süd, West & Nord aus sind
          {
            PumpeVerzAusStart = true;            //Variable um millis als Startzeit für Verzögerung zu speichern
            AktionPumpe = true;                 //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
            //mcp.digitalWrite(7, LOW);           //SSD Relais Pumpe AUS
          }
          StatePumpe = false;
        }
        else
        if (StateTasteSprO == HIGH) //AN *************
        {
          //Sprenger einschalten
          ImpulsStateOan = HIGH;              //Impulsstatus Sprenger Ost soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
          mcp.digitalWrite(7, HIGH);          //SSD Relais Pumpe AN
          StatePumpe = true;
        }
      }
      // Taste 1 *******************************************************************************************************
      if (i == 1) 
      {
        StateTasteSprS = !StateTasteSprS;
        if (StateTasteSprS == LOW) //AUS *************
        {
          //Sprenger ausschalten
          ImpulsStateSaus = HIGH;             //Impulsstatus Sprenger Süd soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
          mcp.digitalWrite(7, LOW);           //SSD Relais Pumpe AUS
          StatePumpe = false;
        }
        else
        if (StateTasteSprS == HIGH) //AN *************
        {
          //Sprenger einschalten
          ImpulsStateSan = HIGH;              //Impulsstatus Sprenger Süd soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
          mcp.digitalWrite(7, HIGH);          //SSD Relais Pumpe AN
          StatePumpe = true;
        }
      }
    }
  }
  // reset our state
  lasttouched = currtouched;
}

Hier der Loop:

void loop() 
{
  //Serial.print("Start: "); Serial.println(millis());
  ReadEmpfaenger();                                     // UP Empfänger auslesen
  //Serial.print("nach Empf.: "); Serial.println(millis());
  ReadKeypad();                                         // UP Touchpad auslesen
  //Serial.print("nach Keypad: "); Serial.println(millis());
  ImpulsMagnetventil();                                 // UP ms Impuls zum Umschalten an Magneten ausgeben
  //Serial.print("nach Impuls MV: "); Serial.println(millis());
  VerzoegerungPumpe();                                  // UP um Pumpe verzögert ein-/auszuschalten
  //Serial.print("nach verz.Pumpe: "); Serial.println(millis());
  AnzeigeEPaper();                                      //UP um erst nach Fertigstellung der Ausgänge Anzeige zu aktualisieren
  //Serial.print("nach Anzeige: "); Serial.println(millis());
  //Serial.println();
  if ( verzoegerungAus.expired() ) {
    //Ausschaltverzoegerung abgelaufen
    ImpulsStateOan = HIGH;              //Impulsstatus Sprenger Ost soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
  }
}

UP für Impuls:

void ImpulsMagnetventil()
{
  // Impuls für Sprenger Ost ***********************************************************
  // Impuls Pin An **************
  if (ImpulsStateOan == HIGH) 
  {
    triggerOan = true;
    previousMillis = millis();
    mcp.digitalWrite(8, HIGH);        // Ausgang AN schalten
    ImpulsStateOan = LOW;
  }
  if (triggerOan && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(8, LOW);        // Ausgang AUS schalten
    triggerOan = false;
    AnzeigeSprengerOstAn = true;      // Symbol Sprenger für Anzeige freigeben
    AnzeigeSprengerOstAus = false;
    Anzeige = true;                   // Anzeige freischalten
  }
  // Impuls Pin Aus **************
  if (ImpulsStateOaus == HIGH) 
  {
    triggerOaus = true;
    previousMillis = millis();
    mcp.digitalWrite(9, HIGH);        // Ausgang AN schalten
    ImpulsStateOaus = LOW;
  }
  if (triggerOaus && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(9, LOW);        // Ausgang AUS schalten
    triggerOaus = false;
    AnzeigeSprengerOstAus = true;     // Symbol Sprenger für Anzeige freigeben
    AnzeigeSprengerOstAn = false;
    Anzeige = true;                   // Anzeige freischalten
  }
  // Impuls für Sprenger Süd ***********************************************************
  // Impuls Pin An
  if (ImpulsStateSan == HIGH) 
  {
    triggerSan = true;
    previousMillis = millis();
    mcp.digitalWrite(10, HIGH);        // Ausgang AN schalten
    ImpulsStateSan = LOW;
  }
  if (triggerSan && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(10, LOW);        // Ausgang AUS schalten
    triggerSan = false;
    AnzeigeSprengerSuedAn = true;      // Symbol Sprenger für Anzeige freigeben
    AnzeigeSprengerSuedAus = false;
    Anzeige = true;                   // Anzeige freischalten
  }
  // Impuls Pin Aus **************
  if (ImpulsStateSaus == HIGH) 
  {
    triggerSaus = true;
    previousMillis = millis();
    mcp.digitalWrite(11, HIGH);        // Ausgang AN schalten
    ImpulsStateSaus = LOW;
  }
  if (triggerSaus && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(11, LOW);        // Ausgang AUS schalten
    triggerSaus = false;
    AnzeigeSprengerSuedAus = true;      // Symbol Sprenger für Anzeige freigeben
    AnzeigeSprengerSuedAn = false;
    Anzeige = true;                   // Anzeige freischalten
  }
  // Impuls für Sprenger West ***********************************************************
  // Impuls Pin An
  if (ImpulsStateWan == HIGH) 
  {
    triggerWan = true;
    previousMillis = millis();
    mcp.digitalWrite(12, LOW);        // Ausgang AN schalten
    ImpulsStateWan = LOW;
  }
  if (triggerWan && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(12, HIGH);        // Ausgang AUS schalten
    triggerWan = false;
  }
  // Impuls Pin Aus **************
  if (ImpulsStateWaus == HIGH) 
  {
    triggerWaus = true;
    previousMillis = millis();
    mcp.digitalWrite(13, LOW);        // Ausgang AN schalten
    ImpulsStateWaus = LOW;
  }
  if (triggerWaus && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(13, HIGH);        // Ausgang AUS schalten
    triggerWaus = false;
  }
  // Impuls für Sprenger Nord ***********************************************************
  // Impuls Pin An
  if (ImpulsStateNan == HIGH) 
  {
    triggerNan = true;
    previousMillis = millis();
    mcp.digitalWrite(14, LOW);        // Ausgang AN schalten
    ImpulsStateNan = LOW;
  }
  if (triggerNan && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(14, HIGH);        // Ausgang AUS schalten
    triggerNan = false;
  }
  // Impuls Pin Aus **************
  if (ImpulsStateNaus == HIGH) 
  {
    triggerNaus = true;
    previousMillis = millis();
    mcp.digitalWrite(15, LOW);        // Ausgang AN schalten
    ImpulsStateNaus = LOW;
  }
  if (triggerNaus && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(15, HIGH);        // Ausgang AUS schalten
    triggerNaus = false;
  }
}

Ist schwierig zu beschreiben was ich machen will. Sorry für den Kauderwelsch. Ich hoffe ihr könnt es trotzdem nachvollziehen...

timer.h könnte man auch evtl. dafür missbrauchen. Geht ja auch ein 1maliger Durchlauf.

// The timer will repeat every 1000 ms and will call the callback only 5 times
timer.setInterval(1000, 5);