Millis zu schnell - Fehlerquellen gesucht

In meinem aktuellen Projekt-Code sind die millis zu schnell.

Teste ich die millis mit einem Minimalcode ist alles genau.:open_mouth:

Liegt also an meinem Code.:fearful:
Wie zum Teufel kann man es schaffen das die Millis schneller laufen?:thinking:

Vielleicht mal das Programm korrigieren.
Dazu ist es sinnvoll, zu schauen, warum das passiert.

Dazu gehört es auch WidersprĂŒche zu erkennen und aufzulösen!

Musste ich das jetzt sagen?
War das beleidigend, o.Ă€.?

Widerspruch/Paradox:

Verstehe ich nicht so, eher
"verdammt, wie habe ich es geschafft, dass hier die millis schneller laufen als im einfachen Test-Sketch?"

(Wenn diese Frage geklÀrt ist, kann man es entweder abstellen oder trickreich ausnutzen)


Sind sie um 1% oder ums doppelte zu schnell ?

Das ich was irgend etwas versaut habe ist mir seit dem "Minimaltest" auch bewusst.:hugs: Das mir gerne mal sowas passiert auch.:grin:

Ich habe momentan noch keine Vorstellung nach was ich suchen soll. Gibt es "ĂŒbliche VerdĂ€chtige"?

Ca. 25% zu schnell...

OK....
Kann so gemeint sein.

Mein Leitsatz:

Immer dahin schauen, wo man hin will!
Nie dahin, wovor man Angst hat.

AusfĂŒhrlicher:
Das Unterbewusstsein fĂŒhrt einen dahin, wo man hinschaut.
Das weiß jeder Skateboardfahrer, jeder Motorradfahrer.

Wenn man schon auf die Nase fÀllt, dann schaut man auf die RasenflÀche und fixiert nicht die Bordsteinkante.
Immer dort hin schauen, wo das Überleben möglich erscheint.
Dem Unterbewusstsein eine Chance geben.

Das gilt natĂŒrlich auch alles uneingeschrĂ€nkt, wenn gerade keine Gefahr droht.
Denn:
Das Unterbewusstsein, kann irgendwas um 300 Entscheidungen/Impulse pro Sekunde verarbeiten. Das Großhirn gerade mal 3 pro Sekunde, oder so...

Hier:
Es ist kein Geheimnis, wie millis() funktoniert.
Es gibt gefĂŒhlte 200 Tausend Varianten, wie man das stören kann.

Diese Art zu denken, auf die möglichen Fehler zu schauen, halte ich nicht fĂŒr ZielfĂŒhrend.
Ich werde hier also nicht anfangen die Fehlermöglichkeiten aufzulisten.

Die Wege zur Lösung sehen anders aus!

Wenn die millis zu langsam wĂ€ren wĂŒrde ich auf lange Interrups-Deaktivierung tippen.
noInterrupts()
interrupts()

FĂŒr zu schnell hab ich keine Idee.

GrĂŒĂŸe Uwe

Wahrscheinlich sind auch die millis nicht zu schnell. Schon gar keine 25%. Eher stimmt eine/mehrere (wahrscheinlich globale) Variable(n) bzw. eine oder mehrere If Bedingung(en) nicht.

Ohne in die Details zu gehen:

  1. Rumfummeln an Timer 0
  2. Zeiger/Index Verwirrungen
  3. millis() ist voll ok, der Bock ist ganz woanders
  4. delay() in ISR macht die Probleme

Das waren jetzt ein paar einsame Böcke, welche man schießen kann.
Die Auswahl ist wohl noch weitaus grĂ¶ĂŸer.

Davon mal abgesehen:
Ich halte diesen Thread fĂŒr einen Trollversuch. Ob absichtlich, oder aus versehen, ist mir dabei egal.
"Ich habe ein Problem mit meinem Programm, aber Ihr dĂŒrft das nicht sehen."
"Sagt mir aber trotzdem was ich falsch mache."
Wie soll das gehen?

MĂŒĂŸte das nicht die millis() verlangsamen und nicht beschleunigen?

ja, der Blick in die Glaskugel sagt mir, Zeile 150 ist schuld. :pleading_face:

Weiß nicht.....

Ich behaupte:
Unser @stoni99 verwendet delay() in einer ISR. Das funktioniert nicht so wie erwartet, denn die delay() werden "scheinbar" kĂŒrzer. Das bringt ihn zu der Annahme, dass mit millis() irgendwas nicht stimmt.

PS:
Und das behaupte ich solange, bis mir das widerlegt wird.
Danach behaupte ich das Gegenteil.

Klingt logish.
Danke fĂŒr die ErklĂ€hrung.
GrĂŒĂŸe Uwe

Ick trau mir nicht das combie zu zeigen: Da krich ich doch wieder Dresche...:joy::grimacing:

Ich alter Troll schau lieber noch mal alles durch.

Also delay gibt es bei mir nicht. Momentan habe die Timer im Verdacht. Ich versuch es mal nach dem Ausschlussverfahren...

Stell dich!

Im Moment bekommst du wegen deiner Geheimhaltung Dresche von mir.
(scheint mir zumindest so zu sein)

wie mans macht ist falsch :stuck_out_tongue_winking_eye: :grimacing: :grimacing: :woozy_face:

Na, dann mal los...

/*
 * Steuerzentrale Pumpe & Sprenger fĂŒr Lilygo T5 V2,3 ESP32
 * Ausgang fĂŒr 9V Impulsspulen Hunter
 * Bilder fĂŒr Epaper umwandeln: http://javl.github.io/image2cpp/
*/
// According to the board, cancel the corresponding macro definition
#define LILYGO_T5_V213                    // ist 250, 122 px (soll 212 x 104)

