Kaminofen Klappensteuerung

Antwort erstellen

Bestätigungscode
Gib den Code genau so ein, wie du ihn siehst; Groß- und Kleinschreibung wird nicht unterschieden.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :arrow: :| :mrgreen: :geek: :ugeek:

BBCode ist ausgeschaltet
Smilies sind eingeschaltet

Die letzten Beiträge des Themas
   

Ansicht erweitern Die letzten Beiträge des Themas: Kaminofen Klappensteuerung

Re: Kaminofen Klappensteuerung

von eltoro » Sa Apr 10, 2021 7:46 am

Hier schon mal zum Geniessen der mittlerweile seit mindestens 2015 laufende Code.
An 1000 Stellen optimierbar, aber : "never touch a running system"


Code: Alles auswählen

#include <DS3231.h>         //Uhrenmodul
#include <EEPROM.h>
#include "Wire.h"
#include "TwoWireLCD.h"
//#include "PinChangeInt.h"
#include <SoftwareSerial.h>       
char progVersion[] {"13_2_BT"};    //  25.1.20 
//  Zeiteinstellung
//+++++++++++++++++++  Neue Auswertung PAP-designer ++++++++++++++++
SoftwareSerial BTSerial(10,11); // RX, TX (Board); TX, RX (Modul)  BlueToth
// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);
// Init a Time-data structure
Time  t;
char TasteSer;                              // Taste Serielle Eingabe vom Terminal
unsigned char second = 0;                   //
unsigned char minute = 0;
unsigned char hour = 0;

int T1;                                     //  RohrTemperatur
// Status n=Neustart, t=Timer läuft (Klappe fährt), p=Pause
char Status = 'n';
char Folgebefehl = 'P';                     // B=Blockieren, F=12s auf, S=Schließen, T=Turbo
uint8_t Anzeige = 0;                        // 0=Raum  1=Rohr 2=KlappeWinkel 3=Anheizenstatus 4=usw
uint8_t Heizphase = 1;                      // 1=Anheizen bis Rohrtempmax  0= rohrtempmax erreich 2=wenn unter 
                                            // 120 grad dann bleibt Klappe zu
int KlappeOffset = 0;                       // verhindert Klappe ganz zu bis unter 120°C
uint8_t RTOffset;                           // Klappenoffset in Abhängigkeit von Raumtemperatur
int KlappeWAkt = 0;                         // 0= zu   150= auf 
int KlappeWNeu =0, KlappeWAktAlt=0,KlappeMittOeffnung=14,KlappeZug=18;
int KlappeWeit=19; 
// [9]-eeAdRohrGrund  ={18}
int eeAdresse, eeWert;                      // Temp Adresse zum Einzelne Daten schreiben
int eeAd[] {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40};
bool TimerStop = false;                     //Unerbrechung möglich j n
int8_t TastenCode = 0;                      // 1. oder 2. Belegung 0,4,8 oder 8= kein Befehl
int RohrTemp, RohrTempMin, RohrTempMax,RohrTempMitte,RohrTempTief=100, RohrTempAlt, RohrDiff, RohrTempFenster=50;
int RohrGrund=170, RohrDiffFakt=7;          // für Berechnung RohrTempMin
char RohrTempTendenz = 'n';                 // +, n (neutral), -
int RaumTemp, RaumTempAlt, RaumTempZiel=23, RaumTempKorr=4;
float RaumTempF;                  // für Temperaturanzeige mit Nachkommastellen
bool AuswertungFertig = 0;
int PT1000 = 0; 
int PT1000Offset=0;   //Offset für Rohrtemperatur 
int x;  
int ZStunde, ZMinute, ZSekunde;
const char KlappeZu = 8 ;               // Relais Klappe zu an Pin 8
const char KlappeAuf = 7 ;              // Relais Klappe auf an Pin 7 
unsigned long pos;                      // für KlappeFahrtD
unsigned long AlteZeit5 =0 ; 
unsigned long EndZeit5= 1800000; // 1/2 Stunde
unsigned long AlteZeit4=0,EndZeit4=1000;             // 1 sec für schnellere Ausgaben
unsigned long AlteZeit = 0 , EndZeit=0;           //          Klappenlaufzeit
unsigned long AlteZeit2 = 0 , EndZeit2 = 4000;  // 2 sec    Displayausgabe Wiederholung  
unsigned long AlteZeit3 = 0 , EndZeit3 = 40000;// 180 sec  Auswertezeit Wiederholung
int ZFaktor = 0;                // Zähler wie oft abgekühlt
char Text1[] = "RaumRohrKlapMaxTMinTStatZeitFaktDiffVers";  
char Phase='A',PhaseAlt='A';  
bool Buzzer=true;
int KlappeFahrt(unsigned long, char);
unsigned long messzeit;           // Für Schleifenzeitmessung
void keyPress();                          // Funktion wenn Gerätetaste gedrückt
void TimerStart(unsigned long);               // Funktion Klappentimer
unsigned char keys;                           // Zustand der Tasten am Gerät
unsigned char keysAlt;
volatile unsigned char keyPressDetected = 0;  // Anzeige, ob eine Taste am Gerät gedrückt wurde
volatile int keyanzahl=0;
void(*resetFunc)(void)=0;                     // Resetfunktion zu adresse 0 
void sekundenBefehle();                       // Funktion Ausführung jede sekunde
void HPhase(uint8_t);                         // Heizphase setzen und speichern
int KlappeFahrtD(unsigned long);     
void eePromEinzelnWrite();
void eePromEinzelnRead();
void eePromReadZuweisen();  
int eepromReadInt(int);    
void Zeitanzeige();
void eepromWriteInt(int, int);        

