Poolsteuerung 3-Wege-Ventil_Pumpe_Pumpe

Danke, wenn es doch nur so einfach wäre.
Ich müsste nochmal 20 Jahre jünger sein, dann würde es mir sicher leichter fallen.

Vielleicht wäre es ja möglich mal genau aufzuzählen welche Sensoren es gibt (z.B. Wassertemperatur) und für was die da sind, und als nächstes dann auch was muss gesteuert werden (z.B. Umlauf Pumpe, Heizung). Dass man mal einen Überblick bekommt, was am Ende alles gehen muss, was wie zusammenspielen muss.

Franz

Das ist relativ schnell erklärt.
Ich habe ein Sensor zum messen der Luftfeuchtigkeit, der Temperatur, der Helligkeit und der Spannung meiner PV Batterie.
Also wir stellen uns vor das schönes Wetter ist, die Sonne scheint, die Luftfeuchtigkeit unter 70% ist, die Temperatur 19°C hat und die Sonne scheint. Jetzt soll das 3 Wege Ventil auf den Kollektorpumpenkreis schalten. Dies dauert ca 90 Sekunden. Wenn die Position erreicht ist soll die Kollektorpumpe das Wasser vom Pool durch die Kollektoren pumpen.
Dazu muss auch die Spannung der Batterie hoch genug sein.
Ist einer dieser Werte nicht erfüllt soll das 3 Wege Ventil wieder umschalten auf den Wärmepumpenkreis, auch das dauert wieder ca. 90 Sekunden. Dann soll die Wärmepumpe sich einschalten und das Wasser vom Pool erwärmen.

Der Manuelle Betrieb ist eigentlich nur dazu da, falls die Kollektoren sich im Wärmepumpenbetrieb dennoch aufheizen um per Tasterdruck das Ventil Wieder auf den Kollektorkreis zu stellen, die Pumpe für 7 Minuten laufen zu lassen um das Warme Wasser in den Pool zu spülen und danach wieder auf den Wärmepumpenkreis zu wechseln und die Wärmepumpe wieder zu starten.
Das 3 Wege Ventil sowie die Pumpen, kennen nur 1 und 0. also an oder aus.

Na das ist ja nu keine soo schwere Anforderung.
Erste Entscheidung manuell oder Automatik.
Beide Zweige unabhängig entwickeln.
Da Du komplett auf die Sensorik ohne Uhrzeiten etc. setzt, braucht es da nicht allzuviel Aufwand.

Ich such mal nen Zettel und nen Stift und schau mal ob ich Deine Variablen verstehe...

So gefunden...
Helligkeit>60%
luftfeuchte<70%
Temperatur>19
Voltage>12
starte 3wegeventil
warte 90sek
starte Pumpe

Das könnte aber bedeuten, das wenn der Helligkeitssensor kurz verdeckt ist oder die Temperatur mal kurz abfällt, z.B. durch verdecken, das das System umschaltet.
Also Karrenzzeit mit einbauen, die die Anlage mindestens in der Stellung läuft? Oder besser eine Mindestzeit die dieser Zustand mindestens dauern muss?
Was auch noch nicht klar ist ob und welche Bedingungen erfüllt sein müssen, um die Wärmepumpe einzuschalten.
Dann fehlen noch die ganzen Abschaltbedingungen.
Wann schaltet die Pumpe ab, wenn die im Wärmepumpenkreislauf hängt?
Gibst Du die Wärmepumpe frei oder hat die eigene Sensorik? Bei ersterem könnte das takten ein Problem sein.
Was muss abgeschalten werden, wenn der Akku niedrig geht?

Die Kollektoren werden sich aufheizen, weil die Strahlung auf die die reagieren eine andere ist, als Du mit dem Sensor misst.
Wenn Du kannst, sehe einen Temp-Sensor am Kollektor vor.
Sowas gibt es auch in wasserdicht.

Und ich hab auch rausgelesen, das das 3WV eines ist, welches spannungslos in Ausgangsstellung fährt. ;(

if ((lux = LightSensor.GetLightIntensity() >= sollLux) && (dht.readHumidity() <= Regen_an) && (dht.readTemperature() >= sollTemp) && (Volt >= Einschaltspannung))

Soweit habe ich da schon eine Differenz drin denn wenn "false"
Sind die Werte Andere.

Also Helligkei messe ich in Lux
Schalte bei 3500 Lux auf Kollektoren und bei 2000 Auf Wärmepumpe.
Das Gleiche mache ich mit allen Werten.
Temperatur, Lux, Luftfeuchtigkeit und Spannung. Was vergessen? Egal, auch da habe ich eine Schwelle eingebaut.

Richtig ist das das 3WV im Spannungslosen bzw zu niedrigen Batteriestrom auf Wärmepumpe Schaltet.

Eigentlich schalte ich nicht die Wärmepumpe sondern die Pumpe die das Wasser durch die Wärmepumpe fördert. Die hat einen integrierten Strömungssensor und schaltet dann ein.

Bei schlechtem Wetter oder niedrigem Batteriestand hat immer die WP Vorrang.

Das war die wichtige antwort - danke.
Ich schau drauf....

Das wäre super, danke

Sooo..
Du hast Dich verhaspelt unzwar mit den ganzen if.

Das fängt schon hier an:

      if ((lux = LightSensor.GetLightIntensity() >= sollLux) && (dht.readHumidity() <= Regen_an) && (dht.readTemperature() >= sollTemp) && (Volt >= Einschaltspannung))       //... wenn alle erfüllt sind
        Serial.println("Kollektorpumpe true");
      Startzeit_Automatik = millis();                               // Timer nullen
      digitalWrite(WaermepumpePin, HIGH);                                  // Wärmepumpe aus
      Serial.println("Wärmepumpe aus");
    }