#include <boards.h>
#include <GxEPD.h>
#include <SD.h>
#include <FS.h>
#include <Wire.h>                         // I2C Bus
#include <Adafruit_MCP23X17.h>            // Porterweiterung
#include "Adafruit_MPR121.h"              // Touch Keypad
#include "timer.h"                        // Lib von brunocalou Einschaltverzögerungen und Timer fĂŒr AUTO

// Create the timer instance
Timer timer1;               // Instanzen von Timer ertellen: Sprenger Ost
Timer timer2;               // Sprenger SĂŒd 
Timer timer3;               // Sprenger West
Timer timer4;               // Sprenger Nord
Timer timer5;               // Auto Sprenger Ost an
Timer timer6;               // Auto Sprenger Ost aus
Timer timer7;               // Auto Sprenger SĂŒd an
Timer timer8;               // Auto Sprenger SĂŒd aus
Timer timer9;               // Auto Sprenger West an
Timer timer10;               // Auto Sprenger West aus
Timer timer11;               // Auto Sprenger Nord an
Timer timer12;               // Auto Sprenger Nord aus

#include <GxDEPG0213BN/GxDEPG0213BN.h>    // 2.13" b/w  form DKE GROUP

#ifndef _BV
#define _BV(bit) (1 << (bit)) 
#endif

Adafruit_MPR121 cap = Adafruit_MPR121();

// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>

#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

GxIO_Class io(SPI,  EPD_CS, EPD_DC,  EPD_RSET);
GxEPD_Class display(io, /*RST=*/ EPD_RSET, /*BUSY=*/ EPD_BUSY); // default selection of (9), 7

Adafruit_MCP23X17 mcp; // Create MCP

// Keypad : Keeps track of the last pins touched
// so we know when buttons are 'released'
uint16_t lasttouched = 0;
uint16_t currtouched = 0;

// Position und GrĂ¶ĂŸe der Bilder Sprenger und Pumpe festlegen fĂŒr partielle Löschung und dann Aktualisierung
uint16_t SprObox_x = 26;
uint16_t SprObox_y = 22;
uint16_t SprObox_w = 30;
uint16_t SprObox_h = 30;

uint16_t SprSbox_x = 82;
uint16_t SprSbox_y = 22;
uint16_t SprSbox_w = 30;
uint16_t SprSbox_h = 30;

uint16_t SprWbox_x = 138;
uint16_t SprWbox_y = 22;
uint16_t SprWbox_w = 30;
uint16_t SprWbox_h = 30;

uint16_t SprNbox_x = 194;
uint16_t SprNbox_y = 22;
uint16_t SprNbox_w = 30;
uint16_t SprNbox_h = 30;

uint16_t Pumpbox_x = 26;
uint16_t Pumpbox_y = 80;
uint16_t Pumpbox_w = 30;
uint16_t Pumpbox_h = 30;

uint16_t Ausbox_x = Pumpbox_x+42;
uint16_t Ausbox_y = Pumpbox_y+8;
uint16_t Ausbox_w = 38;
uint16_t Ausbox_h = 17;

uint16_t Autobox_x = Pumpbox_x+87;
uint16_t Autobox_y = Pumpbox_y+8;
uint16_t Autobox_w = 48;
uint16_t Autobox_h = 17;

//Bilder laden (Bild muss im selben Ordner sein)
#include "IMG_Sprenger3.h"
#include "IMG_Pumpe1.h"
//#include "IMG_Pumpe2.h"
//#include "IMG_Pumpe3.h"

boolean StateEmpfSprO = LOW;
boolean StateEmpfSprS = LOW;
boolean StateEmpfSprW = LOW;
boolean StateEmpfSprN = LOW;
boolean StateEmpfSprOold = HIGH;
boolean StateEmpfSprSold = HIGH;
boolean StateEmpfSprWold = HIGH;
boolean StateEmpfSprNold = HIGH;

boolean StateTasteSprO = LOW;
boolean StateTasteSprS = LOW;
boolean StateTasteSprW = LOW;
boolean StateTasteSprN = LOW;
boolean StateTasteAuto = LOW;
boolean StateTasteAus = LOW;
boolean StateTasteSprOold = HIGH;

boolean State = LOW;      //Taster intern Status
boolean StartImpulsMagnetventil = false;
boolean ImpulsStateOan = LOW;                     
boolean ImpulsStateOaus = LOW;
boolean ImpulsStateSan = LOW;
boolean ImpulsStateSaus = LOW;
boolean ImpulsStateWan = LOW;                     
boolean ImpulsStateWaus = LOW;
boolean ImpulsStateNan = LOW;
boolean ImpulsStateNaus = LOW;

boolean StatePumpe = false;
boolean StatePumpeVerz = false;     

bool triggerOan;
bool triggerOaus;
bool triggerSan;
bool triggerSaus;
bool triggerWan;
bool triggerWaus;
bool triggerNan;
bool triggerNaus;

bool AktionPumpe;
bool triggerPan;
bool triggerPaus;
bool PumpeVerzAnStart;
bool PumpeVerzAusStart;
bool triggerImpulsVerz;
bool AktionSprengerAus = false;
bool SprengerVerzAusStart = false;
bool triggerOSTaus = false;
bool triggerSUEDaus = false;
bool triggerWESTaus = false;
bool triggerNORDaus = false;

bool Anzeige = false;
bool AnzeigeSprengerOstAn = false;
bool AnzeigeSprengerOstAus = false;
bool AnzeigeSprengerSuedAn = false;
bool AnzeigeSprengerSuedAus = false;
bool AnzeigeSprengerWestAn = false;
bool AnzeigeSprengerWestAus = false;
bool AnzeigeSprengerNordAn = false;
bool AnzeigeSprengerNordAus = false;
bool AnzeigeAus = false;
bool AnzeigeAuto= false;