char getCommand();
//***********************************************************
void setup()
{
//eepromWriteInt(eeAd[12],19);    //  EINMALIG zum setzen des Grundwertes  
//eepromWriteInt(eeAd[11],14);    //  EINMALIG zum setzen des Grundwertes 
//RohrGrund=176;
// der Interrupt-Pin des I2C-LCD-Moduls liegt auf dem Pin D15=A1 (jetzt D2) des Arduino-Boards
 pinMode(2, INPUT);                               // Gerätetastatur Funktionsaufruf bei Tastendruck.
  attachInterrupt(digitalPinToInterrupt(2), keyPress, FALLING);  // durch Interrupt(0) Pin D2  
// BT und Terminal      auch möglich: attachInterrupt(0, keyPress, FALLING)   (RISING CHANGE)
  BTSerial.begin(19200);                          // Bluetooth
  Serial.begin(115200);                           // Terminal
// Initialisierung des I2C und des I2C-LCD-Moduls
  Wire.begin();
  LCD.begin();
// den Interrupt des I2C-LCD-Moduls zurücksetzen und anschließend aktiveren.
  LCD.resetKeyInterrupt();
  LCD.enableKeyInterrupt();
// Setup Serial connection
  pinMode(KlappeZu, OUTPUT);
  pinMode(KlappeAuf, OUTPUT);
  rtc.begin();                                // Uhrenmodul startet
  digitalWrite(KlappeZu, 1);                  // Relais 1 aus
  digitalWrite(KlappeAuf, 1);                 // Relais 2 aus
// Zum Uhr stellen folgende Zeilen Auskommentierung entfernen
  //rtc.setDOW(SUNDAY);                     // Setze Wochentag
  //rtc.setTime(10, 40, 00);                 // Setze Zeit 08:44:15 (24hr format)
  //rtc.setDate(25, 01, 2020);              // Setze Datum 26.11.2016
//---------------------------------------------------------------------------------
  Status = 'n';                             // Neustart
  //Folgebefehl = 'F';                        // Öffnen nach Neustart
  TimerStop = false;                        // keine Unterbrechung möglich
  TastenCode = 0;                           // Belegung 8=kein Tastendruck möglich
  Serial.print(F("Status = n (Neustart). Startzeit millis = "));
  Serial.println(millis());
  LCD.setLeds(~0); 
  eePromReadZuweisen();                 // EEPROMDATEN lesen und zuweisen
 Serial.println("Aktuelle EEPROMWERTE"); 
 RohrTempFenster=50;                      // ARCHTUNG FEHLER NOCH NICHT GEFUNDEN
for(x=0;x<=12;x++)
{
Serial.print(eepromReadInt(eeAd[x]));
Serial.print("  ");
} 
delay(10000);
  AlteZeit2 = millis();                       // Anzeigetimer auf 0
  AlteZeit3 = millis();                       // Auswertezeit auf 0
  AlteZeit4 = millis();
  AlteZeit5 = millis();
  RaumTemp = (rtc.getTemp());
  RaumTemp = RaumTemp - RaumTempKorr;              // Raumtemperatur korrigieren 
  RohrTempMin = RohrGrund + ((RaumTempZiel - RaumTemp) * RohrDiffFakt); // Untere Temperatur
  RohrTempMax = RohrTempMin + RohrTempFenster;                          // obere Temperatur (+50°)
  Serial.print("RohrGrund    ---  ");
  Serial.println(RohrGrund);
  T1 = ((analogRead(PT1000)+analogRead(PT1000)+analogRead(PT1000))/3)+PT1000Offset;
  RohrTemp = T1;
  RohrTempAlt=RohrTemp;
  if (RohrTemp<RohrTempMax)
  {
  EndZeit3 = ((((RohrTempFenster/2+RohrTempMin) - RohrTemp) * 1000UL) + 40000UL); 
  }
  else 
  {
  EndZeit3=40000;
  }
  if ((RohrTemp > RohrTempMin) && (RohrTemp < RohrTempMax) || (RaumTemp >= RaumTempZiel))
  {
    HPhase (0); 
  } 
}
//************************ Start Loop ******************************
void loop()
{    
// ---------- einmal pro Stunde Klappe justieren --------------
    if (millis()-AlteZeit5> EndZeit5)
      {
      //EndZeit3=(KlappeWAkt*2+10)*1000;
      AlteZeit5=millis();
      //KlappeWAktAlt=KlappeWAkt; 
      //Folgebefehl='G';
      //KlappeFahrt(KlappeWAkt+3,'z'); 
      if ((Heizphase==1)&&(RohrTemp<RohrTempTief))      // Wird zu langsam warm
      {
      Folgebefehl='B';
      Heizphase=2;
      KlappeFahrtD(0);
      }
      }
      
//// ----------------------- Zeitmessung loop ---------------------------------
//    Serial.print("      ein loop dauert (ms) = ");
//    Serial.println(millis()-messzeit);
//    messzeit=millis();
//// ----------------------- Zeitmessung Ende -----------------------------------
   if (millis() -AlteZeit4 > EndZeit4)          // alle 1sec ausführen 
   {
   AlteZeit4= millis();
   sekundenBefehle();                           // Funktion: alles was einmal pro sec läuft
   }
// ----------------------- alle 2 sec ausführen----------------------------------
  if (millis() - AlteZeit2 > EndZeit2)          
  { AlteZeit2 = millis();
    RaumTemp = (rtc.getTemp());         //Temperatur von Uhr holen
    RaumTemp = RaumTemp - 4;
    RohrTempMin = RohrGrund + ((RaumTempZiel - RaumTemp) * RohrDiffFakt); // bei 10° =240  bei 25° 150
    RohrTempMax = RohrTempMin + RohrTempFenster;
    RohrTempMitte=RohrTempFenster/2+RohrTempMin;                                                                                       

//------- Rohrtemperatur einlesen --------------
    T1 = (analogRead(PT1000)+analogRead(PT1000)+analogRead(PT1000)+analogRead(PT1000)+analogRead(PT1000))/5;
    RohrTemp =T1+PT1000Offset;             // reelle werte errechnen 
    Serial.print(F("RohrSensoraKTUELL "));
    Serial.print(T1);
    Serial.print("    ");   
    Serial.println(RohrTemp);

//-------------------------  Anzeige der Daten -------------------------------
//----------  Ausgabe auf Display am Gerät --------------------------
    LCD.clearSegments();                
      ++Anzeige;                          //--- Namme aus Array
      switch (Anzeige)                    // auswerten
      {
      case 1:
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 2:
        RaumTempF = (rtc.getTemp());
            RaumTempF = RaumTempF - 4;
        LCD.print(RaumTempF * 100, NO_LEADING_ZEROS, 2);
        break;
      case 3:
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 4:
        LCD.print(RohrTemp * 1, NO_LEADING_ZEROS, 0);
        break;
      case 5:// Ausgabe K und Winkel   KlappeWAkt
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 6:
        LCD.print(KlappeWAkt, NO_LEADING_ZEROS, 0);
        break;
      case 7:
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 8:
        LCD.print(RohrTempMax, NO_LEADING_ZEROS, 0);
        break;
      case 9:
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 10:
        LCD.print(RohrTempMin, NO_LEADING_ZEROS, 0);
        break;
      case 11:
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 12:
        LCD.print(Heizphase, NO_LEADING_ZEROS, 0);
        break;
      case 13:
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 14:
        LCD.print(((millis() - AlteZeit3) / 1000), NO_LEADING_ZEROS, 0);
        break;
      case 15:
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 16:
        LCD.print(ZFaktor, NO_LEADING_ZEROS, 0);
        break;
      case 17:
        LCD.print(&Text1[(Anzeige - 1) / 2 * 4], 4);
        break;
      case 18:
        LCD.print(RohrDiff, NO_LEADING_ZEROS, 0);
        break;
      case 19:
        LCD.print(&Text1[(Anzeige -  1) / 2 *4], 4);
        break;
      case 20:
        LCD.print(progVersion, 4);
        break;        
      case 21:// Anzeige auf 0 setzen
        Anzeige = 0;
        break;
      default:
        break;
    }
    //LCD.showColon(second & 0x02);
    LCD.update();
//----------  Ausgabe auf Display am Gerät fertig --------------------------    
//------------- Anzeige fertig ----------------------------------------
//------------- Serielle Ausgabe Terminal --------------------------------------
    Serial.print(F("PROGRAMMVERSION"));
    Serial.println(progVersion);
    Serial.print(F("AlteZeit5 "));
    Serial.println((EndZeit5/1000)-((millis()-AlteZeit5)/1000));
    Serial.print(F("Raumtemperatur "));
    Serial.println(RaumTempF);
    Serial.print(F("Raumtemp Ziel  "));
    Serial.println(RaumTempZiel);    
    Serial.print(F("RohrTempMax    "));
    Serial.println(RohrTempMax);
    Serial.print(F("ROHRTEMPERATUR "));
    Serial.println(RohrTemp); 
    Serial.print(F("RohrGrund    "));
    Serial.println(RohrGrund);
    Serial.print(F("RohrTempMin    "));
    Serial.println(RohrTempMin);
    Serial.print(F("RohrDifferenz = "));
    Serial.print(RohrDiff);
    Serial.println(RohrTempTendenz);
    Serial.print(F("Klappe Winkel  "));
    Serial.println(KlappeWAkt); 
    Serial.print(F("Heizphase=      "));
    Serial.print(Heizphase);
    Serial.print(PhaseAlt);
    Serial.println(Phase);
    Serial.print(F("millis - AlteZeit3 = "));
    Serial.println(((millis() - AlteZeit3) / 1000));
    Serial.print(F("EndZeit 3 ist eingestellt auf:  "));
    Serial.println(EndZeit3 / 1000);
    Serial.print(F("Folgebefehl:  "));
    Serial.println(Folgebefehl);
    Serial.print(F("Zeit seit letzter Klappenbewegung: "));
    Serial.println(((millis() - AlteZeit) / 1000));
    Serial.print(F("ZFaktor =       "));
    Serial.println(ZFaktor);
    Serial.print(F("Buzzer  =  "));
    Serial.println(Buzzer);
    Serial.print(F("KEYANZAHL  =  "));
    Serial.print(keyanzahl);
    if (keysAlt!=255)
    {
    Serial.println(keysAlt);
    }
    Serial.print(F("TASTENCODE  =  "));
    Serial.println(TastenCode); 
    Serial.print(F("TimerStop =  "));
    Serial.println(TimerStop);
    Serial.print(" -------    RohrtempMitte=  ");  
    Serial.println(RohrTempFenster/2+RohrTempMin);
    Serial.print("KlappeMIttOeffnung ");
    Serial.println(KlappeMittOeffnung);
    Serial.print("KlappeWeit");
    Serial.println(KlappeWeit);
 //-----------------Serielle Ausgabe Terminal fertig --------------------------- 
 //-----------------Serielle Ausgabe an PC -------------------------------------
    //byte i;                         // Beispiel 100 mal Wert an Instrumente
    //for (i = 0; i < 100; i++){
    //SendString(1,RaumTemp);  // Instrument #01
    //SendString(2,RohrTemp);  // Instrument #40
    //SendString(41,i);  // Instrument #41
    //SendString(2,i);  // Instrument #02
    //SendString(42,i);  // Instrument #42
    //SendString(43,i);  // Instrument #43
    //SendString(90,i);  // Instrument #90
    //SendString(44,i);  // Instrument #44
    //SendString(60,i * 2);  // Instrument #60
    //delay(500);
    //} 
 //----------------- Ausgabe Bluetooth-------------------------------------------
    BTSerial.print("*k");
    BTSerial.print(eepromReadInt(eeAd[4]));
    BTSerial.print("*");    
    BTSerial.print("*v");
    BTSerial.print(progVersion);
    BTSerial.print("*");
    BTSerial.print("*r");
    BTSerial.print(RaumTempF);
    BTSerial.print(",");
    BTSerial.print(RaumTempZiel);
    BTSerial.print("*");
    BTSerial.print("*R");
    BTSerial.print(RaumTempF);
    BTSerial.print("*");
    BTSerial.print("*Z");
    BTSerial.print(RaumTempZiel);
    BTSerial.print("*");
    BTSerial.print("*O");
    BTSerial.print(RohrTemp); 
    BTSerial.print("*");
    BTSerial.print("*o");
    BTSerial.print(RohrTemp); 
    BTSerial.print(",");
    BTSerial.print(RohrTempMax);
    BTSerial.print(",");
    BTSerial.print(RohrTempMin);
    BTSerial.print(",");
    BTSerial.print(RohrTempMitte);
    BTSerial.print("*"); 
    BTSerial.print("*K");
    BTSerial.print(KlappeWAkt);
    BTSerial.print("*");
    BTSerial.print("*N");
    BTSerial.print(RohrTempMax);
    BTSerial.print("*");  
    BTSerial.print("*n");
    BTSerial.print(RohrTempMin);
    BTSerial.print("*");
    BTSerial.print("*z");
    BTSerial.print(AlteZeit);
    BTSerial.print("*");    
    BTSerial.print("*S");
    BTSerial.print(Heizphase);
    BTSerial.print("*");
    BTSerial.print("*V");
    BTSerial.print(RohrTempTendenz);
    BTSerial.print("*");
    BTSerial.print("*sR255G120B0*");
    BTSerial.print("*E");
    BTSerial.print(EndZeit3 / 1000);
    BTSerial.print("*"); 
    BTSerial.print("*L");
    BTSerial.print((millis() - AlteZeit3) / 1000);
    BTSerial.print("*");
    BTSerial.print("*U");
    BTSerial.print(EndZeit/1000);
    BTSerial.print("*");
    BTSerial.print("*F");
    BTSerial.print(ZFaktor);
    BTSerial.print("*");
    BTSerial.print("*D");
    BTSerial.print(RohrDiff);
    BTSerial.print("**w");
    //BTSerial.print("*w");     
    BTSerial.print(KlappeWeit);
    BTSerial.print("**x");
    //BTSerial.print("*x");     
    BTSerial.print(KlappeMittOeffnung);   
    BTSerial.print("*");

//----------- Ausgabe Bluetooth fertig-------------------------------------------------


    if (Folgebefehl=='B')           //-------------------Zustand blockieren für 6 min --------------          
      {
      EndZeit3=(60000UL*480UL);      
      Folgebefehl='P'; 
      }
    if (Folgebefehl=='W')           //-------------------in 10 sec weiter-----------------
      {
      EndZeit3=5000;                //------------------ Endzeit neu---------------
      Folgebefehl='P';             //------------------- Kein Befehl --------------
      }
    if (Folgebefehl=='T')          //----------------- Turbo Klappe 3min auf +15     
      {
      EndZeit3=480000;
      KlappeFahrt(15,'a');
      Folgebefehl='t'; 
      }
      if (Folgebefehl=='A')
        {
        EndZeit3=20000;
        Folgebefehl='P';
        KlappeFahrt(15,'z') ;
        }
//----- Neue Auswertung ---------------------------------------------------------------------------------------------------
    
//----- Normale Auswertung ALTE VERSION -----------------------------------------------------------------------------------       
    if (millis() - AlteZeit3 > EndZeit3)    // 3 min
    { 
      if (Folgebefehl=='t')
        {
          EndZeit3=20000;
          Folgebefehl='P';
          //Phase='t';
          KlappeFahrtD(KlappeWeit);
        }
      if (Folgebefehl=='B')
        {
        //Phase='b';
        Folgebefehl='W';
        }
      //if (Folgebefehl=='A')
      //  {
      //  Phase='a';
      //  Folgebefehl='W';
      //  KlappeFahrt(15,'z') ;
      //  }
      AlteZeit3 = millis();

//-------------------- Neue Auswertungsvariante siehe PAP ------------------------
//--------------------------RohrTemp einlesen Rohrdaten berechnen-----------------
      T1 = (analogRead(PT1000)+analogRead(PT1000)+analogRead(PT1000)+analogRead(PT1000)+analogRead(PT1000))/5;
      RohrTemp = T1+PT1000Offset;             // reelle werte errechnen
      RohrDiff = RohrTemp - RohrTempAlt;   // differenz alte und neue Rohrtemperatur
      RohrTempMin = RohrGrund + ((RaumTempZiel - RaumTemp) * RohrDiffFakt); // bei 10° =275  bei 25° 200
      RohrTempMax = RohrTempMin + RohrTempFenster;
      //EndZeit3 = (((RohrTempMax - RohrTemp) * 1000UL) + 90000UL);       // Zeit bis zur nächsten Auswertung
    if (RohrTemp<RohrTempMax)
    {
    EndZeit3 = ((((RohrTempFenster/2+RohrTempMin) - RohrTemp) * 1000UL) + 40000UL);
    }
    else
    {
    EndZeit3 = ((((RohrTempFenster/2+RohrTempMin) - RohrTemp) * 500UL) + 40000UL);
    }
    Serial.print(F("RohrSensor "));
      Serial.println(T1); 
//-------------------------- Rohrberechnung fertig ------------------------------
//-------------------------RohrTempTendenz berechnen-----------------------------
    if (RohrTemp> RohrTempAlt+1)
    {
      RohrTempTendenz = '+';             // Temp steigt Z-Faktor =0
      if (ZFaktor>0)
      {
      ZFaktor--;
      }
    }
    else  if (((RohrTemp<RohrTempAlt)&&(RohrTemp<RohrTempMin))||(RohrTemp<30))
    {
      RohrTempTendenz = '-';               //---- RohrTempTendenz -----------
      ZFaktor++;
    }
    else if (RohrTemp==RohrTempAlt)
    {
      RohrTempTendenz='n';
    }
      RohrTempAlt = RohrTemp;              // aktuelle Rohrtemperatur 
      AuswertungFertig = 0;

//---------------------------RohrTempTendenz fertig-------------------------------- 
    if ((RaumTemp>=RaumTempZiel)&&(Heizphase!=2)) 
        {                       //ja
         Heizphase=2;
         KlappeWNeu=0;
         PhaseAlt=Phase;
         Phase='A';
        }
         else 
            {
            if (Heizphase!=1) 
                {
                if (Heizphase==2)
                  {
                  Folgebefehl='B';
                  KlappeWNeu=0;
                  PhaseAlt=Phase;
                  Phase='B';
                  }
                  else
                  {  
                      if (RohrTemp>=RohrTempMax)
                        {
                        Serial.println("----------Rohr> RohrMax");
                        Serial.print(RohrTemp);
                        Serial.print("   ");   
                        Serial.println(RohrTempMax);
                        KlappeWNeu=5;   //Test wegen Klappendifferenz bei 0
                        PhaseAlt=Phase;
                        Phase='C';
                        }
                      else 
                        {
                        if (RohrTemp<(RohrTempFenster/2+RohrTempMin))
                          {
                          Heizphase=2;
                          KlappeWNeu=0;
                          PhaseAlt=Phase; 
                          Phase='d';
                          }
                        else
                          {
                          Serial.println("----------Rohr kleiner RohrMax");
                          //Heizphase=1;
                          KlappeWNeu=KlappeMittOeffnung;
                          PhaseAlt=Phase;
                          Phase='D';
                          }                    
                        }                       
                  }
            }                          
              else
                {
                  //KlappeWNeu=KlappeMittOeffnung;
                  if ((RohrTemp>RohrTempMin)&&(RohrTemp<(RohrTempFenster/2+RohrTempMin)))
                    {
                    KlappeWNeu=9;
                    PhaseAlt=Phase;
                    Phase='e';
                    }
                    PhaseAlt=Phase;
                    Phase='E';
                  if (RohrTemp>=(RohrTempFenster/2+RohrTempMin))
                    {
                      if (RohrTemp>=RohrTempMax)
                      {
                      Heizphase=0;
                      KlappeWNeu=0;
                      PhaseAlt=Phase;
                      Phase='F';
                      }
                      else
                      {
                      KlappeWNeu=KlappeMittOeffnung;
            //          Heizphase=1;
                      PhaseAlt=Phase;
                      Phase='G';
                      }
                    }
                  else
                  {
                  KlappeWNeu=KlappeWeit+ZFaktor;
                  PhaseAlt=Phase;
                  Phase='H';
                  }
               if (RohrTempTendenz=='-')
                  {
                  //ZFaktor++;
                  PhaseAlt=Phase;
                  Phase='I';
                  }
                  else if(RohrTempTendenz=='+')
                  {
                  //if (ZFaktor>0)
                  //{
                  //ZFaktor--;
                  //}
                  PhaseAlt=Phase;
                  Phase='J';
                  }
              if ((ZFaktor>=6)&&(RohrTemp<RohrTempMin) )
                  {
                  Heizphase=2;
                  PhaseAlt=Phase;
                  Phase='K';
                  BTSerial.print("*B*");
                  
                  }
                  
                
                }  
            }            // IF 1 ende 
          if ((RohrTemp>RohrTempTief)&&(RohrTemp<RohrTempMax+25))                   // Rohrtemptief einstellen
              {
              KlappeOffset=2;
              }
              else
              {
              KlappeOffset=0;
              }
          if ((KlappeWNeu==0)&&(RohrTemp > 120) && (Heizphase < 2) && (RaumTemp <= RaumTempZiel)&&(RohrTemp<RohrTempMax+15) )
              {
              RTOffset = KlappeOffset + (RaumTempZiel - RaumTemp);    // lässt Klappe weiter offen, wenn Raumtemp nicht erreicht ist
              KlappeWNeu=RTOffset; //Offset, damit Klappe nicht ganz zu geht
              }
            eepromWriteInt(eeAd[2],KlappeOffset);
            KlappeFahrtD(KlappeWNeu);
          if ((RohrTemp< (RohrTempFenster/2+RohrTempMin))&&(Buzzer==true))
              {
              Buzzer=false;
              BTSerial.print("*B*");
              }
              else if ((RohrTemp> (RohrTempFenster/2+RohrTempMin))&&(Buzzer==false))
              {
              Buzzer=true;
              BTSerial.print("*B*");        
              }
              eepromWriteInt(eeAd[0],Buzzer);
//++++++++++++++++++++++++++++++ ALT +++++++++++++++++++++++++++++++++++++++++++++++
//----- entfernt
// ++++++++++++++++++++++++++++++++++++++++++ ALT ++++++++++++++++++++++++
      BTSerial.print("*p");
      BTSerial.print("Phase ");
      BTSerial.print(PhaseAlt);
      BTSerial.print(Phase);      
      BTSerial.print("*");
    }                                        // Ende EndZeit3
  }                                          // Ende EndZeit2


  // Abfrage ob Taste gedrückt. Auswertung der Tasten
  //TasteSer = getCommand();//seriell eingabe Terminal
  //keyPressDetected=0;     //Tasten am Gerät sperren
  if (keyPressDetected)     //Eingabe am gerät
  { 

    keys = (LCD.readKeys() & 240); //untere Bits ausblenden 
    if (keys!=255)
    {
    keysAlt=keys;
    }
    LCD.resetKeyInterrupt();
    keyPressDetected = 0;
    keys = keys + TastenCode; 
    keyanzahl++;
  }
  else  //keine Taste gedrückt
  {
    keys = NO_KEY;
  }
  // Auswertung Tasten 1=112 2=176 3=208  4=224
  switch (keys)
  {
    case 224:          //Klappe voll auf oder zu
      if (KlappeWAkt > 75)
      {
        LCD.setLeds(~7);
        KlappeFahrt(KlappeWAkt + 5, 'z');
        HPhase(1);
      }
      else
      {
        LCD.setLeds(~8);
        KlappeFahrt(156 - KlappeWAkt, 'a'); // 160 sec Klappe auf
        HPhase(3);
      }
      break;
    case 208:
      LCD.setLeds(~9);
      KlappeFahrt(5, 'z'); // 5 sec Klappe zu
      if (Heizphase < 3)
      {
        //Hphase(0);
      }
      break;
      case 212://  zweite Funktion (+4)
      TastenCode=0;
      LCD.setLeds(~6);
      break;
    case 176:
      TastenCode=4;
      LCD.setLeds(~10);
      KlappeFahrt(5, 'a'); // 5 sec Klappe auf
      if (Heizphase < 3)
      {
        //Hphase(0);
      }
      break;
    case 180://     zweite Funktion (+4)
      TastenCode=0;
      LCD.setLeds(~5);
      RaumTempZiel=RaumTempZiel+1;
      eepromWriteInt(eeAd[5],RaumTempZiel);
      break;
    case 112: // Anheizphase. heizen klappe voll zu und 20s auf
      eePromReadZuweisen();                 // EEPROMDATEN lesen und zuweisen
      eepromWriteInt(eeAd[5],RaumTempZiel);
      HPhase(1); //Anheizphase neu 
      LCD.setLeds(~11);
      EndZeit3=40000;
      EndZeit5=1800000;
      AlteZeit5=millis();
      Folgebefehl = 'F';                              // Folgebefehl
      TimerStop = false;                              // Timer kann nicht gestoppt werden
      TastenCode = 8;                                 // keine Tastenfunktion
      ZFaktor = 0;                                    // 
      RohrTempTendenz = '+';
      RohrTempAlt=RohrTemp;
      RohrDiff=0;      
      KlappeFahrt(KlappeWAkt + 5, 'z');               // Klappe voll zu
      AlteZeit3 = millis();
      //EndZeit3 = (((RohrTempMax - RohrTemp) * 1000UL) + 90000UL); // Endzeit3 > 90 s wenn Rohr kalt
    if (RohrTemp<RohrTempMax)
    {
    EndZeit3 = ((((RohrTempFenster/2+RohrTempMin) - RohrTemp) * 1000UL) + 40000UL);
    }
    else
    {
    EndZeit3=30000;
    }
      break;
    case 113:
      break;
    case 115:
      TimerStop = true;
      break;
    default:
      break;
  }

 // ---------------------------serielle Eingabe vom Terminal------------------------ 
TasteSer = getCommand();//seriell eingabe Terminal 
 switch (TasteSer)
  { 
    case 'm':
      eepromWriteInt(eeAd[11],KlappeMittOeffnung++);
      KlappeFahrtD(KlappeMittOeffnung);   
      BTSerial.print("*x");      // aktuelle EEpromAdresse ausgeben
      BTSerial.print(KlappeMittOeffnung);
      BTSerial.print("*");
      break;    
    case 'n':
      eepromWriteInt(eeAd[11],KlappeMittOeffnung--);   
      KlappeFahrtD(KlappeMittOeffnung);   
      BTSerial.print("*x");      // aktuelle EEpromAdresse ausgeben
      BTSerial.print(KlappeMittOeffnung);
      BTSerial.print("*");
      break;
    case 'u':
      eepromWriteInt(eeAd[12],KlappeWeit++); 
      KlappeFahrtD(KlappeWeit);    
      BTSerial.print("*w");      // aktuelle EEpromAdresse ausgeben
      BTSerial.print(KlappeWeit);
      BTSerial.print("*");
      break;
    case 'v':
      eepromWriteInt(eeAd[12],KlappeWeit--); 
      KlappeFahrtD(KlappeWeit);    
      BTSerial.print("*w");      // aktuelle EEpromAdresse ausgeben
      BTSerial.print(KlappeWeit);
      BTSerial.print("*");
      break;
    case 'V':
      Serial.print("-----------------------------------");
      Serial.print(char(BTSerial.read()) );   
      Serial.print(char(BTSerial.read()) );  
      break;
    case 'E':
      EndZeit2=EndZeit2+2000; 
      eepromWriteInt(eeAd[10],EndZeit2); 
      break;
    case 'F':
      if (EndZeit2>2000)
      {
      EndZeit2=EndZeit2-2000; 
      eepromWriteInt(eeAd[10],EndZeit2); 
      }
      break;    
    case 'J':
      RohrGrund=RohrGrund+10; 
      HPhase(1);
      eepromWriteInt(eeAd[9],RohrGrund); 
      break;
    case 'K':
      RohrGrund=RohrGrund-10; 
      HPhase(1);
      eepromWriteInt(eeAd[9],RohrGrund); 
      break;
    case 'L':
      RohrTempFenster=RohrTempFenster+5; 
      HPhase(1);
      eepromWriteInt(eeAd[8],RohrTempFenster); 
      break;
    case 'M':
      RohrTempFenster=RohrTempFenster-5; 
      HPhase(1);
      eepromWriteInt(eeAd[8],RohrTempFenster); 
      break;
    case '1':
      HPhase(1); //Anheizphase neu
      eePromReadZuweisen();                 // EEPROMDATEN lesen und zuweisen
      eepromWriteInt(eeAd[5],RaumTempZiel);
      EndZeit3=40000;
      EndZeit5=1800000;  
      AlteZeit5=millis();
      Folgebefehl = 'F';
      TimerStop = false;
      TastenCode = 8;
      ZFaktor = 0;
      RohrTempTendenz = '+' ;
      RohrTempAlt=RohrTemp;
      RohrDiff=0;
      KlappeFahrt(KlappeWAkt + 5, 'z');       
      AlteZeit3 = millis();
      // EndZeit3 = (((RohrTempMax - RohrTemp) * 1000) + 90000);    // Neu1
     break;
   case 'p':
      HPhase(1);
      break; 
   case 'l':
      EndZeit3=600000;
      KlappeFahrtD(150);   //Klappe 150s auf
      break;
   case 't':
        rtc.setTime(17, 43, 02);                 // Setze Zeit 08:44:15 (24hr format)
   case 'h':
     RaumTempZiel=RaumTempZiel+1;
      eepromWriteInt(eeAd[5],RaumTempZiel); 
      BTSerial.print("*Z");
      BTSerial.print(RaumTempZiel);
      BTSerial.print("*");
     break;
   case 'r':
     RaumTempZiel=RaumTempZiel-1;
      eepromWriteInt(eeAd[5],RaumTempZiel); 
      BTSerial.print("*Z");
      BTSerial.print(RaumTempZiel);
      BTSerial.print("*");
     break;
   case 's':
      AlteZeit3=millis();
      EndZeit3=5000;
      break;
   case 'a':
      LCD.setLeds(~10);
      KlappeFahrt(3, 'a'); // 3 sec Klappe auf     
      break;
   case 'z': 
      LCD.setLeds(~9);   
      KlappeFahrt(3, 'z'); // 3 sec Klappe zu
      break;
   case '2':
      LCD.setLeds(~9);   
      KlappeFahrt(1, 'z'); // 1 sec Klappe zu   
      break;
   case '3':
      LCD.setLeds(~9);
      KlappeFahrt(1, 'a'); // 1 sec Klappe auf    
      break; 
   case 'k':               // komplett auf oder zu
   if (KlappeWAkt > 75)
      {
        LCD.setLeds(~7);
        KlappeFahrt(KlappeWAkt + 5, 'z'); //Klappe zu mit 4 s Reserve   
        HPhase(1);
      }
      else
      {
        LCD.setLeds(~8);
        KlappeFahrt(156 - KlappeWAkt, 'a'); // Klappe auf mit 4s Reserve
        HPhase(3);
      }
      break;
   case 'B':                  // Jede weitere Auswertung blockieren 
      Folgebefehl='B';
      break;
   case 'W':                  // Blockierung aufheben
      Folgebefehl='W';
      break;
  case 'T':                   // Turbo
      Folgebefehl='T';
      break;
  case 'A':
      {
      Folgebefehl='A';          // Abbruch Turbo
      }
      break;
      case 'b':
      KlappeFahrtD(0);         // Klappe Fahrt direkt Pos.0
      break;
      case 'c':
      KlappeFahrtD(5);         // Klappe Fahrt direkt Pos.5
      break;
      case 'd':
      KlappeFahrtD(15);         // Klappe Fahrt direkt Pos.15
      break;
      case 'j':
      eePromEinzelnWrite();     // EEprom einzelnen Wert schreiben
      break;
      case 'e':
      if (eeAdresse<100)        // EEprom Adresse um 1 erhöhen
      {
      eeAdresse++;
      }
      BTSerial.print("*e");      // aktuelle EEpromAdresse ausgeben
      BTSerial.print(eeAdresse);
      BTSerial.print("*");
      eePromEinzelnRead();       // EEprom auslesen
      BTSerial.print("*d");
      BTSerial.print(eeWert);    // Gespeicherten Wert ausgeben
      BTSerial.print("*");
      break;
      //----------------------------------------------------------
      case 'i':                  // EEpromadresse um 1 verringern
      if (eeAdresse>0)
      {
      eeAdresse--;
      }
      BTSerial.print("*e");      // aktuelle EEpromAdresse ausgeben
      BTSerial.print(eeAdresse);
      BTSerial.print("*");
      eePromEinzelnRead();       // EEprom auslesen
      BTSerial.print("*d");
      BTSerial.print(eeWert);    // Gespeicherten Wert ausgeben
      BTSerial.print("*");
      break;
      //----------------------------------------------------------
      case 'f':
      eeWert++;
      BTSerial.print("*d");      // zu speichernder Wert +1
      BTSerial.print(eeWert);
      BTSerial.print("*");
      break;
      case 'g':
      eeWert--;
      BTSerial.print("*d");      // zu speichernder Wert -1
      BTSerial.print(eeWert);
      BTSerial.print("*");
      break;
      case 'H':
     HPhase(2);                  // Heizphase 2 einstellen
     break; 
      break;
     case 'O':                   // Reset
      resetFunc();
      break;
     case 'G':                   // Heizphase 1
     HPhase(1);
     break; 
     case 'I':                   // Heizphase 0
     HPhase(0);
     break; 
     case'X':                    // Heizphase 1
     HPhase(1);
     eepromWriteInt(eeAd[4],0);  // Klappe WAkt =0
     KlappeWAkt=150;             // speichern
     KlappeFahrt(150,'z');       // Klappe 150s zu
     break;                                         
     case 'Z':
     rtc.setTime(ZStunde,ZMinute,ZSekunde);                 // Setze Zeit 08:44:15 (24hr format)      
     break;
     case '4':
     ZStunde++;
     Zeitanzeige();
     break;
     case '5':
     ZMinute++;
     Zeitanzeige();
     break;
     case '6':
     ZSekunde++;
     Zeitanzeige();
     break;
     case 'Y':                   // Heizphase 2
     HPhase(2);                  
     eepromWriteInt(eeAd[4],0);  // Klappe WAkt =0
     KlappeWAkt=150;             // speichern
     KlappeFahrt(150,'z');       // Klappe 150s zu
     Folgebefehl='B' ;           // Endzeit3 1 std (Blockierung)
     break;
     default:
     break;
  }
  //********* Timerabfrage *******************
  if (Status == 't') //Timer läuft solange Klappe läuft
  {
    AlteZeit3 = millis(); //Timer3 reset solange klappe fährt
    if ((millis() - AlteZeit > EndZeit) || (TimerStop == true)) 
    {                             // Wenn Zeit abgelaufen                               
                                  // oder Timer stop Befehl
      TastenCode = 0;             // Solange Klappe läuft 2. Code möglich
      TimerStop = false;
      Serial.print(F("Zeit ist um -  Status = "));
      Serial.println(Status);
      Status = 'p';               //Pause  Zeit ist um
      LCD.setLeds(~0);
      KlappeFahrt(1, 's');        // Klappe Stop
      }
  
      
 // Startöffnung 16s einstellen ------------------------------------------  
  }
  if (Folgebefehl == 'F' && Status == 'p')
  {                                // Folgebefehl Klappe auf 16s
    LCD.setLeds(~13);
    Serial.print(F("Folgebefehl F Klappe öffnet 9s"));
    KlappeFahrt(KlappeWeit, 'a');          // Startöffnung
    TimerStop = false;
    TastenCode = 8;
    Folgebefehl = 'P';
  } 
 // ----------------------------------------------------------------------
  ////else if ((KlappeWAkt == 0) && (Status == 'p') && (KlappeOffset > 0) && (RohrTemp > 120) && (Heizphase < 2) && (RaumTemp <= RaumTempZiel) )
  ////  //else if ((KlappeWAkt == 0) && (Status == 'p') && (KlappeOffset > 0) && (RohrTemp > 120) && (RohrTemp < RohrTempMax)&&(Heizphase<2)&&(RaumTemp<=RaumTempZiel) )
  ////{
  ////  LCD.setLeds(~14);
  ////  RTOffset = KlappeOffset + (RaumTempZiel - RaumTemp);                  // lässt Klappe weiter offen, wenn Raumtemp nicht erreicht ist
  ////  KlappeFahrt(RTOffset, 'a'); //Offset, damit Klappe nicht ganz zu geht
  ////}
  // Tastenabfrage fertig

}  //Loop Ende
//********************  Funktionen ************
void eePromReadZuweisen()           // Fkt. Eepromdaten lesen und an Variablen zuweisen
    {                               
    Buzzer=eepromReadInt(eeAd[0]);
    RohrTempTief=eepromReadInt(eeAd[1]);
    KlappeOffset=eepromReadInt(eeAd[2]);
    RohrDiffFakt=eepromReadInt(eeAd[3]);
    KlappeWAkt=eepromReadInt(eeAd[4]);
    RaumTempZiel=eepromReadInt(eeAd[5]);
    Heizphase=eepromReadInt(eeAd[6]);
    RaumTempKorr=eepromReadInt(eeAd[7]);
    RohrTempFenster=eepromReadInt(eeAd[8]);
    RohrGrund=eepromReadInt(eeAd[9]);
    EndZeit2=eepromReadInt(eeAd[10]); 
    KlappeMittOeffnung=eepromReadInt(eeAd[11]);
    KlappeWeit=eepromReadInt(eeAd[12]);
    }
