@fabiwxyz So, ich denke, ich habe soweit fertig. In der neu hinzu gekommenen Funktion 'CountdownBeendet' Kannst du all das reinschreiben, was passieren soll, wenn die eingestellte 'Back-Zeit' erreicht ist.. Diese Funktion wird aufgerufen, wenn der Countdown abgelaufen ist.
ich hoffe, es hilft Dir weiter. Die temperatur-ausgabe hab ich gefixt. und auch das CounterPoti sollte jetzt richtig angezeigt werden. bei mir tut es das jedenfalls.
// PulverOfen V2
#define TEST true // Hier , wenn Du das Programm mit Minuten-Timer brauchst auf 'false' setzten
#include <LCD_I2C.h>
LCD_I2C LCD1(0x27, 20, 4);
// deklaration der Worte für HeizschlangenStatus 0 und 1 für das LCD
const char* HeizschlangenText[] = { "AUS", "EIN" };
//Taster für Heizschlangen unten
const int Taster_Heizschlangen_unten = 50;
int tasterStatus = HIGH;
unsigned int Tasterzaehler = 0;
bool LEDSTATUS = false;
unsigned long entprellZeit = 100; //Hier wird die Zeit die entprellt wird eingestellt.
unsigned long tasterZeit = 0; //Hier wird die Zeit in ms abgespeichert
bool LCD_Variable_HeizenOben = 0;
//Taster für Heizschlangen oben
const int Taster_Heizschlangen_oben = 48;
int tasterStatus_1 = HIGH;
unsigned int Tasterzaehler_1 = 0;
bool LEDSTATUS_1 = false;
unsigned long entprellZeit_1 = 100; //Hier wird die Zeit die entprellt wird eingestellt.
unsigned long tasterZeit_1 = 0; //Hier wird die Zeit in ms abgespeichert
bool LCD_Variable_HeizenUnten = 0;
//Temperatursimulation
int Heizen = A7;
int Heizen_MIN = 0;
int Heizen_MAX = 400;
int HeizenState;
int HeizenValue; //Müsste eigentlich der Mittelwert aus den Sensorwerten sein
//Counter-Poti Parameter
int CounterPoti = A0;
int CounterValue;
bool CounterStarted = false;
int Poti_Counter_MIN = 0;
int Poti_Counter_MAX = 120;
int TemperaturValue;
int TemperaturState;
int Poti_Temperatur_MIN = 100;
int Poti_Temperatur_MAX = 400;
//"Relaisausgaenge"
int Heizschlange_KF1 = 6;
int Heizschlange_KF2 = 32;
int Heizschlange_KF3 = 33;
int Heizschlange_KF4 = 7;
int Heizschlange_KF5 = 34;
int Luefter_oben = 9;
int Luefter_unten = 8;
int Summer = 28;
//Funktionsvariablen
int selectedHeater = 0; //0 fuer untere Heizschlangen, 1 fuer obere Heizschlangen. Wenn beide angewaehlt Wert = 3
bool HeizschlangenStatus = false;
bool CounterGO = false;
long unsigned int start;
long unsigned int intervall = 1000; // 1 Sekunde = "delay"
long unsigned int refreshStart = 20; // Damit das LCD gleich im ersten loop beschrieben wird
long unsigned int refreshIntervall = 20; // intervall mit dem das UpdateLCD aufgerufen wird(50x / Sekunde)
int CounterState() {
if (!CounterGO) {
return map(analogRead(CounterPoti), 0, 1023, Poti_Counter_MIN, Poti_Counter_MAX);
} // hier wird, solange CounterGo auf false ist, also der CountDown noch nicht gestartet ist
// die Stellung des Counter-Potis eingelesen.
else {
return CounterValue; // Sorgt dafür, dass CounterValue sich nicht ändert, falls der Countdown bereits läuft
}
}
void setup() {
LCD1.begin();
LCD1.backlight();
initLCD();
Serial.begin(9600);
pinMode(Heizschlange_KF1, OUTPUT);
pinMode(Heizschlange_KF2, OUTPUT);
pinMode(Heizschlange_KF3, OUTPUT);
pinMode(Heizschlange_KF4, OUTPUT);
pinMode(Heizschlange_KF5, OUTPUT);
pinMode(Luefter_oben, OUTPUT);
pinMode(Luefter_unten, OUTPUT);
pinMode(Summer, OUTPUT);
pinMode(Taster_Heizschlangen_oben, INPUT_PULLUP);
pinMode(Taster_Heizschlangen_unten, INPUT_PULLUP);
}
void loop() {
//*******************************************Einschalten der Luefter im Einschaltmoment der Steuerung**************************
digitalWrite(Luefter_oben, HIGH);
digitalWrite(Luefter_unten, HIGH);
//*****************************************************************************************************************************
//********************************************************Tasterabfrage fuer Taster Heizschlagen oben**************************
tasterStatus_1 = digitalRead(Taster_Heizschlangen_oben);
if (tasterStatus_1 == LOW) {
tasterZeit_1 = millis();
Tasterzaehler_1 = 1;
}
if ((millis() - tasterZeit_1 > entprellZeit_1) && Tasterzaehler_1 == 1) {
LEDSTATUS_1 = !LEDSTATUS_1;
Tasterzaehler_1 = 0;
}
if (LEDSTATUS_1 == true) {
selectedHeater = 1; //Oberen Heizschlangen angewaehlt
LCD_Variable_HeizenOben = 1;
digitalWrite(Heizschlange_KF1, HIGH);
digitalWrite(Heizschlange_KF2, HIGH);
} else {
LCD_Variable_HeizenOben = 0;
digitalWrite(Heizschlange_KF1, LOW);
digitalWrite(Heizschlange_KF2, LOW);
}
//************************************************************Heizschlangen unten**********************************************FERTIG!!!!!!
tasterStatus = digitalRead(Taster_Heizschlangen_unten);
if (tasterStatus == LOW) {
tasterZeit = millis();
Tasterzaehler = 1;
}
if ((millis() - tasterZeit > entprellZeit) && Tasterzaehler == 1) {
LEDSTATUS = !LEDSTATUS;
Tasterzaehler = 0;
}
if (LEDSTATUS == true) {
selectedHeater = 2; //Untere Heizschlangen angewaehlt
LCD_Variable_HeizenUnten = 1;
digitalWrite(Heizschlange_KF5, HIGH);
digitalWrite(Heizschlange_KF4, HIGH);
digitalWrite(Heizschlange_KF3, HIGH);
} else {
LCD_Variable_HeizenUnten = 0;
digitalWrite(Heizschlange_KF5, LOW);
digitalWrite(Heizschlange_KF4, LOW);
digitalWrite(Heizschlange_KF3, LOW);
}
//******************************************************************************************************************************
//******************************************************Verweis auf Funktion je nach Auswahl der Heizschlangen******************
if (LEDSTATUS && LEDSTATUS_1) // Bedingung wenn beide Taster betätigt wurden.
{
selectedHeater = 3;
Temperaturstabilisierung_both(); // Fertig
}
else if (LEDSTATUS) // Bedingung wenn Heizschlangen unten angewählt wurden
{
selectedHeater = 1;
Temperaturstabilisierung_unten(); // Fertig
}
else if (LEDSTATUS_1) {
selectedHeater = 2; // Bedingung wenn Heizschlangenoben angewählt wurden
Temperaturstabilisierung_oben();
}
else // Bedingung wenn kein taster betätigt wurde
{
selectedHeater = 0;
}
//Potiabfrage für Temperatur
TemperaturState = analogRead(A1);
TemperaturValue = map(TemperaturState, 0, 1023, Poti_Temperatur_MIN, Poti_Temperatur_MAX);
//Simulation Heizschlange mit Poti
HeizenState = analogRead(Heizen); // Heizen = Analoginput A7
HeizenValue = map(HeizenState, 0, 1023, Heizen_MIN, Heizen_MAX);
Serial.print("Temperatur =");
Serial.println(HeizenValue);
//*********************************************************Verweis auf LCD-Funktion************************************************
if (millis() - refreshStart > refreshIntervall) { //refreshTimerfür LCD
refreshStart = millis();
updateLCD();
}
//*********************************************************************************************************************************
//*********************************************************Verweis auf TimerFunction sobald die eingestellte Temperatur erreich wurde*******
if (CounterGO) {
static uint8_t SekundenCounter = 0; // wird benutzt um 60 Sekunden abzuzählen
if (!TEST && !CounterStarted) { //wenn Prgamm nicht in TEST Modus undDer Countdown gerade erst gestartet
SekundenCounter = 60; // Zähler für 1 Minute (60 Sekunden) setzen
CounterStarted = true; // ab jetzt werden Minuten gezählt anstatt nur Sekunden
}
unsigned long currentMillis = millis(); // Aktuelle Zeit abrufen
if (currentMillis - start >= intervall) // Intervall = 1 Sekunde.
{
start = currentMillis;
if (SekundenCounter > 0) SekundenCounter--; // Sekundenzähler runter zählen bis 0
if (CounterValue > 0 && SekundenCounter == 0) { // wenn 60 Sekunden um sind
CounterValue--; // CounterValue um 1 Min. runter
Serial.print("Minuten");
Serial.println(CounterValue);
if (CounterStarted) SekundenCounter = 60; // SekundenCounter wieder auf 60 Sekunden setzen
if (CounterValue == 0) { // Wenn counterValu = 0 --> Zeit abgelaufen
// Zeit abgelaufen
CountdownBeendet();
}
}
}
} else {
if (!CounterStarted) CounterValue = CounterState();
updateLCD(); // sofortiges LCD update wenn am Poti gedreht wird und der Countdown noch nicht läuft.
}
//*****************************************************************************************************************************************
} //Loop geschlossen
/*currentMillis wird initalisiert und bekommt im Moment der initialisierung den Wert aus millis(). Dadurch das aber millis logischerweise im Startmoment = 0 ist, hat die Variable currentMillis auch den Wert = 0.
innerhalb der if-Abfrage wird dann die Startzeit (currentMillis) - der letzten Zeit abgezogen. Beim ersten durchlauf ergibt das also 0-0 = 0 (if-Abfrage nicht erfüllt). Jetzt wird vor der if-Abfrage solange gewartet (1000ms)
bis currentMillis > als intervall ist. Das bedeutet die if-Abfrage ist somit true. Innerhalb der if-Abfrage wird der Wert von currentMillis an start übergeben. Das bedeutet also das start nun den Wert 1000 hat. Da ja die
if-Abfrage erst true war wenn der intervall >= der Berechnung war. Im nächsten Durchlauf passiert nun das selbe. Der wird von currentMillis wird wieder auf 0 gesetzt und die if-Abfrage ist erst dann true wenn 1000ms vergangen
sind. Somit wird statt einem delay(1000); bei dem das Programm stehen bleibt übergangen. Kurz gesagt ist die Variable intervall gleich dein delay() denn man normalerweise eintellt.*/
//********************************************************Fertig*********************************************************************
void CountdownBeendet() {
Serial.println("****** FERTIG ******");
CounterStarted = false; // Counter stopp
CounterGO = false; // CountDown abschalten
// diese beiden Zeilen müssen unbedingt bleiben, egal was Du alles in diese Funktion schreibst
// Sonst kannst Du keinen neuen Zyklus starten ohne den Arduino neu zu starten
// Falls Du irgendeine Ende-Nachricht aufs LCD schreibst, musst Du dafür sorgen, dass beim Start
// eines neuen "Back-Zyklus" die Funktion initLCD() aufgerufen wird, damit das lcd wieder den korrekten
// Inhalt hat.
}
void Temperaturstabilisierung_oben() {
if (HeizenValue < TemperaturValue && !HeizschlangenStatus) {
HeizschlangenStatus = true;
}
else if (HeizenValue >= TemperaturValue && HeizschlangenStatus) {
HeizschlangenStatus = false;
CounterGO = true;
CounterValue = CounterState(); // Counter-Poti einsesen
}
if (HeizschlangenStatus == true) {
digitalWrite(Heizschlange_KF1, HIGH);
digitalWrite(Heizschlange_KF2, HIGH);
}
if (HeizschlangenStatus == false) {
digitalWrite(Heizschlange_KF1, LOW);
digitalWrite(Heizschlange_KF2, LOW);
}
}
//********************************************************************************************************************************
//********************************************************Fertig****************************************************************
void Temperaturstabilisierung_unten() {
if (HeizenValue < TemperaturValue && !HeizschlangenStatus) {
HeizschlangenStatus = true;
}
else if (HeizenValue >= TemperaturValue && HeizschlangenStatus) {
HeizschlangenStatus = false;
CounterGO = true;
CounterValue = CounterState(); // Counter-Poti einsesen
}
if (HeizschlangenStatus == true) {
digitalWrite(Heizschlange_KF5, HIGH);
digitalWrite(Heizschlange_KF4, HIGH);
digitalWrite(Heizschlange_KF3, HIGH);
}
if (HeizschlangenStatus == false) {
digitalWrite(Heizschlange_KF5, LOW);
digitalWrite(Heizschlange_KF4, LOW);
digitalWrite(Heizschlange_KF3, LOW);
}
}
//********************************************************************************************************************************
//********************************************************Fertig****************************************************************
void Temperaturstabilisierung_both() {
if (HeizenValue < TemperaturValue && !HeizschlangenStatus) {
HeizschlangenStatus = true;
}
else if (HeizenValue >= TemperaturValue && HeizschlangenStatus) {
HeizschlangenStatus = false;
CounterGO = true;
CounterValue = CounterState(); // Counter-Poti einsesen
}
if (HeizschlangenStatus == true) {
digitalWrite(Heizschlange_KF5, HIGH);
digitalWrite(Heizschlange_KF4, HIGH);
digitalWrite(Heizschlange_KF3, HIGH);
digitalWrite(Heizschlange_KF2, HIGH);
digitalWrite(Heizschlange_KF1, HIGH);
}
if (HeizschlangenStatus == false) {
digitalWrite(Heizschlange_KF5, LOW);
digitalWrite(Heizschlange_KF4, LOW);
digitalWrite(Heizschlange_KF3, LOW);
digitalWrite(Heizschlange_KF2, LOW);
digitalWrite(Heizschlange_KF1, LOW);
}
}
//********************************************************************************************************************************
// Hier werden nun NUR diejenigen Werte neu geschrieben, die sich wirklich verändert haben.
//damit ist ein Flackerfreier Betrieb des LCD möglich weil es so viel schneller beschrieben werden kann,
// als wenn es jedesmal komplett gelöscht wird und komplett neu beschrieben werden muss
void updateLCD() {
/* die static-variablen bleiben beim verlassen von updateLCD erhalten, darin wird der jeweils zuletzt
** geschriebene Wert gesichert , zur Feststellung, ob er sich geändert hat und neu geschrieben werden muss
*/
static int oldCounterValue = -1;
static int oldTemperaturValue = -20;
static bool oldHeizenOben = 0;
static bool oldHeizenUnten = 0;
// CounterValue --> LCD
if (CounterValue != oldCounterValue) {
oldCounterValue = CounterValue; // neuen Wert übernehmen und sichern
LCD1.setCursor(10, 0);
LCD1.print(" "); // 3x space zum löschen des alten Wertes ausgeben
LCD1.setCursor(10, 0);
LCD1.print(CounterValue); // neuen CounterValue schreiben
}
// TempValue --> LCD
if (TemperaturValue != oldTemperaturValue) {
oldTemperaturValue = TemperaturValue;
LCD1.setCursor(13, 1);
LCD1.print(" "); // 3x space zum löschen des alten Wertes ausgeben
LCD1.setCursor(13, 1);
LCD1.print(TemperaturValue); // neuen TempValue schreiben
}
// HeizenOben --> LCD
if (LCD_Variable_HeizenOben != oldHeizenOben) {
oldHeizenOben = LCD_Variable_HeizenOben;
LCD1.setCursor(15, 2);
LCD1.print(HeizschlangenText[LCD_Variable_HeizenOben]);
// je nach dem ob Heizschlange gewählt oder nicht wird "EIN" oder "AUS" aufs LCD gebracht.
}
// HeizenUnten --> LCD
if (LCD_Variable_HeizenUnten != oldHeizenUnten) {
oldHeizenUnten = LCD_Variable_HeizenUnten;
LCD1.setCursor(15, 3);
LCD1.print(HeizschlangenText[LCD_Variable_HeizenUnten]);
// je nach dem ob Heizschlange gewählt oder nicht wird "EIN" oder "AUS" aufs LCD gebracht.
}
}
// LCD mit dem Grundtext beschreiben. dieser Text wird nur zu beginn komplet geschrieben
// beim UpdateLCD werden nur noch die veränderten Werte ans LCD gesendet, dafür aber 50x/Sekunde.
void initLCD() {
LCD1.clear();
LCD1.setCursor(0, 0);
LCD1.print("Counter = ");
LCD1.print(CounterValue);
LCD1.setCursor(13, 0);
LCD1.print("Minuten");
LCD1.setCursor(0, 1);
LCD1.print("Temperatur = ");
LCD1.setCursor(13, 1);
LCD1.print(TemperaturValue);
LCD1.setCursor(17, 1);
LCD1.print("\337C"); // '\337' erzeugt das °-Zeichen auf dem LCD , das 'C' steht nat. für Celsius
LCD1.setCursor(0, 2);
LCD1.print("Heizen oben = AUS");
LCD1.setCursor(0, 3);
LCD1.print("Heizen unten = AUS");
}
Ganz am Anfang des Programms hab ich ein #define TEST eingefügt, da kannst du von Sekunden auf Minuten umstellen indem Du TEST auf false setzt. (danach natürlichh neu kompilieren und hochladen.