unsigned long currentMillis;
unsigned long previousMillis;               // will store last time LED was updated
unsigned long previousMillisPumpe;          
unsigned long previousMillisImpulsVerz;     
unsigned long saved_millis;
unsigned long previousMillisAlleAus;


const int impuls = 100;                     // impuls 10ms fĂŒr 9V Impulsventil Hunter (milliseconds)
const int ZeitBisPumpeAus =5000;            // 31s Verzögerung bis Pumpe aus
const int ZeitBisPumpeAn = 5000;            // 30s Verzögerung bis Pumpe an
const int ZeitAutoAus = 20000;              // Sprengerlaufzeit bei AUTO (20min)
const int ZeitAlleSprengerAus = 1200;       // 1,2s Verzögerung beim Ausschalten aller Sprenger









void setup()
{
    Serial.begin(9600);
    mcp.begin_I2C(0x20);             // Start MCP Porterweiterung Adresse 0x20
    cap.begin(0x5A);                 // Start Keypad
    //EingÀnge MCP Kanal A = 4x EmpfÀnger
    mcp.pinMode(0, INPUT_PULLUP);    // Define GPA0 on MCP as input
    mcp.pinMode(1, INPUT_PULLUP);    
    mcp.pinMode(2, INPUT_PULLUP);    
    mcp.pinMode(3, INPUT_PULLUP);    
    //Ausgang MCP Kanal A = 1x zur SSD Relais Pumpe
    mcp.pinMode(7, OUTPUT);          // Define GPB0 on MCP as OUTPUT
    //Ausgang MCP Kanal A = 1x LED Tastendruck
    mcp.pinMode(6, OUTPUT);          // Define GPB0 on MCP as OUTPUT
    //AusgÀnge MCP Kanal B = 8x zur H-Bridge
    mcp.pinMode(8, OUTPUT);          // Define GPB0 on MCP as OUTPUT
    mcp.pinMode(9, OUTPUT);          
    mcp.pinMode(10, OUTPUT);          
    mcp.pinMode(11, OUTPUT);          
    mcp.pinMode(12, OUTPUT);          
    mcp.pinMode(13, OUTPUT);          
    mcp.pinMode(14, OUTPUT);          
    mcp.pinMode(15, OUTPUT);          

    mcp.digitalWrite(7, LOW);         //SSD Relais Pumpe
    mcp.digitalWrite(8, LOW);         //H-Bridge Ost
    mcp.digitalWrite(9, LOW);         //H-Bridge
    mcp.digitalWrite(10, LOW);        //H-Bridge SĂŒd
    mcp.digitalWrite(11, LOW);        //H-Bridge
    mcp.digitalWrite(12, LOW);        //H-Bridge West
    mcp.digitalWrite(13, LOW);        //H-Bridge
    mcp.digitalWrite(14, LOW);        //H-Bridge Nord
    mcp.digitalWrite(15, LOW);        //H-Bridge
    
    display.init();
    display.eraseDisplay();
    display.setTextColor(GxEPD_BLACK);
    display.setRotation(1);
    display.setFont(&FreeMonoBold9pt7b);
    display.drawRect(0, 0, 250, 18, GxEPD_BLACK);                                   // x,y,w(nach re),h(nach unten),Farbe
    display.setCursor(40, 12);
    display.print("Sprengerzentrale");
    display.drawBitmap(gImage_SprengerAn3, SprObox_x, SprObox_y, SprObox_w , SprObox_h, GxEPD_WHITE);    // Bildname,X-Position,Y-Position,Breite Bild, Höhe Bild, Farbe
    display.drawBitmap(gImage_SprengerAn3, SprSbox_x, SprSbox_y, SprSbox_w , SprSbox_h, GxEPD_WHITE);     
    display.drawBitmap(gImage_SprengerAn3, SprWbox_x, SprWbox_y, SprWbox_w , SprWbox_h, GxEPD_WHITE);     
    display.drawBitmap(gImage_SprengerAn3, SprNbox_x, SprNbox_y, SprNbox_w , SprNbox_h, GxEPD_WHITE);     
    //display.drawBitmap(gImage_Pumpe1, Pumpbox_x, Pumpbox_y, Pumpbox_w , Pumpbox_h, GxEPD_WHITE);     
    display.setCursor(26, 63);
    display.print("Ost");
    display.setCursor(77, 63);
    display.print("Sued");
    display.setCursor(133, 63);
    display.print("West");
    display.setCursor(189, 63);
    display.print("Nord");
    
    display.setCursor(Pumpbox_x+45, Pumpbox_y+20);
    display.print("Aus Auto");

    display.setFont();                // kleine Schrift (Grund-Font)
    display.setCursor(25, 67);
    display.print("0 min");
    display.setCursor(81, 67);
    display.print("10 min");
    display.setCursor(137, 67);
    display.print("20 min");
    display.setCursor(193, 67);
    display.print("30 min");
    display.update();                 // Display aktualisieren
    
    // es verhindert unerwĂŒnschte Hintergrund-Anzeigen:
    display.updateWindow(0, 0, GxEPD_WIDTH, GxEPD_HEIGHT, false);

    //Timer setzen
    timer1.setInterval(ZeitBisPumpeAn,1);           //(ms, Wiederholungen) nur 1x ausfĂŒhren        
    timer1.setCallback(UPImpulsStateOan);           //UP aufrufen
    
    timer2.setInterval(ZeitBisPumpeAn,1);                  
    timer2.setCallback(UPImpulsStateSan);           

    timer3.setInterval(ZeitBisPumpeAn,1);                   
    timer3.setCallback(UPImpulsStateSan);           

    timer4.setInterval(ZeitBisPumpeAn,1);                   
    timer4.setCallback(UPImpulsStateSan);           
    
    //AUTO Verzögerungen ++++++++++++++++
    timer5.setInterval(ZeitBisPumpeAn,1);                   
    timer5.setCallback(UPImpulsStateAutoOan);       

    timer6.setInterval(ZeitAutoAus,1);              //(ms, Wiederholungen) nur 1x ausfĂŒhren    +(((ZeitAutoAus*30)/100))    
    timer6.setCallback(UPImpulsStateAutoOaus);      //UP aufrufen um bei Auto Sprenger Ost auszuschalten
          
    timer7.setInterval((1*ZeitAutoAus)+3000,1);            
    timer7.setCallback(UPImpulsStateAutoSan);       

    timer8.setInterval((2*ZeitAutoAus),1);                
    timer8.setCallback(UPImpulsStateAutoSaus);      
          
    timer9.setInterval((2*ZeitAutoAus)+3000,1);            
    timer9.setCallback(UPImpulsStateAutoWan);       

    timer10.setInterval((3*ZeitAutoAus),1);                
    timer10.setCallback(UPImpulsStateAutoWaus);     
          
    timer11.setInterval((3*ZeitAutoAus)+3000,1);            
    timer11.setCallback(UPImpulsStateAutoNan);      

    timer12.setInterval((4*ZeitAutoAus),1);                 
    timer12.setCallback(UPImpulsStateAutoNaus);     
}







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());
  VerzoegerungAlleSprengerAus();                        // UP um alle Sprenger verzögert auszuschalten
  //Serial.print("nach verz. alle Sprenger aus: "); Serial.println(millis());
  AnzeigeEPaper();                                      //UP um erst nach Fertigstellung der AusgÀnge Anzeige zu aktualisieren
  //Serial.print("nach Anzeige: "); Serial.println(millis());
  //Serial.println();
  timer1.update();
  timer2.update();
  timer3.update();
  timer4.update();
  timer5.update();
  timer6.update();
  timer7.update();
  timer8.update();
  timer9.update();
  timer10.update();
  timer11.update();
  timer12.update();
}






