China Standheizungssteuerung

Hallo, ich habe mal wieder ein Projekt zum Verzweifeln.
Ich habe mir für mein Gewächshaus eine China Standheizung gekauft, diese funktioniert auch so weit tadellos, ABER!!!
Ich würde diese gerne über einen Arduino UNO steuern, die Fernbedienung hat 4 Taster, 1x An, 1x Aus, 1x Heizstufe +, 1x Heizstufe -. Zum Einschalten muss man die Taste 2 Sekunden drücken, und zum Ausschalten ebenfalls 2 Sekunden drücken. Wenn ich die Powertaste lange drücke kommt sie in irgendein Menü, und reagiert nicht mehr.

Ich überwache die Temperatur über einen DHT11. Soweit habe ich auch alles geschafft zu Coden, aber ich schaffe es nicht, dass das Relais für An oder Aus nur 2 Sekunden getriggert wird, und dann wieder abschaltet.
Ich habe es soweit das der Arduino bei unterschreiten der Solltemperatur auf Pin 10 sagt Heizung an, aber halt als Dauer Signal, dieses soll auf Pin A1 gehen, und dann soll das Signal auf 2 sec getriggert über Pin A2 rausgehen und mittels eines Relais den Taster für an 2 Sekunden Triggern.
Ich möchte um nicht den ganzen Arduino zu blockieren auf Delay befehle verzichten, stattdessen soll das über millis() laufen.
Dazu suche ich auch noch nach einem Sinnvollen Befehl, der den Arduino alle X Tage neustartet, falls ich mal auf Montage oder im Urlaub bin. ( Ja ich habe Frau und Kinder, aber wie Kinder nur mal so sind, ist das Handy so wichtig dass ich davon ausgehen muss dass sie es vergessen).

In Arbeit ist auch noch ein 2. Arduino der mittels innen und Außentemperatur 4 Schrittmotoren Steuern soll, der die Dachfenster zum Lüften öffnen und schließen kann.
Ein 3. Arduino ist im Bau, der im Gewächshaus 4 Ventile ansteuern soll zum Bewässern der Beete im Gewächshaus.
Ein 4. Arduino soll dann Messen wieviel Stunden Sonne die Pflanzen bekommen haben und dementsprechend Pflanzlicht ein und ausschalten können.
Ein 5. Arduino soll noch als Wetterstation aufgebaut werden, um auf einem Ausrangierten Tablet mir alle interessanten wetter- und Luftqualitätsdaten anzuzeigen.
Und zu guter Letzt soll noch ein Arduino Mega kommen, der die Bewässerung des Restlichen Grundstückes steuert.
Diese solle alle über den I2C verbunden werden und mir die Daten über IoBroker ausgeben. Aber das ist alles Zukunft.

Wichtig ist mir erstmal das, ich das Problem mit dem Ausgang auf 2 Sekunden triggern hinbekomme. Ich glaube fas ich denke zu kompliziert um 8 Ecken. Bitte mich wegen dem Code nicht lünchen, Ich bin zwar IT-ler aber vom Programmieren habe ich so gut wie kein plan, nur die Grundübungen aus diversen Arduino Büchern.
Ich hoffe mir kann jemand helfen, ich sitze hier seit 2 Wochen dran und bekomme das Signal nicht getriggert, ansonsten läuft das seit 8 Tagen.

Bekomme das mit dem Code hochladen nicht hin, wo finde ich den das ensprechende modul dafür? :face_with_spiral_eyes:

Hier.

Gruß Tommy

#include <LiquidCrystal.h>
#include <DHT.h>
unsigned long timer = 0;

//const uint8_t HeizungAn1_pin = A1;
//const uint8_t HeizungAus1_pin = A2;
//const uint8_t RelaisAn1_pin = A3;
//const uint8_t RelaisAus1_pin = A4;
uint32_t on_zeit;
bool HeizungAn1_state, HeizungAn1_state_alt = 1;
bool HeizungAus1_state, HeizungAus1_state_alt = 1;

const int
  DHT_PIN = A0,                                         // Sensor Pin für Temperatur und Luftfeuchtigkeit
  DHT_TYPE = DHT11;                                     // sensor Typ DTH11

DHT sensor(DHT_PIN, DHT_TYPE);


const int                                               // LCD-Konfiguration: Sollte Temperatur und Luftfeuchtigkeit zuordnen
  LCD_PIN_RS = 11,                                      // Datenverbindungen zum Display
  LCD_PIN_EN = 12,
  LCD_PIN_D4 = 2,
  LCD_PIN_D5 = 3,
  LCD_PIN_D6 = 4,
  LCD_PIN_D7 = 5;