Nehmen wir an, das die Bedingung wahr ist:
Es wird daraufhin(!) genau eine Zeile, nämlich das Serial.println ausgeführt.
Alle anderen Zeilen werden auch ausgeführt, wenn die Bedingung falsch ist!
Damit

Startzeit_Automatik = millis();                               // Timer nullen

immer gesetzt, egal ob die Sensoren das hergeben oder nicht.

Dir fehlt über der Zeile 171

        Serial.println("Kollektorpumpe true");

eine öffnende Klammer.

Die zweite Baustelle ist das else if.
Du prüfst oben ob ALLE Sensoren WAHR sind und prüfst unten nochmal. Wenn oben einer UNWAHR ist, ist da sowieso Schluß.
Aus dem else if könnte auch nur ein reines else ohne weitere Prüfungen werden, da muss aber der Codeblock irgendwie anders verschoben werden.

Da gibt es noch ne Menge Baustellen.
Setze die Klammer und drücke STRG-T damit Du anhand der Einrückungen siehst, auf welcher Ebene Du stehst. Dann bau den Code so, das es passt indem Du die einzelnen Blöcke richtig zuordnest.
Es fehlt jetzt eine schliessende Klammer. Den Punkt wo die hingehört musst Du finen.

Hier prüfe ich ob die Werte die ich zum einschalten der Kollektorpumpe erfüllt sind, da ich aber eine Differenz brauche, damit bei kleinsten Änderungen nicht ständig umher geschaltet wird, prüfe ich unten die Sollwerte für das Ausschalten.