//UP's um nach timer Ablauf Sprenger einzuschalten
void UPImpulsStateOan() {
  ImpulsStateOan = HIGH;
  timer1.stop();
}
void UPImpulsStateSan() {
  ImpulsStateSan = HIGH;
  timer2.stop();
}
void UPImpulsStateWan() {
  ImpulsStateWan = HIGH;
  timer3.stop();
}
void UPImpulsStateNan() {
  ImpulsStateNan = HIGH;
  timer4.stop();
}
//UP's um timer bei Sprenger bei AUTO zu schalten
void UPImpulsStateAutoOan() {
  ImpulsStateOan = HIGH;
  timer5.stop();
}
void UPImpulsStateAutoOaus() {
  ImpulsStateOaus = HIGH;
  timer6.stop();
}
void UPImpulsStateAutoSan() {
  ImpulsStateSan = HIGH;
  timer7.stop();
}
void UPImpulsStateAutoSaus() {
  ImpulsStateSaus = HIGH;
  timer8.stop();
}
void UPImpulsStateAutoWan() {
  ImpulsStateWan = HIGH;
  timer8.stop();
}
void UPImpulsStateAutoWaus() {
  ImpulsStateWaus = HIGH;
  timer10.stop();
}
void UPImpulsStateAutoNan() {
  ImpulsStateNan = HIGH;
  timer11.stop();
}
void UPImpulsStateAutoNaus() {
  StatePumpe = false;
  mcp.digitalWrite(7, LOW);              //SSD Relais Pumpe AUS
  StateTasteAuto = !StateTasteAuto;      // Status Auto wieder Umschalten um einen erneuten Aufruf zu ermöglichen
  AnzeigeAuto = false;
  ImpulsStateNaus = HIGH;
  timer12.stop();
}