LiquidCrystal lcd

  (
    LCD_PIN_RS,                                         // Datenverbindungen zum Display
    LCD_PIN_EN,
    LCD_PIN_D4,
    LCD_PIN_D5,
    LCD_PIN_D6,
    LCD_PIN_D7);


const int
  DECREMENT_BTN_PIN = 7,                                // Taster konfiguration
  TOGGLE_BTN_PIN = 8,
  INCREMENT_BTN_PIN = 9;

                                                        // "Heizung An" und "Aus" configuration
const int
  HeizungAn_PIN = 13,
  HeizungAus_PIN = 10;
  HeizungAn1_pin = A1;
  HeizungAus1_pin = A2;               
  RelaisAn1_pin = A3;                       
  RelaisAus1_pin = A4;                     


                                                        // Controls
bool useFahrenheit = false;
int targetF = 68, targetC = 20;                         // Soll Temperatur

void setup() {
                                                        // Serial (for logging)
    Serial.begin(9600);
    Serial.print("setup()\n");

                                                        // Sensor starten
    sensor.begin();
    Serial.print("\tsensor initialized\n");

                                                        // LCD
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
      lcd.clear();
    Serial.print("\tLCD initialized\n");

                                                        // Taster
  pinMode(INCREMENT_BTN_PIN, INPUT);
  pinMode(DECREMENT_BTN_PIN, INPUT);
  pinMode(TOGGLE_BTN_PIN, INPUT);
    Serial.print("\tButtons initialized\n");

                                                        // Temperatur Kontrolle
  pinMode(HeizungAn_PIN, OUTPUT);                       // Ausgang pin 10 Dauersignal Output // Heizen An
  pinMode(HeizungAus_PIN, OUTPUT);                      // Ausgang pin 13 Dauersignal Output // Heizen Aus
  pinMode(HeizungAn1_pin, INPUT_PULLUP);                // Eingang Dauersignal von pin 10 auf pin A1 als Input
  PinMode(HeizungAus1_pin, INPUT_PULLUP);               // Eingang Dauersignal von pin 13 auf pin A2 als Input
  pinMode(RelaisAn1_pin, OUTPUT);                       // Ausgang von pin A1 auf A3 2 sec Output // Heizung An
  pinMode(RelaisAus1_pin, OUTPUT);                      // Ausgang von pin A2 auf A4 2 sec Output // Heizung Aus

    Serial.print("setup() DONE\n");
}

void loop() {
    Serial.print("loop()\n");

                                                        // Taster status lesen
  bool incrementTarget = digitalRead(INCREMENT_BTN_PIN);
  bool decrementTarget = digitalRead(DECREMENT_BTN_PIN);
  bool toggle = digitalRead(TOGGLE_BTN_PIN) == HIGH;
  bool wait = incrementTarget || decrementTarget || toggle;

                                                        // Taster konfiguration
  if (toggle) useFahrenheit = !useFahrenheit;
  if (incrementTarget) {
    targetF++;
    targetC++;
  }
  if (decrementTarget) {
    targetF--;
    targetC--;
  }
  const char symbol = useFahrenheit ? 'F' : 'C';
  const int target = useFahrenheit ? targetF : targetC;

HeizungAn1_state = digitalRead(HeizungAn1_pin);
     if (HeizungAn1_state != HeizungAn1_state_alt)  
  {
      on_zeit = millis();
      HeizungAn1_state_alt = HeizungAn1_state;
  }
    if (!HeizungAn1_state)
  {
    digitalWrite(HeizungAn1_pin,HIGH);
    if (millis()-on_zeit >warten) digitalWrite(RelaisAn1_pin, HIGH);
    // if (millis(2000)-on_zeit >warten) RelaisAn1(RelaisAn1_pin, 400);
  }
    else
    {
      digitalWrite(HeizungAn1_pin,LOW); digitalWrite(RelaisAn1, LOW);
    }

HeizungAn2_state = digitalRead(HeizungAn2_pin);
     if (HeizungAn2_state != HeizungAn2_state_alt)  
  {
      on_zeit = millis();
      HeizungAn2_state_alt = HeizungAn2_state;
  }
    if (!HeizungAn2_state)
  {
    digitalWrite(HeizungAn2_pin,HIGH);
    if (millis()-on_zeit >warten) digitalWrite(RelaisAn2_pin, HIGH);
    // if (millis(2000)-on_zeit >warten) RelaisAn2(RelaisAn1_pin, 400);
  }
    else
    {
      digitalWrite(HeizungAn2_pin,LOW); digitalWrite(RelaisAn2, LOW);
    }
                                                      // Read Sensor Data
  float temperature = sensor.readTemperature(useFahrenheit);
  float humidity = sensor.readHumidity();
  
      Serial.print(
    "\t" + String(temperature) + "°" + symbol + ", Relative Humidity " + String(humidity) + "% \n");

                                                      // Ausgabe an LCD
  lcdWrite(0, "Temp:   " + String(temperature) + symbol);
  lcdWrite(1, "Soll:   " + String(target) + ".00" + symbol);

                                                        // Active Temperatur Kontrolle
  if (round(target) > round(temperature)) digitalWrite(HeizungAn_PIN, HIGH);
  else digitalWrite(HeizungAn_PIN, LOW);

  if (round(target) < round(temperature)) digitalWrite(HeizungAus_PIN, HIGH);
  else digitalWrite(HeizungAus_PIN, LOW);

                                                            // Pause to allow finger to lift from button(s)
  if (wait) delay(500);
}

                                                            // Utility to simplify writing to LCD