else if ((lux = LightSensor.GetLightIntensity() <= minLux) || (dht.readHumidity() >= Regen_aus) || (dht.readTemperature() <= minTemp) || (Volt <= Ausschaltspannung)) { // sonst wenn eine nicht erfüllt ist

Wenn jetzt hier ein Wert unter den vordefinierten Wert fällt soll die Pumpe ausschalten und das 3-Wege-Ventil auf den Wärmepumpenkreis umstellen und die Wärmepumpe einschalten.
Wenn ich hier nur mit einem "else" arbeiten würde, schaltet es ständig ein und aus.

Das war meine Steuerung vor einem Jahr.
Ohne 3-Wege-Ventil!
Das hat so komplett funktioniert.
Ich musste nur immer das Ventil vom Wärmepumpenkreis manuell umstellen.
Da der Mensch von Grund auf ja "faul" ist möchte ich eben alles etwas automatisierter gestalten.
Also letztendlich soll das hin und herstellen des 3-Wege-Ventils und das Ein,- und Ausschalten der Pumpen mein Arduino für mich übernehmen, mir jedoch die Möglichket geben, manuell eingreifen zu können.

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <BH1750FVI.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHT22_PIN 2 //Temperatursensor
#define DHTTYPE    DHT22     // DHT 22 (AM2302)
#define RST_PIN -1 // Definiere Reset_PIN.
#define I2C_ADDRESS 0x3C // 0X3C+SA0 - 0x3C or 0x3D
SSD1306AsciiWire oled; //Display

BH1750FVI LightSensor(BH1750FVI::k_DevModeContLowRes);
DHT dht(DHT22_PIN, DHT22);//Temperatursensor

int Taster = 4;
int LED = 3;
int Tasterstatus = 0;
int wert1;
int Relais1 = 11;
double lux_alt;
uint16_t lux;
float h_alt;
float t_alt;
float Volt;


unsigned long currentMillis;
unsigned long previousMillis;
unsigned long oledMillis;


long oled_akt = 5000;                                                   // Wartezeit OLED
long Volt_akt = 60000;                                                  // Wartezeit Spannungssensor
long myTimer = 0;                                                       // Wert zum internen rechnen
unsigned long myTimeout = 0;                                            // Wert zum internen rechnen

double sollTemp = 19;                                                   // Temperatur, Auslöser zum Einschalten
double minTemp = 17;                                                    // Temperatur, Auslöser zum Ausschalten
uint16_t sollLux = 3500;                                                // Lichtsensor, Auslöser zum Einschalten
uint16_t minLux = 2000;                                                 // Lichtsensor, Auslöser zum Ausschalten
double Regen_an = 70;                                                   // Regensensor, Auslöser zum Einschalten
double Regen_aus = 90;                                                  // Regensensor, Auslöser zum Ausschalten
double Einschaltspannung = 12.5;                                        // Spannungssensor, Auslöden zum Einschalten
double Ausschaltspannung = 11.2;                                        // Spannungssensor, Auslöden zum Ausschalten

boolean manuell;




uint8_t col0 = 0;                                                       // First value column
uint8_t col1 = 0;                                                       // Last value column.
uint8_t rows;                                                           // Rows per line.
//------------------------------------------------------------------------------
void setup() {
  const char* label[] = {"Temp:", "Feuchte:", "Licht:", "U ="};           //vor den Werten
  const char* units[] = {"   C", "   \45", "   Lux", "   Volt" };         // nach den Werten
  Wire.begin();
  Wire.setClock(400000L);
  Serial.begin(9600);

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0

  // oled.setFont(Callibri15);
  oled.setFont(Arial14);
  // oled.setFont(Callibri11_bold);
  // oled.setFont(TimesNewRoman13);
  // oled.setFont(Arial_bold_14);
  // oled.setFont(Callibri11);
  // oled.setFont(Callibri11_italic);
  // oled.setFont(Corsiva_12);
  // oled.setFont(fixed_bold10x15);
  // oled.setFont(TimesNewRoman16);
  // oled.setFont(TimesNewRoman16_italic);
  // oled.setFont(utf8font10x16);
  // oled.setFont(ZevvPeep8x16);


  oled.setLetterSpacing(2);                             // Buchstabenabstand.

  oled.clear();

  // Setup
  for (uint8_t i = 0; i < 4; i++) {
    oled.println(label[i]);
    uint8_t w = oled.strWidth(label[i]);
    col0 = col0 < w ? w : col0;
  }

  col0 += 3;                                          // Nachzeilen
  col1 = col0 + oled.strWidth("99.9") + 2;            // Schriftweite
  rows = oled.fontRows();                             // Zeilenöhe


  for ( uint8_t i = 0; i < 4; i++) {
    oled.setCursor(col1 + 1, i * rows);               // schreibe
    oled.print(units[i]);
  }
  delay(3000);
  pinMode(Relais1, OUTPUT);                           // Hier wird Relais1 angeschlossen
  pinMode (LED, OUTPUT);                              // Hier wird die Status LED für Tip Betrieb angeschlossen
  pinMode(wert1, INPUT);                              // Wert zum rechnen der Temperatur
  pinMode(Taster, INPUT_PULLUP);                      // Hier wird der Taster angeschlossen

  dht.begin();
  LightSensor.begin();


  Serial.println(sollLux);
  Serial.println(Regen_an);
  Serial.println(sollTemp);
  Serial.println(Ausschaltspannung);


}
//------------------------------------------------------------------------------
void clearValue(uint8_t row) {
  oled.clear(col0, col1, row, row + rows - 1);
}
//------------------------------------------------------------------------------
void loop()
{
  currentMillis = millis();                           // Zeitschleife setzen


  if ( currentMillis - previousMillis > Volt_akt ) {
    previousMillis = currentMillis;
    wert1 = analogRead (A1);
    Volt = ((wert1 / 40.6086956522));

  }



  if ( currentMillis - oledMillis > oled_akt )
  {


    oledMillis = currentMillis;
    clearValue(0);
    oled.print(dht.readTemperature(), 1);
    clearValue(rows);
    oled.print(dht.readHumidity(), 1);
    clearValue(2 * rows);
    oled.print(lux = LightSensor.GetLightIntensity(), 1);
    clearValue(3 * rows);
    oled.print(Volt, 1);




    // Serial Print .... Ausgabe auf dem Computer

    Serial.println(dht.readTemperature(), 1);
    Serial.println(dht.readHumidity(), 1);
    Serial.println(lux);
    Serial.println(dht.readHumidity(), 1);
    Serial.println(wert1);
    Serial.println(Volt);
  }
  //----------------------------------------------- Hier folgen die Bedingungen ------------------------------------------------------------------------------------------------------------------------------------------
  {
    if (Taster == false)                                        // Wenn der Taster nicht gedrückt ist aber die Sensoren die Bedingungen erfüllen
      if ((lux = LightSensor.GetLightIntensity() >= sollLux) && (dht.readHumidity() <= Regen_an) && (dht.readTemperature() >= sollTemp) && (Volt >= Einschaltspannung))       //... wenn alle erfüllt sind
      {
        digitalWrite(Relais1, LOW);                             // schalte Relais _ Pumpe an
      }
      else if ((lux = LightSensor.GetLightIntensity() <= minLux) || (dht.readHumidity() >= Regen_aus) || (dht.readTemperature() <= minTemp) || (Volt <= Ausschaltspannung))  // sonst wenn eine nicht erfüllt ist
      {
        digitalWrite(Relais1, HIGH);                            // schalte Relais _ Pumpe aus
      }
  }
  //---------------------------------------------- Manuelles einschalten der Pumpe ---------------------------------------------------------------------------------------------------------------------------------------
  Tasterstatus = digitalRead(Taster);
  if (Tasterstatus == LOW  && (Volt >= Einschaltspannung)) {    // Taster gedrückt und Spannung > Einschaltspannung
    {
      myTimeout = 420000;                                       // Timerzeit in mS (1min = 60000 mS)
    }
    if (millis() < myTimeout + myTimer)                         // starte den Timer
    {

      digitalWrite(LED, HIGH);                                  // schalte LED an
      digitalWrite(Relais1, LOW);                               // schalte Relais _ Pumpe an
    }
    else                                                        // ansonsten

    {
      digitalWrite(LED, LOW);                                   // schalte die LED aus
      digitalWrite(Relais1, HIGH);                              // Schalte das Relais _ Pumpe aus
    }
  }
}

Das ist ein Codevorschlag, den ich gestern schon angefangen hatte.
Ganz wenige if's, die sich nur auf jeweils eine Bedingung beziehen.
Die Zeilenzahl hat sich nicht grossartig verändert.

Bitte unbedingt die Kommentare lesen.

Dein Code hat mit meinen Libs nicht kompiliert - wenn Du nicht weiterkommst, dann musst Du mir sagen, was Du für libs verwendest (Herkunft).

Ich habe eine Funktion int Temp() gebaut - nach dem Muster kannst Du auch für hum, voltage und lux vorgehen, damit Du nicht auf jeden kleinen Unterschied einen Zyklus durchlaufen musst.

// Forumcode https://forum.arduino.cc/t/poolsteuerung-3-wege-ventil-pumpe-pumpe/858918/31?u=my_xy_projekt

// basiert auf: https://forum.arduino.cc/t/poolsteuerung-3-wege-ventil-pumpe-pumpe/858918?u=my_xy_projekt
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <BH1750FVI.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

const byte DHT22_PIN = 2; //Temperatursensor
const byte LEDPin = 3;
const byte TasterPin = 4;
const byte SpannungPin = A1;
const byte WaermepumpePin = 10;
const byte WegeventilPin = 11;
const byte KollektorpumpePin = 12;

const int sollTemp = 19;            // Temperatur, Auslöser zum Einschalten
const int minTemp = 17;             // Temperatur, Auslöser zum Ausschalten
const int sollLux = 3500;         // Lichtsensor, Auslöser zum Einschalten
const int minLux = 2000;          // Lichtsensor, Auslöser zum Ausschalten
const int Regen_an = 70;            // Regensensor, Auslöser zum Einschalten
const int Regen_aus = 90;           // Regensensor, Auslöser zum Ausschalten
const float Einschaltspannung = 12.5; // Spannungssensor, Auslöden zum Einschalten
const float Ausschaltspannung = 11.2; // Spannungssensor, Auslöden zum Ausschalten

#define DHTTYPE    DHT22     // DHT 22 (AM2302)
#define RST_PIN -1 // Definiere Reset_PIN.
#define I2C_ADDRESS 0x3C // 0X3C+SA0 - 0x3C or 0x3D
SSD1306AsciiWire oled; //Display

BH1750FVI LightSensor(BH1750FVI::k_DevModeContLowRes);
DHT dht(DHT22_PIN, DHT22);//Temperatursensor

unsigned long oledMillis;
const unsigned long oledWait = 5000;         // Wartezeit OLED
const unsigned long Pumpzeit = 20000;        // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
const unsigned long Ventilstellzeit = 9000;  // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten

uint8_t col0 = 0;                                                       // First value column
uint8_t col1 = 0;                                                       // Last value column.
uint8_t rows;                                                           // Rows per line.
//------------------------------------------------------------------------------
void setup() {
  const char* label[] = {"Temp:", "Feuchte:", "Licht:", "U ="};           //vor den Werten
  const char* units[] = {"   C", "   \45", "   Lux", "   Volt" };         // nach den Werten
  Wire.begin();
  Wire.setClock(400000L);
  Serial.begin(115200);

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0
  oled.setFont(Arial14);
  oled.setLetterSpacing(2);                             // Buchstabenabstand.
  oled.clear();

  // Setup
  for (uint8_t i = 0; i < 4; i++) {
    oled.println(label[i]);
    uint8_t w = oled.strWidth(label[i]);
    col0 = col0 < w ? w : col0;
  }

  col0 += 3;
  col1 = col0 + oled.strWidth("99.9") + 2;
  rows = oled.fontRows();


  for ( uint8_t i = 0; i < 4; i++) {
    oled.setCursor(col1 + 1, i * rows);
    oled.print(units[i]);
  }
  pinMode(WegeventilPin, OUTPUT);
  pinMode(KollektorpumpePin, OUTPUT);
  pinMode(WaermepumpePin, OUTPUT);
  pinMode (LEDPin, OUTPUT);
  pinMode(SpannungPin, INPUT);
  pinMode(TasterPin, INPUT_PULLUP);
  // init der Pins auf definierten Zustand
  digitalWrite(WegeventilPin, LOW);
  digitalWrite(KollektorpumpePin, HIGH);
  digitalWrite(WaermepumpePin, HIGH);

  dht.begin();
  LightSensor.begin();

  Serial.println(sollLux);
  Serial.println(Regen_an);
  Serial.println(sollTemp);
  Serial.println(Ausschaltspannung);
}

void loop()
{
  automatik();
  setDisplay();
}


void automatik()
{
  // Alle Schritte für Kollektor und Wp
  enum {startK, wartenK1, einK, wartenK2, endeK,
        startWP, wartenWP1, einWP, wartenWP2, endeWP
       };
  static unsigned long waitmillis = 0;              // Merker für Pausenstart
  static int schritt = startK;                      // Merker für "Was wird gerade ausgeführt?"

  switch (schritt)
  {
    case startK:                                    // Ab hier startet Kollektor
      digitalWrite(WaermepumpePin, HIGH);
      Serial.println("Wärmepumpe aus");
      digitalWrite(WegeventilPin, LOW);
      Serial.println("3-Wege-Ventil auf Kollektorpumpe");
      waitmillis = millis();                        // merkt sich die aktuelle Zeit
      schritt = wartenK1;                           // Nächster Schritt
      break;
    case wartenK1:
      if (millis() - waitmillis > Ventilstellzeit)  // Wenn Zeit abgelaufen ...
      {
        schritt = einK;                             // ... nächster Schritt
      }
      break;
    case einK:                                      // Startet Pumpe
      Serial.println("Ventil umgestellt");
      digitalWrite(KollektorpumpePin, LOW);
      Serial.println("Kollektorpumpe an");
      waitmillis = millis();                        // Merkt sich Startzeit
      schritt = wartenK2;
      break;
    case wartenK2:
      if (millis() - waitmillis > Pumpzeit)         // Pumpenlaufzeit um?
      {
        schritt = endeK;
      }
      schritt = endeK;                              // Eine Pumpenrunde ist abgelaufen
      break;
    case endeK:                                     // hier bleibe bis sich das mit den Sensoren ändert
      if (!getAllSensors())                         // Wenn NICHT Sommer, Tag, und trocken ...
      {
        schritt = startWP;                          // ...dann starte Wärempumpe
      }
      break;
    case startWP:                                   // Ab hier startet Wärmepumpe
      digitalWrite(KollektorpumpePin, HIGH);        // Kollektorpumpe aus
      Serial.println("Kollektorpumpe Off");
      digitalWrite(WegeventilPin, HIGH);            // 3-Wege-Ventil wird auf Wärmepumpenkreis umgestellt
      Serial.println("3-Wege-Ventil auf Wärmepumpe");
      waitmillis = millis();
      schritt = wartenWP1;
      break;
    case wartenWP1:
      if (millis() - waitmillis > Ventilstellzeit)  // Wenn Zeit abgelaufen ...
      {
        schritt = einWP;                            // ... nächster Schritt
      }
      break;
    case einWP:
      digitalWrite(WaermepumpePin, LOW);            // Wärmepumpe an
      Serial.println("Wärmepumpe On");
      waitmillis = millis();                        // Startzeit merken
      schritt = wartenWP2;
      break;
    case wartenWP2:
      if (millis() - waitmillis > Pumpzeit)         // Pumpenlaufzeit um?
      {
        schritt = endeWP;
      }
      break;
    case endeWP:                                    // bleibe hier....
      if (getAllSensors())                          // Wenn Sommer, Tag, und trocken ...
      {
        schritt = startK;                           // ...dann starte KollektorZyklus
      }
      if (digitalRead(TasterPin) == LOW)
      {
        Serial.println("Taster gedrückt");
        schritt = startK;
      }
      break;
  }
}

bool getAllSensors()
{
  if ((getLux() >= sollLux)
      && ( getHum() <= Regen_an)
      && (getTemp() >= sollTemp)
      && (getVolt() >= Einschaltspannung))
  {
    return true;
  }
  return false;
}

int getLux()
{
  return LightSensor.GetLightIntensity();
}

int getHum()
{
  return dht.readHumidity();
}

int getTemp()
{
  static int temp = 0;
  static unsigned long previousMillis = 0;
  static unsigned int zaehler = 0;
  const unsigned long tempWait = 1000;       // Wartezeit in ms
  /*
    Die folgende Zeile kann man einbauen, wenn unbedingt
    mit dem Einschalten ein erster Wert erfasst werden soll
  */
  // if (previousMillis==0) Temp=dht.readTemperature()
  if (millis() - previousMillis > tempWait ) // Ist Wartezeit um?
  {
    previousMillis = millis();               // Setze Merker
    if (dht.readTemperature() != temp)       // Temperaturunterschied? ...
    { // ... der muss mehrmals passieren  ...
      if (zaehler < Ventilstellzeit / tempWait)
      {
        zaehler++;
      }
      else                                   // Wenn Zaehler voll
      {
        temp = (int)dht.readTemperature();
        zaehler = 0;
      }
    }
    else                                     // Kein Temperaturunterschied?
    {
      zaehler = 0;
    }
  }
  return temp;
}

float getVolt()
{
  static float Volt = 0;
  const unsigned long VoltWait = 60000;
  static unsigned long previousMillis = 0;
  if (millis() - previousMillis > VoltWait ) {
    previousMillis = millis();
    Volt = (((analogRead(SpannungPin) + 0.1) / 40.6086956522)); // Soviele Stellen hinterm Komma braucht keiner!
  }
  return Volt;
}


void clearValue(uint8_t row)
{
  oled.clear(col0, col1, row, row + rows - 1);
}

void setDisplay()
{
  if (millis() - oledMillis > oledWait )
  {
    oledMillis = millis();
    clearValue(0);
    oled.print(getTemp());
    clearValue(rows);
    oled.print(getHum());
    clearValue(2 * rows);
    oled.print(getLux());
    clearValue(3 * rows);
    oled.print(getVolt(), 1);

    // Serial Print .... Ausgabe auf dem Computer

    Serial.println(getTemp());
    Serial.println(getHum());
    Serial.println(getLux());
    Serial.println(getVolt(),1);
  }
}

Vielen Dank erst einmal.
Die Herangehensweise ist natürlich eine andere und auch vllt. schönere.
Ich werde es einfach mal ausprobieren aber parallel auch an meiner Variante feilen.
Irgendwie muss man damit ja auch auf das Ergebnis kommen.
Ich sehe aber auch das ich da noch viel Nachholbedarf habe um solche programme so strukturieren zu können.

Gruß Norman

Könnte es so auch gehen?
ich habe an dem Rechner wo ich gerade sitze nicht die Möglichkeit mit Strg, T einzurücken und meine Klammern zu prüfen, da ich hier keine Arduino Software drauf habe und die auch nicht installieren kann/darf.
@ my_xy_projekt könntest du das mal bitte schnell checken?

Danke
Gruß Norman

      if (Getastet == false) 	                      // Wenn der Taster nicht gedrückt ist aber die Sensoren die Bedingungen erfüllen
   {                           
      if ((lux = LightSensor.GetLightIntensity() >= sollLux) && (dht.readHumidity() <= Regen_an) && (dht.readTemperature() >= sollTemp) && (Volt >= Einschaltspannung))       		 //... wenn alle erfüllt sind
   {
     Serial.println("Sensorbedingungen erfüllt");
     Startzeit_Automatik = millis();                  // Timer nullen
     Ventilstellzeit_Automatik = 9000;                // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
     digitalWrite(Relais3, HIGH);                     // Wärmepumpe aus
     Serial.println("Wärmepumpe aus");
     digitalWrite(Relais1, LOW);                      // 3-Wegeventil-Ventil wird auf Kollektorkreis umgestellt
     Serial.println("3-Wege-Ventil auf Kollektorpumpe");
   }
    if (millis() - Startzeit_Automatik >= Ventilstellzeit_Automatik){
      digitalWrite(Relais2, LOW);                                   // Kollektorpumpe an
      Serial.println("Kollektorpumpe On");
   }
    else if ((lux = LightSensor.GetLightIntensity() <= minLux) || (dht.readHumidity() >= Regen_aus) || (dht.readTemperature() <= minTemp) || (Volt <= Ausschaltspannung)) 			 // sonst wenn eine nicht erfüllt ist
    Waermepumpe = true;   
   {
     if (Waermepumpe == true)
   {
      digitalWrite(Relais1, HIGH);                                  // 3-Wege-Ventil wird auf Wärmepumpenkreis umgestellt
      Serial.println("3-Wege-Ventil auf Wärmepumpe");
      digitalWrite(Relais2, HIGH);                                  // Kollektorpumpe aus
      Serial.println("Kollektorpumpe AUS"); 
   }
    if (millis() - Startzeit_Automatik >= Ventilstellzeit_Automatik)
   {
      digitalWrite(Relais3, LOW);                                   //Wärmepumpe an
      Serial.println("Wärmepumpe AN");
    }
  }
-----------------------------------------------------------------------------------------------------------------------------------------
  Tasterstatus = digitalRead(Taster);
  if (Tasterstatus == LOW  && (Volt >= Einschaltspannung))   // Taster gedrückt und Spannung > Einschaltspannung
 {
    Startzeit = millis();                                    // Timer nullen
    Ventilstellzeit = 9000;                                  // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Pumpzeit = 20000;                                        // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Serial.println("Taster gedrückt");
  }
    if (millis() - Startzeit <= Ventilstellzeit + Pumpzeit)
  {
    digitalWrite(LED, HIGH);                                 // Taster LED AN
    digitalWrite(Relais3, HIGH);                             // Wärmepumpe aus
    Serial.println("Wärmepumpe aus_manuell");
    digitalWrite(Relais1, LOW);                              // 3-Wegeventil-Ventil auf Kollektorkreis
    Serial.println("3-Wege-Ventil auf Kollektorpumpe_manuell");
  }
  if (millis() - Startzeit >= Ventilstellzeit) 
  {
    Serial.println("Ventil umgestellt");
    digitalWrite(Relais2, LOW);                              // Kollektorpumpe an
    Serial.println("Kollektorpumpe an");
  }
    if (millis() - Startzeit >= Pumpzeit + Ventilstellzeit) 
  {
     digitalWrite(LED, LOW);                                // Taster LED aus
     Waermepumpe = true;
     Getastet = false;
  }
}

Na schnell ist relativ. Ich hab jetzt auch nur drauf geschaut, was mir sofort auffällt.
Da ich anders formatiere kommen die Klammern natürlich besser zum Vorschein.

Ich gehe jetzt von dem aus, was ich Dir ranhänge.
In Zeile 19 gibst Du der Var Waermepumpe den Wert true.
Danach kommt eine öffnende Klammer. Die braucht es an der Stelle nicht.
Das Pendant dazu ist dann die schliessende Klammer in Zeile 33.
ICH würde, weil ich das mit der Übersichtlichkeit anders handhabe, die öffnende Klammer in Zeile 19 setzen Zeile 19 wird dann 20 und neue Zeile 21 die schliessende Klammer.
Damit wird auch für einen aussenstehenden klar, das nur die Wertzuweisung auf die Bedingung folgt.

Ansonsten könnte das - wenn ich das richtig interpretiere - so funktionieren.

Inwieweit sich die if's gegenseitig beeinflussen, kann ich so aus dem Stehgreif nicht sagen....

if (Getastet == false)                         // Wenn der Taster nicht gedrückt ist aber die Sensoren die Bedingungen erfüllen
{
  if ((lux = LightSensor.GetLightIntensity() >= sollLux) && (dht.readHumidity() <= Regen_an) && (dht.readTemperature() >= sollTemp) && (Volt >= Einschaltspannung))            //... wenn alle erfüllt sind
  {
    Serial.println("Sensorbedingungen erfüllt");
    Startzeit_Automatik = millis();                  // Timer nullen
    Ventilstellzeit_Automatik = 9000;                // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    digitalWrite(Relais3, HIGH);                     // Wärmepumpe aus
    Serial.println("Wärmepumpe aus");
    digitalWrite(Relais1, LOW);                      // 3-Wegeventil-Ventil wird auf Kollektorkreis umgestellt
    Serial.println("3-Wege-Ventil auf Kollektorpumpe");
  }
  if (millis() - Startzeit_Automatik >= Ventilstellzeit_Automatik) 
  {
    digitalWrite(Relais2, LOW);                                   // Kollektorpumpe an
    Serial.println("Kollektorpumpe On");
  }
  else if ((lux = LightSensor.GetLightIntensity() <= minLux) || (dht.readHumidity() >= Regen_aus) || (dht.readTemperature() <= minTemp) || (Volt <= Ausschaltspannung))        // sonst wenn eine nicht erfüllt ist
    Waermepumpe = true;
  {
    if (Waermepumpe == true)
    {
      digitalWrite(Relais1, HIGH);                                  // 3-Wege-Ventil wird auf Wärmepumpenkreis umgestellt
      Serial.println("3-Wege-Ventil auf Wärmepumpe");
      digitalWrite(Relais2, HIGH);                                  // Kollektorpumpe aus
      Serial.println("Kollektorpumpe AUS");
    }
    if (millis() - Startzeit_Automatik >= Ventilstellzeit_Automatik)
    {
      digitalWrite(Relais3, LOW);                                   //Wärmepumpe an
      Serial.println("Wärmepumpe AN");
    }
  }
  ---------------------------------------------------------------------------------------------------------------------------------------- -
  Tasterstatus = digitalRead(Taster);
  if (Tasterstatus == LOW  && (Volt >= Einschaltspannung))   // Taster gedrückt und Spannung > Einschaltspannung
  {
    Startzeit = millis();                                    // Timer nullen
    Ventilstellzeit = 9000;                                  // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Pumpzeit = 20000;                                        // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Serial.println("Taster gedrückt");
  }
  if (millis() - Startzeit <= Ventilstellzeit + Pumpzeit)
  {
    digitalWrite(LED, HIGH);                                 // Taster LED AN
    digitalWrite(Relais3, HIGH);                             // Wärmepumpe aus
    Serial.println("Wärmepumpe aus_manuell");
    digitalWrite(Relais1, LOW);                              // 3-Wegeventil-Ventil auf Kollektorkreis
    Serial.println("3-Wege-Ventil auf Kollektorpumpe_manuell");
  }
  if (millis() - Startzeit >= Ventilstellzeit)
  {
    Serial.println("Ventil umgestellt");
    digitalWrite(Relais2, LOW);                              // Kollektorpumpe an
    Serial.println("Kollektorpumpe an");
  }
  if (millis() - Startzeit >= Pumpzeit + Ventilstellzeit)
  {
    digitalWrite(LED, LOW);                                // Taster LED aus
    Waermepumpe = true;
    Getastet = false;
  }
}

Also so funktioniert es leider auch nicht.
Ich kapiers einfach nicht. :face_with_raised_eyebrow:

Das ist ne Aussage.
Aber was funktioniert denn nicht?

Ich hab mir mal den Teil von oben ab Zeile 35 ( Tasterstatus = digitalRead(Taster); ) angesehen.
Du setzt Dir zwar die Zeiten, aber merkst Dir nicht, das der Taster gedrückt wurde.
Das führt dazu, das die Bedingung in Zeile 1 IMMER ERFÜLLT ist.

Nochmal: Du verhaust Dich, weil Du alles gegeneinander verriegeln und gedanklich auch noch die Zustände merken musst. Sobald ein if Dir dazwischen manscht, fliegt Dir der Kram um die Ohren.
Du hast jetzt nur zwei Bedingungen - Taste gedrückt; Taste nicht gedrückt.
Wenn Du später irgendwas dazu bauen willst, musst Du für mindestens 9 (NEUN) Bedingungen prüfen.

Okay, aber wie bekomme ich meine "Merker" jetzt da rein?

Zwischen Zeile 40 und 41 eine neue Zeile

  Getastet = true;

???

Ich komme nicht mehr mit.
Wenn das so weiter geht schmeiß ich den Scheiß hinter und baue mir einen Stecker betriebenen Tauchsieder in meinen Pool.
Ich glaube mir fehlen um das zu verstehen die Synapsen. :stuck_out_tongue:

Alt:

  if (Tasterstatus == LOW  && (Volt >= Einschaltspannung))   // Taster gedrückt und Spannung > Einschaltspannung
  {
    Startzeit = millis();                                    // Timer nullen
    Ventilstellzeit = 9000;                                  // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Pumpzeit = 20000;                                        // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Serial.println("Taster gedrückt");
  }

NEU:

  if (Tasterstatus == LOW  && (Volt >= Einschaltspannung))   // Taster gedrückt und Spannung > Einschaltspannung
  {
    Startzeit = millis();                                    // Timer nullen
    Ventilstellzeit = 9000;                                  // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Pumpzeit = 20000;                                        // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Getastet = true;
    Serial.println("Taster gedrückt");
  }

ABER! Du kommst in Teufels Küche, wenn Du Dich in der Automatik befindest! Weil Du den manuellen Zweig nicht verriegelst.

Darum ab Zeile 35 neu:

  Tasterstatus = digitalRead(Taster);
  if (Tasterstatus == LOW  && (Volt >= Einschaltspannung))   // Taster gedrückt und Spannung > Einschaltspannung
  {
    Startzeit = millis();                                    // Timer nullen
    Ventilstellzeit = 9000;                                  // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Pumpzeit = 20000;                                        // Timerzeit in mS (1min = 60000 mS) 1,5 min um das 3 Wegeventil zu schalten
    Getastet = true;
    Serial.println("Taster gedrückt");
  }
  if (getastet == true)
  {
    if (millis() - Startzeit <= Ventilstellzeit + Pumpzeit)
    {
      digitalWrite(LED, HIGH);                                 // Taster LED AN
      digitalWrite(Relais3, HIGH);                             // Wärmepumpe aus
      Serial.println("Wärmepumpe aus_manuell");
      digitalWrite(Relais1, LOW);                              // 3-Wegeventil-Ventil auf Kollektorkreis
      Serial.println("3-Wege-Ventil auf Kollektorpumpe_manuell");
    }
    if (millis() - Startzeit >= Ventilstellzeit)
    {
      Serial.println("Ventil umgestellt");
      digitalWrite(Relais2, LOW);                              // Kollektorpumpe an
      Serial.println("Kollektorpumpe an");
    }
    if (millis() - Startzeit >= Pumpzeit + Ventilstellzeit)
    {
      digitalWrite(LED, LOW);                                // Taster LED aus
      Waermepumpe = true;
      Getastet = false;
    }
  }
}