void ReadEmpfaenger()
{
  // Kanal 1 Sprenger ****** Ost ***********************************************************************
  if (mcp.digitalRead(0) != StateEmpfSprOold){          //Funkkanal auslesen, nur bei Änderung 
    StateEmpfSprO = mcp.digitalRead(0);
    if (StateEmpfSprO == LOW){        //AN ***********************
      //Sprenger einschalten
      if (mcp.digitalRead(7) == LOW){         //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
        //ImpulsStateOan = HIGH;              //Impulsstatus Sprenger Ost an
        timer1.start();                       //timer starten
      }
      else{
        ImpulsStateOan = HIGH;                //Impulsstatus Sprenger Ost sofort an
      } 
      mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
      StatePumpe = true;
      StateEmpfSprOold = !StateEmpfSprOold;
    }
    if (StateEmpfSprO == HIGH){       //AUS *********************
      //Sprenger ausschalten
      ImpulsStateOaus = HIGH;                 //Impulsstatus Sprenger Ost soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
      if ((mcp.digitalRead(1) == HIGH) && (mcp.digitalRead(2) == HIGH) && (mcp.digitalRead(3) == HIGH)){         //Pumpe nur aus wenn Sprenger SĂŒd, West & Nord aus sind
        PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
        AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
      }
      StatePumpe = false;
      StateEmpfSprOold = !StateEmpfSprOold;
    }
  }
  // Kanal 2 Sprenger ****** SĂŒd ***********************************************************************
  if (mcp.digitalRead(1) != StateEmpfSprSold){          //Funkkanal auslesen, nur bei Änderung 
    StateEmpfSprS = mcp.digitalRead(1);
    if (StateEmpfSprS == LOW){       //AN ***********************
      //Sprenger einschalten
      if (mcp.digitalRead(7) == LOW){         //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
        //ImpulsStateSan = HIGH;              //Impulsstatus Sprenger SĂŒd an
        timer1.start();                       //timer starten
      }
      else{
        ImpulsStateSan = HIGH;                //Impulsstatus Sprenger Ost sofort an
      } 
      mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
      StatePumpe = true;
      StateEmpfSprSold = !StateEmpfSprSold;
    }
    if (StateEmpfSprS == HIGH){      //AUS *********************
      //Sprenger ausschalten
      ImpulsStateSaus = HIGH;                 //Impulsstatus Sprenger SĂŒd soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
      if ((mcp.digitalRead(0) == HIGH) && (mcp.digitalRead(2) == HIGH) && (mcp.digitalRead(3) == HIGH)){         //Pumpe nur aus wenn EmpfÀngerkanal Ost, West & Nord aus sind
        PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
        AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
      }
      StatePumpe = false;
      StateEmpfSprSold = !StateEmpfSprSold;
    }
  }
  // Kanal 3 Sprenger ****** West ***********************************************************************
  if (mcp.digitalRead(2) != StateEmpfSprWold){          //Funkkanal auslesen, nur bei Änderung 
    StateEmpfSprW = mcp.digitalRead(2);
    if (StateEmpfSprW == LOW){       //AN ***********************
      //Sprenger einschalten
      if (mcp.digitalRead(7) == LOW){         //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
        //ImpulsStateWan = HIGH;              //Impulsstatus Sprenger West an
        timer1.start();                       //timer starten
      }
      else{
        ImpulsStateWan = HIGH;                //Impulsstatus Sprenger West sofort an
      } 
      mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
      StatePumpe = true;
      StateEmpfSprWold = !StateEmpfSprWold;
    }
    if (StateEmpfSprW == HIGH){      //AUS *********************
      //Sprenger ausschalten
      ImpulsStateWaus = HIGH;                 //Impulsstatus Sprenger West soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
      if ((mcp.digitalRead(0) == HIGH) && (mcp.digitalRead(1) == HIGH) && (mcp.digitalRead(3) == HIGH)){         //Pumpe nur aus wenn EmpfĂ€ngerkanal Ost, SĂŒd & Nord aus sind
        PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
        AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
      }
      StatePumpe = false;
      StateEmpfSprWold = !StateEmpfSprWold;
    }
  }
  // Kanal 4 Sprenger ****** Nord ***********************************************************************
  if (mcp.digitalRead(3) != StateEmpfSprNold){          //Funkkanal auslesen, nur bei Änderung 
    StateEmpfSprN = mcp.digitalRead(3);
    if (StateEmpfSprN == LOW){       //AN ***********************
      //Sprenger einschalten
      if (mcp.digitalRead(7) == LOW){         //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
        //ImpulsStateNan = HIGH;              //Impulsstatus Sprenger SĂŒd an
        timer1.start();                       //timer starten
      }
      else{
        ImpulsStateNan = HIGH;                //Impulsstatus Sprenger Nord sofort an
      } 
      mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
      StatePumpe = true;
      StateEmpfSprNold = !StateEmpfSprNold;
    }
    if (StateEmpfSprN == HIGH){      //AUS *********************
      //Sprenger ausschalten
      ImpulsStateNaus = HIGH;                 //Impulsstatus Sprenger SĂŒd soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
      if ((mcp.digitalRead(0) == HIGH) && (mcp.digitalRead(1) == HIGH) && (mcp.digitalRead(2) == HIGH)){         //Pumpe nur aus wenn EmpfĂ€ngerkanal Ost, West & SĂŒd aus sind
        PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
        AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
      }
      StatePumpe = false;
      StateEmpfSprNold = !StateEmpfSprNold;
    }
  }
}








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)) ) mcp.digitalWrite(6, HIGH);        // Taste gedrĂŒckt LED an
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ){
      mcp.digitalWrite(6, LOW);                                                               // Taste gelöst LED aus
      // Taste 0 ***** OST **************************************************************************************************
      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 Pumpe-Aus zu speichern
            AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
          }
          StatePumpe = false;
        }
        else
        if (StateTasteSprO == HIGH){        //AN **************
          //Sprenger einschalten
          if (mcp.digitalRead(7) == LOW){         //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
            //ImpulsStateOan = HIGH;              //Impulsstatus Sprenger Ost an
            timer1.start();                       //timer starten
          }
          else{
            ImpulsStateOan = HIGH;                //Impulsstatus Sprenger Ost sofort an
          } 
          mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
          StatePumpe = true;
          AktionPumpe = false;                    //Verzögerte Pumpenausschaltung stoppen
          AnzeigeAus = false;                     //Rahmen um ePaperSymbol "AUS" löschen
        }
      }
      // Taste 1 ******* SÜD ************************************************************************************************
      if (i == 1){
        StateTasteSprS = !StateTasteSprS;
        if (StateTasteSprS == LOW){         //AUS *************
          //Sprenger ausschalten
          ImpulsStateSaus = HIGH;                 //Impulsstatus Sprenger SĂŒd soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
          if ((StateTasteSprO == LOW) && (StateTasteSprW == LOW) && (StateTasteSprN == LOW)){         //Pumpe nur aus wenn Sprenger Ost, West & Nord aus sind
            PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
            AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
          }
          StatePumpe = false;
        }
        else
        if (StateTasteSprS == HIGH){        //AN *************
          //Sprenger einschalten
          if (mcp.digitalRead(7) == LOW){         //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
            //ImpulsStateSan = HIGH;              //Impulsstatus Sprenger SĂŒd an
            timer2.start();                       //timer starten
          }
          else{
            ImpulsStateSan = HIGH;                //Impulsstatus Sprenger SĂŒd sofort an
          }
          mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
          StatePumpe = true;
          AktionPumpe = false;                    //Verzögerte Pumpenausschaltung stoppen
          AnzeigeAus = false;                     //Rahmen um ePaperSymbol "AUS" löschen
        }
      }
      // Taste 2 ***** WEST **************************************************************************************************
      if (i == 2){
        StateTasteSprW = !StateTasteSprW;
        if (StateTasteSprW == LOW){         //AUS *************
          //Sprenger ausschalten
          ImpulsStateWaus = HIGH;                 //Impulsstatus Sprenger West soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
          if ((StateTasteSprO == LOW) && (StateTasteSprS == LOW) && (StateTasteSprN == LOW)){         //Pumpe nur aus wenn Sprenger SĂŒd, Ost & Nord aus sind
            PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
            AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
          }
          StatePumpe = false;
        }
        else
        if (StateTasteSprW == HIGH){        //AN **************
          //Sprenger einschalten
          if (mcp.digitalRead(7) == LOW){         //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
            //ImpulsStateWan = HIGH;              //Impulsstatus Sprenger Ost an
            timer3.start();                       //timer starten
          }
          else{
            ImpulsStateWan = HIGH;                //Impulsstatus Sprenger West sofort an
          } 
          mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
          StatePumpe = true;
          AktionPumpe = false;                    //Verzögerte Pumpenausschaltung stoppen
          AnzeigeAus = false;                     //Rahmen um ePaperSymbol "AUS" löschen
        }
      }
      // Taste 3 ***** NORD **************************************************************************************************
      if (i == 3){
        StateTasteSprN = !StateTasteSprN;
        if (StateTasteSprN == LOW){         //AUS *************
          //Sprenger ausschalten
          ImpulsStateNaus = HIGH;                 //Impulsstatus Sprenger Nord soll einschalten (UP ImpulsMagnetventil im Haupt-Loop)
          if ((StateTasteSprS == LOW) && (StateTasteSprW == LOW) && (StateTasteSprO == LOW)){         //Pumpe nur aus wenn Sprenger SĂŒd, West & Ost aus sind
            PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
            AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
          }
          StatePumpe = false;
        }
        else
        if (StateTasteSprN == HIGH){        //AN **************
          //Sprenger einschalten
          if (mcp.digitalRead(7) == LOW){         //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
            //ImpulsStateNan = HIGH;              //Impulsstatus Sprenger Nord an
            timer4.start();                       //timer starten
          }
          else{
            ImpulsStateNan = HIGH;                //Impulsstatus Sprenger Nord sofort an
          } 
          mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
          StatePumpe = true;
          AktionPumpe = false;                    //Verzögerte Pumpenausschaltung stoppen
          AnzeigeAus = false;                     //Rahmen um ePaperSymbol "AUS" löschen
        }
      }
      // Taste 8 ***** AUTO **************************************************************************************************
      if (i == 8){
        StateTasteAuto = !StateTasteAuto;
        if (StateTasteAuto == LOW){         //AUS *************
          //alle Sprenger ausschalten
          AktionSprengerAus = true;             //UP im Hauptloop freigeben um alle Sprenger verzögert auszuschalten
          SprengerVerzAusStart = true;
          //Pumpe verzögert ausschalten
          PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
          AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
          StatePumpe = false;
          AnzeigeAuto = false;
        }
        else
        if (StateTasteAuto == HIGH){        //AN **************
          //Sprenger Ost per Timer einschalten *** Ost AN
          if (mcp.digitalRead(7) == LOW){             //Ausgang Pumpe on/off lesen - nur wenn Pumpe "aus" Verzögerung timer starten um Sprenger verzögert einzuschalten
            //ImpulsStateOan = HIGH;                  //Impulsstatus Sprenger Ost an
            timer5.start();                           //timer starten
          }
          else{
            ImpulsStateOan = HIGH;                //Impulsstatus Sprenger Nord sofort an
          }
          //Timer fĂŒr Sprenger an setzen
          //Ausschaltzeit Auto Sprenger **** Ost AUS
          timer6.start();
          //Einschaltzeit Auto Sprenger **** SĂŒd AN
          timer7.start();
          //Ausschaltzeit Auto Sprenger **** SĂŒd AUS
          timer8.start();
          //Einschaltzeit Auto Sprenger **** West AN
          timer9.start();
          //Ausschaltzeit Auto Sprenger **** West AUS
          timer10.start();
          //Einschaltzeit Auto Sprenger **** Nord AN
          timer11.start();
          //Ausschaltzeit Auto Sprenger **** Nord AUS
          timer12.start();
          
          mcp.digitalWrite(7, HIGH);              //SSD Relais Pumpe AN
          StatePumpe = true;
          AnzeigeAus = false;                     //Rahmen um ePaperSymbol "AUS" löschen
          AnzeigeAuto = true;
        }
      }
      // Taste 11 ***** AUS **************************************************************************************************
      if (i == 11){
        AktionSprengerAus = true;             //UP im Hauptloop freigeben um alle Sprenger verzögert auszuschalten
        SprengerVerzAusStart = true;
        //Pumpe verzögert ausschalten
        PumpeVerzAusStart = true;             //Variable um millis als Startzeit fĂŒr Verzögerung Pumpe-Aus zu speichern
        AktionPumpe = true;                   //Variable um Pumpenaktion zu starten: UP im loop um Pumpe verzögert aus zuschalten
        StatePumpe = false;
        AnzeigeAuto = false;
        AnzeigeAus = true;
      }
    }
  }
  // reset our state
  lasttouched = currtouched;
}







