/*start============================================================================================================================================================================================== Automatische Steuerung zum Maischen Überarbeitung "Bitter" (Lothar) und Borsti84 (Sebastian) Genauere Beschreibung der Versionen immer aktuell im Hobbybrauer-Wiki! https://hobbybrauer.de/forum/wiki/doku.php/brauen_mit_arduino_all_in_one_aio xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Die Software wird unter der MIT - Lizenz veröffentlicht Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files , to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY4 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der zugehörigen Dokumentationen erhält, die Erlaubnis erteilt, sie uneingeschränkt zu benutzen, inklusive und ohne Ausnahme dem Recht, sie zu verwenden, kopieren, ändern, fusionieren, verlegen, verbreiten, unterlizenzieren und/oder zu verkaufen, und Personen, die diese Software erhalten, diese Rechte zu geben, unter den folgenden Bedingungen: Der obige Urheberrechtsvermerk und dieser Erlaubnisvermerk sind in allen Kopien oder Teilkopien der Software beizulegen. DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE GARANTIE BEREITGESTELLT, EINSCHLIESSLICH DER GARANTIE ZUR BENUTZUNG FÜR DEN VORGESEHENEN ODER EINEM BESTIMMTEN ZWECK SOWIE JEGLICHER RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM FALL SIND DIE AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER SONSTIGE ANSPRÜCHE HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG EINES VERTRAGES, EINES DELIKTES ODER ANDERS IM ZUSAMMENHANG MIT DER SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Die Funktionen die auf den Vergleich Sollwert mit Istwert beruhen werden immer erst nach mehreren Messungen ausgeführt. Anschlüsse: PIN 2 : Encoder => Pullup geschaltet => Encoderzuleitung mit GND versorgen PIN 3 : Encoder => Pullup geschaltet => Encoderzuleitung mit GND versorgen PIN 4 : Taster von Encoder => Pullup geschaltet => Zuleitung mit GND versorgen PIN 5 : DS1820 ONE_WIRE_BUS Sensor => 4,7k zw. 5V und PIN5 PIN 6 : Reset ESP8266 PIN 7 : Heizung Nullleiter PIN 8 : Heizung Phase PIN 9 : Geschwindigkeitsumschaltung PIN 10: Ruf (Summer) PIN 11: Rührwerk Nullleiter PIN 12: Rührwerk Phase PIN 16: Bluetoothmodul HC-06 RX PIN 17: Bluetoothmodul HC-06 TX PIN 18: Funkempfänger (INT 5) PIN 19: Funksender PIN 20: Anschluss SDA vom Display PIN 21: Anschluss SCL vom Display PIN A0: Würzeumpensensor (Schwimmschalter) PIN A1: Würzepumpenrelais PIN A4: Nachgussheizung Phase PIN A5: Nachgussheizung Nullleiter PIN A6: A0 vom Gassensor Die folgenden Definitionen und Einstellungen beeinflussen das Verhalten der AiO. Diese Einstellungen können nicht im Setup verändert werden. */ //#include //für PlatformIO, in der Arduino-IDE einkommentieren //wenn dbg auskommentiert wird, dann können beim Anlernen der Funksteckdosen das Protokoll u.a. Parameter //im Serial-Monitor eingesehen werden. Als Test, ob es sich um "Rolling-Code-Steckdosen" handelt, für alle //sechs Signale den gleichen Button auf der Fernsteuerung drücken. Erscheint jedesmal ein anderer Code, dann //handelt es sich um ein Rolling-Code-System, was NICHT unterstützt wird! //DEBUG im Serial-Monitor++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //#define dbg //Ausgabe von Schlüsselwerten über die serielle Schnittstelle ->Für Debuggen auskommentieren //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Funk- und/oder Relaissteuerung? Es sind hier beide Optionen gleichzeitig aktivierbar! Bei Speicherplatzproblemen //sollte aber nur eine Option ausgewählt werden! //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //#define funksteuerung //Funksteuerung aktivieren/deaktivieren #define relaissteuerung //Relaisansteuerung aktivieren/deaktivieren //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*Relaislogik festlegen ACHTUNG!!!!!!! bei Verwendung der China Relais-Platinen muss die Logik immer "AUS = HIGH" sein. Alle Geräte müssen dann am Schließer der Relais angeschlossen werden! Ansonsten liegt im ausgeschalteten Zustand Spannung am Ausgang! Schema im Wiki! Ist H_AUS/R_AUS/NG_AUS als HIGH definiert, dann schaltet das Relais im ANGEZOGENEN ZUSTAND AUS (Voreinstellung für Relaisplatinen) Ist H_EIN/R_EIN/NG_AUS als HIGH definiert, dann schaltet das Relais im ANGEZOGENEN ZUSTAND EIN Die gewünschte Logik auskommentieren und die jeweils andere einkommentieren */ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #ifdef relaissteuerung #define normal //Relaislogik umdrehen //Heizungsrelais +++++++++++++++++ #ifdef normal #define H_AUS LOW #define H_EIN HIGH #else #define H_AUS HIGH #define H_EIN LOW //z.B. für die Ansteuerung über einen ULN-Treiber #endif //Nachgussrelais +++++++++++++++++ #ifdef normal #define NG_AUS LOW #define NG_EIN HIGH #else #define NG_AUS HIGH #define NG_EIN LOW //z.B. für die Ansteuerung über einen ULN-Treiber #endif //Mischerrelais +++++++++++++++++++ #ifdef normal #define R_AUS LOW #define R_EIN HIGH #else #define R_AUS HIGH #define R_EIN LOW //z.B. für die Ansteuerung über einen ULN-Treiber #endif #endif //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Display und Encoder angeschlossen? //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #define MitDisplayUndEncoder //für Steuerung über KBH2AiO kann die Direktive einkommentiert werden //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //RTC-RealTimeClock für Timerfunktion verbaut/nicht verbaut? //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //#define RTC_Hardware //Hardware RTC ist eingebaut //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Kommunikation mit dem PC, entweder Bluetooth (HC05/06) oder UDP (ESP8266) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #define bluetooth //else UDP //#define bit32 // else 64 Bit //KBH2AiO unter Windows32 - Timing ist sonst ggf. zu schnell! #ifdef bluetooth bool bluetooth_steuerung = false; //Vorgabe falls mit Display / ohne Display wird dieser Wert automatisch auf true gesetzt (diesen Wert hier nicht ändern!) #else bool wlan_steuerung = false; //Vorgabe falls mit Display / ohne Display wird dieser Wert automatisch auf true gesetzt (diesen Wert hier nicht ändern!) #endif uint8_t kbh2aio = 0; //Hilfsvariable //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Verwendung eines 433 MHz-Funksensors //Achtung! - es darf bei der Verwendung eines Funksensors zusätzlich nur ein kabelgebundener Sensor angeschlossen sein. //Der kabelgebundene Sensor ist immer der Nachgusssensor! //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //#define Tempsensor433 //Auswahl der Versionen - mit FunkTempsensor oder ohne (einkommentiert = ohne Funksensor) #ifdef Tempsensor433 int16_t alivetime; #endif //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Ist ein Gassensor (MQ6) Propan/Butan/LPG verbaut? //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //#define gassensor //wenn Gassensor verbaut ist #ifdef gassensor #define analogpin A6 // an A0 des Sensors float sensor_volt; //Define variable for sensor voltage float RS_air; //Define variable for sensor resistance float R0; //Define variable for R0 float sensorValue; //Define variable for analog readings float mm = -0.411; //Slope float bb = 1.22; //Y-Intercept float RS_gas; //Define variable for sensor resistance float ratio; //Define variable for ratio bool alarm; bool externer_aufruf = false; double ppm_log; //Get ppm value in linear scale according to the the ratio value double ppm; //Convert ppm value to log scale float PPM_LPG; float test_sensor; int16_t lpg_grenzwert = 3000; //Vorgabe ppm boolean sensor_angeschlossen; #endif //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Geschwindigkeitsumschaltung Rührmotor (Scheibenwischermotor mit zwei Geschwindigkeitsanschlüssen? //Anschluss wird im Hobbybrauerwiki beschrieben: //(http://hobbybrauer.de/forum/wiki/doku.php/brauen_mit_arduino_all_in_one_aio#aufbau_der_aio-uno) //während der Rasten ist durch Drücken des Encoders die Geschwindigkeit umschaltbar //sonst der Rührer vom Intervall in den dauerbetrieb umschaltbar. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //#define geschwindigkeitsrelais //Scheibenwischermotoren - Geschwindigkeiten umschalten. Umschaltrelais für den Rührer verbaut? #ifdef geschwindigkeitsrelais bool geschwindigkeitsrel = true; #define LOW_SPEED LOW #define HIGH_SPEED HIGH //#define LOW_SPEED HIGH //#define HIGH_SPEED LOW #define Speedrelais 9 #else bool geschwindigkeitsrel = false; #endif //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Würzepumpe (Läuterbottich -> Sudpfanne) verbaut? //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //#define WUERZEPUMPE_AKTIV #ifdef WUERZEPUMPE_AKTIV #define WUERZEPUMPE_AUS LOW //wenn ein Pumpenrelais verbaut ist #define WUERZEPUMPE_EIN HIGH //#define WUERZEPUMPE_AUS HIGH //#define WUERZEPUMPE_EIN LOW //Levelsensor (Schwimmschalter)+++++++++++++++++++++ //welches Signal kommt vom Schwimmschalter? (kann an den meisten Schwimmschaltern konfiguriert werden!) //Folgende Zuordnung wenn der Schwimmschalter schliesst //#define Sensor_AUS 1 //#define Sensor_EIN 0 //Folgende Zuordnung wenn der Schwimmschalter öffnet #define Sensor_AUS 0 #define Sensor_EIN 1 uint8_t wpumpe = 0; #endif //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Ruftiming------------------------------------------------------------------------------------------------------------- #define einmaischzyklus 5 //wie oft wird gerufen #define einmaischtonlaenge 2500 //wie lang ist der einzelne Rufton #define jodrufZyklus 3 //Zyklus des Jodprobenrufs #define jodrufLaenge 500 //Dauer des Jodprobenrufs #define schwellenrufdauer 2000 //Kochschwelle erreicht #define TonRasterreichtDauer 500 // Meldung Rasttemperatur erreicht #define endeMaischenTon 1000 //Maischprozess beendet #define quittungston 200 // Länge Quittungston bei Datenempfang von der AiO //---------------------------------------------------------------------------------------------------------------------- //die folgenden Parameter können teilweise auch im Setup geändert werden! //Daher bitte ab hier nichts mehr ändern! //---------------------------------------------------------------------------------------------------------------------- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Einschaltverzögerung Nachgusstopf nach Heizphase //Sicherheitsschwelle damit nicht beide Kessel gleichzeitig eingeschaltet sind #define esv_nachguss 2000 //Einschaltverzögerung Nachgussheizung in den Rasten in ms //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Gärhysterese - eine zu kleine Hysterese führt zu einer konkurrierenden Regelung im Übergangsbereich zwischen Kühlen und Heizen! //Die Gärhysterese wird ausschließlich für die automatische Gärführung verwendet! float gaerhysterese = 0.3; //0,3K über/unter dem Zielwert - diesen Wert bitte nicht viel kleiner einstellen (testen!) //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Verwendungsart der 3. Funksteckdose (Variabel) #ifdef funksteuerung bool funkruf = true; //3. Steckdose als Funkruf-Weiterleitung (Vorgabe) //kann im Setup auch als Nachgussdose konfiguriert werden! uint8_t funkdelay = 1; //Verzögerung nach Absetzen eines Funkbefehls - 100ms wenn Probleme #endif //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //Hinweis Startbildschirm ---------------------------------------------------------------------------------------------- String hinweis; //Anzeige im Startdisplay, welche Logik aktiv ist! //Rufrelais------------------------------------------------------------------------------------------------------------- #define B_AUS 0 //Rührwerk beim Einmaischen aktiv?-------------------------------------------------------------------------------------- bool ruehrer_beim_einmaischen = true; //Mischer beim Einmaischen aktiv //Kann im Setup geändert werden, z.B wenn der Mischer eine Malzrohrpumpe ist! //Rührwerk über KBH2AiO ausgeschaltet?---------------------------------------------------------------------------------- bool fern = true; //Rührwerk Nachlauf----------------------------------------------------------------------------------------------------- bool ruehrer_nachlauf = true; //Rührer läuft nach //Kann im Setup geändert werden! //Zykluszeiten Daten senden--------------------------------------------------------------------------------------------- //Mit diesen Werten kann experimentiert werden. Es hängt von der Geschwindigkeit des verwendeten Rechners ab! #ifdef bluetooth #ifdef bit32 #define PCZyklus 50 // Zykluszeit in ms für Daten zur AiO #define AIOZyklus 200 // Zykluszeit in ms für Daten zum PC #else #define PCZyklus 10 // Zykluszeit in ms für Daten zur AiO #define AIOZyklus 100 // Zykluszeit in ms für Daten zum PC #endif #else #ifdef bit32 #define PCZyklus 50 // Zykluszeit in ms für Daten zur AiO #define AIOZyklus 200 // Zykluszeit in ms für Daten zum PC #else #define PCZyklus 50 // Zykluszeit in ms für Daten zur AiO #define AIOZyklus 200 // Zykluszeit in ms für Daten zum PC #endif #endif //ESP8266 wird verwendet (UDP)------------------------------------------------------------------------------------------ #ifndef bluetooth #define reset8266 6 #endif //EMV-probleme---------------------------------------------------------------------------------------------------------- //sporadischer -127 °C - Fehler durch elektromagnetische Einstreuungen (z.B. Zündtrafo, Induktionsplatte) #define emcSchutz //einkommentieren, falls kein Problem! #ifdef emcSchutz int32_t emccounter = 10000; // nach emccounter-Versuchen läuft das Programm in die Fehlermeldung int32_t emc; #endif //---------------------------------------------------------------------------------------------------------------------- //Ausgänge an DigitalPIN ----------------------------------------------------------------------------------------------- #define ONE_WIRE_BUS 5 //Temperatursensoren - Hauptsensor/sep. Nachgusskessel //Für die Ansteuerung von Heizung, Rührwerk und Nachguss können insgesamt 3/6 Relais für eine allpolige //Ansteuerung angeschlossen werden. Natürlich kann man jeweils auch nur ein Relais zum Schalten verwenden. //Aus Sicherheitsgründen habe ich aber die Möglichkeit der allpoligen Schaltung eingebaut! //Man könnte natürlich auch zwei Relais an einen Ausgang anschließen, möglicherweise wird der Ausgang dann aber zu stark belastet. #ifdef relaissteuerung #define HeizungR1 8 //Zuordnung Heizung Phase Relais1 #define HeizungR2 7 //Zuordnung Heizung Nullleiter Relais2 #endif #define RufR 10 //Zuordnung Braumeisterruf #ifdef relaissteuerung #define UmwaelzR2 11 //Zuordnung Umwaelzer (Rührer/Pumpe) Nullleiter Relais 2 #define UmwaelzR1 12 //Zuordnung Umwaelzer (Rührer/Pumpe) Phase Relais 1 #endif //Ausgänge am AnalogPIN------------------------------------------------------------------------------------------------ #ifdef WUERZEPUMPE_AKTIV #define fuellstand_sensor A0 //Steuerung der Würzepumpe #define fuellstand_pumpe A1 #endif //Ausgänge am AnalogPIN-/Nachgussregelung nur MIT 2. Temperatursensor möglich!----------------------------------------- //Ist eine Funkdose für die Ansteuerung des Nachgusskessels konfiguriert, kann der dort eingebaute Sensor die Steuerung übernehmen! //Ein 2. Temperatursensor ist dann NICHT notwendig! Allerdings zeit ein zweiter Sensor die aktuelle Nachgusstemperatur an! #ifdef relaissteuerung #define NachgussR1 A4 //Zuordnung Nachgussrelais Phase Relais1 #define NachgussR2 A5 //Zuordnung Nachgussrelais Nullleiter Relais2 #endif //433MHz Sender/Empfänger---------------------------------------------------------------------------------------------- #ifdef funksteuerung #define sender 19 //Sender an Anschluss 19 #define empfaenger_int 5 //477 MHz Empfänger an Interrupt 5 (Pin #18) #define empfaengerPin 18 //Digitalpin des Empfaengers (Temperatur Funksensor) #endif //--------------------------------------------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------------------------------------------- Speicheraufteilung EEPROM Falls die EEPROM-Adressen geändert werden, bitte auf den benötigten Speicherplatz achten uint8_t (uuint8_t) benötigt 1 uint8_t Speicherplatz int (uInteger) benötigt 2 uint8_t Speicherplatz long int (uLong Int) benötigt 4 uint8_t Speicherplatz */ #define rastnr 1 //uint8_t - Letzte Rast vor Stromausfall #define rasttemp_aktuell 2 //uint8_t - aktuelle Rasttemperatur vor Stromausfall #define rastzeit_aktuell 3 //uint8_t - aktuelle Rastzeit vor Stromausfall #define rastzeit_1 4 //uint8_t - Speicher für eingestellte Rastzeitwerte #define rasttemp_1 5 //uint8_t - Speicher für eingestellte Rasttemperaturen #define rastzeit_2 6 //uint8_t #define rasttemp_2 7 //uint8_t #define rastzeit_3 8 //uint8_t #define rasttemp_3 9 //uint8_t #define rastzeit_4 10 //uint8_t #define rasttemp_4 11 //uint8_t #define rastzeit_5 12 //uint8_t #define rasttemp_5 13 //uint8_t #define rastzeit_6 14 //uint8_t #define rasttemp_6 15 //uint8_t #define MaischTemp 16 //uint8_t - Einmaischtemperatur #define zeit_h 17 //uint8_t - gespeicherte Zeit h,m,s #define zeit_m 18 //uint8_t #define zeit_s 19 //uint8_t #define Rasten 20 //uint8_t #define rastmodus 21 //uint32t - als long gespeichert - 4 uint8_t Platz lassen #define notfall 25 //uint8_t - Setupvariable #define udauer 26 //uint8_t - Rührer/Pumpe Dauerbetrieb ? #define umwaelzer_ie 27 //uint8_t - Rührer/Pumpe Intervall EIN #define umwaelzer_ia 28 //uint8_t - Rührer/Pumpe Intervall AUS #define Kochschwelle 29 //uint8_t #define logging 30 //uint8_t - Setupvariable Logging EIN/AUS #define kuehlverz 31 //uint32t - als long gespeichert - 4 uint8_t Platz lassn - Einschaltverzögerung Kühlen #define wein_h 35 //uint32t - als long gespeichert - 4 uint8_t Platz lassen - Einschaltverzögerung Heizen #define graf_h 39 //uint32t - als long gespeichert - 4 uint8_t Platz lassen - Gradientenfaktor Heizen #define graf_k 43 //uint32t - als long gespeichert - 4 uint8_t Platz lassen - Gradientenfaktor Kühlen #define k_aktiv 47 //uint8_t - Kühlen im Notfallmodus #define Kochzeit 55 //uint8_t - Kochzeit Notfallspeicher #ifdef bluetooth #define Bluetooth 56 //uint8_t - Bluetooth Ein/Aus #else #define Wlan 56 //uint8_t - WLAN Ein/Aus #endif #define Heizung_EIN 57 //uint32_t Speicheradressen Steckdosencode #define Heizung_AUS 61 //uint32_t Speicheradressen Steckdosencode #define Umwaelz_EIN 65 //uint32_t Speicheradressen Steckdosencode #define Umwaelz_AUS 69 //uint32_t Speicheradressen Steckdosencode #define Nachguss_EIN 73 //uint32_t Speicheradressen Steckdosencode-auch für Funkrufversion #define Nachguss_AUS 77 //uint32_t Speicheradressen Steckdosencode-auch für Funkrufversion #define isozeit_h 81 //uint8_t Stundenwert Nachisomerisierung #define isozeit_m 82 //uint8_t Minutenwert Nachisomerisierung #define isozeit_s 83 //uint8_t Sekundenwert Nachisomerisierung #define niso 84 //uint8_t Dauer Nachisomerisierung #define loggerwahl 85 //uint8_t Loggerprogramm auswählen #define umwaelzwahl 86 //uint8_t Rührwerk oder Malzrohrpumpe ? #define dritte_funksteckdose 87 //uint8_t 3. Dose als Funkruf oder als Nachgussschalter #define heiz_kuehl 88 //uint8_t - Modus Kühlen/Heizen als Wahl #define ruepumeinmaisch 89 //uint8_t - Pumpe/Rührer während des Einmaischens aktiv? #define sound 90 //uint8_t - Soundeinstellung für den Buzzer (Piezosummer) #define g_kuehltemp 91 //uint16-t - zuletzt eingestellte Kühltemperatur #define hopfengabe1 93 //uint16-t - Hopfengaben Notfallspeicher #define hopfengabe2 95 //uint16-t #define hopfengabe3 97 //uint16-t #define hopfengabe4 99 //uint16-t #define hopfengabe5 101 //uint16-t #define hopfengabe6 103 //uint16-t #define startstunde 105 //uint16-t #define startminute 106 //uint16-t #define rueNachlauf 107 //uint16-t #define nachgusssoll 108 //uint16-t #ifdef gassensor #define gas_r0 109 //uint16-t - Kalibrierung Widerstand des Sensors in "Clean Air" #define gas_grenzwert 111 //uint16-t - Alarmschwelle #define gas_kontrollwert 113 //uint16-t - wenn hier der Wert 8888 gespeichert ist, dann wurde der Grenzwert eingestellt, sonst #endif #define notfallmodus 115 //uint16-t - Flag für Notfallmodus Maischen/Kochen //beim ersten Start sofort der Sprung zum Gasmenü! #define jungfraustart 117 //uint8_t //Modi der Aio -------------------------------------------------------------------------------------------------------- #define HAUPTMENUE 0 #define KUEHLEN 1 #define NACHGUSS 2 #ifdef WUERZEPUMPE_AKTIV #define WUERZEPUMPE 3 #endif #define MPUMPE 4 #define SETUPMENUE 5 #define BRAUMENUE 6 #define OPTIONENMENUE 7 #define SOUNDEINSTELLUNG 8 #ifdef RTC_Hardware #define TIMER 9 #define UHR 10 #define STELLEN 99 #endif #define EXTERNMENUE 51 #define GRADIENTENFAKTOR_HEIZEN 11 #define EINSCHALTVERZOEGERUNG_HEIZRELAIS 12 #define GRADIENTENFAKTOR_KUEHLEN 13 #define WARTEZEIT_KUEHLEN 14 #define RUEPUMAKTIV 15 #define RASTANZAHL 19 #define EINMAISCHTEMPERATUR 20 #define RASTTEMPERATUREN 21 #define RASTZEITEN 22 #define AUSWAHL_UMWAELZER 23 #define NACHLAUF 16 #define NACHLAUFEN 17 #define NACHGUSSSOLLWERT 100 //alt 253 #define UMWAELZER_DAUERLAUF 233 #define UMWAELZER_INTERVALL_EIN 234 #define UMWAELZER_INTERVALL_AUS 235 #define DRITTE_FUNKSTECKDOSE 236 #define STECKDOSENCODE 237 #define FRAGESTECKDOSENCODEEINGEBEN 238 #define KOCHSCHWELLE 239 #define WECHSEL_TEMP_ZEIT 24 #ifdef bluetooth #define CONNECT_BLUETOOTH 242 #define BLUETOOTH_EIN_AUS 243 #define BLUETOOTHSTEUERUNG_AKTIV 48 #else #define CONNECT_WIFI 242 #define WIFI_EIN_AUS 243 #define WLANSTEUERUNG_AKTIV 48 #endif #define ABMAISCHTEMPERATUR 25 #define MAISCHEN_START 26 #define EINMAISCHEN 27 #define TEMPERATURAUTOMATIK 28 #define ZEITAUTOMATIK 29 #define ENDTEMPERATURAUTOMATIK 30 #define RUFALARM 31 #define BRAUMEISTERRUFALARM 32 #define ANZAHL_HOPFENGABEN 37 #define NACHISOZEIT 38 #define HOPFENGABE 39 #define KOCHZEIT 40 #define STARTKOCHEN 41 #define KOCHEN 42 #define NACHISOMERISIERUNG 43 #define LOGGING_EIN_AUS 44 #define LOGWAHL 45 #define NOTFALLMODUS 46 #define ABBRUCH 80 #define NOTGASMENUE 81 #define GASSENSORINIT 82 #define GAS_GRENZWERT 83 #define GAERFUEHRUNG 245 #define GAERSTARTTEMPERATUR 246 #define GAERTEMPERATUREN 247 #define GAERZEITEN 248 #define WECHSEL_GAER_TEMP_ZEIT 249 #define ANSTELLTEMPERATUR 250 #define GAERZEITAUTOMATIK 251 #define ANLAUFGAERSTUFEN 252 //Speichervariable Steckdosencode -------------------------------------------------------------------------- #ifdef funksteuerung int32_t funk_heizung_ein; int32_t funk_heizung_aus; int32_t funk_umwaelzer_ein; int32_t funk_umwaelzer_aus; int32_t funk_variabel_ein; int32_t funk_variabel_aus; uint8_t adr = 1; //Adresse im EPROM #define RESEND_SNIFFED_VALUES 3 //jeden Funkbefehl 3 mal wiederholen int32_t value; #endif //---------------------------------------------------------------------------------------------------------- bool eingeschaltet = false; //für Heizung EIN uint32_t heizungInterval1 = 0; //Zeitstartwert um den den Zustand der Heizung zu überprüfen (aktuell im Sketch 5s!) uint32_t heizungInterval2 = 0; //Variablen Textblink für das LCD-Display ------------------------------------------------------------------ uint32_t aktuelleMillis, alteMillis; uint16_t blinkintervall = 1000; //ms bool textsichtbar = true; //Blinken der Startabfrage für das Maischen //LCD Initialisierung -------------------------------------------------------------------------------------- #ifdef MitDisplayUndEncoder #include //je nach gefundenen LCD-Treiber, hier die Initialisierung ändern //auch im Setup() die Initialisierung überprüfen ! aktuell Zeile ab 1103 //----------------------------------------------------------------------------------------------------------- //LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // aktuelle I2C-Adresse //LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Alternative I2C-Adresse LiquidCrystal_I2C lcd(0x27, 20, 4); //neue Library //LiquidCrystal_I2C lcd(0x3F, 20, 4); // falls 0x27 nicht funktioniert! // Sollten beide Adressen nicht funktionieren, // dann die Adresse mit dem I2C-Scanner (im Wiki) herausfinden! #endif //----------------------------------------------------------------------------------------------------------- //433 MHz Funk-sender/Empfänger------------------------------------------------------------------------------ #ifdef funksteuerung #include RCSwitch mySwitch = RCSwitch(); #endif //----------------------------------------------------------------------------------------------------------- //Temperaturempfang über 433 MHz Sender//-------------------------------------------------------------------- //Schaltplan und Aufbau im Wiki! #ifdef Tempsensor433 #include #endif //----------------------------------------------------------------------------------------------------------- //Click Encoder---------------------------------------------------------------------------------------------- //die Bibliothek TimerOne ist nicht kompatibel mit VirtualWire, da beide //den gleichen Interrupt verwenden. Daher kommt hier dann TimerThree zum //Einsatz. #include #ifdef Tempsensor433 #include #else #include #endif //Encoder Initialisierung ------------------------------------------------------------------------------------ //Bei Problemen mit dem Encoder versuche: //#define ENC_DECODER (1 << 1) //#define ENC_NORMAL (1 << 2) // Peter Danneger's Decoder #define ENC_FLAKY (1 << 2) // Table-based Decoder //Voreinstellung ist ENC_HALFSTEP 1. #define ENC_HALFSTEP 1 //Encoder drehen #define pinA 3 //können auch beliebige andere Anschlüsse sein! #define pinB 2 //tauschen der Werte für Drehumkehr #ifndef ENC_DECODER #define ENC_DECODER ENC_NORMAL #endif #if ENC_DECODER == ENC_FLAKY #ifndef ENC_HALFSTEP #define ENC_HALFSTEP 1 // Voreinstellung Halfstep #endif #endif //Abhängig vom Typ des Encoders kannst du verschiedene "StepsPerNotch"-Parameter verwenden. Setze den Wert auf 1,2 oder 4 Schritte pro Encoderclick. #define STEPSPERNOTCH 4 // Steps bis zum nächsten Schritt // Encoder - Taster drücken------------------------------------------------------------------------------------- #define taster 4 // Taster am Pin 4 für Bestätigung und Abbruch //-------------------------------------------------------------------------------------------------------------- ClickEncoder *encoder; void timerIsr() { encoder->service(); } int16_t last; //letzter eingelesener Wert bool ButtonPressed = false; //wurde der Taster gedrückt? //---------------------------------------------------------------------------------------------------------------- //Temperatursensor DS1820 Initialisierung ------------------------------------------------------------------------ #include #include // OneWire-Referenz OneWire oneWire(ONE_WIRE_BUS); // DS18B20 initialisieren DallasTemperature sensors(&oneWire); // Array für die Deviceadressen DeviceAddress insideThermometer; float sensorwert; //eingelesener Istwert (alle außer sep. Nachgussbereitung) float sensortemp; //temporärer Temperaturspeicher zur Messwertmittelung float alter_sensorwert; float alte_sensortemp; int16_t anzahl_werte_mittlung = 5; //Anzahl von Messwerten, die für Isttemp gemittelt werden int16_t mess_count = anzahl_werte_mittlung; //Zähler für Messwertemittlung float isttemp = 20; //Vorgabe 20 damit Sensorfehler am Anfang nicht anspricht float nachgusssensor; //2er Sensor für die Nachgussbereitung uint8_t nachgusssolltemp = 78; //Nachgusstemperatur und 2. Sensor!! ohne 2. Sensor Vorgabe 78°C uint8_t anzahlTempsensoren; //ist der Nachgusssensor angeschlossen? uint8_t nachgussheizung = 0; //Merker ob Nachgussheizung EIN- bzw. Ausgeschaltet bool funksensor = false; //Vorgabe - nicht ändern! //---------------------------------------------------------------------------------------------------------------- //Zeitmessung----------------------------------------------------------------------------------------------------- #include //---------------------------------------------------------------------------------------------------------------- //EEPROM für Voreinstellungen------------------------------------------------------------------------------------- #include //---------------------------------------------------------------------------------------------------------------- // Messergebnisse ------------------------------------------------------------------------------------------------ //uint8_t val = 0; // Variable um Messergebnis zu speichern //---------------------------------------------------------------------------------------------------------------- #define EIN 1 //allgemeine Definitionen #define AUS 0 //Informationen zur AiO ------------------------------------------------------------------------------------------ String AiOversion = "AiO-MEGA-04.03.2021"; #ifdef MitDisplayUndEncoder String displayart = "1"; #else String displayart = "0"; #endif #ifdef RTC_Hardware String realtime = "1"; #else String realtime = "0"; #endif //Allgemein Initialisierung--------------------------------------------------------------------------------------- uint8_t anfang = 0; //Start des jeweiligen Modus float altsekunden; //Hilfsvariable Zeitmessung uint8_t altstunden = 0; //Hilfsvariable Zeitmessung uint8_t regelung = AUS; //Regelung aktiv/inaktiv - gilt nicht für die Gärführung uint8_t heizung = AUS; //Heizung EIN/AUS uint8_t sensorfehler = 0; //Temperaturfühler defekt oder fehlt uint8_t umwaelzer_stat = AUS; //Umwaelzerstatus EIN/AUS bool sollwerterreicht = false; //eingestellte Temperatur erreicht/nicht erreicht uint32_t kwarten = 0; //Wartezeit kühlen uint8_t modus = HAUPTMENUE; //Programmmodus - 0=Hauptmenü uint8_t sondermodus = 0; //Sonderbehandlung im Brauerruf (Einmaischen und Ruflänge) uint8_t externmodus; //Modus bei Unterbrechung durch Software speichern uint8_t rufmodus = 0; //merkt sich den Modus nach Brauerruf float rufsignalzeit = 0; //so lange dauert der Ruf - wird im Programm gesetzt bool nachgussruf = false; //Signal wenn Nachgusstemp erreicht uint32_t nachgusswarten; //Einschaltverzögerung Nachgussheizung uint8_t x = 1; //aktuelle Rast Nummer uint8_t altx; //Merker für letzte Rast uint8_t h = 0; //aktuelle Hopfengabe uint8_t y = 1; //Übergabewert von x für Braumeisterruf uint8_t n = 0; //Counter Messungserhöhung zur Fehlervermeidung int16_t m = 0; //EMC - Fehlerzähler uint8_t pause = 0; //Counter für Ruftonanzahl uint8_t sekunden = 0; //Zeitzählung uint8_t minuten = 0; //Zeitzählung uint8_t minutenwert = 0; //Zeitzählung uint8_t stundenwert = 0; //Zeitzählung uint8_t stunden = 0; //Zeitzählung bool gespeichert = false; //Abspeichern der Zustände im Notfallmodus uint8_t blinker; //Hilfsvariable blinken; uint8_t abbruchkochen; //Zeitzählung bis Kochabbruch uint8_t rufZ; //Rufzähler für PC-Sound static const char *bin2tristate(const char *bin); //Ausgabe Steckdosencodierung static char *dec2binWzerofill(int32_t Dec, int16_t bitLength); //Vorgabewerte zur ersten Einstellung----------------------------------------------------------------------------- uint8_t sollwert = 20; //Sollwertvorgabe für Anzeige uint8_t maischtemp = 45; //Vorgabe Einmasichtemperatur uint8_t rasten = 3; //Vorgabe Anzahl Rasten uint8_t rastTemp[] = { 0, 55, 64, 72, 72, 72, 72, 72 }; //Rasttemperatur Werte uint8_t rastZeit[] = { 0, 15, 40, 25, 20, 20, 20, 20 }; //Rastzeit Werte uint8_t braumeister[] = { 0, 0, 0, 0, 0, 0 }; //Braumeisterruf Standard ist AUS uint8_t endtemp = 78; //Vorgabewert Endtemperatur uint8_t kochzeit = 90; // 90 min. Kochen //Parameter zur Gärführung --------------------------------------------------------------------------------------- //Startvorgaben uint8_t gaerstart = 8; //°C uint8_t gaerrasten = 3; //Anzahl Gärrasten uint8_t gaerRastTemp[] = {0, 8, 10, 16, 16, 16}; //°C uint8_t gaerRastZeit[] = {0, 24, 72, 254, 254, 254}; //in Stunden! uint8_t gaerregelung = AUS; //wenn innerhalb der Solltemperatur +/- Hysterese /* Hopfengaben---------------------------------------------------------------------------------------------------- "maxrasten" kann geändert werden. die Vorgabewerte in den Klammern müssen nicht, können aber angepasst werden. "hanz" ist die Voreinstellung für die Auswahl der Rastanzahl. */ uint8_t const maxgaben = 6; int8_t hopfengabe[maxgaben] = {90, 20, 10, 0, 0, 0}; //Zeiten für die Hopfengaben 90 min. können vorgegeben werden uint8_t hanz = 3; //Vorgabewert Anzahl Hopfengaben bool rezept_eingelesen = false; bool hknull; //Nachisomerisierung---------------------------------------------------------------------------------------------- uint8_t nachisomerisierung = 20; //Vorgabe 20 min. Wartezeit nach Kochende uint8_t isoTemperatur = 80; //Temperaturgrenze für Nachisomerisierung uint8_t nachiso_h; //Hilfsvariable zur Zeitsetzung nach Stromausfall uint8_t nachiso_m; //Nachiso Minuten uint8_t nachiso_s; //Nachiso Sekunden //---------------------------------------------------------------------------------------------------------------- //Rührwerk/Malzrohrpumpe------------------------------------------------------------------------------------------ char ja_nein[2] = {'N', 'J'}; //Antworten Dauerbetrieb Ja/nein uint8_t intervalEin = 60; //Voreinstellung 60s EIN wenn noch kein Wert im EEPROM uint8_t intervalAus = 60; //dann 60s AUS uint8_t ruehrerspeed = 0; //langsames Drehen beim Start char dauerbetrieb = 'N'; //Voreinstellung Intervallbetrieb int16_t altdrehen; //alten Wert des Drehencoders merken int16_t drehen; //aktueller Wert des Drehgebers int16_t tempdrehen; //Merker für aktuellen Wert von "drehen" (für Doppelclick) bool firstinterval = true; //das erste Rührerintervall startet direkt nach Ende "Heizen" int32_t intervalstart; //Intervallzyklus startet uint8_t rwerk = 0; //Hilfsvariable für Rührwekssteuerung (speichert den alten Zustand) bool ruehrer = true; //Vorgabe Rührer aktiv bool pumpe = false; //Pumpe alternativ uint8_t umwaelzen; //Hilfsvariable Umwälzerwahl uint8_t wahl; //Malzrohrpumpe oder Rührer bool highspeed = false; //Umschaltrelais verbaut? bool button = false; //Einschaltmöglichkeit des Rührers durch Buttondruck im Maischeprozess float startcount; //Nachlaufzeit Rührer/Pumpe 1 min.! //Kochen---------------------------------------------------------------------------------------------------------- bool schwelle_erreicht = false; //Kochschwelle erreicht, danach Wartezeit bis Abbruch uint8_t kschwelle = 98; //Voreinstellung - ab hier ertönt der Brauerruf //Zeitverzögerungen und Initialwerte------------------------------------------------------------------------------ int32_t kzeitverz = 0; //Wartezeit Einschalten Kompressor NICHT ÄNDERN int32_t esvheizen = 0; //Einschaltverzögerung für Heizung - kann im Setup geändert werden int32_t esvpumpen = 30000; //30s Einschaltverzögerung Pumpe - kann im Setup geändert werden bool first = false; //erster Anlauf ohne Zeitverzögerung -> dann first = true bool nachgussfirst = true; //Hilfsvariable Nachgussbereitung während des Maischens bool dclick; //Doppelclick gedrückt ? uint32_t hwarten = 0; //Wartezeitmessung Start //------------Temperaturmessung und Steigungsberechnung K/min -> Kelvin/Minute - Hinweis auf die Aufheizrate des Kessels float alte_zeit; //Zeit bei t-1 float alte_zeit_nachguss; //Nachgusstemperatur bei t-1 float alte_temperatur = 20; //Temperatur bei t-1 float alte_nachgusstemperatur; //Nachgusstemperatur bei t-1 int16_t messzyklus = 10000; //Zeit im ms für dT und dt für die Gradientenberechnung - Vorgabe 10s float gradient; //Steigungswert float gradient_nachguss; //Gradient Nachgusstemperatur float gfh = 1; //Gradientenfaktor kh (Heizen) - Vorgabe 1 float gfk = 1; //Gradientenfaktor kk (Kühlen) - Vorgabe 1 //Logging ----------------------------------------------------------------------------------------------------------- bool loggen = false; //Daten Soll/Ist an Logprogramm übertragen zunächst deaktiviert uint8_t logprog = 0; //Auswahl des Logprogramms bool serialcom = false; //Logger SerialComInterface bool logview = false; //Logview Studio float logintervall = 2900; //Logging Intervall 3s - 0,1 s in der Routine //Doppelclick für temporären Aufruf des Setup-Menüs------------------------------------------------------------------ uint8_t altmodus; //merkt sich den Modus für Doppelclick zum Setupmenü uint8_t zeitz = true; //Zeitzählung nach Doppelclick nicht stoppen (zeitz = false) //Notfallmodus nach Stromausfall ------------------------------------------------------------------------------------ //Speichert den Zustand in Modus 28,29,30,251,252 uint8_t Notfallmodus; //Notfallmodus Maischeprogramm/Gärführung aktiv (es gab einen Stromausfall) uint8_t RastNr; //gespeicherte Rastnummer uint8_t RastTemp; //gespeicherte aktuelle Rasttemperatur uint8_t RastZeit; //gespeicherte aktuelle Rastzeit uint8_t RastZeit_h; //Rastzeit Stundenanteil uint8_t RastZeit_m; //Rastzeit Minutenanteil uint8_t RastZeit_s; //Rastzeit Sekundenanteil uint8_t RastModus; //gespeicherter Modus bool zeit_setzen; //Hilfsvariable für Settime bool notfall_aktiv = false; //soll der Notfallmodus genutzt werden? - nur im Setup ändern! bool notmodus; //Merker für Zeitsetzung im Notfallmodus bool neustart = false; //Auslesen der Rastnummer nach Notstart bool zeit_null_setzen = false; //UDP/Bluetooth - Steuerung------------------------------------------------------------------------------------------ char reply[500]; //Daten zum PC char antwort[500]; //Antwort vom PC const bool printReply = true; char command[20]; String responce; //enthält die Daten vom PC String meldung_detail; //Detailmeldungen in der AiO String alte_detailmeldung; String meldung; //Modusmeldungen in der AiO String alte_meldung; String zeit_detail; //Zeitablauf an AiO #ifdef bluetooth uint32_t DatenZP; //Wartezeit Bluetooth-Steuerung #else bool wlanAktiv = false; //Vorgabe kein WLAN uint32_t lan_aufruf = 30000; //Wartezeit WLAN-Steuerung #endif //Kühlmodus -------------------------------------------------------------------------------------------------------- bool knot; //Kühlmodus nach Notfall gespeichert ? //Jodprobe --------------------------------------------------------------------------------------------------------- uint8_t tz = 0; //Anzahl Piepser für Jodprobe - Vorgabe 3 in Modus 29 bool signalende; //nur einmal an Jodprobe erinnern uint32_t verz; //Ruf zum PC boolean rufpc = true; #ifdef WUERZEPUMPE_AKTIV //Würzepumpe ------------------------------------------------------------------------------------------------------- uint32_t warten; uint32_t pwarten; bool anzeige; bool manuell_ein = false; //Manuelles Ein- und Ausschalten der Würzepumpe #endif //Malzrohrpumpe ---------------------------------------------------------------------------------------------------- bool malzrohrpumpe_dauerbetrieb = false; //Dauerbetrieb nur im Modus 0 ! - Reinigungslauf bool ruf = false; bool rufquittung = false; //------------------------------------------------------------------------------------------------------------------ bool kuehlen = true; //Auswahl für variable Temperaturregelung (Heizen oder Kühlen) //------------------------------------------------------------------------------------------------------------------ uint8_t B_EIN; //Signalwert für den Buzzer (Piezo) #ifdef RTC_Hardware //---RTC------------------------------------------------------------------------------------------------------------ #include RTC_DS1307 RTC; uint8_t weckstunde; //Variablen für den Timer uint8_t weckminute; uint8_t zeigestunde; uint8_t zeigeminute; bool timeractiv; uint8_t hr; uint8_t mi; uint8_t se; uint8_t da; uint8_t mo; uint8_t ye; #endif //Funktionen======================================================================= //------------------------------------------------------------------------------- //schreibt LongInt in das EEPROM //------------------------------------------------------------------------------- void EEPROMWritelong(int16_t address, int32_t value) { uint8_t four = (value & 0xFF); uint8_t three = ((value >> 8) & 0xFF); uint8_t two = ((value >> 16) & 0xFF); EEPROM.write(address, four); EEPROM.write(address + 1, three); EEPROM.write(address + 2, two); }// Ende EEPROMWritelong //------------------------------------------------------------------------------- //liest LongInt aus dem EEPROM //------------------------------------------------------------------------------- int32_t EEPROMReadlong(int32_t address) { int32_t four = EEPROM.read(address); int32_t three = EEPROM.read(address + 1); int32_t two = EEPROM.read(address + 2); return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF); }// Ende EEPROMReadlong //------------------------------------------------------------------------------- //schreibt Integerwerte in das EEPROM //------------------------------------------------------------------------------- void EEPROMWriteInt(int16_t address, int16_t value) { uint8_t lowuint8_t = ((value >> 0) & 0xFF); uint8_t highuint8_t = ((value >> 8) & 0xFF); EEPROM.write(address, lowuint8_t); EEPROM.write(address + 1, highuint8_t); } //------------------------------------------------------------------------------- //liest Integerwerte aus dem EEPROM //------------------------------------------------------------------------------- int16_t EEPROMReadInt(int16_t address) { uint8_t lowuint8_t = EEPROM.read(address); uint8_t highuint8_t = EEPROM.read(address + 1); return ((lowuint8_t << 0) & 0xFF) + ((highuint8_t << 8) & 0xFF00); }// Ende EEPROMReadInt //-------------------------------------------------------------------------------- //zeigt speichern im Display //-------------------------------------------------------------------------------- void speichern(uint8_t zeile) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, zeile); lcd.print("speichern"); delay(500); #endif }// Ende speichern //------------------------------------------------------------------------------- //Test auf den ersten Start und initialisierung der Setupdaten //------------------------------------------------------------------------------- void init_start() { if (EEPROM.read(jungfraustart) != 199) //199 ist ein Wert, der beim ersten Start an der //Adresse nicht gespeichert sein sollte! { EEPROM.write(jungfraustart,199); EEPROM.write(Kochschwelle, 98); EEPROM.write(nachgusssoll, 78); EEPROMWritelong(g_kuehltemp, 10); EEPROM.write(logging, 0); EEPROM.write(sound, 255); EEPROMWritelong(kuehlverz,5 * 60000); //300000ms = 5 min. EEPROMWritelong(wein_h, 5 * 1000); //5000ms = 5 sek. EEPROMWritelong(graf_k, 0.5*10); EEPROMWritelong(graf_h, 1 * 10); EEPROM.write(notfall, 0); EEPROM.write(umwaelzwahl, 0); //Rührer - kein Malzrohr EEPROM.write(umwaelzer_ie, 60); EEPROM.write(umwaelzer_ia, 30); EEPROM.write(ruepumeinmaisch, 1); EEPROM.write(rueNachlauf, 1); } } #ifdef funksteuerung //-------------------------------------------------------------------------------- //Funkcodes einlesen //-------------------------------------------------------------------------------- void init_funk() { funk_heizung_ein = EEPROMReadlong(Heizung_EIN); funk_heizung_aus = EEPROMReadlong(Heizung_AUS); funk_umwaelzer_ein = EEPROMReadlong(Umwaelz_EIN); funk_umwaelzer_aus = EEPROMReadlong(Umwaelz_AUS); funk_variabel_ein = EEPROMReadlong(Nachguss_EIN); funk_variabel_aus = EEPROMReadlong(Nachguss_AUS); }// Ende init_funk #endif //-------------------------------------------------------------------------------- //Umwälzer (Rührer/Pumpe) ausschalten //-------------------------------------------------------------------------------- void UmwaelzerAUS() { #ifdef relaissteuerung digitalWrite(UmwaelzR1, R_AUS); //Mischer (Umwälzer) AUS digitalWrite(UmwaelzR2, R_AUS); #endif #ifdef funksteuerung mySwitch.send(funk_umwaelzer_aus, 24); //24 Bit -Länge - füllt den Wert mit 0en delay(funkdelay); #endif rwerk = 0; umwaelzer_stat = AUS; }// Ende UmwaelzerAUS //-------------------------------------------------------------------------------- //Umwälzer (Rührer/Pumpe) einschalten //-------------------------------------------------------------------------------- void UmwaelzerEIN() { #ifdef relaissteuerung digitalWrite(UmwaelzR2, R_EIN); digitalWrite(UmwaelzR1, R_EIN); #endif #ifdef funksteuerung mySwitch.send(funk_umwaelzer_ein, 24); delay(funkdelay); #endif rwerk = 1; umwaelzer_stat = EIN; }// Ende UmwaelzerEIN //------------------------------------------------------------------------------- //Heizung ausschalten //------------------------------------------------------------------------------- void HeizungAUS() { #ifdef relaissteuerung digitalWrite(HeizungR1, H_AUS); //Heizung aus digitalWrite(HeizungR2, H_AUS); #endif #ifdef funksteuerung mySwitch.send(funk_heizung_aus, 24); delay(funkdelay); #endif firstinterval = true; if ((modus == MAISCHEN_START) || (modus == EINMAISCHEN) || (modus == TEMPERATURAUTOMATIK) || (modus == ZEITAUTOMATIK) || (modus == ENDTEMPERATURAUTOMATIK)) if (umwaelzer_stat == EIN) UmwaelzerAUS(); heizung = AUS; }// Ende HeizungAUS //--------------------------------------------------------------------------------- //Heizung einschalten //--------------------------------------------------------------------------------- void HeizungEIN() { heizung = EIN; #ifdef relaissteuerung digitalWrite(HeizungR1, H_EIN); // einschalten digitalWrite(HeizungR2, H_EIN); // einschalten #endif #ifdef funksteuerung mySwitch.send(funk_heizung_ein, 24); //nicht bei jedem Durchlauf aufrufen delay(funkdelay); #endif }// Ende HeizungEIN //--------------------------------------------------------------------------------- //Nachgusstopf ausschalten (wenn Heizung EIN) //--------------------------------------------------------------------------------- void NachgussAUS() { #ifdef relaissteuerung digitalWrite(NachgussR1, NG_AUS); //Nachgussrelais aus digitalWrite(NachgussR2, NG_AUS); #endif #ifdef funksteuerung if (!funkruf) { mySwitch.send(funk_variabel_aus, 24); delay(funkdelay); } #endif nachgussheizung = AUS; }// Ende void NachgussAUS //--------------------------------------------------------------------------------- //Nachgusstopf einschalten (wenn Heizung AUS) //--------------------------------------------------------------------------------- void NachgussEIN() { if (anzahlTempsensoren == 2) { if (nachgusssensor < (nachgusssolltemp - (gradient_nachguss))) { #ifdef funksteuerung if (!funkruf) { mySwitch.send(funk_variabel_ein, 24); delay(funkdelay); } #endif #ifdef relaissteuerung digitalWrite(NachgussR1, NG_EIN); // Nachgussrelais einschalten digitalWrite(NachgussR2, NG_EIN); // Nachgussrelais einschalten #endif nachgussheizung = EIN; } } else { #ifdef funksteuerung if (!funkruf) { mySwitch.send(funk_variabel_ein, 24); delay(funkdelay); } #endif #ifdef relaissteuerung digitalWrite(NachgussR1, NG_EIN); // Nachgussrelais einschalten digitalWrite(NachgussR2, NG_EIN); // Nachgussrelais einschalten #endif nachgussheizung = EIN; } }// Ende NachgussEIN //--------------------------------------------------------------------------------- //Ruf einschalten //--------------------------------------------------------------------------------- void RufEIN(boolean brauerruf) { analogWrite(RufR, B_EIN); // Ruf einschalten #ifdef funksteuerung if (funkruf) if (brauerruf) mySwitch.send(funk_variabel_ein, 24); delay(funkdelay); #endif }// Ende RufEIN //--------------------------------------------------------------------------------- //Ruf ausschalten //--------------------------------------------------------------------------------- void RufAUS(boolean brauerruf) { analogWrite(RufR, B_AUS); // Ruf ausschalten #ifdef funksteuerung if (funkruf) if (brauerruf) mySwitch.send(funk_variabel_aus, 24); delay(funkdelay); #endif }// Ende RufAUS //--------------------------------------------------------------------------------- //Funktion kurzen Signalton abgeben //--------------------------------------------------------------------------------- void signalton(int16_t dauer) //kein separater Modus { RufEIN(false); delay(dauer); RufAUS(false); }// Ende Signalton //--------------------------------------------------------------------------------- //Funktion Bluetooth-Verbinden (wenn Bluetoothmodul HC05 oder HC06 vorhanden) //--------------------------------------------------------------------------------- #ifdef bluetooth void connectBluetooth() //Modus = CONNECT_BLUETOOTH { bluetooth_steuerung = true; Serial2.begin(115200); #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 3); lcd.print("Init Bluetooth"); delay(1000); #endif if (modus == CONNECT_BLUETOOTH) modus = SETUPMENUE; }// Ende connectBluetooth #endif //--------------------------------------------------------------------------------- //Funktion Setupdaten aufsplitten (Datensatz mit allen Setupwerten am ; aufteilen) //--------------------------------------------------------------------------------- bool splitSetup(String splitmodus) { uint8_t ns; //uint8_t dummy; uint8_t dreh; uint8_t drehtemp; String dummystring; char *pch; pch = strtok(antwort, ";:"); ns = 0; if (splitmodus == "ms239") //Kochschwelle { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { kschwelle = atoi(pch); if (EEPROM.read(Kochschwelle) != kschwelle) EEPROM.write(Kochschwelle, kschwelle); } ns++; } if (ns != 3) return false; else return true; } if (splitmodus == "ngt239") //Nachgusstemperatur { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { nachgusssolltemp = atoi(pch); if (EEPROM.read(nachgusssoll) != nachgusssolltemp) EEPROM.write(nachgusssoll, nachgusssolltemp); } ns++; } if (ns != 3) return false; else return true; } if (splitmodus == "ms46") //Notfallmodus { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { if (EEPROM.read(notfall) != atoi(pch)) EEPROM.write(notfall, atoi(pch)); notfall_aktiv = atoi(pch); } ns++; } if (ns != 3) return false; else return true; } #ifdef gassensor if (splitmodus == "gas") //Gas Alarmschwelle { while (pch != NULL) { pch = strtok(NULL, ";"); switch (ns) { case 1: if (EEPROMReadInt(gas_grenzwert) != atoi(pch) / 100) EEPROMWriteInt(gas_grenzwert, atoi(pch) / 100); lpg_grenzwert = atoi(pch); break; case 2: if (atoi(pch) == 1) { anfang = 0; externmodus = modus; modus = GASSENSORINIT; externer_aufruf = true; } break; } ns++; } if (ns != 4) return false; else return true; } #endif #ifdef RTC_Hardware if (splitmodus == "ti9") //Timermodus { while (pch != NULL) { pch = strtok(NULL, ";"); switch (ns) { case 1: EEPROM.write(startstunde, atoi(pch)); weckstunde = atoi(pch); break; case 2: EEPROM.write(startminute, atoi(pch)); weckminute = atoi(pch); break; case 3: if (strcmp(pch, "1")) timeractiv = true; else timeractiv = false; break; case 4: hr = atoi(pch); #ifdef dbg Serial.println(hr); #endif break; case 5: mi = atoi(pch); #ifdef dbg Serial.println(mi); #endif break; } ns++; }; if (ns != 7) return false; else { DateTime uhrzeit = RTC.now(); ye = uhrzeit.year(); mo = uhrzeit.month(); da = uhrzeit.day(); se = uhrzeit.second(); setTime(hr, mi, se, da, mo, ye); RTC.adjust(now()); modus = HAUPTMENUE; anfang = 0; return true; } } #endif #ifdef funksteuerung if (splitmodus == "ms236") { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { if (EEPROM.read(dritte_funksteckdose) != atoi(pch)) EEPROM.write(dritte_funksteckdose, atoi(pch)); if (atoi(pch) == 1) funkruf = true; else funkruf = false; } ns++; } if (ns != 3) return false; else return true; } #endif if (splitmodus == "ms8") //Lautstärke testen { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { dreh = atoi(pch); drehtemp = B_EIN; B_EIN = dreh; RufEIN(true); delay(1000); RufEIN(false); B_EIN = drehtemp; } ns++; } if (ns != 3) return false; else return true; } if (splitmodus == "msz") //Rastzeit verändern { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { if (modus == ZEITAUTOMATIK) drehen = atoi(pch); if (modus == GAERZEITAUTOMATIK) drehen = atoi(pch); } ns++; } if (ns != 3) return false; else return true; } if (splitmodus == "mst") //Rastzeit verändern { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { if (modus == TEMPERATURAUTOMATIK) drehen = atoi(pch); if (modus == EINMAISCHEN) drehen = atoi(pch); if (modus == ENDTEMPERATURAUTOMATIK) drehen = atoi(pch); } ns++; } if (ns != 3) return false; else return true; } #ifdef WUERZEPUMPE_AKTIV if (splitmodus == "wpv3") //Einschaltverzögerung Würzepumpe { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { esvpumpen = atoi(pch) * 1000; drehen = atoi(pch); } if (modus == WUERZEPUMPE) anfang = 0; if (ns == 2) if (atoi(pch) == 1) manuell_ein = false; else manuell_ein = true; ns++; } if (ns != 4) return false; else return true; } #endif if (splitmodus == "mss8") //Lautstärke speichern { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) dreh = atoi(pch); ns++; } if (ns != 3) return false; else { if (EEPROM.read(sound) != dreh) EEPROM.write(sound, dreh); B_EIN = dreh; return true; } } if (splitmodus == "mk1") //Heizen/Kühlen umschalten { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { sollwert = atoi(pch); drehen = sollwert; modus = KUEHLEN; } if (ns == 2) { if (atoi(pch) == 1) kuehlen = true; else kuehlen = false; } ns++; } if (ns != 4) return false; else return true; } if (splitmodus == "ng2") //Nachguss { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { sollwert = atoi(pch); nachgusssolltemp = sollwert; modus = NACHGUSS; anfang = 0; ruehrer = false; pumpe = false; } ns++; } if (ns != 3) return false; else return true; } if (splitmodus == "mt239") //Mischerwahl { uint8_t dummy; while (pch != NULL) { pch = strtok(NULL, ";"); switch (ns) { case 1: { dummy = atoi(pch); if (EEPROM.read(umwaelzwahl) != dummy) EEPROM.write(umwaelzwahl, dummy); switch (dummy) { case 0: ruehrer = true; fern = true; //Rührer über KBH2AiO -> AUS pumpe = false; break; case 1: ruehrer = false; pumpe = true; break; } } break; case 2: { if (String(pch) == "N") { if (EEPROM.read(udauer) != 0) { EEPROM.write(udauer, 0); dauerbetrieb = 'N'; } } if (String(pch) == "J") { if (EEPROM.read(udauer) != 1) { EEPROM.write(udauer, 1); dauerbetrieb = 'J'; } } } break; case 3: { dummy = atoi(pch); if (EEPROM.read(umwaelzer_ie) != dummy) EEPROM.write(umwaelzer_ie, dummy); intervalEin = dummy; } break; case 4: { dummy = atoi(pch); if (EEPROM.read(umwaelzer_ia) != dummy) EEPROM.write(umwaelzer_ia, dummy); intervalAus = dummy; } break; case 5: { dummy = atoi(pch); if (EEPROM.read(ruepumeinmaisch) != dummy) EEPROM.write(ruepumeinmaisch, dummy); ruehrer_beim_einmaischen = dummy; } break; case 6: { dummy = atoi(pch); if (EEPROM.read(rueNachlauf) != dummy) EEPROM.write(rueNachlauf, dummy); ruehrer_nachlauf = dummy; } break; } ns++; } if (ns != 8) return false; else return true; } if (splitmodus == "mr11") //Regler konfigurieren { while (pch != NULL) { pch = strtok(NULL, ";"); dummystring = pch; switch (ns) { case 1: if (EEPROMReadlong(graf_h) != dummystring.toFloat() * 10) EEPROMWritelong(graf_h, dummystring.toFloat() * 10); gfh = EEPROMReadlong(graf_h) / 10; break; case 2: if (EEPROMReadlong(wein_h) != dummystring.toFloat() * 1000) EEPROMWritelong(wein_h, dummystring.toFloat() * 1000); esvheizen = EEPROMReadlong(wein_h); break; case 3: if (EEPROMReadlong(graf_k) != dummystring.toFloat() * 10) EEPROMWritelong(graf_k, dummystring.toFloat() * 10); gfk = EEPROMReadlong(graf_k) / 10; break; case 4: if (EEPROMReadlong(kuehlverz) != dummystring.toFloat() * 60000) EEPROMWritelong(kuehlverz, dummystring.toFloat() * 60000); kzeitverz = EEPROMReadlong(kuehlverz) * 60000L; break; } ns++; } if (ns != 6) return false; else return true; } if (splitmodus == "ms44") //Loggerwahl { while (pch != NULL) { pch = strtok(NULL, ";"); if (ns == 1) { if (atoi(pch) == 3) { if (EEPROM.read(logging) != 0) EEPROM.write(logging, 0); loggen = false; } else { if (EEPROM.read(logging) != 1) EEPROM.write(logging, 1); loggen = true; if (EEPROM.read(loggerwahl) != atoi(pch)) EEPROM.write(loggerwahl, atoi(pch)); Serial.begin(115200); drehen = EEPROM.read(loggerwahl); switch (drehen) { case 0: { serialcom = true; logview = false; break; } case 1: { logview = true; serialcom = false; break; } } } } ns++; } if (ns != 3) return false; else return true; } } // Ende splitSetup //--------------------------------------------------------------------------------- //Funktion Rezeptdaten aufsplitten (Rezeptparameter separieren) //--------------------------------------------------------------------------------- bool split() { uint8_t np; char *pch; pch = strtok(antwort, ";:"); np = 0; while (pch != NULL) { pch = strtok(NULL, ";"); switch (np) { case 1: maischtemp = atoi(pch); break; case 2: rasten = atoi(pch); break; case 3: kochzeit = atoi(pch); break; case 4: rastTemp[1] = atoi(pch); break; case 5: rastTemp[2] = atoi(pch); break; case 6: rastTemp[3] = atoi(pch); break; case 7: rastTemp[4] = atoi(pch); break; case 8: rastTemp[5] = atoi(pch); break; case 9: rastTemp[6] = atoi(pch); break; case 10: endtemp = atoi(pch); break; case 11: rastZeit[1] = atoi(pch); break; case 12: rastZeit[2] = atoi(pch); break; case 13: rastZeit[3] = atoi(pch); break; case 14: rastZeit[4] = atoi(pch); break; case 15: rastZeit[5] = atoi(pch); break; case 16: rastZeit[6] = atoi(pch); break; case 18: hopfengabe[0] = atoi(pch); break; case 19: hopfengabe[1] = atoi(pch); break; case 20: hopfengabe[2] = atoi(pch); break; case 21: hopfengabe[3] = atoi(pch); break; case 22: hopfengabe[4] = atoi(pch); break; case 23: hopfengabe[5] = atoi(pch); break; case 24: hanz = atoi(pch); break; case 25: nachisomerisierung = atoi(pch); break; } np++; } if (np != 27) { fern = false; return false; } else { fern = true; return true; } }// Ende split //--------------------------------------------------------------------------------- //Funktion Gärplan aufsplitten (Gärplanzeiten separieren) //--------------------------------------------------------------------------------- boolean gaersplit() { uint8_t nt = 0; char *pch; pch = strtok(antwort, ";:"); while (pch != NULL) { pch = strtok(NULL, ";"); switch (nt) { case 1: gaerrasten = atoi(pch); break; case 2: gaerRastTemp[1] = atoi(pch); break; case 3: gaerRastTemp[2] = atoi(pch); break; case 4: gaerRastTemp[3] = atoi(pch); break; case 5: gaerRastTemp[4] = atoi(pch); break; case 6: gaerRastTemp[5] = atoi(pch); break; case 7: gaerRastZeit[1] = atoi(pch); break; case 8: gaerRastZeit[2] = atoi(pch); break; case 9: gaerRastZeit[3] = atoi(pch); break; case 10: gaerRastZeit[4] = atoi(pch); break; case 11: gaerRastZeit[5] = atoi(pch); break; case 12: gaerstart = atoi(pch); if (notfall_aktiv) EEPROM.write(MaischTemp, gaerstart); break; } nt++; } if (nt != 14) return false; else return true; }// Ende gaersplit #ifdef bluetooth //--------------------------------------------------------------------------------- //Funktion Daten vom Empfänger //--------------------------------------------------------------------------------- void getReply(int16_t wait) //kein separater Modus { int16_t tempPos = 0; uint32_t time = millis(); while ((time + wait) > millis()) { while (Serial2.available()) { char c = Serial2.read(); if (tempPos < 500) { reply[tempPos] = c; tempPos++; } } reply[tempPos] = 0; } #ifdef dbg if (printReply) { Serial.println(reply); } #endif }// Ende getReply //------------------------------------------------------------------------------- //Bluetooth EIN-AUS //--------------------------------------------------------------------------------- void Bluetootheinaus() //Modus = BLUETOOTH_EIN_AUS { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Bluetooth:"); lcd.setCursor(0, 1); lcd.print("EIN:"); #endif anfang = 1; drehen = EEPROM.read(Bluetooth); } #ifdef MitDisplayUndEncoder encoder->setAccelerationEnabled(false); char antwort_jn = ja_nein[drehen % 2]; lcd.setCursor(5, 1); lcd.print(antwort_jn); #endif if (ButtonPressed) { modus = SETUPMENUE; if (EEPROM.read(Bluetooth) != drehen % 2) EEPROM.write(Bluetooth, drehen % 2); speichern(2); anfang = 0; if (drehen % 2 == 1) { connectBluetooth(); modus = CONNECT_BLUETOOTH; } else Serial2.end(); } }// Ende Bluetootheinaus #else void getReply(uint16_t wait) //kein separater Modus { uint16_t tempPos = 0; uint32_t time = millis(); while ((time + wait) > millis()) { while (Serial2.available()) { char c = Serial2.read(); if (tempPos < 500) { reply[tempPos] = c; tempPos++; } } reply[tempPos] = 0; } #ifdef dbg if (printReply) { Serial.println(reply); } #endif }// Ende getReply #endif #ifdef bluetooth //--------------------------------------------------------------------------------- //Funktion Setupdaten der AiO zum PC //--------------------------------------------------------------------------------- void Setup_zum_pc() { String data; //0 data = String(kschwelle); //Kochschwelle data += ";"; if (EEPROM.read(udauer) == 0) dauerbetrieb = 'N'; else dauerbetrieb = 'J'; //1 data += dauerbetrieb; //Rührer Dauerbetrieb? data += ";"; intervalEin = EEPROM.read(umwaelzer_ie); intervalAus = EEPROM.read(umwaelzer_ia); //2 data += String(intervalEin); //Rührer/Malzrohrpumpe EIN Intervall data += ";"; //3 data += String(intervalAus); //Rührer/Malzrohrpumpe AUS Intervall data += ";"; uint8_t wahl_u = EEPROM.read(umwaelzwahl); //4 data += String(wahl_u); //Rührer oder Malzrohrpumpe data += ";"; //5 data += String(esvheizen); //Einschaltverzögerung Heizen data += ";"; //6 data += String(EEPROMReadlong(kuehlverz) / 60000L); //Einschaltverzögerung Kühlen data += ";"; //7 data += String(EEPROMReadlong(graf_h)); //Gradientenfaktor Heizen data += ";"; //8 data += String(EEPROMReadlong(graf_k)); //Gradientenfaktor Kühlen data += ";"; //9 data += String(EEPROM.read(logging)); //Logging aktiv? data += ";"; //10 data += String(EEPROM.read(loggerwahl)); //Welches Loggingprogramm aktiv? data += ";"; //11 data += String(notfall_aktiv); //Stromausfallmodus (Notfall) aktiv? data += ";"; //12 data += EEPROM.read(nachgusssoll); //Nachgusstemperatur data += ";"; #ifdef funksteuerung //13 wahl = EEPROM.read(dritte_funksteckdose); #else wahl = 2; #endif data += String(wahl); //Ruf oder Nachgussheizung data += ";"; //14 wahl = EEPROM.read(sound); data += String(wahl); //Lautstärke data += ";"; //15 wahl = EEPROM.read(ruepumeinmaisch); data += String(wahl); //Mischer beim Einmaischen aktiv? data += ";"; //16 #ifdef WUERZEPUMPE_AKTIV wahl = esvpumpen / 1000; data += String(wahl); //Einschaltverzögerung Würzepumpe im Automatikbetrieb #else data += "0"; #endif data += ";"; //17 #ifdef WUERZEPUMPE_AKTIV if (manuell_ein) wahl = 0; else wahl = 1; data += String(wahl); //Würzepumpe Manuell/Automatikbetrieb #else data += "3"; #endif data += ";"; wahl = EEPROM.read(rueNachlauf); //18 data += String(wahl); data += ";"; #ifdef gassensor wahl = EEPROMReadInt(gas_grenzwert); //19 data += String(wahl); data += ";"; #else //19 wahl = 0; data += String(wahl); data += ";"; #endif //20 #ifdef geschwindigkeitsrelais data += "1"; #else data += "0"; #endif data += ";"; //21 data += AiOversion; data += ";"; //22 data += displayart; data += ";"; //23 data += realtime; data += ";"; #ifdef dbg Serial.println(data); //Kontrolle #endif Serial2.println(data); //Sende Setup Serial2.flush(); }// Ende Setup_zum_pc #else void Setup_zum_pc() { String data; data = String(kschwelle); //Kochschwelle data += ";"; if (EEPROM.read(udauer) == 0) dauerbetrieb = 'N'; else dauerbetrieb = 'J'; // if (EEPROM.read(udauer) == 1) dauerbetrieb = 'J'; data += dauerbetrieb; //Rührer Dauerbetrieb? data += ";"; intervalEin = EEPROM.read(umwaelzer_ie); intervalAus = EEPROM.read(umwaelzer_ia); data += String(intervalEin); //Rührer/Malzrohrpumpe EIN Intervall data += ";"; data += String(intervalAus); //Rührer/Malzrohrpumpe AUS Intervall data += ";"; uint8_t wahl = EEPROM.read(umwaelzwahl); data += String(wahl); //Rührer oder Malzrohrpumpe data += ";"; data += String(esvheizen); //Einschaltverzögerung Heizen data += ";"; data += String(EEPROMReadlong(kuehlverz) / 60000L); //Einschaltverzögerung Kühlen data += ";"; data += String(EEPROMReadlong(graf_h)); //Gradientenfaktor Heizen data += ";"; data += String(EEPROMReadlong(graf_k)); //Gradientenfaktor Kühlen data += ";"; data += String(EEPROM.read(logging)); //Logging aktiv? data += ";"; data += String(EEPROM.read(loggerwahl)); //Welches Loggingprogramm aktiv? data += ";"; data += String(notfall_aktiv); //Stromausfallmodus (Notfall) aktiv? data += ";"; data += EEPROM.read(nachgusssoll); //Nachgusstemperatur data += ";"; #ifdef funksteuerung wahl = EEPROM.read(dritte_funksteckdose); #else wahl = 2; #endif data += String(wahl); //Ruf oder Nachgussheizung data += ";"; wahl = EEPROM.read(sound); data += String(wahl); //Lautstärke data += ";"; wahl = EEPROM.read(ruepumeinmaisch); data += String(wahl); //Mischer beim Einmaischen aktiv? data += ";"; #ifdef WUERZEPUMPE_AKTIV wahl = esvpumpen / 1000; data += String(wahl); //Einschaltverzögerung Würzepumpe im Automatikbetrieb #else data += "0"; #endif data += ";"; #ifdef WUERZEPUMPE_AKTIV if (manuell_ein) wahl = 0; else wahl = 1; data += String(wahl); //Würzepumpe Manuell/Automatikbetrieb #else data += "3"; #endif data += ";"; wahl = EEPROM.read(rueNachlauf); data += String(wahl); data += ";"; #ifdef gassensor wahl = EEPROMReadInt(gas_grenzwert); data += String(wahl); data += ";"; #else wahl = 0; data += String(wahl); data += ";"; #endif //20 #ifdef geschwindigkeitsrelais data += "1"; #else data += "0"; #endif data += ";"; //21 data += AiOversion; data += ";"; //22 data += displayart; data += ";"; //23 data += realtime; data += ";"; #ifdef dbg Serial.println(data); //Kontrolle #endif Serial2.print("AT+CIPSEND=4,"); //Sende Messdaten Serial2.println(data.length() + 2); delay(50); if (Serial2.find('>')) { //ESP8266 sendebereit Serial2.print(data); //abschicken Serial2.print("\r\n"); } }// Ende Setup_zum_pc #endif //--------------------------------------------------------------------------------- //Limitiert den Drehwert (drehen) auf einen maximalen und minimalen Wert //--------------------------------------------------------------------------------- int16_t min_max_drehen(int16_t d, int16_t mindrehen, int16_t maxdrehen) { if (d < mindrehen) d = maxdrehen; if (d > maxdrehen) d = mindrehen; return d; }// Ende min_max_drehen //--------------------------------------------------------------------------------- //Gibt "J" oder "Nein" zurück, abhängig von //--------------------------------------------------------------------------------- String j_n_drehen(int16_t d) { d %= 2; if (d == 1) return "J"; else return "N"; }// Ende j_n_drehen //--------------------------------------------------------------------------------- //Hauptmenü //--------------------------------------------------------------------------------- void funktion_hauptschirm() //Modus=HAUPTMENUE { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); #endif #ifdef RTC_Hardware if (EEPROM.read(startstunde) != 255 && EEPROM.read(startminute) != 255) { #ifdef MitDisplayUndEncoder lcd.setCursor(14, 0); lcd.print("(T)"); lcd.setCursor(14, 1); lcd.print(EEPROM.read(startstunde)); lcd.print(":"); if (EEPROM.read(startminute) < 10) { lcd.print("0"); lcd.print(EEPROM.read(startminute)); } else lcd.print(EEPROM.read(startminute)); #endif timeractiv = true; } else timeractiv = false; #endif #ifdef MitDisplayUndEncoder lcd.setCursor(2, 0); lcd.print("Brauen"); lcd.setCursor(2, 1); lcd.print("Optionen"); lcd.setCursor(2, 2); lcd.print("Setup"); #endif drehen = 0; altdrehen = 0; anfang = 1; dclick = false; } #ifdef RTC_Hardware DateTime uhrzeit = RTC.now(); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); if (uhrzeit.hour() < 10) { lcd.print("0"); } lcd.print(uhrzeit.hour()); lcd.print(":"); if (uhrzeit.minute() < 10) { lcd.print("0"); } lcd.print(uhrzeit.minute()); #endif #endif drehen = min_max_drehen(drehen, 0, 2); if (drehen != altdrehen) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 2); lcd.print(" "); #endif } if (drehen == 0) { altdrehen = 0; rufmodus = BRAUMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("=>"); #endif } if (drehen == 1) { altdrehen = 1; rufmodus = OPTIONENMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("=>"); #endif } if (drehen == 2) { altdrehen = 2; rufmodus = SETUPMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("=>"); #endif } if (ButtonPressed) { modus = rufmodus; anfang = 0; #ifdef MitDisplayUndEncoder lcd.clear(); #endif } }// Ende funktion_hauptschirm //----------------------------------------------------------------------------------- //Braumenü //--------------------------------------------------------------------------------- void funktion_braumenue() //Modus=BRAUMENUE { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(2, 0); lcd.print("Maischen"); lcd.setCursor(2, 1); lcd.print("Nachguss"); lcd.setCursor(2, 2); lcd.print("Kochen"); lcd.setCursor(13, 0); lcd.print("Zur"); lcd.print(char(0xF5)); lcd.print("ck"); #endif drehen = 0; altdrehen = 0; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 0, 3); if (drehen != altdrehen) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 2); lcd.print(" "); lcd.setCursor(11, 0); lcd.print(" "); #endif } if (drehen == 0) { altdrehen = 0; rufmodus = RASTANZAHL; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("=>"); #endif } if (drehen == 1) { altdrehen = 1; rufmodus = NACHGUSS; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("=>"); #endif } if (drehen == 2) { altdrehen = 2; rufmodus = KOCHZEIT; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("=>"); #endif } if (drehen == 3) { altdrehen = 3; rufmodus = HAUPTMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(11, 0); lcd.print("=>"); #endif } if (ButtonPressed) { modus = rufmodus; if (modus == NACHGUSS) { //Übergabe an Modus NACHGUSS drehen = nachgusssolltemp; //Nachgusstemperatur Sollwert } anfang = 0; #ifdef MitDisplayUndEncoder lcd.clear(); #endif } }// Ende funktion_braumenue //----------------------------------------------------------------------------------- //Optionsmenü //--------------------------------------------------------------------------------- void funktion_optionsmenue() //Modus=OPTIONENMENUE { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.setCursor(2, 0); lcd.print("Var.K/H"); lcd.setCursor(2, 1); lcd.print("MPumpe"); //Malzrohrpumpe Dauerbetrieb EIN-AUS lcd.setCursor(2, 2); #ifdef WUERZEPUMPE_AKTIV lcd.print("WPumpe"); //Würzepumpe! #else lcd.print("WPump(nc)"); //Würzepumpe inaktiv! #endif lcd.setCursor(13, 0); lcd.print("G"); lcd.print(char(0xE1)); lcd.print("rf"); lcd.print(char(0xF5)); lcd.print("hr"); //Gärführung #ifdef RTC_Hardware lcd.setCursor(13, 1); lcd.print("Timer"); lcd.setCursor(13, 2); lcd.print("Zur"); lcd.print(char(0xF5)); lcd.print("ck"); #else lcd.setCursor(13, 1); lcd.print("Zur"); lcd.print(char(0xF5)); lcd.print("ck"); #endif #endif drehen = 0; altdrehen = 0; anfang = 1; dclick = false; } #ifdef RTC_Hardware drehen = min_max_drehen(drehen, 0, 5); #else drehen = min_max_drehen(drehen, 0, 4); #endif if (drehen != altdrehen) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 2); lcd.print(" "); lcd.setCursor(11, 0); lcd.print(" "); lcd.setCursor(11, 1); lcd.print(" "); #ifdef RTC_Hardware lcd.setCursor(11, 2); lcd.print(" "); #endif #endif } if (drehen == 0) { altdrehen = 0; rufmodus = KUEHLEN; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("=>"); #endif } if (drehen == 1) { altdrehen = 1; rufmodus = MPUMPE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("=>"); #endif } if (drehen == 2) { altdrehen = 2; #ifdef WUERZEPUMPE_AKTIV rufmodus = WUERZEPUMPE; #else rufmodus = OPTIONENMENUE; #endif #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("=>"); #endif } if (drehen == 3) { altdrehen = 3; rufmodus = GAERFUEHRUNG; #ifdef MitDisplayUndEncoder lcd.setCursor(11, 0); lcd.print("=>"); #endif } #ifdef RTC_Hardware if (drehen == 4) { altdrehen = 4; rufmodus = UHR; #ifdef MitDisplayUndEncoder lcd.setCursor(11, 1); lcd.print("=>"); #endif } if (drehen == 5) { altdrehen = 5; rufmodus = HAUPTMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(11, 2); lcd.print("=>"); #endif } #else if (drehen == 4) { altdrehen = 4; rufmodus = HAUPTMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(11, 1); lcd.print("=>"); #endif } #endif if (ButtonPressed) { modus = rufmodus; if (modus == KUEHLEN) { //Übergabe an Modus kuehlen/heizen drehen = EEPROMReadlong(g_kuehltemp); //ganzzahliger Vorgabewert für Kühlen EEPROM.write(k_aktiv, 1); //Kühlmodus bei Stromausfall aktiv altmodus = KUEHLEN; } anfang = 0; #ifdef MitDisplayUndEncoder lcd.clear(); #endif } }// Ende funktion_optionsmenue //--------------------------------------------------------------------------------- //SetupMenü //--------------------------------------------------------------------------------- void funktion_SetupMenu() //Modus = SETUPMENUE { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(2, 0); lcd.print("Schwellen"); lcd.setCursor(2, 1); lcd.print("R"); lcd.print(char(0xF5)); lcd.print("h/Pump"); lcd.setCursor(2, 2); lcd.print("Regler"); lcd.setCursor(2, 3); lcd.print("Logging"); lcd.setCursor(13, 0); lcd.print("Extern"); lcd.setCursor(13, 1); lcd.print("Sound"); lcd.setCursor(13, 2); lcd.print("Zur"); lcd.print(char(0xF5)); lcd.print("ck"); #endif drehen = 0; altdrehen = 0; anfang = 1; } drehen = min_max_drehen(drehen, 0, 6); if (drehen != altdrehen) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 2); lcd.print(" "); lcd.setCursor(0, 3); lcd.print(" "); lcd.setCursor(11, 0); lcd.print(" "); lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(11, 2); lcd.print(" "); #endif altdrehen = drehen; } if (drehen == 0) { altdrehen = 0; rufmodus = KOCHSCHWELLE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("=>"); #endif } if (drehen == 1) { altdrehen = 1; rufmodus = AUSWAHL_UMWAELZER; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("=>"); #endif } if (drehen == 2) { altdrehen = 2; rufmodus = GRADIENTENFAKTOR_HEIZEN; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("=>"); #endif } if (drehen == 3) { altdrehen = 3; rufmodus = LOGGING_EIN_AUS; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("=>"); #endif } if (drehen == 4) { altdrehen = 4; rufmodus = EXTERNMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(11, 0); lcd.print("=>"); #endif } if (drehen == 5) { altdrehen = 5; rufmodus = SOUNDEINSTELLUNG; #ifdef MitDisplayUndEncoder lcd.setCursor(11, 1); lcd.print("=>"); #endif } if (drehen == 6) { altdrehen = 6; rufmodus = altmodus; #ifdef MitDisplayUndEncoder lcd.setCursor(11, 2); lcd.print("=>"); #endif } if (ButtonPressed) { if (dclick) { anfang = 1; } else { anfang = 0; } modus = rufmodus; drehen = tempdrehen; first = true; #ifdef MitDisplayUndEncoder lcd.clear(); #endif } }// Ende funktion_SetupMenu //--------------------------------------------------------------------------------- //Externmenü //--------------------------------------------------------------------------------- void funktion_Externmenu() //Modus = EXTERNMENUE { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(2, 0); #ifdef bluetooth lcd.print("BT-Steuerung"); #else lcd.print("WLAN-Steuerung"); #endif #ifdef funksteuerung lcd.setCursor(2, 1); lcd.print("Funk"); lcd.setCursor(2, 2); lcd.print("Events"); lcd.setCursor(2, 3); lcd.print("Zur"); lcd.print(char(0xF5)); lcd.print("ck"); #else lcd.setCursor(2, 1); lcd.print("Events"); lcd.setCursor(2, 2); lcd.print("Zur"); lcd.print(char(0xF5)); lcd.print("ck"); #endif #endif drehen = 0; altdrehen = 0; anfang = 1; } #ifdef funksteuerung drehen = min_max_drehen(drehen, 0, 3); if (drehen != altdrehen) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 2); lcd.print(" "); lcd.setCursor(0, 3); lcd.print(" "); #endif altdrehen = drehen; } #else drehen = min_max_drehen(drehen, 0, 2); if (drehen != altdrehen) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 2); lcd.print(" "); #endif altdrehen = drehen; } #endif if (drehen == 0) { altdrehen = 0; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("=>"); #endif #ifdef bluetooth rufmodus = BLUETOOTHSTEUERUNG_AKTIV; #else rufmodus = WLANSTEUERUNG_AKTIV; #endif } #ifdef funksteuerung if (drehen == 1) { altdrehen = 1; rufmodus = DRITTE_FUNKSTECKDOSE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("=>"); #endif } if (drehen == 2) { altdrehen = 2; rufmodus = NOTGASMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("=>"); #endif } if (drehen == 3) { altdrehen = 3; rufmodus = SETUPMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("=>"); #endif } #else if (drehen == 1) { altdrehen = 1; rufmodus = NOTGASMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("=>"); #endif } if (drehen == 2) { altdrehen = 2; rufmodus = SETUPMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("=>"); #endif } #endif if (ButtonPressed) { anfang = 0; modus = rufmodus; #ifdef MitDisplayUndEncoder lcd.clear(); #endif } }// Ende funktion_Externmenu //---------------------------------------------------------------------------------- //Uhrmenue-Timer //--------------------------------------------------------------------------------- #ifdef RTC_Hardware void funktion_uhrmenue() //Modus = UHR { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(2, 0); lcd.print("Uhr stellen"); lcd.setCursor(2, 1); lcd.print("Startzeit eingeben"); lcd.setCursor(2, 2); lcd.print("Zur"); lcd.print(char(0xF5)); lcd.print("ck"); #endif drehen = 0; altdrehen = 0; anfang = 1; } drehen = min_max_drehen(drehen, 0, 2); if (drehen != altdrehen) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 2); lcd.print(" "); #endif altdrehen = drehen; } if (drehen == 0) { altdrehen = 0; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("=>"); #endif rufmodus = STELLEN; } if (drehen == 1) { altdrehen = 1; rufmodus = TIMER; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("=>"); #endif } if (drehen == 2) { altdrehen = 2; rufmodus = HAUPTMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("=>"); #endif } if (ButtonPressed) { anfang = 0; modus = rufmodus; #ifdef MitDisplayUndEncoder lcd.clear(); #endif } }// Ende funktion_uhrmenue #endif //--------------------------------------------------------------------------------- //Uhr stellen //--------------------------------------------------------------------------------- #ifdef RTC_Hardware void funktion_stellen() { if (anfang == 0) { DateTime uhrzeit = RTC.now(); ye = uhrzeit.year(); mo = uhrzeit.month(); da = uhrzeit.day(); se = uhrzeit.second(); #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Aktuelle Zeit:"); if (uhrzeit.hour() > 9) { lcd.print(uhrzeit.hour()); lcd.print(":"); } else { lcd.print("0"); lcd.print(uhrzeit.hour()); lcd.print(":"); } if (uhrzeit.minute() > 9) { lcd.print(uhrzeit.minute()); } else { lcd.print("0"); lcd.print(uhrzeit.minute()); } #endif drehen = uhrzeit.hour(); anfang = 1; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("drehen = Std. einst."); #endif } if (anfang == 1) { drehen = min_max_drehen(drehen, 0, 23); #ifdef MitDisplayUndEncoder lcd.setCursor(14, 0); if (drehen < 10) { lcd.print("0"); lcd.print(drehen); } else { lcd.print(drehen); } #endif } if (ButtonPressed && anfang == 1) { hr = drehen; anfang = 2; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("drehen = min. einst."); #endif DateTime uhrzeit = RTC.now(); drehen = uhrzeit.minute(); ButtonPressed = false; } if (anfang == 2) { drehen = min_max_drehen(drehen, 0, 59); #ifdef MitDisplayUndEncoder lcd.setCursor(17, 0); if (drehen < 10) { lcd.print("0"); lcd.print(drehen); } else { lcd.print(drehen); } #endif } if (ButtonPressed && anfang == 2) { mi = drehen; anfang = 3; } if (anfang == 3) { setTime(hr, mi, se, da, mo, ye); RTC.adjust(now()); modus = UHR; anfang = 0; } }// Ende funktion_stellen #endif //--------------------------------------------------------------------------------- //Gasmenü //--------------------------------------------------------------------------------- void funktion_NotGasMenue() //Modus=NOTGASMENUE { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(2, 0); lcd.print("Notfall"); lcd.setCursor(2, 1); lcd.print("Gassensor"); lcd.setCursor(2, 2); lcd.print("Zur"); lcd.print(char(0xF5)); lcd.print("ck"); #endif drehen = 0; altdrehen = 0; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 0, 2); if (drehen != altdrehen) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 2); lcd.print(" "); #endif } if (drehen == 0) { altdrehen = 0; rufmodus = NOTFALLMODUS; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("=>"); #endif } if (drehen == 1) { altdrehen = 1; rufmodus = GASSENSORINIT; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("=>"); #endif } if (drehen == 2) { altdrehen = 2; rufmodus = SETUPMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("=>"); #endif } if (ButtonPressed) { modus = rufmodus; anfang = 0; #ifdef MitDisplayUndEncoder lcd.clear(); #endif } }// Ende funktion_NotGasMenue //----------------------------------------------------------------------------------- //Temperaturregelung //--------------------------------------------------------------------------------- void funktion_temperatur() //Modus= KUEHLEN und NACHGUSS (separater Nachguss!) { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); #endif if (umwaelzer_stat == EIN) UmwaelzerAUS(); if (modus == NACHGUSS) { #ifdef MitDisplayUndEncoder lcd.setCursor(10, 1); lcd.print("soll"); #endif drehen = nachgusssolltemp; } anfang = 1; } if (modus == NACHGUSS) { drehen = min_max_drehen(drehen, 30, 78); } if (modus == KUEHLEN) if (drehen < -10) drehen = -10; sollwert = drehen; if (modus == KUEHLEN) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); #endif if (kuehlen) { #ifdef MitDisplayUndEncoder lcd.print("K"); lcd.print(char(0xF5)); lcd.print("hlen "); #endif } else { #ifdef MitDisplayUndEncoder lcd.print("Heizen "); #endif } altmodus = KUEHLEN; // Merker für Doppelclick #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("Modus = "); #endif if (kuehlen) { #ifdef MitDisplayUndEncoder lcd.print("K"); lcd.print(char(0xF5)); lcd.print("hlen "); #endif } else { #ifdef MitDisplayUndEncoder lcd.print("Heizen "); #endif } } #ifdef MitDisplayUndEncoder if (modus == NACHGUSS) { lcd.setCursor(0, 0); lcd.print("Nachguss"); } #endif if ((modus == NACHGUSS) && (isttemp >= sollwert) && (nachgussruf == false)) //Nachgussruf -> Sollwert erreicht { meldung_detail = "Temperatur-erreicht!"; nachgussruf = true; rufmodus = modus; //Rufalarm altmodus = modus; modus = RUFALARM; y = 0; braumeister[y] = 2; //nur Ruf und weiter mit Regelung } }// Ende funktion_temperatur //--------------------------------------------------------------------------------- //Malzrohr //--------------------------------------------------------------------------------- void malzrohrDauerbetrieb() { if (anfang == 0) { if (pumpe) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Malzrohrpumpe"); lcd.setCursor(0, 1); lcd.print("Reinigungslauf"); lcd.setCursor(0, 3); lcd.print("Ende Taste halten"); #endif if (umwaelzer_stat == AUS) UmwaelzerEIN(); } else { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("keine Pumpe gew.!"); lcd.setCursor(0, 3); lcd.print("Ende Taste halten"); #endif } } anfang = 1; }// Ende malzrohrDauerbetrieb #ifdef WUERZEPUMPE_AKTIV //--------------------------------------------------------------------------------- //Würzepumpe schalten //--------------------------------------------------------------------------------- void WuerzepumpeEinAus(uint8_t EinAus) { if (EinAus == 0) { digitalWrite(fuellstand_pumpe, WUERZEPUMPE_AUS); //Pumpe ist ausgeschaltet wpumpe = 0; } else { digitalWrite(fuellstand_pumpe, WUERZEPUMPE_EIN); wpumpe = 1; } } void wuerzepumpe() //Modus = WUERZEPUMPE { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Pumpe: "); lcd.setCursor(7, 0); if (WUERZEPUMPE_EIN) lcd.print("EIN"); else lcd.print("AUS"); #endif anfang = 1; anzeige = true; warten = millis(); pwarten = millis(); drehen = esvpumpen / 1000; } if (manuell_ein) { WuerzepumpeEinAus(1); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Dauerbetrieb EIN"); lcd.setCursor(7, 0); lcd.print("EIN"); lcd.setCursor(0, 2); lcd.print(" "); #endif meldung_detail = "Pumpe_Dauerbetrieb"; } else { digitalWrite(fuellstand_sensor, HIGH); //PullUp-Widerstand wenn Signal vom Sensor = GND (0V) //wenn das Signal vom Sensor = 5V dann realen PullDown-Widerstand (10K) vom Anschluss gegen GND (0V) int16_t val = digitalRead(fuellstand_sensor); meldung_detail = "Pumpe_Automatik"; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("ESV: "); lcd.setCursor(6, 2); lcd.print(" s"); #endif if (drehen < 0) drehen = 0; #ifdef MitDisplayUndEncoder lcd.setCursor(5, 2); lcd.print(drehen); #endif esvpumpen = drehen * 1000; //ist die Pumpe bei Sensor LOW aktiv, dann if (val == Sensor_EIN) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); #endif if (millis() > warten + 1000) { if (anzeige) { #ifdef MitDisplayUndEncoder lcd.print("Bitte warten! "); #endif } warten = millis(); } else if (anzeige) { #ifdef MitDisplayUndEncoder lcd.print(" "); #endif } anzeige = false; WuerzepumpeEinAus(1); meldung_detail = "Pumpe-Automatik"; pwarten = millis(); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(7, 0); lcd.print("EIN"); #endif } if (val == Sensor_AUS) { if (millis() > (pwarten + esvpumpen)) { WuerzepumpeEinAus(0); #ifdef MitDisplayUndEncoder lcd.setCursor(7, 0); lcd.print("AUS"); lcd.setCursor(0, 1); lcd.print("Automatik "); #endif meldung_detail = "Pumpe-Automatik"; anzeige = true; } } } }// Ende wuerzepumpe #endif //-------------------------------------------------------------------------------- //Eingabe der Rastanzahl //--------------------------------------------------------------------------------- void funktion_rastanzahl() //Modus = RASTANZAHL { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Eingabe"); lcd.setCursor(12, 1); lcd.print("Rasten"); #endif drehen = rasten; anfang = 1; dclick = false; } //Vorgabewerte bei verschiedenen Rasten if (rasten != drehen) { if (drehen == 1) { rastTemp[1] = 67; rastZeit[1] = 60; maischtemp = 65; } if (drehen == 2) { rastTemp[1] = 62; rastZeit[1] = 30; rastTemp[2] = 72; rastZeit[2] = 35; maischtemp = 62; } if (drehen == 3) { rastTemp[1] = 55; rastZeit[1] = 10; rastTemp[2] = 62; rastZeit[2] = 35; rastTemp[3] = 72; rastZeit[3] = 25; maischtemp = 55; } if (drehen == 4) { rastTemp[1] = 40; rastZeit[1] = 20; rastTemp[2] = 55; rastZeit[2] = 15; rastTemp[3] = 64; rastZeit[3] = 35; rastTemp[4] = 72; rastZeit[4] = 25; maischtemp = 35; } if (drehen == 5) { rastTemp[1] = 35; rastZeit[1] = 20; rastTemp[2] = 40; rastZeit[2] = 20; rastTemp[3] = 55; rastZeit[3] = 15; rastTemp[4] = 64; rastZeit[4] = 35; rastTemp[5] = 72; rastZeit[5] = 25; maischtemp = 30; } if (drehen == 6) { rastTemp[1] = 35; rastZeit[1] = 20; rastTemp[2] = 40; rastZeit[2] = 20; rastTemp[3] = 55; rastZeit[3] = 15; rastTemp[4] = 64; rastZeit[4] = 35; rastTemp[5] = 72; rastZeit[5] = 25; rastTemp[6] = 78; rastZeit[6] = 10; maischtemp = 30; } } drehen = min_max_drehen(drehen, 1, 6); rasten = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(19, 1); lcd.print(rasten); #endif if (ButtonPressed) { modus = EINMAISCHTEMPERATUR; anfang = 0; } }// Ende funktion_rastanzahl //--------------------------------------------------------------------------------- //Maischtemperaturen //--------------------------------------------------------------------------------- void funktion_maischtemperatur() //Modus = EINMAISCHTEMPERATUR { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Eingabe"); lcd.setCursor(0, 1); lcd.print("Einmaischen "); #endif drehen = maischtemp; first = true; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 30, 72); maischtemp = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(16, 1); lcd.print(maischtemp); lcd.print(char(0xDF)); lcd.print("C "); #endif if (ButtonPressed) { modus = RASTTEMPERATUREN; anfang = 0; } }// Ende funktion_maischtemperatur //--------------------------------------------------------------------------------- //Rasteingabe Temperatur //--------------------------------------------------------------------------------- void funktion_rasteingabe() //Modus = RASTTEMPERATUREN { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Eingabe"); #endif drehen = rastTemp[x]; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 30, 78); rastTemp[x] = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(14, 0); lcd.print(x); lcd.print(".Rast"); lcd.setCursor(14, 1); lcd.print(uint8_t(rastTemp[x])); lcd.print(char(0xDF)); lcd.print("C "); #endif if (ButtonPressed) { modus = RASTZEITEN; anfang = 0; } }// Ende funktion_rasteingabe //--------------------------------------------------------------------------------- //Rasteingabe Zeit //--------------------------------------------------------------------------------- void funktion_zeiteingabe() //Modus = RASTZEITEN { if ((anfang == 0) || (dclick)) { drehen = rastZeit[x]; anfang = 1; dclick = false; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Eingabe"); lcd.setCursor(14, 0); lcd.print(x); lcd.print(".Rast"); lcd.setCursor(14, 1); lcd.print(uint8_t(rastTemp[x])); lcd.print(char(0xDF)); lcd.print("C "); #endif } drehen = min_max_drehen(drehen, 1, 200); rastZeit[x] = drehen; #ifdef MitDisplayUndEncoder if (rastZeit[x] < 10) { lcd.setCursor(14, 2); lcd.print(" "); lcd.print(uint8_t(rastZeit[x])); lcd.print(" min"); } else { lcd.setCursor(14, 2); lcd.print(uint8_t(rastZeit[x])); lcd.print(" min"); } #endif if (ButtonPressed) { modus = WECHSEL_TEMP_ZEIT; anfang = 0; } }// Ende funktion_zeiteingabe //--------------------------------------------------------------------------------- //Wahl des Umwälzers (Rührer/Pumpe) //--------------------------------------------------------------------------------- void umwaelzer() //Modus = UMWAELZERWAHL { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Umwaelzer"); lcd.setCursor(0, 1); lcd.print("Dauerbetrieb"); #endif drehen = EEPROM.read(udauer); anfang = 1; dclick = false; } char antwort_jn = ja_nein[drehen % 2]; #ifdef MitDisplayUndEncoder lcd.setCursor(14, 1); lcd.print(antwort_jn); #endif dauerbetrieb = antwort_jn; if (ButtonPressed) { if (dauerbetrieb == 'N') { modus = UMWAELZER_INTERVALL_EIN; if (EEPROM.read(udauer) != 0) EEPROM.write(udauer, 0); } else { if (!pumpe) modus = RUEPUMAKTIV; else modus = SETUPMENUE; //Pumpe während des Einmaischens immer deaktiviert! if (EEPROM.read(udauer) != 1) EEPROM.write(udauer, 1); } speichern(2); anfang = 0; } }// Ende umwaelzer //--------------------------------------------------------------------------------- //Rührwerk Intervall EIN //--------------------------------------------------------------------------------- void umwaelzer_ein() //Modus = UMWAELZER_INTERVALL_EIN { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); if (ruehrer) { lcd.print("R"); lcd.print(char(0xF5)); lcd.print("hrwerk"); } if (pumpe) { lcd.print("Pumpe"); } lcd.setCursor(0, 1); lcd.print("Intervall"); #endif drehen = intervalEin; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 0, 250); intervalEin = drehen; #ifdef MitDisplayUndEncoder if (intervalEin > 9) { lcd.setCursor(0, 1); lcd.print("Intervall EIN: "); lcd.print(intervalEin); lcd.print("s "); } else { lcd.setCursor(0, 1); lcd.print("Intervall EIN: "); lcd.print(intervalEin); lcd.print("s "); } #endif if (ButtonPressed) { if (EEPROM.read(umwaelzer_ie) != intervalEin) EEPROM.write(umwaelzer_ie, intervalEin); speichern(2); modus = UMWAELZER_INTERVALL_AUS; anfang = 0; } }// Ende umwaelzer_ein //--------------------------------------------------------------------------------- //Rührwerk Intervall AUS //--------------------------------------------------------------------------------- void umwaelzer_aus() //Modus = UMWAELZER_INTERVALL_AUS { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); if (ruehrer) { lcd.print("R"); lcd.print(char(0xF5)); lcd.print("hrwerk"); } if (pumpe) { lcd.print("Pumpe"); } lcd.setCursor(0, 1); lcd.print("Intervall"); #endif drehen = intervalAus; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 0, 250); intervalAus = drehen; #ifdef MitDisplayUndEncoder if (intervalAus > 9) { lcd.setCursor(0, 1); lcd.print("Intervall AUS: "); lcd.print(intervalAus); lcd.print("s "); } else { lcd.setCursor(0, 1); lcd.print("Intervall AUS: "); lcd.print(intervalAus); lcd.print("s "); } #endif if (ButtonPressed) { if (EEPROM.read(umwaelzer_ia) != intervalAus) EEPROM.write(umwaelzer_ia, intervalAus); speichern(2); if (!pumpe) modus = RUEPUMAKTIV; else { modus = SETUPMENUE; if (EEPROM.read(ruepumeinmaisch) != 0) EEPROM.write(ruepumeinmaisch, 0); } anfang = 0; } }// Ende umwaelzer_aus //--------------------------------------------------------------------------------- //Steckdosencode eingeben //--------------------------------------------------------------------------------- #ifdef funksteuerung #ifdef dbg //--------------------------------------------------------------------------------- //Codierung der Funksteckdosen im Seriellen Monitor anzeigen //--------------------------------------------------------------------------------- void output(int32_t decimal, int16_t length, int16_t delay, uint32_t *raw, int16_t protocol) { const char *b = dec2binWzerofill(decimal, length); Serial.print("Decimal: "); Serial.print(decimal); Serial.print(" ("); Serial.print(length); Serial.print("Bit) Binary: "); Serial.print(b); Serial.print(" Tri-State: "); Serial.print(bin2tristate(b)); Serial.print(" PulseLength: "); Serial.print(delay); Serial.print(" microseconds"); Serial.print(" Protocol: "); Serial.println(protocol); Serial.print("Raw data: "); for (int16_t i = 0; i <= length * 2; i++) { Serial.print(raw[i]); Serial.print(","); } Serial.println(); Serial.println(); } //Ende output #endif void steckdosencode() //Modus = STECKDOSENCODE { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); #endif mySwitch.enableReceive(empfaenger_int); anfang = 1; drehen = 1; } else { if (drehen == 1) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Taste Heizung EIN"); #endif meldung_detail = "Heizung-EIN-drücken"; adr = Heizung_EIN; } if (drehen == 2) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Taste Heizung AUS"); #endif meldung_detail = "Heizung-AUS-drücken"; adr = Heizung_AUS; } if (drehen == 3) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Taste Umwaelz EIN"); #endif meldung_detail = "Umwaelzer-EIN-drücken"; adr = Umwaelz_EIN; } if (drehen == 4) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Taste Umwaelz AUS"); #endif meldung_detail = "Umwaelzer-AUS-drücken"; adr = Umwaelz_AUS; } if (!funkruf) { if (drehen == 5) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Taste Nachguss EIN"); #endif meldung_detail = "Nachguss/Ruf-EIN-drücken"; adr = Nachguss_EIN; } if (drehen == 6) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Taste Nachguss AUS"); #endif meldung_detail = "Nachguss/Ruf-AUS-drücken"; adr = Nachguss_AUS; } } else { if (drehen == 5) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Taste Ruf EIN"); #endif meldung_detail = "Ruf-EIN-drücken"; adr = Nachguss_EIN; } if (drehen == 6) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Taste Ruf AUS"); #endif meldung_detail = "Ruf-AUS-drücken"; adr = Nachguss_AUS; } } if (drehen > 6) drehen = 1; value = mySwitch.getReceivedValue(); #ifdef dbg if (mySwitch.available()) { output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(), mySwitch.getReceivedProtocol()); } #endif if (value) { // value in EPROM schreiben if (EEPROMReadlong(adr) != value) EEPROMWritelong(adr, value); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("speichern"); #endif meldung_detail = "Code-gespeichert"; signalton(quittungston); drehen++; if (drehen == 7) { modus = HAUPTMENUE; anfang = 0; mySwitch.disableReceive(); //Empfänger wieder deaktivieren } #ifdef MitDisplayUndEncoder lcd.clear(); #endif } mySwitch.resetAvailable(); init_funk(); } }// Ende steckdosencode #endif //--------------------------------------------------------------------------------- //Kochschwelle einstellen //--------------------------------------------------------------------------------- void kochschwelle() //Modus = KOCHSCHWELLE { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Kochschwelle"); lcd.setCursor(0, 1); lcd.print("Ruf bei:"); lcd.setCursor(12, 1); lcd.print(char(0xDF)); lcd.print("C "); #endif drehen = EEPROM.read(Kochschwelle); //EPROM-Speicher auslesen anfang = 1; dclick = false; } else { drehen = min_max_drehen(drehen, 20, 99); kschwelle = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(9, 1); lcd.print(kschwelle); #endif if (ButtonPressed) { if (EEPROM.read(Kochschwelle) != kschwelle) EEPROM.write(Kochschwelle, kschwelle); speichern(2); modus = NACHGUSSSOLLWERT; anfang = 0; } } }// Ende kochschwelle //-------------------------------------------------------------------------------- //Intervallbetrieb der Umwälzeinheit //--------------------------------------------------------------------------------- void intervallbetrieb() //kein separator Modus { if (regelung == EIN) { uint32_t ein = 1000 * (uint32_t)intervalEin; uint32_t aus = 1000 * (uint32_t)intervalAus; if (firstinterval) { intervalstart = millis(); firstinterval = false; } else if ((intervalstart + ein) >= millis()) { UmwaelzerEIN(); } else if ((intervalstart + ein + aus) >= millis()) UmwaelzerAUS(); else firstinterval = true; } }// Ende intervallbetrieb //--------------------------------------------------------------------------------- //Umwälzer Ein/Aus //--------------------------------------------------------------------------------- void umwaelzerEinAus(int16_t rueh) // kein separator Modus { if ((regelung == EIN) && (modus != NACHGUSS) && (modus != KUEHLEN) && (modus != ABBRUCH)) // außer bei Nachgußbereitung/Kühlen { if (rueh == 1) { if (rwerk == 0) if (umwaelzer_stat == AUS) UmwaelzerEIN(); } else { if (rueh == 0) if (rwerk == 1) if (umwaelzer_stat == EIN) UmwaelzerAUS(); if (rueh == 2) if (umwaelzer_stat == AUS) UmwaelzerEIN(); } } }// Ende umwaelzerEinAus //--------------------------------------------------------------------------------- //Rastwechsel Temperatur - Zeit //--------------------------------------------------------------------------------- void wechsel_temp_zeit_eingabe() //Modus = WECHSEL_TEMP_ZEIT { braumeister[x] = 0; if (x < rasten) { x++; modus = RASTTEMPERATUREN; //Sprung zur Rasttemperatureingabe anfang = 0; } else { x = 1; modus = ABMAISCHTEMPERATUR; //Sprung zur Rastzeiteingabe anfang = 0; } }// Ende wechsel_temp_zeit_eingabe //--------------------------------------------------------------------------------- //Abmaischtemperatur //--------------------------------------------------------------------------------- void funktion_endtempeingabe() //Modus = ABMAISCHTEMPERATUR { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Eingabe"); #endif drehen = endtemp; anfang = 1; } drehen = min_max_drehen(drehen, 30, 78); endtemp = drehen; /* if (endtemp < 30) endtemp = 30; if (endtemp > 78) endtemp = 78; */ #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Abmaischen"); lcd.setCursor(16, 1); lcd.print(uint8_t(endtemp)); lcd.print(char(0xDF)); lcd.print("C "); #endif if (ButtonPressed) { modus = MAISCHEN_START; anfang = 0; } }// Ende funktion_endtempeingabe //--------------------------------------------------------------------------------- //Startabfrage //--------------------------------------------------------------------------------- void funktion_startabfrage() //Modus = MAISCHEN_START { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Aufheizen zum"); lcd.setCursor(0, 1); lcd.print("Einmaischen"); #endif anfang = 1; } //------------------------------------------------------------------------------- //Behandlung des Nachgusses //------------------------------------------------------------------------------- if (anzahlTempsensoren == 2) if (nachgusssensor >= (nachgusssolltemp - (gradient_nachguss))) { if (nachgussheizung == EIN) { NachgussAUS(); nachgusswarten = millis(); } } //------------------------------------------------------------------------------- //Anzeige der Isttemperatur //------------------------------------------------------------------------------- #ifdef MitDisplayUndEncoder lcd.setCursor(12, 3); lcd.print(float(isttemp), 1); if (isttemp > 10) { lcd.print(char(0xDF)); lcd.print("C"); } else { lcd.print(char(0xDF)); lcd.print("C "); } #endif aktuelleMillis = millis(); if (aktuelleMillis - alteMillis >= blinkintervall) { alteMillis = aktuelleMillis; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); if (textsichtbar) { lcd.print("Taste = Start"); textsichtbar = false; } else { lcd.print(" "); textsichtbar = true; } #endif } if ((ButtonPressed) || (fern)) { if (notfall_aktiv) { { Notfallmodus = EEPROMReadInt(notfallmodus); if (EEPROMReadInt(notfallmodus) != 1) EEPROMWriteInt(notfallmodus, 1); //Notfallmodus aktiviert EEPROM.write(Rasten, rasten); EEPROM.write(MaischTemp, maischtemp); switch (rasten) { case 1: { EEPROM.write(rastzeit_1, rastZeit[1]); EEPROM.write(rasttemp_1, rastTemp[1]); break; } case 2: { EEPROM.write(rastzeit_1, rastZeit[1]); EEPROM.write(rasttemp_1, rastTemp[1]); EEPROM.write(rastzeit_2, rastZeit[2]); EEPROM.write(rasttemp_2, rastTemp[2]); break; } case 3: { EEPROM.write(rastzeit_1, rastZeit[1]); EEPROM.write(rasttemp_1, rastTemp[1]); EEPROM.write(rastzeit_2, rastZeit[2]); EEPROM.write(rasttemp_2, rastTemp[2]); EEPROM.write(rastzeit_3, rastZeit[3]); EEPROM.write(rasttemp_3, rastTemp[3]); break; } case 4: { EEPROM.write(rastzeit_1, rastZeit[1]); EEPROM.write(rasttemp_1, rastTemp[1]); EEPROM.write(rastzeit_2, rastZeit[2]); EEPROM.write(rasttemp_2, rastTemp[2]); EEPROM.write(rastzeit_3, rastZeit[3]); EEPROM.write(rasttemp_3, rastTemp[3]); EEPROM.write(rastzeit_4, rastZeit[4]); EEPROM.write(rasttemp_4, rastTemp[4]); break; } case 5: { EEPROM.write(rastzeit_1, rastZeit[1]); EEPROM.write(rasttemp_1, rastTemp[1]); EEPROM.write(rastzeit_2, rastZeit[2]); EEPROM.write(rasttemp_2, rastTemp[2]); EEPROM.write(rastzeit_3, rastZeit[3]); EEPROM.write(rasttemp_3, rastTemp[3]); EEPROM.write(rastzeit_4, rastZeit[4]); EEPROM.write(rasttemp_4, rastTemp[4]); EEPROM.write(rastzeit_5, rastZeit[5]); EEPROM.write(rasttemp_5, rastTemp[5]); break; } case 6: { EEPROM.write(rastzeit_1, rastZeit[1]); EEPROM.write(rasttemp_1, rastTemp[1]); EEPROM.write(rastzeit_2, rastZeit[2]); EEPROM.write(rasttemp_2, rastTemp[2]); EEPROM.write(rastzeit_3, rastZeit[3]); EEPROM.write(rasttemp_3, rastTemp[3]); EEPROM.write(rastzeit_4, rastZeit[4]); EEPROM.write(rasttemp_4, rastTemp[4]); EEPROM.write(rastzeit_5, rastZeit[5]); EEPROM.write(rasttemp_5, rastTemp[5]); EEPROM.write(rastzeit_6, rastZeit[6]); EEPROM.write(rasttemp_6, rastTemp[6]); break; } } } } anfang = 0; modus = EINMAISCHEN; } }// Ende funktion_startabfrage //--------------------------------------------------------------------------------- //Einmaischen //--------------------------------------------------------------------------------- void funktion_einmaischen() //Modus = EINMAISCHEN { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); #endif meldung_detail = "Aufheizen_Einmaischen"; drehen = maischtemp; //Zuordnung Encoder anfang = 1; dclick = false; fern = false; if (umwaelzer_stat == AUS) UmwaelzerEIN(); nachgussheizung = AUS; if (notfall_aktiv) EEPROMWriteInt(rastmodus, modus); //für Notfall Modus merken } drehen = min_max_drehen(drehen, 30, 72); maischtemp = drehen; sollwert = maischtemp; if (isttemp >= sollwert) // Sollwert erreicht ? { fern = false; //Benutzereinstellung Mischer wird gelöscht altmodus = modus; sondermodus = modus; //Sonderbehandlung im Modus "Rufalarm"! modus = TEMPERATURAUTOMATIK; rufmodus = modus; y = 0; braumeister[y] = 2; modus = RUFALARM; anfang = 0; pause = 0; //Rufalarm Anzahl Erinnerungstöne } }// Ende funktion_einmaischen //--------------------------------------------------------------------------------- //Automatik Maischtemperatur //--------------------------------------------------------------------------------- void funktion_tempautomatik() //Modus = TEMPERATURAUTOMATIK { if ((anfang == 0) || (dclick)) { if ((notmodus) && (neustart)) { x = RastNr; neustart = false; zeit_null_setzen = true; } meldung_detail = String(x) + "_Rast_anfahren"; firstinterval = true; //Intervallbetrieb Rührwerk rwerk = 0; drehen = rastTemp[x]; anfang = 1; first = true; dclick = false; if (notfall_aktiv) { EEPROMWriteInt(rastmodus, modus); //für Notfall Modus merken EEPROM.write(rastnr, x); EEPROM.write(rasttemp_aktuell, rastTemp[x]); EEPROM.write(rastzeit_aktuell, rastZeit[x]); } rufZ = 0; #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(14, 0); lcd.print(x); lcd.print(".Rast"); #endif } drehen = min_max_drehen(drehen, 30, 78); rastTemp[x] = drehen; sollwert = rastTemp[x]; if (isttemp >= sollwert) // Sollwert erreicht ? { modus = ZEITAUTOMATIK; //zur Zeitautomatik anfang = 0; signalton(1000); } }// Ende funktion_tempautomatik //--------------------------------------------------------------------------------- //Maischen Zeitautomatik //--------------------------------------------------------------------------------- void funktion_zeitautomatik() //Modus = ZEITAUTOMATIK { if (anfang == 0) { if ((notmodus) && (neustart)) { x = RastNr; neustart = false; } drehen = rastZeit[x]; //Zuordnung für Encoder signalende = false; if (altx != x) { meldung_detail = String(x) + "_Rast_erreicht"; //bei Rastwechsel Zeit wieder bei 0 starten! gespeichert = false; //bei Rastwechsel unabhängig vom Zeitablauf den Zustand speichern zeitz = true; ruf = true; RufEIN(true); delay(TonRasterreichtDauer); RufAUS(true); } if (notfall_aktiv) { EEPROMWriteInt(rastmodus, modus); //für Notfall Modus merken EEPROM.write(rastnr, x); EEPROM.write(rasttemp_aktuell, rastTemp[x]); EEPROM.write(rastzeit_aktuell, rastZeit[x]); } // Initialisiere Zeitzählung------------------------------------------------------------------ if (zeitz) setTime(00, 00, 00, 00, 01, 01); //.........Sekunden auf 0 stellen if (zeit_setzen) //beim ersten Anlauf nach Notfall { RastZeit_h = EEPROM.read(zeit_h); RastZeit_m = EEPROM.read(zeit_m); RastZeit_s = EEPROM.read(zeit_s); setTime(RastZeit_h, RastZeit_m, RastZeit_s, 00, 01, 01); zeit_setzen = false; } if (zeit_null_setzen) { zeit_null_setzen = false; setTime(00, 00, 00, 00, 01, 01); //.........Sekunden auf 0 stellen } sekunden = second(); //aktuell Sekunde abspeichern für die Zeitrechnung minutenwert = minute(); //aktuell Minute abspeichern für die Zeitrechnung stunden = hour(); //aktuell Stunde abspeichern für die Zeitrechnung #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print(" "); #endif anfang = 1; rufpc = true; gespeichert = false; } altx = x; #ifdef MitDisplayUndEncoder lcd.setCursor(14, 0); lcd.print(x); lcd.print(".Rast"); if (rastZeit[x] < 10) { lcd.setCursor(14, 2); lcd.print(" "); lcd.print(uint8_t(rastZeit[x])); lcd.print(" min"); } else { lcd.setCursor(13, 2); lcd.print(uint8_t(rastZeit[x])); lcd.print(" min"); } lcd.setCursor(0, 2); if (sekunden < 10) { if (minuten == 0) { lcd.setCursor(1, 2); lcd.print("00:0"); lcd.print(sekunden); } } else { if (minuten == 0) { lcd.setCursor(1, 2); lcd.print("00:"); lcd.print(sekunden); } } #endif if (stunden == 0) minuten = minutenwert; else minuten = ((stunden * 60) + minutenwert); #ifdef MitDisplayUndEncoder if ((minuten < 10) && (minuten > 0)) { lcd.setCursor(1, 2); lcd.print("0"); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } if ((minuten >= 10) && (minuten < 100)) { lcd.setCursor(1, 2); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } if (minuten >= 100) { lcd.setCursor(0, 2); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } #endif String mi_; String s; mi_ = String(minutenwert); s = String(sekunden); if (minutenwert < 10) mi_ = "0" + String(minutenwert); //Aktuelle Zeit zum PC if (sekunden < 10) s = "0" + String(sekunden); zeit_detail = mi_ + ":" + s; //--------------------------------------------------------------------------------- //Aktuellen Prozesszustand bei Stromausfall speichern //--------------------------------------------------------------------------------- if (notfall_aktiv) { if ((sekunden == 0) && (!gespeichert)) //einmal pro Minute speichern { EEPROMWriteInt(rastmodus, modus); EEPROM.write(rastnr, x); EEPROM.write(rasttemp_aktuell, rastTemp[x]); EEPROM.write(rastzeit_aktuell, rastZeit[x]); EEPROM.write(zeit_h, stunden); EEPROM.write(zeit_m, minuten); EEPROM.write(zeit_s, sekunden); gespeichert = true; } if ((gespeichert) && (sekunden > 0)) gespeichert = false; } //Erinnerung Jodprobe------------------------------------------------------------- if (rufpc) verz = millis(); if (x == rasten) { if ((minuten >= rastZeit[x] - 5) && (!signalende)) //5 min. vor Ende der letzten Rast { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("Jodprobe!"); #endif meldung_detail = "Jodprobe!"; for (tz = 0; tz < jodrufZyklus; tz++) { signalton(quittungston); RufEIN(true); delay(jodrufLaenge); RufAUS(true); rufZ = 0; } RufAUS(true); signalende = true; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print(" "); #endif if (rufZ < 8) ruf = true; else ruf = false; } } drehen = min_max_drehen(drehen, 0, 200); rastZeit[x] = drehen; //Encoderzuordnung if (minuten >= rastZeit[x]) // Sollwert erreicht ? { anfang = 0; y = x; signalton(1000); ruf = true; meldung_detail = String(x) + "_Rast_beendet"; if (x < rasten) { modus = TEMPERATURAUTOMATIK; // zur Temperaturregelung x++; // nächste Stufe ruf = true; RufEIN(true); delay(TonRasterreichtDauer); RufAUS(true); } else { x = 1; //Endtemperatur modus = ENDTEMPERATURAUTOMATIK; //Endtemperatur ruf = true; } if (braumeister[y] > 0) { rufmodus = modus; modus = RUFALARM; } } }// Ende funktion_zeitautomatik //-------------------------------------------------------------------------------- //Abmaischtemperatur Automatik //--------------------------------------------------------------------------------- void funktion_endtempautomatik() //Modus = ENDTEMPERATURAUTOMATIK { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(10, 0); lcd.print("Abmaischen"); #endif drehen = endtemp; //Zuordnung Encoder anfang = 1; dclick = false; if (notfall_aktiv) EEPROMWriteInt(rastmodus, modus); //für Notfall Modus merken } drehen = min_max_drehen(drehen, 30, 78); endtemp = drehen; sollwert = endtemp; if (isttemp >= sollwert) // Sollwert erreicht ? { sondermodus = 0; meldung_detail = "Maischen_Abbruch=ENDE"; RufEIN(true); delay(endeMaischenTon); // RufAUS(true); if (ruehrer_nachlauf == 1) { modus = NACHLAUFEN; signalton(1000); RufAUS(true); } else { modus = ABBRUCH; rufmodus = modus; modus = RUFALARM; y = 0; braumeister[y] = 1; RufAUS(true); } regelung = AUS; //Regelung aus heizung = AUS; //Heizung aus anfang = 0; } }// Ende funktion_endtempautomatik //--------------------------------------------------------------------------------- //Nachlauf Mischer vor Abmaischen //--------------------------------------------------------------------------------- void funktion_nachlaufen() //Modus = NACHLAUFEN { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Nachlauf!"); lcd.setCursor(0, 1); lcd.print("ENDE = Druecken"); lcd.setCursor(0, 2); lcd.print("oder 5 min. warten!"); #endif startcount = 300000 + millis(); //ms Nachlauf (hier 5 min.) anfang = 1; meldung_detail = "Nachlauf_Mischer_5min"; signalton(1000); if (umwaelzer_stat == AUS) UmwaelzerEIN(); ruf = true; rufZ = 0; RufAUS(true); } if (anfang == 1) { ruf = true; anfang = 2; rufZ = 0; } if ((ButtonPressed) || (millis() > startcount)) // Maischen beenden! { meldung_detail = "Maischen_beendet"; if (umwaelzer_stat == EIN) UmwaelzerAUS(); signalton(1000); modus = ABBRUCH; } }// Ende funktion_nachlaufen //--------------------------------------------------------------------------------- //Braumeisterrufalarm //--------------------------------------------------------------------------------- void funktion_braumeisterrufalarm() //Modus = RUFALARM { if (anfang == 0) { rufsignalzeit = millis(); altsekunden = millis(); anfang = 1; #ifdef MitDisplayUndEncoder if (anzahlTempsensoren == 2) { lcd.setCursor(0, 3); lcd.print(" "); } #endif rufZ = 0; } if (sondermodus == EINMAISCHEN) //Einmaischtemperatur erreicht ! Heizung AUS Rührer EIN oder AUS bis "weiter" { altmodus = RUFALARM; heizung = AUS; if (ruehrer_beim_einmaischen){ if (rwerk == 0) UmwaelzerEIN(); } else if (rwerk == 1) if (umwaelzer_stat == EIN) UmwaelzerAUS(); if (anzahlTempsensoren == 2) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("N:"); lcd.print(float(nachgusssensor), 1); lcd.print(char(0xDF)); lcd.print("C "); #endif if (nachgusssensor >= (nachgusssolltemp - (gradient_nachguss))) { if (nachgussheizung == EIN) { NachgussAUS(); nachgusswarten = millis(); } } } if (isttemp >= (sollwert - (gradient * gfh))) { if (heizung == EIN) { HeizungAUS(); umwaelzerEinAus(2); //Nachlauf } } #ifdef MitDisplayUndEncoder lcd.setCursor(12, 3); lcd.print(float(isttemp), 1); if (isttemp > 10) { lcd.print(char(0xDF)); lcd.print("C"); } else { lcd.print(char(0xDF)); lcd.print("C "); } #endif } if (millis() >= (altsekunden + 1500)) //Blinken der Anzeige und RUF { if (pause < einmaischzyklus) RufEIN(true); #ifdef MitDisplayUndEncoder lcd.setCursor(17, 2); lcd.print(" "); #endif if (sondermodus == EINMAISCHEN) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Einmaischen!"); #endif meldung_detail = "Einmaischen-Ruf_quittieren!"; } if (rufZ < 9) ruf = true; else ruf = false; if (millis() >= (altsekunden + einmaischtonlaenge)) { altsekunden = millis(); pause++; } } else { #ifdef MitDisplayUndEncoder lcd.setCursor(17, 2); lcd.print("Ruf"); if (sondermodus == EINMAISCHEN) { lcd.setCursor(0, 0); lcd.print(" "); } #endif RufAUS(true); if (sondermodus != EINMAISCHEN) if (pause > 8) pause = 0; } //Blinken der Anzeige und RUF if ((ButtonPressed) || (rufquittung)) { pause = 0; anfang = 0; RufAUS(true); ruf = false; if (braumeister[2] == 2) { #ifdef MitDisplayUndEncoder lcd.setCursor(17, 2); lcd.print(" "); #endif if (sensorfehler == 1) { #ifdef emcSchutz emccounter = emc; #endif sensorfehler = 0; //Sensorfehler oder Alarmtest } modus = rufmodus; if (modus == NACHGUSS) anfang = 1; } else modus = BRAUMEISTERRUFALARM; } if (rufquittung) { modus = rufmodus; anfang = 3; if (sondermodus == EINMAISCHEN) { anfang = 0; sondermodus = 0; modus = TEMPERATURAUTOMATIK; RufAUS(true); } if (rufmodus == ENDTEMPERATURAUTOMATIK) modus = ABBRUCH; rufquittung = false; } }// Ende funktion_braumeisterrufalarm //--------------------------------------------------------------------------------- //Braumeisterrufalarm //--------------------------------------------------------------------------------- void funktion_braumeisterruf() //Modus = BRAUMEISTERRUFALARM { if (anfang == 0) anfang = 1; #ifdef MitDisplayUndEncoder if (millis() >= (altsekunden + 1000)) { RufEIN(true); lcd.setCursor(12, 2); lcd.print(" "); if (millis() >= (altsekunden + 1500)) altsekunden = millis(); } else { RufAUS(true); lcd.setCursor(0, 2); lcd.print(" "); lcd.setCursor(12, 2); lcd.print("weiter ?"); } #endif if (ButtonPressed) { #ifdef MitDisplayUndEncoder RufAUS(true); lcd.setCursor(12, 2); lcd.print(" "); //Text "weiter ?" löschen lcd.setCursor(0, 3); lcd.print(" "); //Löscht Text bei #endif if (sensorfehler == 1) { sensorfehler = 0; //Sensorfehler oder Alarmtest #ifdef MitDisplayUndEncoder lcd.setCursor(8, 0); lcd.print(" "); #endif } anfang = 0; modus = rufmodus; if (rufmodus == KOCHEN) { anfang = 1; // Hopfen zugegeben! #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print(" "); #endif } } }// Ende funktion_braumeisterruf //--------------------------------------------------------------------------------- //Anzahl Hopfengaben //--------------------------------------------------------------------------------- void anzahl_hopfengaben() //Modus = ANZAHL_HOPFENGABEN { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Hopfengaben"); lcd.setCursor(5, 1); lcd.print("Anzahl"); #endif anfang = 1; drehen = hanz; #ifdef MitDisplayUndEncoder lcd.setCursor(14, 1); lcd.print(hanz); #endif dclick = false; } #ifdef MitDisplayUndEncoder if (hanz < 9) { lcd.setCursor(14, 1); lcd.print(hanz); } else { lcd.setCursor(13, 1); lcd.print(hanz); } #endif drehen = min_max_drehen(drehen, 1, maxgaben); hanz = drehen; if (ButtonPressed) { modus = NACHISOZEIT; anfang = 0; } }// Ende anzahl_hopfengaben //--------------------------------------------------------------------------------- //Nachisomerisierung //--------------------------------------------------------------------------------- void nachisozeit() //Modus = NACHISOZEIT { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Nachisomerisierung"); lcd.setCursor(0, 1); lcd.print("Zeit:"); #endif drehen = nachisomerisierung; anfang = 1; dclick = false; } #ifdef MitDisplayUndEncoder lcd.setCursor(6, 1); lcd.print(nachisomerisierung); lcd.print(" min. "); #endif drehen = min_max_drehen(drehen, 0, 90); nachisomerisierung = drehen; if (ButtonPressed) { modus = HOPFENGABE; anfang = 0; } }// Ende nachisozeit //--------------------------------------------------------------------------------- //Hopfengaben //--------------------------------------------------------------------------------- void funktion_hopfengabe() //Modus = HOPFENGABE { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Hopfengabe:"); lcd.setCursor(0, 1); lcd.print("Kochen "); lcd.print("f"); lcd.print(char(0xF5)); lcd.print("r"); #endif if (!rezept_eingelesen) //sonst gelten die Daten aus dem Rezept { if (kochzeit >= 60) // weniger ist eigentlich nicht sinnvoll { if (h == 0) hopfengabe[h] = kochzeit; //Typische Zeiten für das Hopfenkochen if (h == 1) hopfengabe[h] = kochzeit - 20; if (h == 2) hopfengabe[h] = 10; } } drehen = hopfengabe[h]; anfang = 1; dclick = false; hknull = false; } #ifdef MitDisplayUndEncoder lcd.setCursor(11, 0); lcd.print(h + 1); hopfengabe[h] = drehen; lcd.setCursor(12, 1); lcd.print(drehen); lcd.print(" min "); #endif if (hopfengabe[h] <= (-1 * nachisomerisierung)) { hopfengabe[h] = -1 * nachisomerisierung; drehen = -1 * nachisomerisierung; } if (hopfengabe[h] >= kochzeit) { hopfengabe[h] = kochzeit; drehen = kochzeit; } if (hopfengabe[h] < 0) { hknull = true; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print(" "); if (-hopfengabe[h] == nachisomerisierung) { lcd.setCursor(0, 1); lcd.print("Whirlpool "); } else { lcd.setCursor(0, 1); lcd.print("n. FlameOut"); } #endif } else { if (drehen > 0) { if (hknull) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Kochen "); lcd.print("f"); lcd.print(char(0xF5)); lcd.print("r "); #endif } } } if (ButtonPressed) { if (h == (hanz - 1)) { #ifdef MitDisplayUndEncoder lcd.clear(); #endif modus = STARTKOCHEN; } else { h++; } anfang = 0; } }// Ende funktion_hopfengabe //--------------------------------------------------------------------------------- //Kochzeit //--------------------------------------------------------------------------------- void funktion_kochzeit() //Modus = KOCHZEIT { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Vorgaben"); lcd.setCursor(3, 1); lcd.print("Kochzeit"); lcd.setCursor(16, 1); lcd.print("min."); lcd.setCursor(2, 2); lcd.print("Dr"); lcd.print(char(0xF5)); lcd.print("cken = weiter"); #endif encoder->setAccelerationEnabled(true); drehen = kochzeit; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 60, 180); kochzeit = drehen; #ifdef MitDisplayUndEncoder if (kochzeit < 100) { lcd.setCursor(11, 1); lcd.print(" "); lcd.print(kochzeit); } else { lcd.setCursor(11, 1); lcd.print(" "); lcd.print(kochzeit); } #endif if (ButtonPressed) { encoder->setAccelerationEnabled(false); modus = ANZAHL_HOPFENGABEN; // Anzahl Hopfengaben anfang = 0; } }// Ende funktion_kochzeit //--------------------------------------------------------------------------------- //Startkochzeit //--------------------------------------------------------------------------------- void funktion_startkochen() //Modus = STARTKOCHEN { if ((anfang == 0) || (dclick)) { anfang = 1; altsekunden = millis(); abbruchkochen = 60; blinker = 0; altmodus = STARTKOCHEN; dclick = false; sollwert = kschwelle; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Ruf bei "); lcd.print(kschwelle); lcd.print(char(0xDF)); lcd.print("C"); lcd.print(" "); #endif if (heizung == AUS) HeizungEIN(); if (umwaelzer_stat == EIN) UmwaelzerAUS(); } if (millis() <= (altsekunden + schwellenrufdauer)) { if ((isttemp >= kschwelle) || (schwelle_erreicht)) { schwelle_erreicht = true; if (anfang != 3) { ruf = true; rufZ = 0; meldung_detail = "Kochschwelle-erreicht-60s-Zeit!"; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Abbruch in "); if (abbruchkochen <= 60) { lcd.print(abbruchkochen); lcd.print(" s "); ; } #endif } #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); #endif if (blinker == 0) { if (anfang == 3) { #ifdef MitDisplayUndEncoder lcd.print("Start Zeitz"); lcd.print(char(0xE1)); lcd.print("hlung? "); #endif meldung_detail = "Button-Kochen-Start!!"; ruf = false; RufAUS(true); } else { #ifdef MitDisplayUndEncoder lcd.print("Bitte quittieren!"); #endif meldung_detail = "Ruf-quittieren!"; } if (anfang == 1) { signalton(quittungston); RufEIN(true); anfang = 2; } else if (anfang == 2) { if (abbruchkochen > 61) modus = ABBRUCH; if (abbruchkochen % 10 == 0) { signalton(quittungston); ruf = true; RufEIN(true); } else { ruf = false; RufAUS(true); } } } #ifdef MitDisplayUndEncoder else lcd.print(" "); #endif } else { if (blinker == 0) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("Warten!"); #endif meldung_detail = "Bitte-warten!"; schwelle_erreicht = false; } #ifdef MitDisplayUndEncoder if (blinker == 1) { lcd.setCursor(0, 2); lcd.print(" "); } #endif } } else { if (blinker == 0) blinker = 1; else blinker = 0; altsekunden = millis(); if (schwelle_erreicht) { abbruchkochen--; abbruchkochen--; if (abbruchkochen % 10 == 0) { // signalton(quittungston); if (meldung_detail != "Button-Kochen-Start!!") ruf = true; } else ruf = false; }; } if (schwelle_erreicht) { if ((ButtonPressed) || (rufquittung)) { altmodus = STARTKOCHEN; if (anfang == 3) { anfang = 0; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print(" "); #endif modus = KOCHEN; } if (anfang == 2) { anfang = 3; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print(" "); #endif } } } }// Ende funktion_startkochen //--------------------------------------------------------------------------------- //Kochen //--------------------------------------------------------------------------------- void funktion_kochen() //Modus = KOCHEN { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Kochen"); lcd.setCursor(3, 1); lcd.print("Kochzeit "); #endif meldung_detail = "Kochen_gestartet"; meldung = "41-Kochen"; if (!dclick) setTime(00, 00, 00, 00, 01, 01); //.........Sekunden auf 0 stellen if (zeit_setzen) { RastZeit_h = EEPROM.read(zeit_h); RastZeit_m = EEPROM.read(zeit_m); RastZeit_s = EEPROM.read(zeit_s); setTime(RastZeit_h, RastZeit_m, RastZeit_s, 00, 01, 01); zeit_setzen = false; } if (notfall_aktiv) { Notfallmodus = EEPROMReadInt(notfallmodus); if (EEPROMReadInt(notfallmodus) != 1) EEPROMWriteInt(notfallmodus, 1); //Notfallmodus aktiviert EEPROMWriteInt(rastmodus, modus); //für Notfall Modus merken EEPROMWriteInt(hopfengabe1, hopfengabe[0]); EEPROMWriteInt(hopfengabe2, hopfengabe[1]); EEPROMWriteInt(hopfengabe3, hopfengabe[2]); EEPROMWriteInt(hopfengabe4, hopfengabe[3]); EEPROMWriteInt(hopfengabe5, hopfengabe[4]); EEPROMWriteInt(hopfengabe6, hopfengabe[5]); EEPROM.write(Kochzeit, kochzeit); } sekunden = second(); //aktuell Sekunde abspeichern für die Zeitrechnung minutenwert = minute(); //aktuell Minute abspeichern für die Zeitrechnung stunden = hour(); //aktuell Stunde abspeichern für die Zeitrechnung anfang = 1; if (!dclick) h = 0; //Hopfengabengabe Zähler drehen = kochzeit; dclick = false; } #ifdef MitDisplayUndEncoder if (kochzeit < 100) { lcd.setCursor(12, 1); lcd.print(" "); lcd.print(kochzeit); } else { lcd.setCursor(12, 1); lcd.print(" "); lcd.print(kochzeit); } lcd.setCursor(12, 1); lcd.print(kochzeit); lcd.print(" min. "); if (sekunden < 10) { if (minuten == 0) { lcd.setCursor(14, 0); lcd.print("00:0"); lcd.print(sekunden); } } else { if (minuten == 0) { lcd.setCursor(14, 0); lcd.print("00:"); lcd.print(sekunden); } } #endif minuten = ((stunden * 60) + minutenwert); if (sekunden < 10) //in den ersten 10 s einer Minute wird //der Minutenwert übertragen, zeit_detail = String(minuten); else { //meldung_detail = "Kochen-gestartet"; //sonst die aktuelle Aktion meldung = "Kochen"; } if ((h < hanz) && (kochzeit - minuten == hopfengabe[h])) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print(h + 1); lcd.print(". H-Gabe"); #endif meldung_detail = String(h + 1) + ".-Hopfengabe"; h++; ruf = true; rufZ = 0; signalton(2000); } #ifdef MitDisplayUndEncoder if ((sekunden + 10) % 30 == 0) { lcd.setCursor(0, 2); lcd.print(" "); } if ((minuten < 10) && (minuten > 0)) { lcd.setCursor(14, 0); lcd.print("0"); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } if ((minuten >= 10) && (minuten < 100)) { lcd.setCursor(14, 0); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } if (minuten >= 100) { lcd.setCursor(13, 0); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } #endif encoder->setAccelerationEnabled(true); drehen = min_max_drehen(drehen, 20, 180); kochzeit = drehen; if (notfall_aktiv) { if (sekunden == 0) //einmal pro Minute speichern { EEPROM.write(zeit_h, stunden); EEPROM.write(zeit_m, minuten); EEPROM.write(zeit_s, sekunden); } } if (minuten >= kochzeit) //Kochzeitende { meldung_detail = "Kochzeit-beendet"; rufmodus = modus; altmodus = modus; modus = RUFALARM; regelung = AUS; //Regelung aus if (heizung == EIN) HeizungAUS(); y = 0; braumeister[y] = 2; anfang = 0; for (tz = 0; tz <= 3; tz++) { signalton(quittungston); delay(200); } meldung_detail = "Kochen-beendet"; if (nachisomerisierung > 0) modus = NACHISOMERISIERUNG; else modus = ABBRUCH; } }// Ende funktion_kochen //--------------------------------------------------------------------------------- //Nachisomerisierung Eingabe //--------------------------------------------------------------------------------- void nachiso() //Modus = NACHISOMERISIERUNG { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Nachisom."); lcd.setCursor(0, 1); lcd.print("Wartezeit: "); lcd.setCursor(11, 1); lcd.print("min. "); #endif if (heizung == EIN) HeizungAUS(); //zur Sicherheit !! signalton(2000); if (!dclick) setTime(00, 00, 00, 00, 01, 01); //.........Sekunden auf 0 stellen if (zeit_setzen) { nachiso_h = EEPROM.read(isozeit_h); nachiso_m = EEPROM.read(isozeit_m); nachiso_s = EEPROM.read(isozeit_s); setTime(nachiso_h, nachiso_m, nachiso_s, 00, 01, 01); zeit_setzen = false; } if (notfall_aktiv) { Notfallmodus = EEPROMReadInt(notfallmodus); if (EEPROMReadInt(notfallmodus) != 1) EEPROMWriteInt(notfallmodus, 1); //Notfallmodus aktiviert EEPROMWriteInt(rastmodus, modus); //für Notfall Modus merken EEPROM.write(niso, nachisomerisierung); } sekunden = second(); //aktuell Sekunde abspeichern für die Zeitrechnung minutenwert = minute(); //aktuell Minute abspeichern für die Zeitrechnung stunden = hour(); //aktuell Stunde abspeichern für die Zeitrechnung anfang = 1; drehen = nachisomerisierung; dclick = false; } zeit_detail = String(minuten); #ifdef MitDisplayUndEncoder if (nachisomerisierung < 100) { lcd.setCursor(11, 1); lcd.print(" "); lcd.print(nachisomerisierung); lcd.print(" min. "); } else { lcd.setCursor(11, 1); lcd.print(" "); lcd.print(nachisomerisierung); lcd.print(" min. "); } if (sekunden < 10) { if (minuten == 0) { lcd.setCursor(14, 0); lcd.print("00:0"); lcd.print(sekunden); } } else { if (minuten == 0) { lcd.setCursor(14, 0); lcd.print("00:"); lcd.print(sekunden); } } #endif minuten = ((stunden * 60) + minutenwert); #ifdef MitDisplayUndEncoder if ((minuten < 10) && (minuten > 0)) { lcd.setCursor(14, 0); lcd.print("0"); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } if ((minuten >= 10) && (minuten < 100)) { lcd.setCursor(14, 0); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } if (minuten >= 100) { lcd.setCursor(13, 0); lcd.print(minuten); lcd.print(":"); if (sekunden < 10) { lcd.print("0"); lcd.print(sekunden); } else lcd.print(sekunden); } #endif drehen = min_max_drehen(drehen, 0, 90); nachisomerisierung = drehen; if (notfall_aktiv) { if (sekunden == 0) //einmal pro Minute speichern { EEPROM.write(isozeit_h, stunden); EEPROM.write(isozeit_m, minuten); EEPROM.write(isozeit_s, sekunden); } } if (h < hanz && minuten == -hopfengabe[h] && hopfengabe[h] < 0) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print(h + 1); lcd.print(". H-Gabe"); #endif meldung_detail = String(h + 1) + ".-Hopfengabe"; h++; signalton(2000); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print(" "); #endif } if ((minuten >= nachisomerisierung) || (isttemp <= isoTemperatur)) //Nachisomerisierung Ende { meldung_detail = "Nachiso-beendet"; modus = ABBRUCH; //Abbruch nach Rufalarm rufmodus = modus; modus = RUFALARM; y = 0; braumeister[y] = 2; anfang = 0; } }// Ende nachiso //--------------------------------------------------------------------------------- //Gradientenfaktor HEIZEN eingeben //--------------------------------------------------------------------------------- void khwert() //Modus = GRADIENTENFAKTOR_HEIZEN { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Faktor Heizen"); lcd.setCursor(0, 1); lcd.print("kh = "); #endif gfh = EEPROMReadlong(graf_h); anfang = 1; drehen = gfh; dclick = false; } drehen = min_max_drehen(drehen, 0, 200); gfh = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(5, 1); lcd.print(gfh / 10); lcd.print(' '); #endif if (ButtonPressed) { if (EEPROMReadlong(graf_h) != drehen) EEPROMWritelong(graf_h, drehen); speichern(2); modus = EINSCHALTVERZOEGERUNG_HEIZRELAIS; gfh /= 10; anfang = 0; } }// Ende khwert //--------------------------------------------------------------------------------- //Einschaltverzögerung HEIZEN eingeben //--------------------------------------------------------------------------------- void ESVHeiz() //Modus = EINSCHALTVERZOEGERUNG_HEIZRELAIS { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Einschaltv. Heizen"); lcd.setCursor(0, 1); lcd.print("ESVH = "); #endif esvheizen = EEPROMReadlong(wein_h); anfang = 1; drehen = esvheizen / 1000; } drehen = min_max_drehen(drehen, 0, 60); #ifdef MitDisplayUndEncoder lcd.setCursor(7, 1); lcd.print(drehen); lcd.print(" s "); #endif esvheizen = drehen * 1000L; if (ButtonPressed) { if (EEPROMReadlong(wein_h) != esvheizen) EEPROMWritelong(wein_h, esvheizen); speichern(2); modus = GRADIENTENFAKTOR_KUEHLEN; anfang = 0; } }// Ende ESVHeiz //--------------------------------------------------------------------------------- //Gradientenfaktor KÜHLEN eingeben //--------------------------------------------------------------------------------- void kkwert() //Modus = GRADIENTENFAKTOR_KUEHLEN { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Faktor Kuehlen"); lcd.setCursor(0, 1); lcd.print("kk = "); #endif gfk = EEPROMReadlong(graf_k); anfang = 1; drehen = gfk; } drehen = min_max_drehen(drehen, 0, 200); gfk = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(5, 1); lcd.print(gfk / 10); lcd.print(' '); #endif if (ButtonPressed) { if (EEPROMReadlong(graf_k) != drehen) EEPROMWritelong(graf_k, drehen); speichern(2); modus = WARTEZEIT_KUEHLEN; gfk /= 10; anfang = 0; } }// Ende kkwert //--------------------------------------------------------------------------------- //Einschaltverzögerung Kühlen (Kompressorschutz) //--------------------------------------------------------------------------------- void wartenKuehlen() //Modus = WARTEZEIT_KUEHLEN { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Wartezeit Kuehlen"); lcd.setCursor(0, 1); lcd.print("ESVK = "); #endif kzeitverz = EEPROMReadlong(kuehlverz); kzeitverz = kzeitverz / (60000L); drehen = kzeitverz; anfang = 1; } else { drehen = min_max_drehen(drehen, 0, 10); kzeitverz = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(7, 1); lcd.print(kzeitverz); lcd.print(" min "); #endif if (ButtonPressed) { if (EEPROMReadlong(kuehlverz) != kzeitverz * 60000L) EEPROMWritelong(kuehlverz, kzeitverz * 60000L); kzeitverz = kzeitverz * 60000L; speichern(2); modus = SETUPMENUE; anfang = 0; } } }// Ende wartenKuehlen //--------------------------------------------------------------------------------- //Logging EIN-AUS //--------------------------------------------------------------------------------- void LoggingEinAus() //Modus = LOGGING_EIN_AUS { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Logging Ein?"); #endif drehen = EEPROM.read(logging); anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 0, 1); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print(j_n_drehen(drehen)); #endif loggen = drehen; if (ButtonPressed) { modus = SETUPMENUE; if (EEPROM.read(logging) != drehen) EEPROM.write(logging, drehen); if (loggen) { Serial.begin(115200); modus = LOGWAHL; } speichern(2); anfang = 0; } }// Ende LoggingEinAus //--------------------------------------------------------------------------------- //Auswahl des Loggingprogramms //--------------------------------------------------------------------------------- void Logwahl() //Modus = LOGWAHL { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Loggerwahl"); lcd.setCursor(0, 1); lcd.print("SerialCom:"); lcd.setCursor(0, 2); lcd.print("LogView :"); #endif drehen = EEPROM.read(loggerwahl); anfang = 1; dclick = false; } drehen %= 2; #ifdef MitDisplayUndEncoder if (drehen == 0) { lcd.setCursor(11, 1); lcd.print("<-"); lcd.setCursor(11, 2); lcd.print(" "); lcd.setCursor(18, 1); lcd.print(" "); } if (drehen == 1) { lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(11, 2); lcd.print("<-"); lcd.setCursor(18, 1); lcd.print(" "); } #endif loggen = drehen; if (ButtonPressed) { modus = SETUPMENUE; if (EEPROM.read(loggerwahl) != drehen) EEPROM.write(loggerwahl, drehen); switch (drehen) { case 0: { serialcom = true; logview = false; break; } case 1: { logview = true; serialcom = false; break; } } speichern(2); anfang = 0; } }//Ende Logwahl #ifdef bluetooth //--------------------------------------------------------------------------------- //Bluetooth-Steuerung EIN-AUS //--------------------------------------------------------------------------------- void BluetoothSteuerungAktiv() //Modus = BLUETOOTHSTEUERUNG_AKTIV { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("KBH2AiO aktiv?"); #endif drehen = EEPROM.read(Bluetooth); anfang = 1; dclick = false; } drehen %= 2; #ifdef MitDisplayUndEncoder lcd.setCursor(15, 0); lcd.print(j_n_drehen(drehen)); #endif if (ButtonPressed) { modus = EXTERNMENUE; uint8_t alterWert = EEPROM.read(Bluetooth); if (alterWert != drehen) EEPROM.write(Bluetooth, drehen); speichern(2); if (drehen == 0) { bluetooth_steuerung = false; Serial2.end(); } else { if (alterWert == 0) { connectBluetooth(); } } anfang = 0; } }//Ende BluetoothSteuerungAktiv #else //--------------------------------------------------------------------------------- //WLAN-Verbinden //--------------------------------------------------------------------------------- void connectWiFi() //Modus = CONNECT_WIFI { #ifdef MitDisplayUndEncoder lcd.clear(); #endif pinMode(reset8266, OUTPUT); digitalWrite(reset8266, LOW); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Init ESP8266"); #endif digitalWrite(reset8266, HIGH); //Hardware Reset delay(2000); if (Serial2.available()) { delay(1000); Serial2.print("AT+RST\r\n"); //Software Reset getReply(1000); Serial2.print("AT+CIOBAUD=115200\r\n"); //Einstellen der Baudrate getReply(1000); #ifdef dbg Serial.println("Start\r\n\r\n"); #endif #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Start WLAN"); lcd.setCursor(0, 2); lcd.print("Param. UPD ESP8266"); #endif #ifdef dbg Serial.println("Modul Reset"); #endif Serial2.print("AT+RST\r\n"); //Software Reset getReply(1000); #ifdef dbg Serial.println("Firmware"); #endif Serial2.print("AT+GMR\r\n"); //Ausgabe der Firmware getReply(1000); strcpy(command, "AT+CWSAP="); //Zugangsdaten und Verschlüsselung strcat(command, "\""); strcat(command, "AiO-LAN"); strcat(command, "\""); strcat(command, ","); strcat(command, "\""); strcat(command, "Hobbybrauer"); strcat(command, "\""); strcat(command, ",4,3"); //Channel 4 und WPA2_PSK strcat(command, "\r\n"); Serial2.print(command); #ifdef dbg Serial.println(command); #endif getReply(1000); Serial2.print("AT+CWSAP?\r\n"); //wurden die Werte übernommen? getReply(2000); strcpy(command, "AT+CIPAP="); //Setzen der IP-Adresse des ESP strcat(command, "\""); strcat(command, "192.168.100.1"); strcat(command, "\""); strcat(command, "\r\n"); Serial2.print(command); #ifdef dbg Serial.println(command); #endif getReply(3000); #ifdef dbg Serial.println("IP-Adresse holen"); #endif Serial2.print("AT+CIFSR\r\n"); getReply(2000); Serial2.println("AT+CIPMUX=1"); //Multiple Connections getReply(1500); #ifdef dbg Serial.println("Server einrichten"); #endif Serial2.print("AT+CIPSERVER=1\r\n"); getReply(2000); strcpy(command, "AT+CIPSTART=4,"); strcat(command, "\""); strcat(command, "UDP"); strcat(command, "\""); strcat(command, ","); strcat(command, "\""); strcat(command, "192.168.100.255"); strcat(command, "\""); strcat(command, ",50000,50000,0"); strcat(command, "\r\n"); Serial2.print(command); #ifdef dbg Serial.println(command); #endif getReply(3000); } if (modus == CONNECT_WIFI) modus = SETUPMENUE; }// Ende connectWiFi //--------------------------------------------------------------------------------- //WLAN-Steuerung EIN-AUS //--------------------------------------------------------------------------------- void wifieinaus() //Modus = WIFI_EIN_AUS { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("WLAN:"); lcd.setCursor(0, 1); lcd.print("EIN:"); #endif anfang = 1; drehen = EEPROM.read(Wlan); } #ifdef MitDisplayUndEncoder char antwort = ja_nein[drehen % 2]; lcd.setCursor(5, 1); lcd.print(antwort); #endif if (ButtonPressed) { modus = SETUPMENUE; if (EEPROM.read(Wlan) != drehen % 2) EEPROM.write(Wlan, drehen % 2); speichern(2); anfang = 0; if (drehen % 2 == 1) { Serial2.begin(115200); wlanAktiv = true; modus = CONNECT_WIFI; } else Serial2.end(); } }// Ende wifieinaus //--------------------------------------------------------------------------------- //WLAN-Steuerung aktiv //--------------------------------------------------------------------------------- void WLANSteuerungAktiv() //Modus = WLANSTEUERUNG_AKTIV { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("KBH2AiO aktiv?"); #endif drehen = EEPROM.read(Wlan); anfang = 1; dclick = false; } drehen %= 2; #ifdef MitDisplayUndEncoder lcd.setCursor(15, 0); lcd.print(j_n_drehen(drehen)); #endif if (ButtonPressed) { modus = EXTERNMENUE; uint8_t alterWert = EEPROM.read(Wlan); if (alterWert != drehen) EEPROM.write(Wlan, drehen); speichern(2); if (drehen == 0) wlan_steuerung = false; else { if (alterWert == 0) { wlan_steuerung = true; Serial2.begin(115200); connectWiFi(); } } anfang = 0; } }// Ende WLANSteuerungAktiv #endif //--------------------------------------------------------------------------------- //Rührer oder Pumpe ? //--------------------------------------------------------------------------------- void auswahl_umwaelzer() //Modus = AUSWAHL_UMWAELZER { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("R"); lcd.print(char(0xF5)); lcd.print("hrer oder Pumpe?"); lcd.setCursor(0, 1); lcd.print("R"); lcd.print(char(0xF5)); lcd.print("hrer :"); lcd.setCursor(0, 2); lcd.print("Pumpe :"); #endif drehen = EEPROM.read(umwaelzwahl); #ifdef MitDisplayUndEncoder if (drehen == 0) { lcd.setCursor(11, 1); lcd.print("<-"); lcd.setCursor(11, 2); lcd.print(" "); } if (drehen == 1) { lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(11, 2); lcd.print("<-"); } #endif anfang = 1; dclick = false; } drehen %= 2; #ifdef MitDisplayUndEncoder if (drehen == 0) { lcd.setCursor(11, 1); lcd.print("<-"); lcd.setCursor(11, 2); lcd.print(" "); } if (drehen == 1) { lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(11, 2); lcd.print("<-"); } #endif umwaelzen = drehen; if (ButtonPressed) { if (EEPROM.read(umwaelzwahl) != drehen) EEPROM.write(umwaelzwahl, drehen); switch (drehen) { case 0: { ruehrer = true; pumpe = false; break; } case 1: { ruehrer = false; pumpe = true; break; } } speichern(2); anfang = 0; modus = UMWAELZER_DAUERLAUF; } }// Ende auswahl_umwaelzer //--------------------------------------------------------------------------------- //Rührer/Pumpe aktiv beim Einmaischen? //--------------------------------------------------------------------------------- void RuePumAktiv() //Modus = RUEPUMAKTIV { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("R"); lcd.print(char(0xF5)); lcd.print("hrer aktiv"); lcd.setCursor(0, 1); lcd.print("beim Einmaischen?"); #endif drehen = EEPROM.read(ruepumeinmaisch); anfang = 1; dclick = false; } drehen %= 2; #ifdef MitDisplayUndEncoder lcd.setCursor(18, 1); lcd.print(j_n_drehen(drehen)); #endif ruehrer_beim_einmaischen = drehen; if (ButtonPressed) { modus = NACHLAUF; if (EEPROM.read(ruepumeinmaisch) != drehen) EEPROM.write(ruepumeinmaisch, drehen); speichern(3); anfang = 0; } }// Ende RuePumAktiv //--------------------------------------------------------------------------------- //Rührer-Nachlauf nach Erreichen der Abmaischtemperatur (Nachlauf) //--------------------------------------------------------------------------------- void Nachlauf() //Modus = NACHLAUF { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("R"); lcd.print(char(0xF5)); lcd.print("hrer Nachlauf"); lcd.setCursor(0, 1); lcd.print("vor Abmaischen?"); lcd.setCursor(0, 2); lcd.print("NLZ ="); lcd.print(" 5 min."); #endif drehen = EEPROM.read(rueNachlauf); anfang = 1; } drehen %= 2; #ifdef MitDisplayUndEncoder lcd.setCursor(18, 1); lcd.print(j_n_drehen(drehen)); #endif ruehrer_nachlauf = drehen; if (ButtonPressed) { modus = SETUPMENUE; if (EEPROM.read(rueNachlauf) != drehen) EEPROM.write(rueNachlauf, drehen); speichern(3); anfang = 0; } }//Ende Nachlauf //------------------------------------------------------------------------------------- //Nachguss Solltemperatur einstellen //--------------------------------------------------------------------------------- void NachgussSoll() //Modus = NACHGUSSSOLL { if (anfang == 0) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Nachgusstemperatur: "); #endif nachgusssolltemp = EEPROM.read(nachgusssoll); drehen = nachgusssolltemp; drehen = min_max_drehen(drehen, 30, 78); anfang = 1; } #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print(drehen); lcd.print(" "); lcd.print(char(0xDF)); lcd.print("C "); #endif drehen = min_max_drehen(drehen, 30, 78); nachgusssolltemp = drehen; if (ButtonPressed) { modus = SETUPMENUE; if (EEPROM.read(nachgusssoll) != drehen) EEPROM.write(nachgusssoll, drehen); nachgusssolltemp = drehen; speichern(3); anfang = 0; } }// Ende NachgussSoll #ifdef gassensor //--------------------------------------------------------------------------------- //Gassensor kalibrieren //--------------------------------------------------------------------------------- float kalibrieren(uint8_t AnalogPin) { for (int16_t x = 0; x < 500; x++) //Start for loop { sensorValue = sensorValue + analogRead(AnalogPin); //Add analog values of sensor 500 times } sensorValue = sensorValue / 500.0; //Take average of readings sensor_volt = sensorValue * (5.0 / 1023.0); //Convert average to voltage RS_air = ((5.0 * 10.0) / sensor_volt) - 10.0; //Calculate RS in fresh air R0 = RS_air / 10; //Calculate R0 sensorValue = 0; return R0; }// Ende kalibrieren float getPPM(int16_t AnalogPin) { for (int16_t x = 0; x < 500; x++) //Start for loop { sensorValue = sensorValue + analogRead(AnalogPin); //Read analog values of sensor } sensorValue = sensorValue / 500.0; //Take average of readings sensor_volt = sensorValue * (5.0 / 1023.0); //Convert analog values to voltage RS_gas = ((5.0 * 10.0) / sensor_volt) - 10.0; //Get value of RS in a gas ratio = RS_gas / R0; // Get ratio RS_gas/RS_air ppm_log = (log10(ratio) - bb) / mm; //Get ppm value in linear scale according to the the ratio value ppm = pow(10, ppm_log); //Convert ppm value to log scale sensorValue = 0; return ppm; }// Ende getPPM #endif //--------------------------------------------------------------------------------- //Gassensor initialisieren //--------------------------------------------------------------------------------- void funktion_GasSensorInit() //Modus = GASSENSORINIT { #ifdef gassensor test_sensor = analogRead(analogpin); if (test_sensor < 1000) { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Kalibrieren!"); lcd.setCursor(0, 1); lcd.print("Bitte warten!"); lcd.setCursor(0, 2); lcd.print("R0 = "); #endif anfang = 1; dclick = false; } R0 = kalibrieren(analogpin); #ifdef MitDisplayUndEncoder lcd.print(R0); #endif if (R0 > 0) { speichern(3); EEPROMWriteInt(gas_r0, R0); if (!externer_aufruf) modus = GAS_GRENZWERT; else modus = externmodus; externer_aufruf = false; anfang = 0; } else { anfang = 0; modus = HAUPTMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Sensorfehler!"); #endif } } else { anfang = 0; modus = HAUPTMENUE; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print("Sensorfehler!"); delay(2000); #endif } #else #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Sensor im Sketch"); lcd.setCursor(0, 1); lcd.print("nicht aktiviert!"); delay(3000); #endif modus = HAUPTMENUE; #endif }// Ende funktion_GasSensorInit //--------------------------------------------------------------------------------- //Gas Grenz-(Alarm-)wert eingeben //--------------------------------------------------------------------------------- void funktion_grenzwert() //modus = GAS_GRENZWERT { #ifdef gassensor if (anfang == 0) { lpg_grenzwert = EEPROMReadInt(gas_grenzwert); drehen = lpg_grenzwert; #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Alarm:"); lcd.setCursor(0, 1); lcd.print("Grenzwert = "); #endif anfang = 1; } drehen = min_max_drehen(drehen, 1, 34); //3400 ppm -> max (20% UEG) #ifdef MitDisplayUndEncoder lcd.setCursor(13, 1); lcd.print(drehen * 100); lcd.print(" "); #endif if (ButtonPressed) { modus = SETUPMENUE; if (EEPROMReadInt(gas_grenzwert) != drehen) EEPROMWriteInt(gas_grenzwert, drehen); if (EEPROMReadInt(gas_kontrollwert) != 8888) EEPROMWriteInt(gas_kontrollwert, 8888); lpg_grenzwert = drehen * 100; speichern(3); anfang = 0; } #else modus = HAUPTMENUE; #endif }// Ende funktion_grenzwert //--------------------------------------------------------------------------------- //Notfallmodus EIN-AUS //--------------------------------------------------------------------------------- void StromAus() //Modus = NOTFALLMODUS { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Notfall Ein?"); #endif drehen = EEPROM.read(notfall); anfang = 1; dclick = false; } drehen %= 2; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print(j_n_drehen(drehen)); #endif notfall_aktiv = drehen; if (ButtonPressed) { modus = SETUPMENUE; if (EEPROM.read(notfall) != drehen) EEPROM.write(notfall, drehen); speichern(2); anfang = 0; } }// Ende StromAus #ifdef funksteuerung //--------------------------------------------------------------------------------- //Verwendungszweck der 3. Funksteckdose //--------------------------------------------------------------------------------- void steckdosenwahl() //Modus = DRITTE_FUNKSTECKDOSE { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Funkruf?"); lcd.setCursor(0, 1); lcd.print("sonst Nachguss!"); lcd.setCursor(10, 0); lcd.print(j_n_drehen(drehen)); #endif drehen = EEPROM.read(dritte_funksteckdose); anfang = 1; dclick = false; } drehen %= 2; #ifdef MitDisplayUndEncoder lcd.setCursor(10, 0); lcd.print(j_n_drehen(drehen)); #endif if (ButtonPressed) { modus = FRAGESTECKDOSENCODEEINGEBEN; if (EEPROM.read(dritte_funksteckdose) != drehen) EEPROM.write(dritte_funksteckdose, drehen); speichern(2); if (drehen == 1) funkruf = true; else funkruf = false; anfang = 0; } }// Ende steckdosenwahl //--------------------------------------------------------------------------------- //Steckdosencode anschliessend direkt eingeben? //--------------------------------------------------------------------------------- void frageCodeEingeben() //Modus = FRAGESTECKDOSENCODEEINGEBEN { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Steckdosencode"); lcd.setCursor(0, 1); lcd.print("eingeben?"); #endif drehen = 1; anfang = 1; dclick = false; } drehen %= 2; #ifdef MitDisplayUndEncoder lcd.setCursor(10, 1); lcd.print(j_n_drehen(drehen)); #endif if (ButtonPressed) { anfang = 0; if (drehen == 0) modus = SETUPMENUE; else modus = STECKDOSENCODE; } }// Ende frageCodeEingeben #endif //--------------------------------------------------------------------------------- //LogView Studio -- Download unter : http://www.logview.info/forum/index.php?resources/ //hier können natürlich auch andere Protokolle hinterlegt werden! //--------------------------------------------------------------------------------- void logger_logview() //Daten für Logview-Studio bereitstellen { if (loggen) { String data; data = "$"; data += String(sollwert); data += ";"; data += String(isttemp); data += ("\r\n"); #ifdef bluetooth Serial.println(data); //Sende Messdaten via COM Serial2.println(data); Serial2.flush(); #else Serial.print(data); //Sende Messdaten via COM Serial2.print("AT+CIPSEND=4,"); //Sende Messdaten via UDP Serial2.println(data.length() + 2); delay(50); if (Serial2.find('>')) { //ESP8266 sendebereit Serial2.print(data); //abschicken Serial2.print("\r\n"); } #endif } }// Ende logger_logview //--------------------------------------------------------------------------------- //SerialComInstruments - Download unter: http://www.serialcominstruments.com/instrument4.php //hier können natürlich auch andere Protokolle hinterlegt werden! //--------------------------------------------------------------------------------- void logger_serial() //Daten für SerialComInstruments4 bereitstellen { String data; data = "<#"; data += "01"; //Kanal 1 data += "M"; data += String(isttemp); //Isttemperatur data += "<"; data += "#"; data += "02"; //Kanal 2 data += "M"; data += String(sollwert); //Solltemperatur data += "<"; if (anzahlTempsensoren == 2) { data += "#"; data += "06"; //Kanal 6 data += "M"; data += String(nachgusssensor); //Nachgusstemperatur (wenn mit Sensor) data += "<"; } data += "#"; data += "03"; //Kanal 3 data += "M"; data += String(gradient); //Gradient data += "<"; if (heizung == EIN) { data += "#"; data += "04"; //Kanal 4 data += "M"; data += "3"; //Heizung EIN data += "<"; } else { data += "#"; data += "04"; //Kanal 4 data += "M"; data += "0"; //Heizung AUS data += "<"; } if (nachgussheizung == EIN) { data += "#"; data += "07"; //Kanal 7 data += "M"; data += "3"; //Nachgussheizung EIN data += "<"; } else { data += "#"; data += "07"; //Kanal 7 data += "M"; data += "0"; //Nachgussheizung AUS data += "<"; } if (ruehrerspeed == 1) { data += "#"; data += "09"; //Kanal 9 data += "M"; data += "3"; //Rührgeschwindigkeit HIGH data += "<"; } else { data += "#"; data += "09"; //Kanal 9 data += "M"; data += "0"; //Rührgeschwindigkeit LOW data += "<"; } #ifdef WUERZEPUMPE_AKTIV if (wpumpe == 1) { data += "#"; data += "10"; //Kanal 10 data += "M"; data += "3"; //Würzepumpe EIN data += "<"; } else { data += "#"; data += "10"; //Kanal 10 data += "M"; data += "0"; //Würzepumpe AUS data += "<"; } #else data += "#"; data += "10"; //Kanal 10 data += "M"; data += "0"; //Würzepumpe AUS data += "<"; #endif if ((modus == RUFALARM) || (modus == BRAUMEISTERRUFALARM)) { data += "#"; data += "08"; //Kanal 8 data += "M"; data += "2"; //Rufalarm EIN data += "<"; } else { data += "#"; data += "08"; //Kanal 8 data += "M"; data += "0"; //Rufalarm AUS data += "<"; } if (rwerk == 1) { data += "#"; data += "05"; //Kanal 5 data += "M"; data += "3"; //Umwaelz EIN data += "<"; } else { data += "#"; data += "05"; //Kanal 5 data += "M"; data += "0"; //Umwaelz AUS data += "<"; } if (meldung_detail != alte_detailmeldung) { alte_detailmeldung = meldung_detail; data += "#"; data += "11"; //Kanal 11 data += "M"; data += meldung_detail; data += "<"; } if (meldung != alte_meldung) { alte_meldung = meldung; data += "#"; data += "11"; //Kanal 11 data += "M"; data += meldung; data += "<"; } if (modus == ZEITAUTOMATIK) { data += "#"; data += "12"; //Kanal 12 data += "M"; data += rastZeit[x]; //Sollzeit data += "<"; data += "#"; data += "13"; //Kanal 13 data += "M"; data += minuten; //Istzeit data += "<"; } else { data += "#"; data += "12"; //Kanal 12 data += "M"; data += 0; //Sollzeit data += "<"; data += "#"; data += "13"; //Kanal 13 data += "M"; data += 0; //Istzeit } #ifdef bluetooth Serial.println(data); //Com-Port-Datenübertragung Serial2.println(data); #else Serial.println(data); //Com-Port-Datenübertragung if (wlanAktiv) delay(100); Serial2.print("AT+CIPSEND=4,"); //Sende Messdaten Serial2.println(data.length() + 2); delay(50); if (Serial2.find('>')) { //ESP8266 sendebereit Serial2.print(data); //abschicken Serial2.print("\r\n"); } #endif }// Ende logger_serial //--------------------------------------------------------------------------------- //Eingabe der Anzahl der Gärrasten //--------------------------------------------------------------------------------- void funktion_gaerrastanzahl() //Modus = GAERFUEHRUNG { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Eingabe"); lcd.setCursor(8, 1); lcd.print("G"); lcd.print(char(0xE1)); lcd.print("rrasten"); #endif drehen = gaerrasten; anfang = 1; dclick = false; altstunden = 0; } drehen = min_max_drehen(drehen, 1, 5); gaerrasten = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(19, 1); lcd.print(gaerrasten); #endif if (ButtonPressed) { modus = GAERSTARTTEMPERATUR; anfang = 0; } }// Ende funktion_gaerrastanzahl //--------------------------------------------------------------------------------- //Gärstarttemperatur //--------------------------------------------------------------------------------- void gaerstarttemperatur() //Modus = GAERSTARTTEMPERATUR { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Eingabe"); lcd.setCursor(0, 1); lcd.print("G"); lcd.print(char(0xE1)); lcd.print("rung Start: "); #endif drehen = gaerstart; first = true; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 0, 30); gaerstart = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(16, 1); lcd.print(gaerstart); lcd.print(char(0xDF)); lcd.print("C "); #endif if (ButtonPressed) { modus = GAERTEMPERATUREN; anfang = 0; } }// Ende gaerstarttemperatur //--------------------------------------------------------------------------------- // Wechsel Zeit-Temperatureingabe Gären //--------------------------------------------------------------------------------- void wechsel_gaer_temp_zeit() //Modus = WECHSEL_GAER_TEMP_ZEIT { altstunden = 0; stundenwert = 0; anfang = 0; if (x < gaerrasten) { x++; modus = GAERTEMPERATUREN; //Sprung zur Rasttemperatureingabe } else { x = 1; modus = ANSTELLTEMPERATUR; } }// Ende wechsel_gaer_temp_zeit //-------------------------------------------------------------------------------- //Rasteingabe Gärtemperatur //--------------------------------------------------------------------------------- void gaerrasteingabe() //Modus = GAERTEMPERATUREN { if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Eingabe"); #endif drehen = gaerRastTemp[x]; anfang = 1; dclick = false; } drehen = min_max_drehen(drehen, 0, 40); gaerRastTemp[x] = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(14, 0); lcd.print(x); lcd.print(".Rast"); lcd.setCursor(14, 1); lcd.print(uint8_t(gaerRastTemp[x])); lcd.print(char(0xDF)); lcd.print("C "); #endif if (ButtonPressed) { modus = GAERZEITEN; anfang = 0; } }// Ende gaerrasteingabe //--------------------------------------------------------------------------------- //Gärrasteingabe Zeit //--------------------------------------------------------------------------------- void gaerzeiteingabe() //Modus = GAERZEITEN { if ((anfang == 0) || (dclick)) { drehen = gaerRastZeit[x]; anfang = 1; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Eingabe Std."); lcd.setCursor(14, 0); lcd.print(x); lcd.print(".Rast"); lcd.setCursor(14, 1); lcd.print(uint8_t(gaerRastTemp[x])); lcd.print(char(0xDF)); lcd.print("C "); #endif dclick = false; } encoder->setAccelerationEnabled(true); drehen = min_max_drehen(drehen, 1, 255); gaerRastZeit[x] = drehen; #ifdef MitDisplayUndEncoder lcd.setCursor(14, 2); lcd.print(" "); lcd.setCursor(14, 2); lcd.print(uint8_t(gaerRastZeit[x])); lcd.print(" h"); #endif if (ButtonPressed) { encoder->setAccelerationEnabled(false); modus = WECHSEL_GAER_TEMP_ZEIT; anfang = 0; } } // Ende gaerzeiteingabe //--------------------------------------------------------------------------------- //Anlauf Anstelltemperatur //--------------------------------------------------------------------------------- void anlauf_anstelltemperatur() //Modus = ANSTELLTEMPERATUR { uint8_t altgaerstart = 0; if ((anfang == 0) || (dclick)) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Anstelltemperatur"); lcd.setCursor(9, 1); lcd.print("Soll:"); if (heizung == EIN){ lcd.setCursor(0, 3); lcd.print("Heizen");} #endif anfang = 1; dclick = false; if (notfall_aktiv) { if (EEPROMReadInt(notfallmodus) != 1) EEPROMWriteInt(notfallmodus, 1); //Notfallmodus aktiviert EEPROMWriteInt(rastmodus, modus); //für Notfall Modus merken gaerstart = EEPROM.read(MaischTemp); } drehen = gaerstart; //Zuordnung Encoder } drehen = min_max_drehen(drehen, 0, 40); gaerstart = drehen; if (notfall_aktiv) { if (gaerstart != altgaerstart) { altgaerstart = gaerstart; EEPROM.write(MaischTemp, gaerstart); } } sollwert = gaerstart; #ifdef MitDisplayUndEncoder lcd.setCursor(15, 1); lcd.print(sollwert); lcd.print(char(0xDF)); lcd.print("C "); #endif if ((isttemp >= (sollwert - gaerhysterese)) && (isttemp <= (sollwert + gaerhysterese))) // Sollwert erreicht ? { modus = ANLAUFGAERSTUFEN; anfang = 0; meldung_detail = "Anstelltemperatur_erreicht"; } } // Ende anlauf_anstelltemperatur //--------------------------------------------------------------------------------- //Anlauf Gärstufen //--------------------------------------------------------------------------------- void AnlaufGaerstufen() //Modus = ANLAUFGAERSTUFEN { if ((anfang == 0) || (dclick)) { if ((notmodus) && (neustart)) { x = RastNr; neustart = false; zeit_null_setzen = true; } #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Anlauf "); lcd.print(x); lcd.print(".G"); lcd.print(char(0xE1)); lcd.print("rrast"); lcd.setCursor(9, 1); lcd.print("soll: "); if (heizung == EIN){ lcd.setCursor(0, 3); lcd.print("Heizen");} #endif meldung_detail = "Anl._" + String(x) + "._Gaerstufe"; zeit_detail = "00:00"; minutenwert = 0; stundenwert = 0; drehen = gaerRastTemp[x]; anfang = 1; first = true; dclick = false; if (notfall_aktiv) { EEPROMWriteInt(rastmodus, modus); //für Notfall Modus merken EEPROM.write(rastnr, x); EEPROM.write(rasttemp_aktuell, gaerRastTemp[x]); EEPROM.write(rastzeit_aktuell, gaerRastZeit[x]); } } drehen = min_max_drehen(drehen, 0, 40); gaerRastTemp[x] = drehen; if (notfall_aktiv) { if (drehen != altdrehen) { altdrehen = drehen; EEPROM.write(rasttemp_aktuell, drehen); } } sollwert = gaerRastTemp[x]; #ifdef MitDisplayUndEncoder lcd.setCursor(15, 1); lcd.print(sollwert); lcd.print(char(0xDF)); lcd.print("C "); #endif if ((isttemp >= (sollwert - gaerhysterese)) && (isttemp <= (sollwert + gaerhysterese))) // Sollwert erreicht ? { modus = GAERZEITAUTOMATIK; anfang = 0; meldung_detail = "Gaertemperatur_erreicht"; } } // Ende AnlaufGaerstufen //--------------------------------------------------------------------------------- //Gaerzeitautomatik //--------------------------------------------------------------------------------- void gaerzeitautomatik() //Modus = GAERZEITAUTOMATIK { if ((anfang == 0) || (dclick)) { if ((notmodus) && (neustart)) { x = RastNr; neustart = false; } drehen = gaerRastZeit[x]; //Zuordnung für Encoder #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(9, 1); lcd.print("soll: "); lcd.print(sollwert); lcd.print(char(0xDF)); lcd.print("C "); if (heizung == EIN){ lcd.setCursor(0, 3); lcd.print("Heizen");} #endif meldung_detail = "Gaerzeitautomatik"; if (altx != x) { zeitz = true; altstunden = 0; stundenwert = 0; } if (notfall_aktiv) { Notfallmodus = EEPROMReadInt(notfallmodus); if (EEPROMReadInt(notfallmodus) != 1) EEPROMWriteInt(notfallmodus, 1); //Notfallmodus aktiviert EEPROM.write(Rasten, gaerrasten); EEPROM.write(MaischTemp, gaerstart); switch (gaerrasten) { case 1: { EEPROM.write(rastzeit_1, gaerRastZeit[1]); EEPROM.write(rasttemp_1, gaerRastTemp[1]); break; } case 2: { EEPROM.write(rastzeit_1, gaerRastZeit[1]); EEPROM.write(rasttemp_1, gaerRastTemp[1]); EEPROM.write(rastzeit_2, gaerRastZeit[2]); EEPROM.write(rasttemp_2, gaerRastTemp[2]); break; } case 3: { EEPROM.write(rastzeit_1, gaerRastZeit[1]); EEPROM.write(rasttemp_1, gaerRastTemp[1]); EEPROM.write(rastzeit_2, gaerRastZeit[2]); EEPROM.write(rasttemp_2, gaerRastTemp[2]); EEPROM.write(rastzeit_3, gaerRastZeit[3]); EEPROM.write(rasttemp_3, gaerRastTemp[3]); break; } case 4: { EEPROM.write(rastzeit_1, gaerRastZeit[1]); EEPROM.write(rasttemp_1, gaerRastTemp[1]); EEPROM.write(rastzeit_2, gaerRastZeit[2]); EEPROM.write(rasttemp_2, gaerRastTemp[2]); EEPROM.write(rastzeit_3, gaerRastZeit[3]); EEPROM.write(rasttemp_3, gaerRastTemp[3]); EEPROM.write(rastzeit_4, gaerRastZeit[4]); EEPROM.write(rasttemp_4, gaerRastTemp[4]); break; } case 5: { EEPROM.write(rastzeit_1, gaerRastZeit[1]); EEPROM.write(rasttemp_1, gaerRastTemp[1]); EEPROM.write(rastzeit_2, gaerRastZeit[2]); EEPROM.write(rasttemp_2, gaerRastTemp[2]); EEPROM.write(rastzeit_3, gaerRastZeit[3]); EEPROM.write(rasttemp_3, gaerRastTemp[3]); EEPROM.write(rastzeit_4, gaerRastZeit[4]); EEPROM.write(rasttemp_4, gaerRastTemp[4]); EEPROM.write(rastzeit_5, gaerRastZeit[5]); EEPROM.write(rasttemp_5, gaerRastTemp[5]); break; } } } } altx = x; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(x); lcd.print(".G"); lcd.print(char(0xE1)); lcd.print("rrast"); if (gaerRastZeit[x] < 10) { lcd.setCursor(14, 2); lcd.print(" "); lcd.print(uint8_t(gaerRastZeit[x])); lcd.print(" h"); } else { lcd.setCursor(14, 2); lcd.print(uint8_t(gaerRastZeit[x])); lcd.print(" h "); } #endif // Zeitzählung------------------------------------------------------------------ if (anfang == 0) { setTime(00, 00, 00, 00, 01, 01); //.........Sekunden auf 0 stellen if (zeit_setzen) { RastZeit_h = EEPROM.read(zeit_h); RastZeit_m = EEPROM.read(zeit_m); RastZeit_s = EEPROM.read(zeit_s); setTime(RastZeit_h, RastZeit_m, RastZeit_s, 00, 01, 01); zeit_setzen = false; } if (zeit_null_setzen) { zeit_null_setzen = false; setTime(00, 00, 00, 00, 01, 01); //.........Sekunden auf 0 stellen } #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print(" "); #endif anfang = 1; } sekunden = second(); //aktuelle Sekunde abspeichern für die Zeitrechnung minuten = minute(); //aktuelle Minute abspeichern für die Zeitrechnung stunden = hour(); //aktuelle Stunde abspeichern für die Zeitrechnung if (stunden != altstunden) { stundenwert++; altstunden = stunden; } #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); if (minuten < 10) { if (stundenwert == 0) { lcd.setCursor(1, 2); lcd.print("00:0"); lcd.print(minuten); } } else { if (stundenwert == 0) { lcd.setCursor(1, 2); lcd.print("00:"); lcd.print(minuten); } } if ((stundenwert < 10) && (stundenwert > 0)) { lcd.setCursor(1, 2); lcd.print("0"); lcd.print(stundenwert); lcd.print(":"); if (minuten < 10) { lcd.print("0"); lcd.print(minuten); } else lcd.print(minuten); } if ((stundenwert >= 10) && (stundenwert < 100)) { lcd.setCursor(1, 2); lcd.print(stundenwert); lcd.print(":"); if (minuten < 10) { lcd.print("0"); lcd.print(minuten); } else lcd.print(minuten); } if (stundenwert >= 100) { lcd.setCursor(0, 2); lcd.print(stundenwert); lcd.print(":"); if (minuten < 10) { lcd.print("0"); lcd.print(minuten); } else lcd.print(minuten); } #endif String mi_; String s; mi_ = String(minutenwert); s = String(stundenwert); if (minutenwert < 10) mi_ = "0" + String(minutenwert); //Aktuelle Zeit zum PC if (stundenwert < 10) s = "0" + String(stundenwert); zeit_detail = s + ":" + mi_; // Ende Zeitzählung--------------------------------------------------------------- //Zustand für den Fall von Stromausfall speichern--------------------------------- if (notfall_aktiv) { if ((minuten == 0) && (!gespeichert)) //einmal pro Stunde speichern { EEPROMWriteInt(rastmodus, modus); EEPROM.write(rastnr, x); EEPROM.write(Rasten, gaerrasten); EEPROM.write(rasttemp_aktuell, gaerRastTemp[x]); EEPROM.write(rastzeit_aktuell, gaerRastZeit[x]); EEPROM.write(zeit_h, stunden); EEPROM.write(zeit_m, minuten); EEPROM.write(zeit_s, sekunden); gespeichert = true; } if (minuten == 59) gespeichert = false; } drehen = min_max_drehen(drehen, 0, 255); gaerRastZeit[x] = drehen; //Encoderzuordnung if (stundenwert >= gaerRastZeit[x]) // Sollwert erreicht ? { anfang = 0; y = x; if (x < gaerrasten) { modus = ANLAUFGAERSTUFEN; // zur Temperaturregelung x++; // nächste Stufe } else { anfang = 0; modus = ABBRUCH; } } } // Ende gaerzeitautomatik //--------------------------------------------------------------------------------- //Lautstärke Brauerruf //--------------------------------------------------------------------------------- void sound_einstellen() { if (anfang == 0) { anfang = 1; B_EIN = EEPROM.read(sound); encoder->setAccelerationEnabled(true); //Geschwindigkeitsabhängigkeit beim Drehen des Encoders EIN drehen = B_EIN; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Ton: "); lcd.setCursor(0, 3); lcd.print("mit Taste speichern"); #endif } drehen = min_max_drehen(drehen, 0, 255); #ifdef MitDisplayUndEncoder lcd.setCursor(5, 0); lcd.print(drehen); lcd.print(" "); #endif B_EIN = drehen; RufEIN(false); if (ButtonPressed) { speichern(2); encoder->setAccelerationEnabled(false); //Geschwindigkeitsabhängigkeit beim Drehen des Encoders AUS if (EEPROM.read(sound) != B_EIN) EEPROM.write(sound, B_EIN); RufAUS(false); modus = SETUPMENUE; anfang = 0; } } // Ende sound_einstellen //--------------------------------------------------------------------------------- //Uhr und Timer stellen //--------------------------------------------------------------------------------- #ifdef RTC_Hardware void funktion_timer() //Modus : TIMER { if (anfang == 0) { DateTime uhrzeit = RTC.now(); #ifdef dbg Serial.println("Uhrzeit: "); Serial.print(uhrzeit.day(), DEC); Serial.print("."); Serial.print(uhrzeit.month(), DEC); Serial.print("."); Serial.println(uhrzeit.year(), DEC); Serial.print(uhrzeit.hour(), DEC); Serial.print(":"); Serial.print(uhrzeit.minute(), DEC); Serial.print(":"); Serial.println(uhrzeit.second(), DEC); #endif #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); if (uhrzeit.minute() > 9) { lcd.print("Aktuelle Zeit:"); lcd.print(uhrzeit.hour()); lcd.print(":"); lcd.print(uhrzeit.minute()); } else { lcd.print("Aktuelle Zeit:"); lcd.print(uhrzeit.hour()); lcd.print(":0"); lcd.print(uhrzeit.minute()); } lcd.setCursor(0, 1); if (uhrzeit.minute() < 10) { lcd.print("Start um: "); lcd.print(uhrzeit.hour()); lcd.print(":0"); lcd.print(uhrzeit.minute()); } else { lcd.print("Start um: "); lcd.print(uhrzeit.hour()); lcd.print(":"); lcd.print(uhrzeit.minute()); } #endif drehen = uhrzeit.hour(); anfang = 1; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("drehen = Std. einst."); #endif } if (anfang == 1) { encoder->setAccelerationEnabled(true); drehen = min_max_drehen(drehen, 0, 23); weckstunde = drehen; #ifdef MitDisplayUndEncoder if (drehen < 10) { lcd.setCursor(10, 1); lcd.print("0"); lcd.print(drehen); } else { lcd.setCursor(10, 1); lcd.print(drehen); } #endif } if (ButtonPressed && anfang == 1) { anfang = 2; ButtonPressed = false; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("drehen = Min. einst."); #endif DateTime uhrzeit = RTC.now(); drehen = uhrzeit.minute(); } if (anfang == 2) { encoder->setAccelerationEnabled(true); drehen = min_max_drehen(drehen, 0, 59); weckminute = drehen; #ifdef MitDisplayUndEncoder if (drehen < 10) { lcd.setCursor(13, 1); lcd.print("0"); lcd.print(drehen); } else { lcd.setCursor(13, 1); lcd.print(drehen); } #endif } if (ButtonPressed && anfang == 2) { encoder->setAccelerationEnabled(false); anfang = 3; ButtonPressed = false; #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Timer starten?"); #endif drehen = 1; } if (anfang == 3) { drehen %= 2; #ifdef MitDisplayUndEncoder lcd.setCursor(15, 0); lcd.print(j_n_drehen(drehen)); #endif } if (ButtonPressed && anfang == 3) { #ifdef MitDisplayUndEncoder if (drehen == 1) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Achtung!"); lcd.setCursor(0, 1); lcd.print("Rezept eingegeben?"); lcd.setCursor(0, 2); lcd.print("Brauw. im Kessel?"); lcd.setCursor(0, 3); lcd.print("Wasser aufbereitet?"); delay(5000); } #endif modus = HAUPTMENUE; anfang = 0; if (drehen == 1) { EEPROM.write(startstunde, weckstunde); EEPROM.write(startminute, weckminute); timeractiv = true; } else { EEPROM.write(startstunde, 255); EEPROM.write(startminute, 255); timeractiv = false; } } } //Ende funktion_timer #endif //--------------------------------------------------------------------------------- //Abbruch aktueller Modus //--------------------------------------------------------------------------------- void funktion_abbruch() // Modus = ABBRUCH { meldung = ""; meldung_detail = ""; regelung = AUS; HeizungAUS(); NachgussAUS(); RufAUS(true); ruf = false; UmwaelzerAUS(); #ifdef WUERZEPUMPE_AKTIV WuerzepumpeEinAus(0); #endif #ifdef funksteuerung mySwitch.send(funk_variabel_aus, 24); //unabhängig vom Einsatzzweck AUS #endif x = 1; //Rasteingaben y = 1; n = 0; nachgussruf = false; loggen = EEPROM.read(logging); //aktuellen Status von loggen setzen pause = 0; schwelle_erreicht = false; // für Kochbeginn Meldung first = true; zeitz = true; // Zeit läuft nach Doppelclick weiter wenn zeitz = false anfang = 0; //Daten zurücksetzen rufmodus = ABBRUCH; //bleiben erhalten drehen = sollwert; //Zuweisung für Funktion Temperaturregelung sollwert = 20; if (EEPROMReadInt(notfallmodus) == 1) { EEPROMWriteInt(notfallmodus, 0); //Notfallmodus deaktiviert EEPROM.write(zeit_h, 0); EEPROM.write(zeit_m, 0); EEPROM.write(zeit_s, 0); notmodus = false; } if (altmodus == KUEHLEN) { if (knot) knot = false; else knot = true; if (!knot) { meldung_detail = "NOT->EIN"; if (EEPROM.read(k_aktiv) != 1) EEPROM.write(k_aktiv, 1); //Beim Neustart in Modus 0 , bei Stromausfall in Modus (1) Kühlen if (EEPROMReadlong(g_kuehltemp) != drehen) EEPROMWritelong(g_kuehltemp, drehen); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("NOT->EIN"); meldung_detail = "NOT->EIN"; delay(1000); #endif } if (knot) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("NOT->AUS"); delay(1000); //Notstart zurücksetzen #endif meldung_detail = "NOT->AUS"; if (EEPROM.read(k_aktiv) == 1) EEPROM.write(k_aktiv, 0); } //nach Notfall- wieder Normalmodus } modus = HAUPTMENUE; //Hauptmenue rufmodus = HAUPTMENUE; altmodus = HAUPTMENUE; sondermodus = HAUPTMENUE; minutenwert = 0; stundenwert = 0; zeit_detail = ""; h = 0; //Hopfeneingaben altstunden = 0; fern = true; //Fernsteuerung Rührer AUS #ifdef RTC_Hardware if (modus != MAISCHEN_START) //Wenn Maischeplan eingegeben und Abbruch, dann den Timer nicht löschen { EEPROM.write(startstunde, 255); EEPROM.write(startminute, 255); timeractiv = false; } #endif #ifdef MitDisplayUndEncoder lcd.clear(); #endif } //Ende funktion_abbruch #ifdef bluetooth //--------------------------------------------------------------------------------- //Serielle Daten zum PC (KBH2AiO) //--------------------------------------------------------------------------------- void zum_pc() { String data; String mstartstunde; String mstartminute; //0 data = String(isttemp); //Isttemperatur data += ";"; //1 data += String(sollwert); //Solltemperatur data += ";"; //2 data += String(gradient); //Gradient data += ";"; //3 if (heizung == EIN) data += "1"; else data += "0"; data += ";"; //4 if (rwerk == 0) data += "0"; else data += "1"; data += ";"; //5 data += modus; data += ";"; //6 data += meldung; data += ";"; //7 data += meldung_detail; data += ";"; //8 #ifdef Tempsensor433 if (anzahlTempsensoren == 1) data += String(nachgusssensor); else data += "NC"; #else if (anzahlTempsensoren == 1) data += "NC"; else data += String(nachgusssensor); #endif data += ";"; //9 if (nachgussheizung == EIN) data += "1"; else data += "0"; data += ";"; //10 if (ruf) data += "1"; else data += "0"; data += ";"; //11 data += String(rastZeit[x]); data += ";"; //12 data += zeit_detail; data += ";"; //13 data += String(nachisomerisierung); data += ";"; //14 data += String(gaerRastZeit[x]); data += ";"; //15 data += String(kochzeit); data += ";"; #ifdef gassensor //16 data += String(PPM_LPG); data += ";"; #else //16 data += "0"; data += ";"; #endif #ifdef gassensor //17 if (alarm) data += "1"; else data += "0"; data += ";"; alarm = false; #else //17 data += "0"; data += ";"; #endif #ifdef RTC_Hardware //18 if (timeractiv) data += "1"; else data += "0"; data += ";"; #else data += "0"; data += ";"; #endif #ifdef RTC_Hardware //19 if (uint8_t(EEPROM.read(startstunde)) < 10) mstartstunde = "0" + String(EEPROM.read(startstunde)); else mstartstunde = String(EEPROM.read(startstunde)); if (uint8_t(EEPROM.read(startminute)) < 10) mstartminute = "0" + String(EEPROM.read(startminute)); else mstartminute = String(EEPROM.read(startminute)); data += mstartstunde + ":" + mstartminute; data += ";"; #else data += "00:00"; data += ";"; #endif #ifdef dbg Serial.print("Daten zum PC: "); Serial.println(data); //Com-Port-Datenübertragung #endif Serial2.println(data); Serial2.flush(); }//Ende zum_pc //--------------------------------------------------------------------------------- //Serielle-Daten (Bluetooth) zur AiO (KBH2AiO) //--------------------------------------------------------------------------------- void zurAiO(int16_t wait) { int16_t tpos = 2; String data; uint32_t wtime = millis(); antwort[0] = '-'; antwort[1] = ':'; while ((wtime + wait) > millis()) { while (Serial2.available()) { char c = Serial2.read(); if ((tpos < 500) && (c != '\n') && (c != '\r')) { antwort[tpos] = c; tpos++; } } antwort[tpos] = 0; } responce = String(antwort); #ifdef dbg Serial.println(responce); #endif if (modus == HAUPTMENUE) // Wenn vorher Abbruch gesendet wurde { if (responce.indexOf("m27") != -1) //Starte Maischen { modus = EINMAISCHEN; anfang = 0; signalton(quittungston); meldung_detail = "Maischprogramm-gestartet!"; if (notfall_aktiv) EEPROMWriteInt(notfallmodus, 1); else EEPROMWriteInt(notfallmodus, 0); return; } if (responce.indexOf("ng2") != -1) //Nachguss { if (splitSetup("ng2")) { signalton(quittungston); meldung_detail = "Nachguss_wird_aufgeheizt!"; } return; } if (responce.indexOf("m41") != -1) //Kochen { modus = STARTKOCHEN; anfang = 0; heizung = EIN; signalton(quittungston); meldung_detail = "Kochen-aufgerufen!"; #ifdef MitDisplayUndEncoder lcd.clear(); #endif return; } if (responce.indexOf("mk1") != -1) //Kühlen { if (splitSetup("mk1")) { signalton(quittungston); if (kuehlen) meldung_detail = "Kühlen-eingeschaltet"; else meldung_detail = "Heizen-eingeschaltet"; if (kuehlen) { EEPROM.write(heiz_kuehl, 1); } else { EEPROM.write(heiz_kuehl, 0); } } return; } #ifdef funksteuerung if (responce.indexOf("mx236") != -1) //Einlesen Funksteckdosen { modus = STECKDOSENCODE; anfang = 0; meldung_detail = "Funksteckdosencode-einlesen!"; signalton(quittungston); return; } #endif if (responce.indexOf("RPT") != -1) { //Rezept einlesen if (split()) { rezept_eingelesen = true; h = 0; meldung_detail = "RPT?"; signalton(quittungston); } return; } if (responce.indexOf("GFU") != -1) { //Gärplan einlesen if (gaersplit()) { meldung_detail = "Gärplan_erfolgreich_übertragen!"; signalton(quittungston); } return; } } #ifdef WUERZEPUMPE_AKTIV if (responce.indexOf("wpv3") > 0) //Würzepumpe einschalten { if (modus == HAUPTMENUE) { if (splitSetup("wpv3")) { signalton(quittungston); meldung_detail = "WPumpe_Verz_eing."; } } else meldung_detail = "In_diesem_Modus_nicht_möglich"; return; } if (responce.indexOf("m3P") != -1) //Würzepumpe Modus umschalten { modus = WUERZEPUMPE; anfang = 0; signalton(quittungston); meldung_detail = "Würzepumpe_aktiv"; if (manuell_ein) manuell_ein = false; else manuell_ein = true; return; } #endif if (responce.indexOf("mRPEA") != -1) //Rührer/Pumpe EIN/AUS { if ((modus == HAUPTMENUE) || (modus == EINMAISCHEN)) { signalton(quittungston); if (ruehrer) { if (!fern) { fern = true; if (umwaelzer_stat == EIN) UmwaelzerAUS(); } else { fern = false; if (umwaelzer_stat == AUS) UmwaelzerEIN(); } if (fern) meldung_detail = "Ruehrer/Pumpe_AUS"; else meldung_detail = "Ruehrer/Pumpe_EIN"; } else meldung_detail = "Nicht_möglich->MPumpe"; } else meldung_detail = "Im_Modus_nicht_möglich!"; return; } if (responce.indexOf("ms239") != -1) //Kochschwelle einstellen { if (splitSetup("ms239")) { meldung_detail = "Kochschwelle-eingestellt!"; signalton(quittungston); } return; } if (responce.indexOf("ngt239") != -1) //Nachgusstemperatur einstellen { if (splitSetup("ngt239")) { meldung_detail = "Nachgusstemperatur-eingestellt!"; signalton(quittungston); } return; } if (responce.indexOf("mt239") != -1) //Rührer/Pumpe konfigurieren { if (splitSetup("mt239")) { signalton(quittungston); meldung_detail = "Konfiguration-erfolgreich!"; } return; } if (responce.indexOf("mr11") != -1) //Regler konfigurieren { if (splitSetup("mr11")) { signalton(quittungston); meldung_detail = "Regler-konfiguriert!"; } return; } if (responce.indexOf("ms44") != -1) //Logging konfigurieren { if (splitSetup("ms44")) { meldung_detail = "Logging-konfiguriert!"; signalton(quittungston); } return; } if (responce.indexOf("ms46") != -1) //Notfall { if (splitSetup("ms46")) { if (notfall_aktiv) meldung_detail = "Notfallschaltung_aktiviert!"; else meldung_detail = "Notfallschaltung_deaktiviert!"; signalton(quittungston); } return; } #ifdef gassensor if (responce.indexOf("gas") > 0) //Alarmschwelle { if (splitSetup("gas")) { meldung_detail = "Alarmschwelle_eingestellt"; signalton(quittungston); } return; } #endif if (responce.indexOf("ms236") != -1) //3. Funksteckdose { if (splitSetup("ms236")) { meldung_detail = "3_Funksteckdose_konf."; signalton(quittungston); } return; } if (responce.indexOf("ms8") != -1) //Lautstärke Brauerruf { #ifdef dbg Serial.println(responce); #endif if (splitSetup("ms8")) { meldung_detail = "Brauerruf_Test"; signalton(quittungston); } return; } if (responce.indexOf("mss8") != -1) //Lautstärke Brauerruf speichern { #ifdef dbg Serial.println(responce); #endif if (splitSetup("mss8")) { meldung_detail = "Brauerruf_eingestellt"; signalton(quittungston); } return; } if (responce.indexOf("msz") != -1) //Verlängerung Rastzeit { #ifdef dbg Serial.println(responce); #endif if (splitSetup("msz")) { meldung_detail = "Rastzeit_verändert"; signalton(quittungston); } return; } if (responce.indexOf("mst") > 0) //Verlängerung Rasttemperatur { #ifdef dbg Serial.println(responce); #endif if (splitSetup("mst")) { meldung_detail = "Solltemp_verändert"; signalton(quittungston); } return; } if (responce.indexOf("mKUEP") > 0) //Erhöhung Kühltemperatur { #ifdef dbg Serial.println(responce); #endif drehen++; meldung_detail = "Kuehl-/Heiztemp_verändert"; EEPROMWritelong(g_kuehltemp, drehen); signalton(quittungston); return; } if (responce.indexOf("mKUEM") > 0) //Kühltemperatur verkleinern { #ifdef dbg Serial.println(responce); #endif drehen--; meldung_detail = "Kuehl-/Heiztemp_verändert"; EEPROMWritelong(g_kuehltemp, drehen); signalton(quittungston); return; } #ifdef RTC_Hardware if (responce.indexOf("ti9") != -1) //Timer initialisieren { #ifdef dbg Serial.println(responce); #endif if (splitSetup("ti9")) { meldung_detail = "Timer_initialisiert"; timeractiv = true; signalton(quittungston); } return; } #endif if (responce.indexOf("m31") != -1) //Ruf quittieren { responce = ""; if (modus != EINMAISCHEN) { meldung_detail = "Ruf-quittiert!"; rufquittung = true; ruf = false; signalton(quittungston); rufmodus = modus; modus = RUFALARM; if (altmodus == STARTKOCHEN) anfang = 3; if (altmodus == ENDTEMPERATURAUTOMATIK) modus = ABBRUCH; if (altmodus == NACHGUSS) modus = NACHGUSS; if (altmodus == HAUPTMENUE) modus = HAUPTMENUE; if (altmodus == GAERZEITAUTOMATIK) modus = GAERZEITAUTOMATIK; if (altmodus == ANLAUFGAERSTUFEN) modus = ANLAUFGAERSTUFEN; RufAUS(true); } return; } if (responce.indexOf("m42") != -1) //Kochen Start { modus = KOCHEN; //meldung_detail = "Kochen-gestartet"; anfang = 0; signalton(quittungston); return; } if (responce.indexOf("m80") != -1) //Abbruch { modus = ABBRUCH; anfang = 0; meldung_detail = "Abbruch"; signalton(quittungston); return; } if (responce.indexOf("m250") != -1) //Gärführung { modus = ANSTELLTEMPERATUR; anfang = 0; meldung_detail = "Gärführung-gestartet"; signalton(quittungston); return; } if (responce.indexOf("set") != -1) //Setup zur AiO { Setup_zum_pc(); return; } if (modus == HAUPTMENUE) //Rührer/Pumpe Dauerlauf { if (responce.indexOf("mmazp") != -1) { signalton(quittungston); if (!malzrohrpumpe_dauerbetrieb) { #ifdef funksteuerung delay(funkdelay); mySwitch.send(funk_umwaelzer_ein, 24); #endif #ifdef relaissteuerung digitalWrite(UmwaelzR2, R_EIN); digitalWrite(UmwaelzR1, R_EIN); #endif malzrohrpumpe_dauerbetrieb = true; meldung_detail = "Pumpe/Ruehrer-Dauerbetrieb"; } else { #ifdef funksteuerung delay(funkdelay); mySwitch.send(funk_umwaelzer_aus, 24); #endif #ifdef relaissteuerung digitalWrite(UmwaelzR2, R_AUS); digitalWrite(UmwaelzR1, R_AUS); #endif malzrohrpumpe_dauerbetrieb = false; meldung_detail = "Pumpe/Ruehrer-Dauerbetrieb-AUS"; } } } #ifdef geschwindigkeitsrelais if ((modus == MAISCHEN_START) || (modus == EINMAISCHEN) || (modus == TEMPERATURAUTOMATIK) || (modus == ZEITAUTOMATIK) || (modus == ENDTEMPERATURAUTOMATIK)) if (responce.indexOf("spe") != -1) //Rührer Geschwindigkeit ändern if (ruehrer) if (geschwindigkeitsrel) { meldung = "Rührer_Geschwindigkeit"; if (highspeed) { digitalWrite(Speedrelais, LOW_SPEED); meldung_detail = "Rührer_Low_Speed"; } else { digitalWrite(Speedrelais, HIGH_SPEED); meldung_detail = "Rührer_High_Speed"; } signalton(quittungston); highspeed = !highspeed; } else meldung_detail = "Speedrelais_inaktiv"; #endif } //Ende zurAiO #else //--------------------------------------------------------------------------------- //UDP-Daten zum PC (KBH2AiO) //--------------------------------------------------------------------------------- void zum_pc() { String data; String mstartstunde; String mstartminute; //0 data = String(isttemp); //Isttemperatur data += ";"; //1 data += String(sollwert); //Solltemperatur data += ";"; //2 data += String(gradient); //Gradient data += ";"; //3 if (heizung == EIN) data += "1"; else data += "0"; data += ";"; //4 if (rwerk == 0) data += "0"; else data += "1"; data += ";"; //5 data += modus; data += ";"; //6 data += meldung; data += ";"; //7 data += meldung_detail; data += ";"; if (meldung_detail == "RPT?") meldung_detail = ""; //8 #ifdef Tempsensor433 if (anzahlTempsensoren == 1) data += String(nachgusssensor); else data += "NC"; #else if (anzahlTempsensoren == 1) data += "NC"; else data += String(nachgusssensor); #endif data += ";"; //9 if (nachgussheizung == EIN) data += "1"; else data += "0"; data += ";"; //10 if (ruf) data += "Ruf"; data += ";"; //11 data += String(rastZeit[x]); data += ";"; //12 data += zeit_detail; data += ";"; //13 data += String(nachisomerisierung); data += ";"; //14 data += String(gaerRastZeit[x]); data += ";"; //15 data += String(kochzeit); data += ";"; #ifdef gassensor //16 data += String(PPM_LPG); data += ";"; #else //16 data += "0"; data += ";"; #endif #ifdef gassensor //17 if (alarm) data += "1"; else data += "0"; data += ";"; alarm = false; #else data += "0"; data += ";"; #endif //18 #ifdef RTC_Hardware if (timeractiv) data += "1"; else data += "0"; data += ";"; #else data += "0"; data += ";"; #endif #ifdef RTC_Hardware //19 if (timeractiv) { if (uint8_t(EEPROM.read(startstunde)) < 10) mstartstunde = "0" + String(EEPROM.read(startstunde)); else mstartstunde = String(EEPROM.read(startstunde)); if (uint8_t(EEPROM.read(startminute)) < 10) mstartminute = "0" + String(EEPROM.read(startminute)); else mstartminute = String(EEPROM.read(startminute)); data += mstartstunde + ":" + mstartminute; } else data += "00:00"; data += ";"; #else data += "00:00"; data += ";"; #endif Serial2.print("AT+CIPSEND=4,"); //Sende Messdaten Serial2.println(data.length() + 2); delay(50); if (Serial2.find('>')) { //ESP8266 sendebereit Serial2.print(data); //abschicken Serial2.print("\r\n"); #ifdef dbg Serial.println(data); #endif } }//Ende zum_pc //--------------------------------------------------------------------------------- //UDP-Daten zur AiO (KBH2AiO) //--------------------------------------------------------------------------------- void zurAiO(uint16_t wait) { uint16_t tpos = 0; String data; uint32_t wtime = millis(); while ((wtime + wait) > millis()) { while (Serial2.available()) { char c = Serial2.read(); if ((tpos < 500) && (c != '\n') && (c != '\r')) { antwort[tpos] = c; tpos++; } } antwort[tpos] = 0; } responce = String(antwort); #ifdef dbg Serial.println(responce); #endif if (modus == HAUPTMENUE) // Wenn vorher Abbruch gesendet wurde { if (responce.indexOf("m27") > 0) //Starte Maischen { #ifdef MitDisplayUndEncoder lcd.clear(); #endif modus = EINMAISCHEN; anfang = 0; signalton(quittungston); meldung_detail = "Maischprogramm-gestartet!"; return; } if (responce.indexOf("ng2") > 0) //Nachguss { #ifdef MitDisplayUndEncoder lcd.clear(); #endif if (splitSetup("ng2")) { signalton(quittungston); meldung_detail = "Nachguss_wird_aufgeheizt!"; } return; } if (responce.indexOf("m41") > 0) //Kochen { #ifdef MitDisplayUndEncoder lcd.clear(); #endif modus = STARTKOCHEN; dclick = false; anfang = 0; heizung = EIN; signalton(quittungston); meldung_detail = "Kochen-aufgerufen!"; return; } if (responce.indexOf("mk1") > 0) //Kühlen { #ifdef MitDisplayUndEncoder lcd.clear(); #endif if (splitSetup("mk1")) { signalton(quittungston); if (kuehlen) meldung_detail = "Kühlen-eingeschaltet"; else meldung_detail = "Heizen-eingeschaltet"; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("Modus = "); #endif if (kuehlen) { #ifdef MitDisplayUndEncoder lcd.print("K"); lcd.print(char(0xF5)); lcd.print("hlen"); #endif EEPROM.write(heiz_kuehl, 1); } else { #ifdef MitDisplayUndEncoder lcd.print("Heizen"); #endif EEPROM.write(heiz_kuehl, 0); } } return; } #ifdef funksteuerung if (responce.indexOf("mx236") > 0) //Einlesen Funksteckdosen { #ifdef MitDisplayUndEncoder lcd.clear(); #endif modus = STECKDOSENCODE; anfang = 0; meldung_detail = "Funksteckdosencode-einlesen!"; signalton(quittungston); return; } #endif if (responce.indexOf("RPT") > 0) { //Rezept einlesen if (split()) { rezept_eingelesen = true; h = 0; meldung_detail = "RPT?"; signalton(quittungston); } return; } if (responce.indexOf("GFU") > 0) { //Gärplan einlesen if (gaersplit()) { meldung_detail = "Gärplan_erfolgreich_übertragen!"; signalton(quittungston); } return; } } #ifdef WUERZEPUMPE_AKTIV if (responce.indexOf("wpv3") > 0) //Würzepumpe einschalten { if (modus == HAUPTMENUE) { if (splitSetup("wpv3")) { signalton(quittungston); meldung_detail = "WPumpe_Verz_eing."; } } else meldung_detail = "In_diesem_Modus_nicht_möglich"; return; } if (responce.indexOf("m3P") > 0) //Würzepumpe einschalten { #ifdef MitDisplayUndEncoder lcd.clear(); #endif modus = WUERZEPUMPE; anfang = 0; signalton(quittungston); meldung_detail = "Würzepumpe_aktiv"; if (manuell_ein) manuell_ein = false; else manuell_ein = true; return; } #endif if (responce.indexOf("mRPEA") != -1) //Rührer/Pumpe EIN/AUS { if ((modus == HAUPTMENUE) || (modus == EINMAISCHEN)) { signalton(quittungston); if (ruehrer) { if (!fern) { fern = true; if (umwaelzer_stat == EIN) UmwaelzerAUS(); } else { fern = false; if (umwaelzer_stat == AUS) UmwaelzerEIN(); } if (fern) meldung_detail = "Ruehrer/Pumpe_AUS"; else meldung_detail = "Ruehrer/Pumpe_EIN"; } else meldung_detail = "Nicht_möglich->MPumpe"; } else meldung_detail = "Im_Modus_nicht_möglich!"; return; } if (responce.indexOf("ms239") > 0) //Kochschwelle einstellen { if (splitSetup("ms239")) { meldung_detail = "Kochschwelle-eingestellt!"; signalton(quittungston); } return; } if (responce.indexOf("mt239") > 0) //Rührer/Pumpe konfigurieren { if (splitSetup("mt239")) { signalton(quittungston); meldung_detail = "Konfiguration-erfolgreich!"; } return; } if (responce.indexOf("mr11") > 0) //Regler konfigurieren { if (splitSetup("mr11")) { signalton(quittungston); meldung_detail = "Regler-konfiguriert!"; } return; } if (responce.indexOf("ms44") > 0) //Logging konfigurieren { if (splitSetup("ms44")) { meldung_detail = "Logging-konfiguriert!"; signalton(quittungston); } return; } if (responce.indexOf("ms46") > 0) //Notfall { if (splitSetup("ms46")) { meldung_detail = "Notfallschaltung_aktiviert!"; signalton(quittungston); } return; } #ifdef gassensor if (responce.indexOf("gas") > 0) //Alarmschwelle { if (splitSetup("gas")) { meldung_detail = "alarmschwelle_eingestellt"; signalton(quittungston); } return; } #endif if (responce.indexOf("ms236") > 0) //3. Funksteckdose { if (splitSetup("ms236")) { meldung_detail = "3_Funksteckdose_konf."; signalton(quittungston); } return; } if (responce.indexOf("ms8") != -1) //Lautstärke Brauerruf { #ifdef dbg Serial.println(responce); #endif if (splitSetup("ms8")) { meldung_detail = "Brauerruf_Test"; signalton(quittungston); } return; } if (responce.indexOf("mss8") != -1) //Lautstärke Brauerruf speichern { #ifdef dbg Serial.println(responce); #endif if (splitSetup("mss8")) { meldung_detail = "Brauerruf_eingestellt"; signalton(quittungston); } return; } if (responce.indexOf("msz") > 0) //Verlängerung Rastzeit { #ifdef dbg Serial.println(responce); #endif if (splitSetup("msz")) { meldung_detail = "Rastzeit_verändert"; signalton(quittungston); } return; } if (responce.indexOf("mst") > 0) //Verlängerung Rasttemperatur { #ifdef dbg Serial.println(responce); #endif if (splitSetup("mst")) { meldung_detail = "Solltemp_verändert"; signalton(quittungston); } return; } if (responce.indexOf("mKUEP") > 0) //Erhöhung Kühltemperatur { #ifdef dbg Serial.println(responce); #endif drehen++; meldung_detail = "Kuehl-/Heiztemp_verändert"; EEPROMWritelong(g_kuehltemp, drehen); signalton(quittungston); return; } if (responce.indexOf("mKUEM") > 0) //Kühltemperatur verkleinern { #ifdef dbg Serial.println(responce); #endif drehen--; meldung_detail = "Kuehl-/Heiztemp_verändert"; EEPROMWritelong(g_kuehltemp, drehen); signalton(quittungston); return; } #ifdef RTC_Hardware if (responce.indexOf("ti9") != -1) //Timer initialisieren { #ifdef dbg Serial.println(responce); #endif if (splitSetup("ti9")) { meldung_detail = "Timer_initialisiert"; timeractiv = true; signalton(quittungston); } return; } #endif if (responce.indexOf("m31") > 0) //Ruf quittieren { responce = ""; meldung_detail = "Ruf-quittiert!"; rufquittung = true; ruf = false; signalton(quittungston); rufmodus = modus; modus = RUFALARM; if (altmodus == STARTKOCHEN) anfang = 3; if (altmodus == ENDTEMPERATURAUTOMATIK) modus = ABBRUCH; if (altmodus == NACHGUSS) modus = NACHGUSS; if (altmodus == HAUPTMENUE) modus = HAUPTMENUE; if (altmodus == GAERZEITAUTOMATIK) modus = GAERZEITAUTOMATIK; if (altmodus == ANLAUFGAERSTUFEN) modus = ANLAUFGAERSTUFEN; RufAUS(true); return; } if (responce.indexOf("m42") > 0) //Kochen Start { modus = KOCHEN; // meldung_detail = "Kochen-gestartet"; anfang = 0; signalton(quittungston); return; } if (responce.indexOf("m80") > 0) //Abbruch { modus = ABBRUCH; anfang = 0; meldung_detail = "Abbruch"; signalton(quittungston); return; } if (responce.indexOf("m250") > 0) //Gärführung { modus = ANSTELLTEMPERATUR; anfang = 0; meldung_detail = "Gärführung-gestartet"; signalton(quittungston); return; } if (responce.indexOf("set") > 0) //Setup zur AiO { Setup_zum_pc(); return; } if (modus == HAUPTMENUE) //Pumpe/Rührer Dauerlauf { if (responce.indexOf("mmazp") > 0) { signalton(quittungston); if (!malzrohrpumpe_dauerbetrieb) { if (umwaelzer_stat == AUS) UmwaelzerEIN(); malzrohrpumpe_dauerbetrieb = true; meldung_detail = "Pumpe/Ruehrer-Dauerbetrieb"; } else { if (umwaelzer_stat == EIN) UmwaelzerAUS(); malzrohrpumpe_dauerbetrieb = false; meldung_detail = "Pumpe/Ruehrer-Dauerbetrieb-AUS"; } } } #ifdef geschwindigkeitsrelais if ((modus == MAISCHEN_START) || (modus == EINMAISCHEN) || (modus == TEMPERATURAUTOMATIK) || (modus == ZEITAUTOMATIK) || (modus == ENDTEMPERATURAUTOMATIK)) if (responce.indexOf("spe") > 0) //Rührer Geschwindigkeit ändern if (ruehrer) { meldung = "Rührer_Geschwindigkeit"; if (highspeed) { digitalWrite(Speedrelais, LOW_SPEED); ruehrerspeed = 0; meldung_detail = "Rührer_Low_Speed"; } else { digitalWrite(Speedrelais, HIGH_SPEED); ruehrerspeed = 1; meldung_detail = "Rührer_High_Speed"; } signalton(quittungston); highspeed = !highspeed; } else meldung_detail = "Speedrelais_inaktiv"; #endif } //Ende zurAiO #endif #ifdef bluetooth #ifdef MitDisplayUndEncoder //--------------------------------------------------------------------------------- //Bluetooth-Logo erstellen //--------------------------------------------------------------------------------- void BluetoothChar(uint8_t x, uint8_t y) { uint8_t BT_ROU[8] = { B1000, B1100, B1010, B1001, B1010, B1100, B1000, B00000 }; uint8_t BT_LO[8] = { B000, B000, B000, B10000, B1000, B100, B10, B1 }; uint8_t BT_LU[8] = { B1, B10, B100, B1000, B10000, B000, B000, B000 }; lcd.createChar(0, BT_ROU); lcd.createChar(1, BT_LO); lcd.createChar(2, BT_LU); lcd.setCursor(y, x); lcd.write(uint8_t(1)); lcd.setCursor(y + 1, x); lcd.write(uint8_t(0)); lcd.setCursor(y, x + 1); lcd.write(uint8_t(2)); lcd.setCursor(y + 1, x + 1); lcd.write(uint8_t(0)); } // Ende BluetoothChar #endif #endif #ifdef funksteuerung #ifdef dbg static const char *bin2tristate(const char *bin) { static char returnValue[50]; uint16_t pos = 0; uint16_t pos2 = 0; while (bin[pos] != '\0' && bin[pos + 1] != '\0') { if (bin[pos] == '0' && bin[pos + 1] == '0') { returnValue[pos2] = '0'; } else if (bin[pos] == '1' && bin[pos + 1] == '1') { returnValue[pos2] = '1'; } else if (bin[pos] == '0' && bin[pos + 1] == '1') { returnValue[pos2] = 'F'; } else { return "not applicable"; } pos = pos + 2; pos2++; } returnValue[pos2] = '\0'; return returnValue; } //Ende bin2tristate static char *dec2binWzerofill(int32_t Dec, int16_t bitLength) { static char bin[64]; int16_t t i = 0; while (Dec > 0) { bin[32 + i++] = ((Dec & 1) > 0) ? '1' : '0'; Dec = Dec >> 1; } for (int16_t j = 0; j < bitLength; j++) { if (j >= bitLength - i) { bin[j] = bin[31 + i - (j - (bitLength - i))]; } else { bin[j] = '0'; } } bin[bitLength] = '\0'; return bin; } //Ende dec2binWzerofill #endif #endif //Ende Funktionen------------------------------------------------------------------ //setup============================================================================================================== void setup() { //------------------------------------------------------------------------------- //Serial Monitor mit 115200 Bd //------------------------------------------------------------------------------- #ifdef dbg Serial.begin(115200); #endif //------------------------------------------------------------------------------- //Datentransfer zu KBH2AiO via UDP oder Bluetooth? //------------------------------------------------------------------------------- #ifdef bluetooth kbh2aio = EEPROM.read(Bluetooth); if (kbh2aio == 0) bluetooth_steuerung = false; else { Serial2.begin(115200); connectBluetooth(); } #else kbh2aio = EEPROM.read(Wlan); if (kbh2aio == 0) wlan_steuerung = false; else { wlan_steuerung = true; Serial2.begin(115200); wlanAktiv = true; connectWiFi(); } #endif //------------------------------------------------------------------------------- //LCD Setup (abhängig von der verwendeten Library) //------------------------------------------------------------------------------- #ifdef MitDisplayUndEncoder lcd.backlight(); //neuere Library lcd.begin(20, 4); //neuere Library //lcd.init(); //20 Spalten und 4 Zeilen //alte Library #endif //------------------------------------------------------------------------------- //wenn RTC Modul (DS1307/DS3231) - DS3231 ist zu bevorzugen! //------------------------------------------------------------------------------- #ifdef RTC_Hardware RTC.begin(); // RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); //Initialisierung über die Rechnerzeit #endif #ifdef dbg #ifdef RTC_Hardware if (!RTC.isrunning()) { Serial.println("RTC nicht gefunden!"); } else Serial.println("RTC gefunden!"); #endif #endif //------------------------------------------------------------------------------- //Ausgabe Steckdosencode im Serial Monitor //------------------------------------------------------------------------------- #ifdef funksteuerung #ifdef dbg Serial.println("Steckdosencodierung ------------------------------------------------"); Serial.println(); Serial.println(" DEC HEX BIN"); Serial.print("Heizung EIN: "); Serial.print(EEPROMReadlong(Heizung_EIN)); Serial.print(" / "); Serial.print(EEPROMReadlong(Heizung_EIN), HEX); Serial.print(" / "); Serial.println(EEPROMReadlong(Heizung_EIN), BIN); Serial.print("Heizung AUS: "); Serial.print(EEPROMReadlong(Heizung_AUS)); Serial.print(" / "); Serial.print(EEPROMReadlong(Heizung_AUS), HEX); Serial.print(" / "); Serial.println(EEPROMReadlong(Heizung_AUS), BIN); Serial.print("Mischer EIN: "); Serial.print(EEPROMReadlong(Umwaelz_EIN)); Serial.print(" / "); Serial.print(EEPROMReadlong(Umwaelz_EIN), HEX); Serial.print(" / "); Serial.println(EEPROMReadlong(Umwaelz_EIN), BIN); Serial.print("Mischer AUS: "); Serial.print(EEPROMReadlong(Umwaelz_AUS)); Serial.print(" / "); Serial.print(EEPROMReadlong(Umwaelz_AUS), HEX); Serial.print(" / "); Serial.println(EEPROMReadlong(Umwaelz_AUS), BIN); Serial.print("Ruf/Nachguss EIN: "); Serial.print(EEPROMReadlong(Nachguss_EIN)); Serial.print(" / "); Serial.print(EEPROMReadlong(Nachguss_EIN), HEX); Serial.print(" / "); Serial.println(EEPROMReadlong(Nachguss_EIN), BIN); Serial.print("Ruf/Nachguss AUS: "); Serial.print(EEPROMReadlong(Nachguss_AUS)); Serial.print(" / "); Serial.print(EEPROMReadlong(Nachguss_AUS), HEX); Serial.print(" / "); Serial.println(EEPROMReadlong(Nachguss_AUS), BIN); Serial.println(); Serial.println(); Serial.println("Steckdosencodierung Ende--------------------------------------------"); //------------------------------------------------------------------------------------ #endif #endif //------------------------------------------------------------------------------- //Lautstärke des Brauerrufs einlesen //------------------------------------------------------------------------------- B_EIN = EEPROM.read(sound); //------------------------------------------------------------------------------- //Voreingestellte Kühltemperatur //------------------------------------------------------------------------------- if (EEPROMReadlong(g_kuehltemp) > 40) EEPROMWritelong(g_kuehltemp, 40); //------------------------------------------------------------------------------- //Ist externes Logging aktiv? //------------------------------------------------------------------------------- if (EEPROM.read(logging) == 1) Serial.begin(115200); //------------------------------------------------------------------------------- //Instanz Clickencoder //------------------------------------------------------------------------------- drehen = sollwert; encoder = new ClickEncoder(pinB, pinA, taster, STEPSPERNOTCH); //------------------------------------------------------------------------------- //Temperatur-Funksensor angeschlossen? //------------------------------------------------------------------------------- #ifdef Tempsensor433 //wenn mit Funksender dann Timer3 Timer3.initialize(1000); Timer3.attachInterrupt(timerIsr); Timer3.disablePwm(char(pinA)); Timer3.disablePwm(char(pinB)); funksensor = true; vw_set_tx_pin(sender); vw_set_rx_pin(empfaengerPin); vw_setup(2000); // Bits/sec vw_rx_start(); // Start des Empfaengers #else Timer1.initialize(1000); //sonst Timer1 Timer1.attachInterrupt(timerIsr); #endif //------------------------------------------------------------------------------- //433 MHz-Sender initialisieren //------------------------------------------------------------------------------- #ifdef funksteuerung mySwitch.enableTransmit(sender); // mySwitch.setProtocol(1, 320); //Protocol 1 - pulselength 320 mySwitch.setRepeatTransmit(RESEND_SNIFFED_VALUES); //Senden wiederholen init_funk(); //Funkruf oder Nachgussbereitung wahl = EEPROM.read(dritte_funksteckdose); if (wahl == 1) funkruf = true; else funkruf = false; #endif //------------------------------------------------------------------------------- //Relais den Arduino-Ports zuordnen //------------------------------------------------------------------------------- #ifdef relaissteuerung pinMode(HeizungR1, OUTPUT); pinMode(HeizungR2, OUTPUT); digitalWrite(HeizungR1, H_AUS); //Heizung aus digitalWrite(HeizungR2, H_AUS); pinMode(UmwaelzR1, OUTPUT); pinMode(UmwaelzR2, OUTPUT); digitalWrite(UmwaelzR1, R_AUS); //Mischer (Umwälzer) AUS digitalWrite(UmwaelzR2, R_AUS); pinMode(NachgussR1, OUTPUT); pinMode(NachgussR2, OUTPUT); digitalWrite(NachgussR1, NG_AUS); //Nachgussrelais aus digitalWrite(NachgussR2, NG_AUS); //für Hinweis im Display +++++++++++++++++++++++++++ if (H_AUS == LOW) hinweis = "Relais: AUS->LOW"; else hinweis = "Relais : AUS->HIGH"; #endif //------------------------------------------------------------------------------- //Modus des PINs RufR (Brauerruf) //------------------------------------------------------------------------------- pinMode(RufR, OUTPUT); ruf = false; //------------------------------------------------------------------------------- //Wurde eine Würzepumpe verbaut (Läutergrant -> Läuterbottich) //Pinzuweisung //------------------------------------------------------------------------------- #ifdef WUERZEPUMPE_AKTIV pinMode(fuellstand_sensor, INPUT_PULLUP); pinMode(fuellstand_pumpe, OUTPUT); WuerzepumpeEinAus(0); //ausgeschaltet #endif //------------------------------------------------------------------------------- //Wenn ein Geschwindigkeitsrelais verbaut wurde (Scheibenwischermotor 2 Stufen) //dann hier den PIN zuweisen //------------------------------------------------------------------------------- #ifdef geschwindigkeitsrelais pinMode(Speedrelais, OUTPUT); digitalWrite(Speedrelais, LOW_SPEED); //Normale Geschwindigkeit als Voreinstellung highspeed = false; #endif //------------------------------------------------------------------------------- //Wenn ein Gassensor angschlossen ist //------------------------------------------------------------------------------- #ifdef gassensor pinMode(analogpin, INPUT_PULLUP); #endif //------------------------------------------------------------------------------- //Stabilisierung des Encoders //------------------------------------------------------------------------------- digitalWrite(pinA, HIGH); //PullUp-Widerstand einschalten digitalWrite(pinB, HIGH); //PullUp-Widerstand einschalten last = -1; //Hilfsvariable Drehgeber //------------------------------------------------------------------------------- //Temperatursensor DS18B20 initialisieren und Anzahl der Sensoren abfragen //------------------------------------------------------------------------------- sensors.getAddress(insideThermometer, 0); //Thermometer Maischen, Kochen etc. sensors.getAddress(insideThermometer, 1); //Thermometer Nachguus (Heizlücke füllen!) sensors.setResolution(insideThermometer, 12); //Auflösung 12 BIT (allerdings keine höhere Genauigkeit (+-0,5K) sensors.requestTemperatures(); // Temperatur holen sensorwert = sensors.getTempCByIndex(0); //Überprüfung des Maischesensors if (int8_t(sensorwert) != -127) //wenn keine Störung vorliegt { sensorwert = sensors.getTempCByIndex(1); //Nachgusssensor vorhanden? if (int8_t(sensorwert != -127)) anzahlTempsensoren = 2; else anzahlTempsensoren = 1; //wenn Nachgusssensor vorhanden, dann Anzahl Sensoren = 2 } else anzahlTempsensoren = 0; //wenn Fehler Maischesensor, dann kein Sensor aktiv //------------------------------------------------------------------------------ //Startanzeige im Display //------------------------------------------------------------------------------ #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print(AiOversion); #ifdef bluetooth BluetoothChar(2, 10); #else lcd.setCursor(0, 1); lcd.print("UDP-Version"); #endif #ifdef relaissteuerung lcd.setCursor(0, 1); lcd.print(hinweis); lcd.setCursor(0, 2); lcd.print("R"); #endif #ifdef funksteuerung lcd.setCursor(0, 3); lcd.print("F"); #endif if (EEPROM.read(notfall)) { lcd.setCursor(17, 3); lcd.print("NOT"); } #endif RufEIN(false); delay(2000); //Rufdauer 2 sec. RufAUS(false); delay(2000); //Startanzeige insges. 4 sec. #ifdef MitDisplayUndEncoder lcd.clear(); #endif //allererster Start des Arduino--------------------------------------------------- init_start(); //-------------------------------------------------------------------------------- //------------------------------------------------------------------------------ //Mischer (Rührer/Pumpe) - Parameter einlesen //------------------------------------------------------------------------------ if (EEPROM.read(udauer) == 0) dauerbetrieb = 'N'; else dauerbetrieb = 'J'; intervalEin = EEPROM.read(umwaelzer_ie); intervalAus = EEPROM.read(umwaelzer_ia); if (intervalEin == 0) (intervalEin = 60); if (intervalAus == 0) (intervalAus = 15); //------------------------------------------------------------------------------ //Kochschwelle einlesen //------------------------------------------------------------------------------ kschwelle = EEPROM.read(Kochschwelle); if (kschwelle == 0) (kschwelle = 98); //Vorgabe wenn noch nichts im EEPROM //------------------------------------------------------------------------------ //Wiedereinschaltverzögerung Heizungsrelais //Begrenzung auf max. 100s //------------------------------------------------------------------------------ if (EEPROMReadlong(wein_h) > 100000) EEPROMWritelong(wein_h, 10000); esvheizen = EEPROMReadlong(wein_h); //------------------------------------------------------------------------------ //Wiedereinschaltverzögerung Kühlung //Begrenzung auf max. 300s //------------------------------------------------------------------------------ if (EEPROMReadlong(kuehlverz) > 300000) EEPROMWritelong(kuehlverz, 300000); kzeitverz = EEPROMReadlong(kuehlverz); //------------------------------------------------------------------------------ //Gradientenfaktor HEIZEN - Begrenzung auf 10 //------------------------------------------------------------------------------ if (EEPROMReadlong(graf_h) > 100) EEPROMWritelong(graf_h, gfh * 10); //Vorgabewert Gradientenfaktor für Heizen gfh = EEPROMReadlong(graf_h) / 10; //------------------------------------------------------------------------------ //Gradientenfaktor KÜHLEN - Begrenzung auf 10 //------------------------------------------------------------------------------ if (EEPROMReadlong(graf_k) > 100) EEPROMWritelong(graf_k, gfk * 10); //Vorgabewert Gradientenfaktor für Kühlen gfk = EEPROMReadlong(graf_k) / 10; //------------------------------------------------------------------------------ //Externes Logging verwenden //------------------------------------------------------------------------------ loggen = EEPROM.read(logging); if (loggen) { logprog = EEPROM.read(loggerwahl); switch (logprog) { case 0: { serialcom = true; //SerialComInterface logview = false; break; } case 1: { logview = true; //Logview serialcom = false; break; } } } //------------------------------------------------------------------------------ //Pumpe oder Rührwerk? //------------------------------------------------------------------------------ wahl = EEPROM.read(umwaelzwahl); if (wahl == 0) { ruehrer = true; pumpe = false; } else { ruehrer = false; pumpe = true; } //------------------------------------------------------------------------------ //Funksteckdosen/Relais Heizung/Rührer/Variabel Aus! //------------------------------------------------------------------------------ if (heizung == EIN) HeizungAUS(); NachgussAUS(); if (umwaelzer_stat == EIN) UmwaelzerAUS(); RufAUS(true); //------------------------------------------------------------------------------ //Kühlen/Heizen wurde unterbrochen - Wiedereinsprung nach Stromausfall //------------------------------------------------------------------------------ if (EEPROM.read(k_aktiv) == 1) { modus = KUEHLEN; knot = false; drehen = EEPROMReadlong(g_kuehltemp); } else knot = true; //Stromausfall im Heiz-Kühlmodus ? kuehlen = EEPROM.read(heiz_kuehl); //Kühl- oder Heizfunktion //------------------------------------------------------------------------------ //Rührer/Pumpe während des Einmaischens aktiv? //------------------------------------------------------------------------------ ruehrer_beim_einmaischen = EEPROM.read(ruepumeinmaisch); //------------------------------------------------------------------------------ //Rührer vor Abmaischen aktiv (Nachlauf) //------------------------------------------------------------------------------ ruehrer_nachlauf = EEPROM.read(rueNachlauf); //------------------------------------------------------------------------------ //Nachgusstemperatur-Sollwert //------------------------------------------------------------------------------ nachgusssolltemp = EEPROM.read(nachgusssoll); if (nachgusssolltemp > 78) { nachgusssolltemp = 78; EEPROM.write(nachgusssoll, 78); } //------------------------------------------------------------------------------ //Einsprungstelle nach Stromausfall Maischen/Gären //------------------------------------------------------------------------------ notfall_aktiv = EEPROM.read(notfall); //soll nach einem Stromausfall der letzte Programmpunkt aufgerufen werden? //Die Werte werden einmal pro Minute gespeichert. if (notfall_aktiv) { Notfallmodus = EEPROMReadInt(notfallmodus); if (Notfallmodus == 1) { RastNr = EEPROM.read(rastnr); RastTemp = EEPROM.read(rasttemp_aktuell); sollwert = RastTemp; RastZeit = EEPROM.read(rastzeit_aktuell); RastZeit_h = EEPROM.read(zeit_h); RastZeit_m = EEPROM.read(zeit_m); RastZeit_s = EEPROM.read(zeit_s); maischtemp = EEPROM.read(MaischTemp); gaerstart = EEPROM.read(MaischTemp); rastZeit[1] = EEPROM.read(rastzeit_1); rastTemp[1] = EEPROM.read(rasttemp_1); rastZeit[2] = EEPROM.read(rastzeit_2); rastTemp[2] = EEPROM.read(rasttemp_2); rastZeit[3] = EEPROM.read(rastzeit_3); rastTemp[3] = EEPROM.read(rasttemp_3); rastZeit[4] = EEPROM.read(rastzeit_4); rastTemp[4] = EEPROM.read(rasttemp_4); rastZeit[5] = EEPROM.read(rastzeit_5); rastTemp[5] = EEPROM.read(rasttemp_5); rastZeit[6] = EEPROM.read(rastzeit_6); rastTemp[6] = EEPROM.read(rasttemp_6); rastTemp[RastNr] = RastTemp; rastZeit[RastNr] = RastZeit; rasten = EEPROM.read(Rasten); gaerrasten = EEPROM.read(Rasten); RastModus = EEPROMReadInt(rastmodus); hopfengabe[0] = EEPROMReadInt(hopfengabe1); hopfengabe[1] = EEPROMReadInt(hopfengabe2); hopfengabe[2] = EEPROMReadInt(hopfengabe3); hopfengabe[3] = EEPROMReadInt(hopfengabe4); hopfengabe[4] = EEPROMReadInt(hopfengabe5); hopfengabe[5] = EEPROMReadInt(hopfengabe6); kochzeit = EEPROM.read(Kochzeit); modus = RastModus; anfang = 0; x = RastNr; if (modus > ANSTELLTEMPERATUR) { gaerRastTemp[x] = RastTemp; gaerRastZeit[x] = RastZeit; gaerrasten = x; } zeit_setzen = true; neustart = true; } else zeit_setzen = false; } //------------------------------------------------------------------------------ //benötigte Werte für die Gradientenberechnung //------------------------------------------------------------------------------ alte_zeit = millis(); //beim ersten Anlauf etwas warten alte_zeit_nachguss = millis(); sensors.requestTemperatures(); // Temperatur holen alte_temperatur = sensors.getTempCByIndex(0); if (anzahlTempsensoren == 2) alte_nachgusstemperatur = sensors.getTempCByIndex(1); //------------------------------------------------------------------------------ //Sensorfehler beim kabelgebundenen Temperatursensor //------------------------------------------------------------------------------ #ifndef Tempsensor433 while ((int8_t(alte_temperatur) == -127) || (int8_t(alte_temperatur) == 85)) { sensors.requestTemperatures(); // Temperatur holen alte_temperatur = sensors.getTempCByIndex(0); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Maischesensor-Fehler"); #endif isttemp = alte_temperatur; //erster gültiger Temperaturwert! } #else #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Funksensor aktiv!"); delay(2000); #endif #endif #ifdef MitDisplayUndEncoder lcd.clear(); #endif // modus = HAUPTMENUE; #ifdef gassensor R0 = float(EEPROMReadInt(gas_r0)); lpg_grenzwert = EEPROMReadInt(gas_grenzwert) * 100; if (lpg_grenzwert < 100) lpg_grenzwert = 100; //falls irgendwie eine "0" in den Speicher geschrieben wurde if (EEPROMReadInt(gas_kontrollwert) != 8888) { // 8888 ist ein Fantasiewert!!! modus = GASSENSORINIT; #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Gassensor noch"); lcd.setCursor(0, 1); lcd.print("nicht kalibriert! "); lcd.setCursor(0, 2); lcd.print("Starte mit Gasmenue!"); delay(3000); #endif } alarm = false; test_sensor = analogRead(analogpin); //ist ein Sensor angeschlossen? 1023 wenn nicht! if (test_sensor > 1000) { #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Gassensor fehlt!"); lcd.setCursor(0, 1); lcd.print("Brauen nun ohne"); lcd.setCursor(0, 2); lcd.print("Sensorcheck!!"); #endif sensor_angeschlossen = false; delay(5000); } else sensor_angeschlossen = true; #endif if (Notfallmodus == 0) { notmodus = false; } else { alte_zeit = millis(); alte_temperatur = isttemp; notmodus = true; } #ifdef MitDisplayUndEncoder if (Notfallmodus == 1) lcd.clear(); #endif rufZ = 0; //Rufzähler init x = 1; //Startwert Rastenzähler }; //Ende Setup============================================================================= //loop=================================================================================== void loop() { rufZ++; if (rufZ >= 3) ruf = false; #ifdef gassensor test_sensor = analogRead(analogpin); //ist ein Sensor angeschlossen? < ~1000 wenn nicht! if (test_sensor <= 1000) { PPM_LPG = getPPM(analogpin); #ifdef dbg Serial.print("PPM_LPG: "); Serial.println(PPM_LPG); #endif if ((PPM_LPG >= lpg_grenzwert) && (modus != GASSENSORINIT) && (modus != GAS_GRENZWERT) && (PPM_LPG > 0) && (sensor_angeschlossen)) { meldung_detail = "Gasalarm"; RufEIN(true); if (rufZ % 4 == 0) ruf = true; else ruf = false; delay(2000); RufAUS(true); #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(0, 0); lcd.print("Gasalarm!"); lcd.setCursor(0, 0); lcd.print("Konz. = "); lcd.print(PPM_LPG); lcd.print(" ppm"); lcd.setCursor(0, 1); lcd.print("Abbruch!"); delay(1000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Anlage bitte sofort"); lcd.setCursor(0, 1); lcd.print("stromlos schalten!"); #endif RufEIN(true); delay(2000); RufAUS(true); modus = ABBRUCH; alarm = true; ruf = true; } } #endif #ifdef RTC_Hardware DateTime uhrzeit = RTC.now(); #endif #ifdef Tempsensor433 //nur für Funksensor //Empfangspuffer --------------------------- uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (!(sensorwert < (alter_sensorwert - 2))) { if (vw_get_message(buf, &buflen)) // Non-blocking { uint8_t i; String wert = ""; for (i = 0; i < buflen; i++) wert += char(buf[i]); sensorwert = wert.toFloat(); alter_sensorwert = sensorwert; #ifdef dbg Serial.print("Sensor = "); Serial.println(sensorwert); #endif } } #endif drehen += encoder->getValue(); if (drehen != last) { last = drehen; } ButtonPressed = false; ClickEncoder::Button b = encoder->getButton(); if (b != ClickEncoder::Open) { switch (b) { case ClickEncoder::Open: break; case ClickEncoder::Closed: break; // case ClickEncoder::Pressed: // break; case ClickEncoder::Held: { altmodus = modus; modus = ABBRUCH; } break; case ClickEncoder::Released: ButtonPressed = false; break; case ClickEncoder::Clicked: { ButtonPressed = true; #ifdef geschwindigkeitsrelais if (ruehrer) //wenn als Mischer "Rührer" gewählt wurde, kann die Geschwindigkeit mit einem Click umgeschaltet werden. { if ((modus == MAISCHEN_START) || (modus == EINMAISCHEN) || (modus == TEMPERATURAUTOMATIK) || (modus == ZEITAUTOMATIK) || (modus == ENDTEMPERATURAUTOMATIK)) { if (highspeed) { digitalWrite(Speedrelais, LOW_SPEED); meldung_detail = "Rührer-Low-Speed"; ruehrerspeed = 0; } else { digitalWrite(Speedrelais, HIGH_SPEED); meldung_detail = "Rührer-High-Speed"; ruehrerspeed = 1; } highspeed = !highspeed; } } #else //wenn kein Geschwindigkeitsrelais verbaut ist, durch klicken zwischen Dauerbetrieb und Intervallbetrieb umschalten! if ((modus >= EINMAISCHEN) && (modus <= ENDTEMPERATURAUTOMATIK)) if (ruehrer) if (rwerk == 1) if (dauerbetrieb == 'J') dauerbetrieb = 'N' ; else {dauerbetrieb = 'J'; UmwaelzerEIN();} #endif #ifdef WUERZEPUMPE_AKTIV if (modus == WUERZEPUMPE) //in diesem Modus kann durch einen Click zwischen Automatik und Manuell umgeschaltet werden if (!manuell_ein) manuell_ein = true; else manuell_ein = false; #endif } break; case ClickEncoder::DoubleClicked: { if ((modus != SETUPMENUE) && (modus != RUFALARM) && (modus != EINMAISCHEN)) //gilt nicht für das Setupmenü und Einmaischen { if (modus != KUEHLEN) //Doppelclick führt zum Setupmenü (nicht im Modus "Kühlen/Heizen") { altmodus = modus; //Merker für letzten Modus tempdrehen = drehen; //Merker für aktuellen Wert von drehen anfang = 0; dclick = true; //Doppelclick wurde betätigt modus = SETUPMENUE; zeitz = false; } else { //im Modus "Kühlen/Heizen" wird zwischen "Heizen" und "Kühlen" umgeschaltet #ifdef MitDisplayUndEncoder lcd.setCursor(0, 2); lcd.print("Modus = "); #endif kuehlen = !kuehlen; if (kuehlen) { #ifdef MitDisplayUndEncoder lcd.print("K"); lcd.print(char(0xF5)); lcd.print("hlen"); #endif EEPROM.write(heiz_kuehl, 1); } else { #ifdef MitDisplayUndEncoder lcd.print("Heizen"); #endif EEPROM.write(heiz_kuehl, 0); } } } break; } } } // Temperatursensor DS1820 Temperaturabfrage --------------------------------------- sensors.requestTemperatures(); // Temperatur holen if (anzahlTempsensoren > 0) { #ifndef Tempsensor433 //ohne Funksensor if (anzahlTempsensoren == 1) sensorwert = sensors.getTempCByIndex(0); //kein Funksensor - Temperatursensor Kabel holt Maischetemperatur #else if (anzahlTempsensoren == 1) nachgusssensor = sensors.getTempCByIndex(0); //Funksensor und nur ein Kabelsensor - Kabelsensor holt Nachgusstemperatur #endif if (anzahlTempsensoren == 2) { // Zwei Kabelsensoren und kein Funksensor if (!(sensorwert < (alter_sensorwert - 2))) { sensorwert = sensors.getTempCByIndex(0); alter_sensorwert = sensorwert; } nachgusssensor = sensors.getTempCByIndex(1); } } #ifdef Tempsensor433 //mit Funksensor #ifdef dbg Serial.println("Funksensor aktiviert!"); #endif #endif #ifdef emcSchutz m = 0; while ((int8_t(sensorwert) == -127) && (m < emccounter)) { sensorwert = sensors.getTempCByIndex(0); m++; } #endif // Sensorfehler -------------------------------------------------------------------- // Sensorfehler -127 => VCC fehlt // Sensorfehler 85.00 => interner Sensorfehler ggf. Leitung zu lang // nicht aktiviert // Sensorfehler 0.00 => Datenleitung oder GND fehlt if (int8_t(sensorwert) == -127) { //zur besseren Erkennung Umwandling in (int)-Wert //sonst Probleme mit der Erkennung gerade bei 0.00 if (sensorfehler == 0) { rufmodus = modus; #ifdef MitDisplayUndEncoder lcd.clear(); lcd.setCursor(7, 0); #endif #ifndef Tempsensor433 //Mit Funksensor abgeschaltet #ifdef MitDisplayUndEncoder lcd.print("Sensorfehler!"); #endif meldung_detail = "Sensorfehler-Maischesensor"; #else #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); lcd.print("Funksensor Fehler!"); #endif meldung_detail = "Funkensorfehler-Maischesensor"; #endif regelung = AUS; heizung = AUS; if (umwaelzer_stat == EIN) UmwaelzerAUS(); #ifdef emcSchutz emc = emccounter; emccounter = 1; #endif braumeister[2] = 2; sensorfehler = 1; modus = RUFALARM; } } else sensorfehler = 0; if (mess_count == anzahl_werte_mittlung) // Messfehlervermeidung { // des Sensorwertes isttemp = sensortemp / mess_count; mess_count = 0; sensortemp = 0; int16_t dummy = isttemp * 10; isttemp = (float)dummy / 10; } else { { mess_count++; sensortemp += sensorwert; } } // Zeitermittlung ------------------------------------------------------------------ sekunden = second(); //aktuell Sekunde abspeichern für die Zeitrechnung minutenwert = minute(); //aktuell Minute abspeichern für die Zeitrechnung stunden = hour(); //aktuell Stunde abspeichern für die Zeitrechnung //---------------------------------------------------------------------------------- #ifdef MitDisplayUndEncoder if (modus == NACHISOMERISIERUNG) //Anzeige der Temperatur während der Nachisomerisierung { lcd.setCursor(12, 3); lcd.print(float(isttemp), 1); if (isttemp > 10) { lcd.print(char(0xDF)); lcd.print("C"); } else { lcd.print(char(0xDF)); lcd.print("C "); } } #endif //Kochfunktion - ohne Regelung ------------------------------------------------------- if ((modus > KOCHZEIT) && (modus < NACHISOMERISIERUNG)) { HeizungEIN(); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("Heizen"); #endif if ((alte_zeit + messzyklus) < millis()) { gradient = (isttemp - alte_temperatur) / (millis() - alte_zeit) * 60000; //Gradient/min. dT/dt alte_zeit = millis(); alte_temperatur = isttemp; } #ifdef MitDisplayUndEncoder if (modus > STARTKOCHEN) //Gradientenanzeige auch während des Kochens { lcd.setCursor(0, 1); lcd.print(gradient); if (modus < KOCHEN) lcd.print(" K/m "); else lcd.print(" K/m "); } lcd.setCursor(12, 3); lcd.print(float(isttemp), 1); if (isttemp > 10) { lcd.print(char(0xDF)); lcd.print("C"); } else { lcd.print(char(0xDF)); lcd.print("C "); } #endif } //Regelung Gärführung ------------------------------------------------------------- if (modus >= ANSTELLTEMPERATUR) { // Temperaturanzeige Istwert für Gärführung #ifdef MitDisplayUndEncoder lcd.setCursor(12, 3); lcd.print(float(isttemp), 1); if (isttemp > 10) { lcd.print(char(0xDF)); lcd.print("C"); } else { lcd.print(char(0xDF)); lcd.print("C "); } #endif if ((isttemp >= (sollwert - gaerhysterese)) && (isttemp <= (sollwert + gaerhysterese))) { //in diesem Fenster sind if (gaerregelung == EIN) //Heizung und Kühlung AUS { gaerregelung = AUS; #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print(" "); #endif if (heizung == EIN) HeizungAUS(); if (umwaelzer_stat == EIN) UmwaelzerAUS(); kwarten = millis(); hwarten = millis(); } } else { gaerregelung = EIN; } if ((gaerregelung == EIN) && (isttemp > sollwert)) //Isttemperatur liegt über Solltemperatur { if (heizung == EIN) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print(" "); #endif HeizungAUS(); hwarten = millis(); } if (millis() > (kwarten + kzeitverz)) { if (umwaelzer_stat == AUS) UmwaelzerEIN(); //Umwaelzrelais nun als Kühlrelais konfiguriert #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("K"); lcd.print(char(0xF5)); lcd.print("hlen"); #endif } } if ((gaerregelung == EIN) && (isttemp < sollwert)) //Isttemperatur liegt unter Solltemperatur { if (umwaelzer_stat == EIN) UmwaelzerAUS(); kwarten = millis(); if (heizung == AUS) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print(" "); #endif if (millis() > (hwarten + esvheizen)) { hwarten = millis(); Serial.begin(115200); Serial.println("Heizen"); HeizungEIN(); #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); lcd.print("Heizen"); #endif } } } } #ifdef MitDisplayUndEncoder if ((modus == HAUPTMENUE) || (modus == BRAUMENUE) || (modus == OPTIONENMENUE)) { lcd.setCursor(12, 3); lcd.print(float(isttemp), 1); if (isttemp > 10) { lcd.print(char(0xDF)); lcd.print("C"); } else { lcd.print(char(0xDF)); lcd.print("C "); } } #endif #ifdef funksteuerung if ((modus == ABBRUCH) || (modus == HAUPTMENUE)) //Vorsichtsmassnahme falls Funksteckdosen durch { //Fremdimpulse eingeschaltet werden! mySwitch.send(funk_heizung_aus, 24); if (ruehrer) if (rwerk == 0) if (umwaelzer_stat == EIN) UmwaelzerAUS(); } #endif if (regelung == EIN) //Alle Modi mit Regelung - ausser Gärführung { #ifdef funksteuerung if ((modus != ABBRUCH) && (modus != HAUPTMENUE)) { if (heizung == EIN) //zur Sicherheit überprüfen wir den aktuellen Zustand der Funksteckdosen { if ((heizungInterval1 + 2000) < millis()) { heizungInterval1 = millis(); mySwitch.send(funk_heizung_ein, 24); delay(funkdelay); if (modus != KUEHLEN) if (ruehrer) if (!fern) if (umwaelzer_stat == AUS) UmwaelzerEIN(); } } } #endif if (sensorfehler == 0) { #ifdef MitDisplayUndEncoder // Temperaturanzeige Istwert ---------------------------------------------------- if ((modus >= MAISCHEN_START) && (modus <= ENDTEMPERATURAUTOMATIK)) //Maischeautomatik { lcd.setCursor(9, 3); if (heizung == EIN) lcd.print("MD"); else if (rwerk == 1) { if (dauerbetrieb == 'J') lcd.print("MD"); else lcd.print("MI"); } else lcd.print(" "); } lcd.setCursor(12, 3); lcd.print(float(isttemp), 1); if (isttemp > 10) { lcd.print(char(0xDF)); lcd.print("C"); } else { lcd.print(char(0xDF)); lcd.print("C "); } #endif } if ((modus >= MAISCHEN_START) && (modus <= ENDTEMPERATURAUTOMATIK)) //Maischeautomatik if (heizung == AUS) if (anzahlTempsensoren == 2) //Nachgussbereitung in den Ausschaltlücken der Maischeheizung //wenn zwei Temperatursensoren verbaut sind (inkl. Funksensor) { if ((alte_zeit_nachguss + messzyklus) < millis()) { gradient_nachguss = (nachgusssensor - alte_nachgusstemperatur) / (millis() - alte_zeit_nachguss) * 60000; //Gradient/min. dT/dt alte_zeit_nachguss = millis(); alte_nachgusstemperatur = nachgusssensor; } if (nachgusssensor >= (nachgusssolltemp - (gradient_nachguss))) { if (nachgussheizung == EIN) { NachgussAUS(); nachgusswarten = millis(); } } if (nachgusssensor <= (nachgusssolltemp - (gradient_nachguss))) { if ((millis() > (nachgusswarten + esvheizen)) || nachgussfirst) { nachgussfirst = false; if ((nachgusssensor < nachgusssolltemp) && (modus != EINMAISCHEN)) if (nachgussheizung == AUS) NachgussEIN(); } } } //Heizregelung-------------------------------------------------------------------- #ifdef MitDisplayUndEncoder // Temperaturanzeige Sollwert ------------------------------------------------ lcd.setCursor(15, 1); lcd.print(float(sollwert), 0); lcd.print(char(0xDF)); lcd.print("C "); #endif if ((modus == EINMAISCHTEMPERATUR) || (modus == EINMAISCHEN) || (modus == TEMPERATURAUTOMATIK) || (modus == ZEITAUTOMATIK) || (modus == ENDTEMPERATURAUTOMATIK) || (modus == NACHGUSS) || (modus == KUEHLEN)) //Maischeautomatik/Nachguss/Kühlen { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 0); if ((modus != NACHGUSS) && (modus != KUEHLEN)) lcd.print("Maischen"); #endif if ((alte_zeit + messzyklus) < millis()) { gradient = (isttemp - alte_temperatur) / (millis() - alte_zeit) * 60000; //Gradient/min. dT/dt alte_zeit = millis(); alte_temperatur = isttemp; } if (modus != NACHGUSS) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 1); lcd.print(gradient, 2); lcd.print(" K/m "); #endif } } //Gradientenregelung-------------------------------------------------------------- if (modus != KUEHLEN) { //Heizungsregelung if (isttemp >= (sollwert - (gradient * gfh))) { if (heizung == EIN) { HeizungAUS(); umwaelzerEinAus(2); //Nachlauf if (modus != NACHGUSS) if (nachgussheizung == AUS) { delay(esv_nachguss); NachgussEIN(); } hwarten = millis(); if (isttemp >= sollwert) sollwerterreicht = true; } } if (isttemp < (sollwert - (gradient * gfh))) { if ((millis() > (hwarten + esvheizen)) || first) { first = false; if (isttemp <= sollwert) { if (nachgussheizung == EIN) { NachgussAUS(); delay(esv_nachguss); } if (heizung == AUS) HeizungEIN(); } } if (isttemp < sollwert) sollwerterreicht = false; if ((sondermodus == EINMAISCHEN) && (modus == RUFALARM)) { if (heizung == EIN) HeizungAUS(); if (nachgussheizung == AUS) { delay(esv_nachguss); NachgussEIN(); } } } } //Modus != Kühlen if (modus == KUEHLEN) { //Heiz-/Kühlregelung if (kuehlen) { if (isttemp < (sollwert - (gradient * gfk))) { if (heizung == EIN) { HeizungAUS(); kwarten = millis(); } } if (isttemp >= (sollwert - (gradient * gfk))) { if ((millis() > (kwarten + kzeitverz)) || first) //Kompressorschutz - first = beim 1. Einsch.keine Verzögerung { first = false; if (isttemp > sollwert){ if (heizung == AUS) HeizungEIN(); } } } } else { if (isttemp > (sollwert - (gradient * gfh))) { if (heizung == EIN) { HeizungAUS(); hwarten = millis(); sollwerterreicht = true; } } if (isttemp <= (sollwert - (gradient * gfh))) { if ((millis() > (hwarten + esvheizen)) || first) { first = false; if (heizung == AUS) HeizungEIN(); } sollwerterreicht = false; } } } //--------------------------------------------------------------- // Zeigt "Heizen" wenn Heizen und "Kühlen wenn Kühlen ausserhalb der Gärführung if (heizung == EIN) { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); #endif if (modus != KUEHLEN) { #ifdef MitDisplayUndEncoder lcd.print("Heizen "); #endif } else { if (kuehlen) { #ifdef MitDisplayUndEncoder lcd.print("K"); lcd.print(char(0xF5)); lcd.print("hlen "); #endif } else { #ifdef MitDisplayUndEncoder lcd.print("Heizen "); #endif } } if ((heizung == AUS) && (modus != ABBRUCH)) //bei Modus KUEHLEN verlassen keine Anzeige und kein Einschalten der Heizung { if (nachgussheizung == EIN) { NachgussAUS(); delay(esv_nachguss); } } //--------------------------------------------- if ((modus != KUEHLEN) && (ruehrer) && (modus != EINMAISCHEN)) if (rwerk == 0) umwaelzerEinAus(1); //nicht im Kühlmodus if ((modus != KUEHLEN) && (pumpe) && (dauerbetrieb == 'N')) intervallbetrieb(); if ((modus != KUEHLEN) && (pumpe) && (dauerbetrieb == 'J')) umwaelzerEinAus(1); } else { #ifdef MitDisplayUndEncoder lcd.setCursor(0, 3); if (anzahlTempsensoren == 1) { if (kuehlen) { if (modus == KUEHLEN) { lcd.print("ESVK:"); lcd.print(kzeitverz / 60000L); lcd.print("m"); } else lcd.print(" "); } else lcd.print(" "); } if ((anzahlTempsensoren == 2) || (anzahlTempsensoren == 1 && funksensor)) { lcd.setCursor(0, 3); lcd.print("N:"); lcd.print(float(nachgusssensor), 1); lcd.print(char(0xDF)); lcd.print("C "); } #endif if (heizung == EIN) { HeizungAUS(); umwaelzerEinAus(2); //Nachlauf if ((modus >= MAISCHEN_START) && (modus <= ENDTEMPERATURAUTOMATIK)) if (nachgussheizung == AUS) { delay(esv_nachguss); NachgussEIN(); } } if (modus != KUEHLEN) { //nicht im Kühlmodus if (ruehrer) { if (dauerbetrieb == 'J') { if (umwaelzer_stat == AUS) UmwaelzerEIN(); } else if ((heizung == AUS) && (regelung == EIN) && (modus != NACHGUSS) && (sollwerterreicht) && (dauerbetrieb == 'N')) intervallbetrieb(); //Rührer im Intervallbetrieb } if ((pumpe) && (regelung == EIN) && (dauerbetrieb == 'N')) intervallbetrieb(); if ((ruehrer) && (regelung == EIN) && (dauerbetrieb == 'N')) intervallbetrieb(); if ((pumpe) && (regelung == EIN) && (dauerbetrieb == 'J')) if (umwaelzer_stat == AUS) UmwaelzerEIN(); } //Ende Umwaelz } //Ende Heizregelung-------------------------------------------------------------- } //Regelung = EIN else //Regelung = AUS if (heizung == AUS) { if ((heizungInterval2 + 2000) < millis()) { heizungInterval2 = millis(); #ifdef funksteuerung mySwitch.send(funk_heizung_aus, 24); delay(funkdelay); #endif } } // Abfrage Modus ------------------------------------------------------------------ encoder->setAccelerationEnabled(true); switch (modus) { case HAUPTMENUE: { meldung = "Hauptmenü"; encoder->setAccelerationEnabled(false); //Geschwindigkeitsabhängigkeit beim Drehen des Encoders AUS regelung = AUS; //Hauptmenü funktion_hauptschirm(); break; } case BRAUMENUE: { meldung = "Braumenue"; encoder->setAccelerationEnabled(false); regelung = AUS; //Braumenü funktion_braumenue(); break; } case OPTIONENMENUE: { meldung = "Optionentmenü"; encoder->setAccelerationEnabled(false); regelung = AUS; //Optionenmenü funktion_optionsmenue(); break; } case KUEHLEN: { meldung = "Kühlen/Heizen"; encoder->setAccelerationEnabled(true); //Geschwindigkeitsabhängigkeit beim Drehen des Encoders EIN regelung = EIN; //Kühlen funktion_temperatur(); break; } case NACHGUSS: { meldung = "Nachguss"; encoder->setAccelerationEnabled(true); regelung = EIN; //Nachguss funktion_temperatur(); break; } #ifdef WUERZEPUMPE_AKTIV case WUERZEPUMPE: { meldung = "Würzepumpe"; regelung = AUS; //Würzepumpe wuerzepumpe(); break; } #endif case MPUMPE: { //Malzrohrpumpe Reinigungslauf meldung = "Malzrohrpumpe_Dauerbetrieb"; regelung = AUS; malzrohrDauerbetrieb(); break; } case SETUPMENUE: { meldung = "Setupmenü"; encoder->setAccelerationEnabled(false); regelung = AUS; //Einstellungen funktion_SetupMenu(); break; } case EXTERNMENUE: { encoder->setAccelerationEnabled(false); regelung = AUS; //Einstellungen funktion_Externmenu(); break; } case GRADIENTENFAKTOR_HEIZEN: { meldung = "Gradientenfaktor-Heizen"; encoder->setAccelerationEnabled(true); regelung = AUS; //Gradientenfaktor Heizen khwert(); break; } case EINSCHALTVERZOEGERUNG_HEIZRELAIS: { meldung = "Einschaltverzögerung-Heizrelais"; encoder->setAccelerationEnabled(true); regelung = AUS; //Wartezeit Wiedereinschalten Heizungsrelais ESVHeiz(); break; } case GRADIENTENFAKTOR_KUEHLEN: { meldung = "Gradientenfaktor-Kühlen"; encoder->setAccelerationEnabled(true); regelung = AUS; //Gradientenfaktor Kühlen kkwert(); break; } case WARTEZEIT_KUEHLEN: { meldung = "Wartezeit-Kühlen"; encoder->setAccelerationEnabled(false); regelung = AUS; //Wartezeit bein Kühlen vor dem Wiedereinschalten wartenKuehlen(); break; } case RASTANZAHL: { meldung = "Rastzahl-eingeben"; encoder->setAccelerationEnabled(false); regelung = AUS; //Anzahl Rasten funktion_rastanzahl(); break; } case EINMAISCHTEMPERATUR: { meldung = "Einmaischtemperatur"; encoder->setAccelerationEnabled(true); regelung = AUS; //Eingabe Einmaischtemperatur funktion_maischtemperatur(); break; } case RASTTEMPERATUREN: { meldung = "Rasttemperaturen"; encoder->setAccelerationEnabled(true); regelung = AUS; //Eingabe der Temperatur der Rasten funktion_rasteingabe(); break; } case RASTZEITEN: { meldung = "Rastzeiten"; encoder->setAccelerationEnabled(true); regelung = AUS; //Eingabe der Rastzeitwerte funktion_zeiteingabe(); break; } case AUSWAHL_UMWAELZER: { meldung = "Rührwerk-oder-Pumpe"; encoder->setAccelerationEnabled(false); regelung = AUS; //Rührwerk oder Malzrohrpumpe? auswahl_umwaelzer(); break; } case UMWAELZER_DAUERLAUF: { meldung = "Mischer-Dauerlauf?"; encoder->setAccelerationEnabled(false); regelung = AUS; //Rührwerk Dauerlauf? umwaelzer(); break; } case UMWAELZER_INTERVALL_EIN: { meldung = "Rührwerl-Intervall-Ein"; encoder->setAccelerationEnabled(false); regelung = AUS; //Rührwerk Intervall EIN umwaelzer_ein(); break; } case UMWAELZER_INTERVALL_AUS: { meldung = "Rührwerk-Intervall-Aus"; encoder->setAccelerationEnabled(false); regelung = AUS; //Rührwerk Intervall AUS umwaelzer_aus(); break; } case RUEPUMAKTIV: { meldung = "Rührwerk-Intervall-Aus"; encoder->setAccelerationEnabled(false); regelung = AUS; //Regelung AUS RuePumAktiv(); break; } case NACHLAUF: { meldung = "Nachlauf_Rührer"; encoder->setAccelerationEnabled(false); regelung = AUS; //Regelung AUS Nachlauf(); break; } case NACHLAUFEN: { meldung = "Rührer_läuft_nach"; encoder->setAccelerationEnabled(false); regelung = AUS; //Regelung AUS funktion_nachlaufen(); break; } case NACHGUSSSOLLWERT: { meldung = "Nachgusstemperatur_zweiter_Sensor"; encoder->setAccelerationEnabled(true); NachgussSoll(); break; } #ifdef funksteuerung case DRITTE_FUNKSTECKDOSE: { meldung = "Auswahl-Steckdose"; //Auswahl Verwendung der 3. Funksteckdose steckdosenwahl(); break; } case FRAGESTECKDOSENCODEEINGEBEN: { //soll der Steckdosencode nun eingegeben werden? frageCodeEingeben(); break; } case STECKDOSENCODE: { meldung = "Steckdosencode-eingeben"; //Steckdosencode eingeben steckdosencode(); break; } #endif case KOCHSCHWELLE: { meldung = "Kochschwelle-eingeben"; encoder->setAccelerationEnabled(true); regelung = AUS; //Kochschwelle - ab hier Brauerruf kochschwelle(); break; } case WECHSEL_TEMP_ZEIT: { meldung = "Braumeisterruf"; regelung = AUS; //Eingabe Braumeisterruf An/Aus wechsel_temp_zeit_eingabe(); break; } #ifdef bluetooth case CONNECT_BLUETOOTH: { // Bluetooth starten connectBluetooth(); break; } case BLUETOOTH_EIN_AUS: { //Bluetooth Ein bzw. Aus Bluetootheinaus(); break; } case BLUETOOTHSTEUERUNG_AKTIV: { encoder->setAccelerationEnabled(false); regelung = AUS; BluetoothSteuerungAktiv(); //Bluetooth-Steuerung für KBH2AiO aktiv? break; } #else case CONNECT_WIFI: { // WiFi starten connectWiFi(); break; } case WIFI_EIN_AUS: { //WiFi Ein bzw. Aus wifieinaus(); break; } case WLANSTEUERUNG_AKTIV: { encoder->setAccelerationEnabled(false); regelung = AUS; WLANSteuerungAktiv(); //WLAN-Steuerung für KBH2AiO aktiv? break; } #endif case ABMAISCHTEMPERATUR: { meldung = "Abmaischtemperatur"; encoder->setAccelerationEnabled(true); regelung = AUS; //Abmaischtemperatur funktion_endtempeingabe(); break; } case MAISCHEN_START: { meldung = "Start-Maischen"; regelung = AUS; //Start Maischeprozess funktion_startabfrage(); break; } case EINMAISCHEN: { meldung = "Maischetemperatur-Automatik"; encoder->setAccelerationEnabled(true); regelung = EIN; //Automatischer Ablauf Maischen funktion_einmaischen(); break; } case TEMPERATURAUTOMATIK: { meldung = "Temperaturautomatik"; encoder->setAccelerationEnabled(true); regelung = EIN; funktion_tempautomatik(); break; } case ZEITAUTOMATIK: { meldung = "Zeitautomatik"; encoder->setAccelerationEnabled(true); regelung = EIN; funktion_zeitautomatik(); break; } case ENDTEMPERATURAUTOMATIK: { meldung = "Endtemperatur-Automatik"; encoder->setAccelerationEnabled(true); regelung = EIN; funktion_endtempautomatik(); break; } case RUFALARM: { meldung = "Rufalarm"; regelung = AUS; funktion_braumeisterrufalarm(); break; } case BRAUMEISTERRUFALARM: { meldung = "Rufalarm"; regelung = AUS; funktion_braumeisterruf(); break; } case ANZAHL_HOPFENGABEN: { meldung = "Anzahl-Hopfengaben"; encoder->setAccelerationEnabled(false); regelung = AUS; anzahl_hopfengaben(); break; } case NACHISOZEIT: { meldung = "Nachisozeit"; meldung_detail = "Nachisomerisierung"; encoder->setAccelerationEnabled(true); regelung = AUS; nachisozeit(); break; } case HOPFENGABE: { meldung = "Hopfengabe!"; regelung = AUS; funktion_hopfengabe(); break; } case KOCHZEIT: { meldung = "Kochzeit"; encoder->setAccelerationEnabled(true); regelung = AUS; funktion_kochzeit(); break; } case STARTKOCHEN: { meldung = "Start-Kochen"; regelung = AUS; funktion_startkochen(); break; } case KOCHEN: { meldung = "Kochen"; // meldung_detail = "Kochen-gestartet"; regelung = AUS; funktion_kochen(); break; } case NACHISOMERISIERUNG: { meldung = "Nachisomerisierung"; meldung_detail = "Nachisomerisierung"; regelung = AUS; nachiso(); break; } case LOGGING_EIN_AUS: { encoder->setAccelerationEnabled(false); regelung = AUS; //Logger aktiviert? LoggingEinAus(); break; } case LOGWAHL: { encoder->setAccelerationEnabled(false); regelung = AUS; //LogViewEinAus Logwahl(); break; } case NOTGASMENUE: { meldung = "NotGasMenue"; encoder->setAccelerationEnabled(false); regelung = AUS; //Einstellungen funktion_NotGasMenue(); break; } case GASSENSORINIT: { meldung = "GasSensorInit"; encoder->setAccelerationEnabled(false); regelung = AUS; //Einstellungen funktion_GasSensorInit(); break; } case GAS_GRENZWERT: { meldung = "GasGrenzwert"; encoder->setAccelerationEnabled(true); regelung = AUS; funktion_grenzwert(); break; } case NOTFALLMODUS: { meldung = "Notfallmodus"; encoder->setAccelerationEnabled(false); regelung = AUS; StromAus(); //Notfallmodus Ein/Aus break; } case ABBRUCH: { meldung = "Abbruch"; encoder->setAccelerationEnabled(false); regelung = AUS; funktion_abbruch(); break; } case GAERFUEHRUNG: { meldung = "Gärführung_START"; regelung = AUS; funktion_gaerrastanzahl(); break; } case ANLAUFGAERSTUFEN: { regelung = AUS; meldung_detail = "Gaerstufe_anlaufen"; AnlaufGaerstufen(); break; } case GAERSTARTTEMPERATUR: { meldung = "Anstelltemperatur"; meldung_detail = "Anstelltemperatur_erreicht"; encoder->setAccelerationEnabled(true); regelung = AUS; //Eingabe Gärstarttemperatur gaerstarttemperatur(); break; } case GAERZEITEN: { encoder->setAccelerationEnabled(true); regelung = AUS; //Eingabe der Gärzeitwerte gaerzeiteingabe(); break; } case GAERTEMPERATUREN: { meldung = "Gaertemperaturen"; encoder->setAccelerationEnabled(true); regelung = AUS; //Eingabe der Gärzeitwerte gaerrasteingabe(); break; } case WECHSEL_GAER_TEMP_ZEIT: { meldung = "Gaerzeitautomatik"; regelung = AUS; wechsel_gaer_temp_zeit(); break; } case ANSTELLTEMPERATUR: { regelung = AUS; meldung = "Anstelltemperatur"; anlauf_anstelltemperatur(); break; } case GAERZEITAUTOMATIK: { encoder->setAccelerationEnabled(true); regelung = AUS; meldung = "Gaerzeitautomatik"; gaerzeitautomatik(); break; } case SOUNDEINSTELLUNG: { encoder->setAccelerationEnabled(true); regelung = AUS; sound_einstellen(); break; } #ifdef RTC_Hardware case TIMER: { encoder->setAccelerationEnabled(true); regelung = AUS; funktion_timer(); break; } case UHR: { encoder->setAccelerationEnabled(false); regelung = AUS; //Einstellungen funktion_uhrmenue(); break; } case STELLEN: { regelung = AUS; //Einstellungen funktion_stellen(); break; } #endif } if (loggen) //wenn loggen dann im Intervall (einstellbar) { aktuelleMillis = millis(); if (aktuelleMillis - alteMillis >= logintervall) { alteMillis = aktuelleMillis; if (serialcom) logger_serial(); if (logview) logger_logview(); } } //Datenaustausch AiO -> KBH2AiO --------------------------------------------------- #ifdef bluetooth if (bluetooth_steuerung) { if ((DatenZP + PCZyklus) < millis()) //Daten zum PC senden { DatenZP = millis(); zum_pc(); //von der AiO zum PC } zurAiO(AIOZyklus); //Rezept aus KBH und Menübefehle vom PC } #else if (wlan_steuerung) { if ((lan_aufruf + PCZyklus) < millis()) //Daten zum PC senden { lan_aufruf = millis(); zum_pc(); //von der AiO zum PC } zurAiO(AIOZyklus); //Rezept aus KBH und Menübefehle vom PC } #endif #ifdef RTC_Hardware //RTC-Timer starten --------------------------------------------------------------------- if (timeractiv) { if (uhrzeit.hour() == EEPROM.read(startstunde) && uhrzeit.minute() == EEPROM.read(startminute)) { modus = EINMAISCHEN; anfang = 0; EEPROM.write(startstunde, 255); EEPROM.write(startminute, 255); timeractiv = false; #ifdef MitDisplayUndEncoder lcd.clear(); #endif } } #endif } // Ende Loop //Ende des Programms ---------------------------------------------------------------------