void lcdWrite(const bool line, const String& text) {
  lcd.setCursor(0, line);
  lcd.print(text);
}

Dankeschön

Liegen Deine Grundstücksmaße im Bereich um 20 cm? Weil nur dafür ist I2C spezifiziert (ohne Extender).

Gruß Tommy

Nein, aber ich habe einen Schaltkasten für die Arduinos im Gewächshaus, da passen gefühlt 30 Arduinos sammt Relais rein :sweat_smile:

Das ist der einzige Teil, den ich da rausgelesen habe und beantworten möchte.
Las es sein, das Ding neu zu starten, wenn es nicht notwendig ist.
Wenn Du kein delay() verwendest, dann kannst Du einen Watchdogtimer aktivieren und auf 8Sekunden stellen.
Wird der Wdt nicht in dieser Zeit aufgerufen, gibts einen Reset.

Den Rest lese ich mir evtl. durch, wenn Du in dem Fliesstext mal ein paar Absätze rein baust.

Sorry die würden beim Einfügen getillt, hatte meine kurze auf dem schoß und nur schnell abgesendet

Ok, dann passen die Entfernungen wohl. :wink:
Ist es im Gewächshaus für Elektronik nicht etwas arg feucht?

Gruß Tommy

Wenn du sowieso über Relais arbeiten willst, warum schaltest du die Heizung nicht direkt?

Weil das eine China Diesel Standheizung ist, wen ich da den Außenleiter schalte, leuchtet nur die Stanby leuchte. Deshalb muss ich an der Fernbedienung die Taster für an und aus triggern.

Ne das ist ein Edelstahl Gehäuse in dem vorher die Technik für eine LKW-Waage im Aussenbereich am Hafen verbaut war, und da sind gefühlt 20 Silikat Beutel drinnen

Das problem ist, so wie ich Verstanden habe, das durch millis() ein Timer ab Start des Arduinos arbeitet der nach max 50 Tagen abbricht weil die etwas über 4.000.000 millisekunden vorbei sind.

Nein.
Da hast Du was falsch verstanden.
millis() läuft nach 49 Tagen+x über.
Wenn Du die Auswertung nicht in die Zukunft legst, wird ganz normal gerechnet und der Überlauf juckt Dich kein bissl.
Stell Dir mal vor, es müssten alle Millionen Arduinos, die mit millis() als Zeitbasis arbeiten aller paar Tage neu starten.... :crazy_face:

Ok, schon mal eine Baustelle weniger.

Ich hab grad mal in den code geschaut.
welche pins sollen nur 2 sek ziehen? heizungan/heizungaus?

Genau, entweder direkt 10 & 13 oder über umweg die A2 & A4

Ich hätte gerne was gebaut, aber ich bekomme Deinen Sketch nicht einmal kompiliert - da sind soviele Fehler drin, das ich das nciht aufgelöst bekomme.

Mach mir einen Sketch, der die Temperatur nur in °C ausliest und nur für eine Deiner PIN-Konfiguration gedacht ist.

Deine Fahrenheit-Geschichte kannst Du während der Laufzeit ermitteln, die brauchst Du nicht in targetF zu speichern und der Rest ergibt sich dann.
Ich hatte vor, das hier:


void heatControl()
{
  enum status {start, ausschalten, sperre}; // die drei Zustände
  static byte heatStatus = start;              // Grundzustand
  static uint32_t lastswitch = 0;              // Zeitmerker
  switch (heatStatus)
  {
    case start:                                        // Ab hier gehts los
      // Active Temperatur Kontrolle
      if (target > temperature &&                       // Temperatur zu niedrig
          digitalRead(HeizungAn_Pin) == LOW)            // Und Heizung ist nicht gesetzt
      {
        digitalWrite(HeizungAus_PIN, LOW);              // Vorsichtshalber Pin löschen
        digitalWrite(HeizungAn_PIN, HIGH);              // Pin setzen
        lastswitch = millis();                          // Zeit merken
        heatStatus = ausschalten;                           // nächsten Schritt auslösen
      }
      else if (target < temperature &&                  // (oder) Temperatur zu hoch
               digitalRead(HeizungAus_Pin) == LOW)      // und Aus nocht gesetzt
      {
        digitalWrite(HeizungAn_PIN, LOW);               // Vorsichtshalber PIN löschen
        digitalWrite(HeizungAus_PIN, HIGH);             // PIN setzen
        lastswitch = millis();                          // Zeit merken
        heatStatus = ausschalten;                           // nächsten Schritt auslösen
      }
      break;
    case ausschalten:                                   //
      if (millis() - lastswitch > 2000)                 // Wenn zeit abgelaufen
      {
        digitalWrite(HeizungAn_PIN, LOW);               // Da für beide das gleiche gilt werden
        digitalWrite(HeizungAus_PIN, LOW);              // beide Pins einfach gelöscht
      }
      heatStatus = sperre;
      break;
    case sperre:                                      // Wiederanlaufsperre
      if (millis() - lastswitch > 30000)                // Erst wenn Zeit abgelaufen
      {
        heatStatus = start;                                // gehe wieder in den Anfangszustand
      }
      break;
  }
}

irgendwie zu integrieren - muss aber leider passen.

Das werde ich gleich mal testen, Danke schon mal, und mich an das Pinne eintragen machen, ich habe mal alles was ich wegen dem Triggern versucht habe auskommentiert, jetzt kann man auch wieder kompilieren.

#include <LiquidCrystal.h>
#include <DHT.h>
unsigned long timer = 0;

//const uint8_t HeizungAn1_pin = A1;
//const uint8_t HeizungAus1_pin = A2;
//const uint8_t RelaisAn1_pin = A3;
//const uint8_t RelaisAus1_pin = A4;
uint32_t on_zeit;
//bool HeizungAn1_state, HeizungAn1_state_alt = 1;
//bool HeizungAus1_state, HeizungAus1_state_alt = 1;

const int
  DHT_PIN = A0,                                         // Sensor Pin für Temperatur und Luftfeuchtigkeit
  DHT_TYPE = DHT11;                                     // sensor Typ DTH11

DHT sensor(DHT_PIN, DHT_TYPE);


const int                                               // LCD-Konfiguration: Sollte Temperatur und Luftfeuchtigkeit zuordnen
  LCD_PIN_RS = 11,                                      // Datenverbindungen zum Display
  LCD_PIN_EN = 12,
  LCD_PIN_D4 = 2,
  LCD_PIN_D5 = 3,
  LCD_PIN_D6 = 4,
  LCD_PIN_D7 = 5;

LiquidCrystal lcd

  (
    LCD_PIN_RS,                                         // Datenverbindungen zum Display
    LCD_PIN_EN,
    LCD_PIN_D4,
    LCD_PIN_D5,
    LCD_PIN_D6,
    LCD_PIN_D7);


const int
  DECREMENT_BTN_PIN = 7,                                // Taster konfiguration
  TOGGLE_BTN_PIN = 8,
  INCREMENT_BTN_PIN = 9;

                                                        // "Heizung An" und "Aus" configuration
const int
  HeizungAn_PIN = 13,
  HeizungAus_PIN = 10;
  //HeizungAn1_pin = A1;
  //HeizungAus1_pin = A2;               
  //RelaisAn1_pin = A3;                       
  //RelaisAus1_pin = A4;                     


                                                        // Controls
bool useFahrenheit = false;
int targetF = 68, targetC = 20;                         // Soll Temperatur