void AnzeigeEPaper()
{
  if (Anzeige == true)    //nur Anzeigen wenn nach allen Schaltaktionen Anzeige frei gegeben wird
  {
    display.fillRect(0, 19, 250, 103, GxEPD_WHITE);      // ausser Überschrift alles löschen
    display.drawBitmap(gImage_SprengerAn3, SprObox_x, SprObox_y, SprObox_w , SprObox_h, GxEPD_WHITE);    // Bildname,X-Position,Y-Position,Breite Bild, Höhe Bild, Farbe
    display.drawBitmap(gImage_SprengerAn3, SprSbox_x, SprSbox_y, SprSbox_w , SprSbox_h, GxEPD_WHITE);     
    display.drawBitmap(gImage_SprengerAn3, SprWbox_x, SprWbox_y, SprWbox_w , SprWbox_h, GxEPD_WHITE);     
    display.drawBitmap(gImage_SprengerAn3, SprNbox_x, SprNbox_y, SprNbox_w , SprNbox_h, GxEPD_WHITE);
    display.setFont(&FreeMonoBold9pt7b);
    display.setCursor(26, 63);display.print("Ost");display.setCursor(77, 63);display.print("Sued");display.setCursor(133, 63);display.print("West");display.setCursor(189, 63);display.print("Nord");
    display.setCursor(Pumpbox_x+45, Pumpbox_y+20);display.print("Aus Auto");
    //Anzeige Sprenger **** Ost AN/AUS ********************************************************************
    if (AnzeigeSprengerOstAn == true)
    {
      display.drawBitmap(gImage_SprengerAn3, SprObox_x, SprObox_y, SprObox_w , SprObox_h, GxEPD_BLACK);
    }
    if (AnzeigeSprengerOstAus == true)
    {
      display.drawBitmap(gImage_SprengerAn3, SprObox_x, SprObox_y, SprObox_w , SprObox_h, GxEPD_WHITE);
    }
    //Anzeige Sprenger **** SĂŒd AN/AUS ********************************************************************
    if (AnzeigeSprengerSuedAn == true)
    {
      display.drawBitmap(gImage_SprengerAn3, SprSbox_x, SprSbox_y, SprSbox_w , SprSbox_h, GxEPD_BLACK); 
    }
    if (AnzeigeSprengerSuedAus == true)
    {
      display.drawBitmap(gImage_SprengerAn3, SprSbox_x, SprSbox_y, SprSbox_w , SprSbox_h, GxEPD_WHITE); 
    }
    //Anzeige Sprenger **** West AN/AUS ********************************************************************
    if (AnzeigeSprengerWestAn == true)
    {
      display.drawBitmap(gImage_SprengerAn3, SprWbox_x, SprWbox_y, SprWbox_w , SprWbox_h, GxEPD_BLACK); 
    }
    if (AnzeigeSprengerWestAus == true)
    {
      display.drawBitmap(gImage_SprengerAn3, SprWbox_x, SprWbox_y, SprWbox_w , SprWbox_h, GxEPD_WHITE); 
    }
    //Anzeige Sprenger **** Nord AN/AUS ********************************************************************
    if (AnzeigeSprengerNordAn == true)
    {
      display.drawBitmap(gImage_SprengerAn3, SprNbox_x, SprNbox_y, SprNbox_w , SprNbox_h, GxEPD_BLACK); 
    }
    if (AnzeigeSprengerNordAus == true)
    {
      display.drawBitmap(gImage_SprengerAn3, SprNbox_x, SprNbox_y, SprNbox_w , SprNbox_h, GxEPD_WHITE); 
    }
    //Anzeige **** Pumpe AN *******************************************************************************
    if (AnzeigeSprengerOstAn == true || AnzeigeSprengerSuedAn == true || AnzeigeSprengerWestAn == true || AnzeigeSprengerNordAn == true)  // wenn irgend ein Sprenger noch an ist soll Pumpe "Aktiv" angezeigt bleiben
    {
      StatePumpe = true;
    }
    if (StatePumpe == true)       //Pumpe AN
    {
      display.drawBitmap(gImage_Pumpe1, Pumpbox_x, Pumpbox_y, Pumpbox_w , Pumpbox_h, GxEPD_WHITE);
      StatePumpe = false;
    }
    //Anzeige **** AUTO ***********************************************************************************
    if (AnzeigeAuto == true)
    {
      display.drawRect(112, 87, 50, 18, GxEPD_BLACK); 
    }
    if (AnzeigeAuto == false)
    {
      display.drawRect(112, 87, 50, 28, GxEPD_WHITE); 
    }
    //Anzeige **** AUS ***********************************************************************************
    if (AnzeigeAus == true)
    {
      display.drawRect(67, 87, 40, 18, GxEPD_BLACK); 
    }
    if (AnzeigeAus == false)
    {
      display.drawRect(67, 87, 40, 28, GxEPD_WHITE); 
    }
    display.updateWindow(0, 19, 250, 103, true);           //Display Gesamtausschnitt aktualisieren
  }
  Anzeige = false;        //Anzeige muss erneut nach Impuls aufgerufen werden
}






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, HIGH);        // Ausgang AN schalten
    ImpulsStateWan = LOW;
  }
  if (triggerWan && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(12, LOW);        // Ausgang AUS schalten
    triggerWan = false;
    AnzeigeSprengerWestAn = true;      // Symbol Sprenger fĂŒr Anzeige freigeben
    AnzeigeSprengerWestAus = false;
    Anzeige = true;                   // Anzeige freischalten
  }
  // Impuls Pin **** Aus **************
  if (ImpulsStateWaus == HIGH) 
  {
    triggerWaus = true;
    previousMillis = millis();
    mcp.digitalWrite(13, HIGH);        // Ausgang AN schalten
    ImpulsStateWaus = LOW;
  }
  if (triggerWaus && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(13, LOW);        // Ausgang AUS schalten
    triggerWaus = false;
    AnzeigeSprengerWestAus = true;     // Symbol Sprenger fĂŒr Anzeige freigeben
    AnzeigeSprengerWestAn = false;
    Anzeige = true;                   // Anzeige freischalten
  }
  // Impuls fĂŒr Sprenger **** Nord ***********************************************************
  // Impuls Pin An
  if (ImpulsStateNan == HIGH) 
  {
    triggerNan = true;
    previousMillis = millis();
    mcp.digitalWrite(14, HIGH);        // Ausgang AN schalten
    ImpulsStateNan = LOW;
  }
  if (triggerNan && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(14, LOW);        // Ausgang AUS schalten
    triggerNan = false;
    AnzeigeSprengerNordAn = true;      // Symbol Sprenger fĂŒr Anzeige freigeben
    AnzeigeSprengerNordAus = false;
    Anzeige = true;                   // Anzeige freischalten
  }
  // Impuls Pin **** Aus **************
  if (ImpulsStateNaus == HIGH) 
  {
    triggerNaus = true;
    previousMillis = millis();
    mcp.digitalWrite(15, HIGH);        // Ausgang AN schalten
    ImpulsStateNaus = LOW;
  }
  if (triggerNaus && (millis() - previousMillis > impuls)) {
    mcp.digitalWrite(15, LOW);        // Ausgang AUS schalten
    triggerNaus = false;
    AnzeigeSprengerNordAus = true;     // Symbol Sprenger fĂŒr Anzeige freigeben
    AnzeigeSprengerNordAn = false;
    Anzeige = true;                   // Anzeige freischalten
  }
}