void eePromEinzelnWrite()           // Fkt. Einzelnen EEpromwert schreiben
   {
   eepromWriteInt(eeAd[eeAdresse],eeWert);
   eePromReadZuweisen();            // danach alle Wertw neu lesen und zuweisen
   }
void eePromEinzelnRead()            // Fkt. Einzelnen EEpromwert in eeWert auslesen
    {
    eeWert= eepromReadInt(eeAd [eeAdresse]);
    }
// Fkt. EEprom Schreiben 2 byte                       
void eepromWriteInt(int adr, int wert) 
{
  byte low, high;
  low = wert & 0xFF;
  high = (wert >> 8) & 0xFF;
  //EEPROM.write(adr, low); // dauert 3,3ms
  EEPROM.update(adr, low);  // schreiben nur bei Wertänderung
  delay(50);
  //EEPROM.write(adr + 1, high);
  EEPROM.update(adr+1, high);
  delay(50);
  return;
} //Ende eepromWriteInt
//***********************************************
// Fkt. EEprom Lesen 2 byte -- Aufruf Wert=eepromReadInt(Adresse)
int eepromReadInt(int adr) {
  byte low, high;
  low = EEPROM.read(adr);
  high = EEPROM.read(adr + 1);
  return low + ((high << 8) & 0xFF00);
} //Ende eepromReadInt
//************************************************
// Fkt. Serielle Daten von Terminal lesen
char getCommand()
{
  char c = '\0';
  if (BTSerial.available())     // wenn BT-Eingabe
  {
    c = BTSerial.read();        // dann von BT lesen
  } 
  if (Serial.available())       // wenn Serial-Eingabe
  {
    c = Serial.read();          // dann Serial lesen
  }
  return c;
}
//Serielle Daten lesen Ende
//*************************************************
// die Funktion "keyPress" wird ausgeführt sobald ein Tastendruck detektiert wurde
// (externer Interrupt)
void keyPress()
{
  keyPressDetected = 1;          // bei Tastendruck am Gerät
}
//*****  Funktion TimerStart für Fahrt Klappe  *********************
void TimerStart(unsigned long z) 
  {
  //TimerStop=true;
  EndZeit = z * 1000;
  AlteZeit = millis();
  Status = 't';
  Serial.println(F("Status t -- Timer gestartet"));
  }