void setup() {
                                                        // Serial (for logging)
    Serial.begin(9600);
    Serial.print("setup()\n");

                                                        // Sensor starten
    sensor.begin();
    Serial.print("\tsensor initialized\n");

                                                        // LCD
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
      lcd.clear();
    Serial.print("\tLCD initialized\n");

                                                        // Taster
  pinMode(INCREMENT_BTN_PIN, INPUT);
  pinMode(DECREMENT_BTN_PIN, INPUT);
  pinMode(TOGGLE_BTN_PIN, INPUT);
    Serial.print("\tButtons initialized\n");

                                                        // Temperatur Kontrolle
  pinMode(HeizungAn_PIN, OUTPUT);                       // Ausgang pin 10 Dauersignal Output // Heizen An
  pinMode(HeizungAus_PIN, OUTPUT);                      // Ausgang pin 13 Dauersignal Output // Heizen Aus
  //pinMode(HeizungAn1_pin, INPUT_PULLUP);                // Eingang Dauersignal von pin 10 auf pin A1 als Input
  //PinMode(HeizungAus1_pin, INPUT_PULLUP);               // Eingang Dauersignal von pin 13 auf pin A2 als Input
  //pinMode(RelaisAn1_pin, OUTPUT);                       // Ausgang von pin A1 auf A3 2 sec Output // Heizung An
  //pinMode(RelaisAus1_pin, OUTPUT);                      // Ausgang von pin A2 auf A4 2 sec Output // Heizung Aus

    Serial.print("setup() DONE\n");
}

void loop() {
    Serial.print("loop()\n");

                                                        // Taster status lesen
  bool incrementTarget = digitalRead(INCREMENT_BTN_PIN);
  bool decrementTarget = digitalRead(DECREMENT_BTN_PIN);
  bool toggle = digitalRead(TOGGLE_BTN_PIN) == HIGH;
  bool wait = incrementTarget || decrementTarget || toggle;

                                                        // Taster konfiguration
  if (toggle) useFahrenheit = !useFahrenheit;
  if (incrementTarget) {
    targetF++;
    targetC++;
  }
  if (decrementTarget) {
    targetF--;
    targetC--;
  }
  const char symbol = useFahrenheit ? 'F' : 'C';
  const int target = useFahrenheit ? targetF : targetC;

/*HeizungAn1_state = digitalRead(HeizungAn1_pin);
     if (HeizungAn1_state != HeizungAn1_state_alt)  
 {
      on_zeit = millis();
      HeizungAn1_state_alt = HeizungAn1_state;
  }
    if (!HeizungAn1_state)
 {
    digitalWrite(HeizungAn1_pin,HIGH);
    if (millis()-on_zeit >warten) digitalWrite(RelaisAn1_pin, HIGH);
    // if (millis(2000)-on_zeit >warten) RelaisAn1(RelaisAn1_pin, 400);
  }
    else
    {
      digitalWrite(HeizungAn1_pin,LOW); digitalWrite(RelaisAn1, LOW);
    }

HeizungAn2_state = digitalRead(HeizungAn2_pin);
     if (HeizungAn2_state != HeizungAn2_state_alt)  
  {
      on_zeit = millis();
      HeizungAn2_state_alt = HeizungAn2_state;
  }
    if (!HeizungAn2_state)
  {
    digitalWrite(HeizungAn2_pin,HIGH);
    if (millis()-on_zeit >warten) digitalWrite(RelaisAn2_pin, HIGH);
    // if (millis(2000)-on_zeit >warten) RelaisAn2(RelaisAn1_pin, 400);
  }
    else
    {
      digitalWrite(HeizungAn2_pin,LOW); digitalWrite(RelaisAn2, LOW);
    }
 */
                                                      // Read Sensor Data
  float temperature = sensor.readTemperature(useFahrenheit);
  float humidity = sensor.readHumidity();
  
    Serial.print(
    "\t" + String(temperature) + "°" + symbol + ", Relative Humidity " + String(humidity) + "% \n");

                                                      // Ausgabe an LCD
  lcdWrite(0, "Temp:   " + String(temperature) + symbol);
  lcdWrite(1, "Soll:   " + String(target) + ".00" + symbol);

                                                        // Active Temperatur Kontrolle
  if (round(target) > round(temperature)) digitalWrite(HeizungAn_PIN, HIGH);
  else digitalWrite(HeizungAn_PIN, LOW);

  if (round(target) < round(temperature)) digitalWrite(HeizungAus_PIN, HIGH);
  else digitalWrite(HeizungAus_PIN, LOW);

                                                            // Pause to allow finger to lift from button(s)
  if (wait) delay(500);
}

                                                            // Utility to simplify writing to LCD
void lcdWrite(const bool line, const String& text) {
  lcd.setCursor(0, line);
  lcd.print(text);
}

Vielleicht hilft das meine kaputten gedanken zu verstehen.