void VerzoegerungPumpe()
{
  if (AktionPumpe == true) 
  {
    if (StatePumpe == false) //************* 
    {
      if (PumpeVerzAusStart == true) 
      {
        triggerPaus = true;
        previousMillisPumpe = millis();
        PumpeVerzAusStart = false;
      }
    }
    //+++++++++++++++
    if (triggerPaus && (millis() - previousMillisPumpe > ZeitBisPumpeAus)) 
    {
      mcp.digitalWrite(7, LOW);           //SSD Relais Pumpe AN
      triggerPaus = false;
      AktionPumpe = false;
    }
  }
}






void VerzoegerungAlleSprengerAus()                    //UP Sprenger sollen nacheinander ausschalten
{
  if (AktionSprengerAus == true) 
  {
    //laufende Timer von AUTO stoppen
    timer5.stop();
    timer6.stop();
    timer7.stop();
    timer8.stop();
    timer9.stop();
    timer10.stop();
    timer11.stop();
    timer12.stop();
    if (SprengerVerzAusStart == true) 
    {
      triggerOSTaus = true;
      triggerSUEDaus = true;
      triggerWESTaus = true;
      triggerNORDaus = true;
      previousMillisAlleAus = millis();
      SprengerVerzAusStart = false;
    }
  }
  //+++++++++++++++
  if (triggerOSTaus && (millis() - previousMillisAlleAus > ZeitAlleSprengerAus)) 
  {
    ImpulsStateOaus = HIGH;
    triggerOSTaus = false;
  }
  if (triggerSUEDaus && (millis() - previousMillisAlleAus > (2*ZeitAlleSprengerAus))) 
  {
    ImpulsStateSaus = HIGH;
    triggerSUEDaus = false;
  }
  if (triggerWESTaus && (millis() - previousMillisAlleAus > (3*ZeitAlleSprengerAus))) 
  {
    ImpulsStateWaus = HIGH;
    triggerWESTaus = false;
  }
  if (triggerNORDaus && (millis() - previousMillisAlleAus > (4*ZeitAlleSprengerAus))) 
  {
    ImpulsStateNaus = HIGH;
    triggerNORDaus = false;
    AktionSprengerAus = false;
  }
}