//*********** KlappeFahr mit direktem Ziel *************************
      int KlappeFahrtD(unsigned long p)
      {
      if (p> KlappeWAkt)
      {
      pos=p-KlappeWAkt;
      KlappeFahrt(pos,'a'); 
      }
      else if (p<KlappeWAkt)
      {
      pos=KlappeWAkt-p;
      if (p==0)
        {
        pos=pos+2;
        }
      KlappeFahrt(pos,'z');
      }
      KlappeWAkt=p;
      }
//**** Klappe bewegen
int KlappeFahrt(unsigned long z, char r) //z=zeit  r= richtung a=auf z=zu s=stop
{
  switch (r) {
    case 's':  //stop
      digitalWrite(KlappeZu, 1);
      digitalWrite(KlappeAuf, 1);
      LCD.setLeds(~0);  //Stop alle LED aus
      Serial.println(F("Klappe bleibt stehen."));
      //Status = 'p';
      break;
    case 'a':  //Auf
      digitalWrite(KlappeZu, 1);
      digitalWrite(KlappeAuf, 0);
      TimerStart(z);
      Serial.print(F(" Phase = "));
      Serial.print(Phase);
      Serial.print(F("  --  Klappe faehrt auf fuer "));
      Serial.print(z);
      Serial.println(F(" sekunden."));
      KlappeWAkt = KlappeWAkt + z;
      if (KlappeWAkt >= 150)
      {
        KlappeWAkt = 150;
      }
      eepromWriteInt(eeAd[4],KlappeWAkt);
      break;
    case 'z':  //Zu
      digitalWrite(KlappeAuf, 1);
      digitalWrite(KlappeZu, 0);
      TimerStart(z);
      Serial.print(F(" Phase = "));
      Serial.print(Phase);
      Serial.print(F("  --  Klappe faehrt zu fuer "));
      Serial.print(z);
      Serial.println(F(" sekunden."));
      KlappeWAkt = KlappeWAkt - z;
      if (KlappeWAkt <= 0)
      { 
      KlappeWAkt = 0;
      }
      eepromWriteInt(eeAd[4],KlappeWAkt);
      break;
    default:
      break;
  }
  return KlappeWAkt;
}
// ---------------- Funktion Heizphase einstellen  und speichern----  
    void HPhase(uint8_t h)
      {  
      Heizphase=h;
      eepromWriteInt(eeAd[6],h);
      } 
      // Senden eines T elegramms anden PC
    void SendString(byte InstrNr, int MWert) {
      Serial.print('#');
      Serial.print(InstrNr);
      Serial.print('M');
      Serial.print(MWert);
      Serial.print('<');
      }
    // --------------- Zeitanzeige ----
    void Zeitanzeige()
    {
    BTSerial.print("*Y");
    BTSerial.print(ZStunde, DEC);
    BTSerial.print(":");
    BTSerial.print(ZMinute, DEC);
    BTSerial.print(":");
    BTSerial.print(ZSekunde, DEC);
    BTSerial.print(" Uhr ");
    }
      // ---------------- Sekundenbefehle ----