OK, das ist wirklich etwas viel.

Aha, ein ESP32....

Wie kommst du ĂŒberhaupt auf die Idee, dass millis() schneller lĂ€uft?

ZeitAutoAus ist mit 20000 eingestellt. Geht aber schon bei ca. 15s aus.

Timer 7 bis 12 passen sich der Verschiebung an.

Kann man sicherlich einfach einen Faktor dazurechnen. Aber so einfach kommen mir die millis nicht davon...:hugs:

Es ist mir zu kompliziert......
Oder nicht modular genug!
(ich rate zu endlichen Automaten)

Die durchnummerierten Timer, da bin ich schon ins Stocken geraten.....

Nehmen wir mal timer1
Angeblich der Sprenger Ost Timer.

Aber warum, wird genau der auch bei SĂŒd, West und Nord gestartet?

Dann blicke ich auch bei den if Kaskaden nicht wirklich durch.
Ab einer Schachtelungstiefe von 2, bin ich meist raus.

Es tut mir leid.....
Ich verstehe nicht was das Programm tun soll.
Warum, Was und zu welcher Zeit.
Drum kann ich die Entscheidungen auch nicht prĂŒfen.

Testen kann ich natĂŒrlich auch nicht, da mir das ganze Gelumpe fehlt.

PS:
Die Eingangsfrage war irrefĂŒhrend.
millis() wird es perfekt tun.
Die Timer Lib ist ok. Möchte ich mal behaupten.

1 Like