void sekundenBefehle()
    { 
    BTSerial.print("*T");                                  // Auswertezeiz Rest
    if (((EndZeit3-(millis()-AlteZeit3))/1000)<30000)
    {BTSerial.print((EndZeit3-(millis()-AlteZeit3))/1000);}
    else
    {BTSerial.print("   0");}
    BTSerial.print("*");
    BTSerial.print("*u");
    if (((EndZeit-(millis()-AlteZeit))/1000)<5000)          // Klappe Restzeit
    {BTSerial.print((EndZeit-(millis()-AlteZeit))/1000);}
    else
    {BTSerial.print("   0");}
    BTSerial.print("*");     
//-----------------Zeit auslesen-----------------------------------------------
    t=rtc.getTime();  
    // Send date over serial connection
    BTSerial.print("*t");
    BTSerial.print(t.date, DEC);
    BTSerial.print(". ");
    BTSerial.print(rtc.getMonthStr());
    BTSerial.print(" ");
    BTSerial.print(t.year, DEC);
    BTSerial.print(" - ");
// Send Day-of-Week and time
    if (t.hour<10) 
    {BTSerial.print("0");}
    BTSerial.print(t.hour, DEC);
    BTSerial.print(":");
    if (t.min<10) 
    {BTSerial.print("0");}
    BTSerial.print(t.min, DEC);
    BTSerial.print(":");
    if (t.sec<10) 
    {BTSerial.print("0");}
    BTSerial.print(t.sec, DEC);
    BTSerial.print("*");     
    }

Kaminofen Klappensteuerung

von nullAhnung » So Jul 21, 2019 9:51 pm

Ich habe hier einen Kaminofen im Wochenendhaus zu stehen. Dieser hat, wie jeder Ofen dieser Preisklasse natürlich
keine temperaturabhängige Regelung der Zuluftklappe. Dies hat zur Folge, daß beim unbeobachteten Heizen entweder
die gewollte Abgastemperatur nicht erreicht wird, bzw. das Heizgut zu schnell abbrennt und im Anschluss der Ofen
schnell wieder auskühlt, falls die Klappe zu weit offen ist. Es gibt für einige Öfen Bimetallregler. Die passen aber nicht
für jeden Ofen. Also ist eine Eigenkonstruktion angesagt.
Zuerst habe ich mir einen Stellmotor für die Luftklappe besorgt. Gut geeignet sind Motoren aus Lüftungsanlagen. Die
bekommt man in allen möglichen Ausführungn.
Mein Motor:
Betriebsspannung: 24V AC/DC
Leistungsaufnahme: 4VA / 1,5W
Lastgesteuert: Das bedeutet, er hat keine Endschalter.
Drehmoment: 10 Nm
Stellwinkel: ca. 100°
Fahrzeit für 100°: 150 s

Wichtig war mir der Betrieb ohne 230V Netzspannung. Die gesamte Steuerung wird über ein handelsübliches Stecker-Netzteil
versorgt. Damit gibt es keine Probleme bei der Gehäusegestaltung wegen Trennung von Netzspannung und Kleinspannung.
Alles andere wäre um ein Vielfaches aufwändiger, was die Sicherheit angeht. Ich bin Elektriker und weiß, wovon ich spreche.
Hier der Motor und die Ankopplung an die Klappe:
OfenKlappeScharnier.jpg
Dazu gehört der Hochtemperaturfühler PT1000 am Abgasrohr.
Temperaturfest bis 500°C:
Ofen Fühler.JPG
Installiert wurde alles in Alurohr bis hin zum Steuergerät:
OfenSteuerung.JPG
Das Gehäuse des Steuergerätes ist ein gekauftes Standardgehäuse. Die Steuerungsmöglichkeiten sind begrenzt und das Minidisplay
dient nur der schnellen Kontrolle der Funktionen, Messwerte und des Betriebszustandes.
Mittlerweile drucke ich mir meine Gehäuse nach Bedarf selber.
Die tägliche Bedienung erfolgt per App über Bluetooth bzw. per USB-Schnittstelle. Auf dem 3. Bild ist das USB-Kabel angeschlossen
um die Programmierung zu ändern.
Hier die App zum steuern des Ofens:
OfenTablett.JPG
Das ist die etwas aufwendigere Anzeige. Sie dient nur zu Prüfzwecken. Die einfache Version ist wesentlich übersichtlicher.
KleinesMenue.JPG
Es ist alles sehr flexibel anpassbar. Ob Tablett oder Smartphone, alles ist in der Größe anpassbar.
Die App nennt sich "Bluetooth Electronic", ist absolut werbefrei und ist für mich das absolute Muss.

Weiter gehts mit der Steuerung:

Der gesamte Aufbau besteht aus:
Ein Arduino NANO
Ein Temperaturfühler PT1000 mit Meßwandler der Firma Pollin
Ein RTC-Baustein (misst gleichzeitig die Raumtemperatur
Ein Relaisbaustein
Ein Spannungswandler 24V/5V
Ein Display mit 4 Tasten von der Firma ELV.
Ein Bluetooth Modul HC-06
Ein Pegelwandler für das Bluetooth Modul
Und zu guter letzt ein Steckernetzteil 24V DC


Bei Interesse:
Fortsetzung folgt

Nach oben