Hallo erstmal, vielen Dank, dass ihr euch mein Problem mal angesehen habt.
Zur Erklärung bzw. Verdeutlichung, warum ich glaube, einen Task zu benötigen:
Eigentlich war die ursprüngliche Funktion kein Task. In der Funktion wurde, je nach Zustand der (Alarm-)Anlage, eine Taste auf einem TFT angezeigt. Das hat auch sehr gut funktioniert. Dann kam mir die Idee, die angezeigte Taste (rot) könnte nach Betätigung einen Countdown von 15 sekunden anzeigen. Während dieses Countdowns muss vom Benutzer eine Chipcard vor die Anlage gehalten werden. Wenn er das macht, springt die Taste wieder auf ihren Normalzustand um (grün).
Das hat aber nur mit einem Task funktioniert (zumindest ist mir keine andere Lösung eingefallen, um den Countdown darzustellen, ohne delay zu benutzen).
MIt dem Task läuft es auch so wie ich es mir vorstellte, aber sobald die ChipKarte an die Anlage gehalten wird, spring der Arduino von der Funktion (Alarm aus) wieder in den Task (Alarm an mit Countdown der Taste) und startet den Countdown neu.
Mein serieller Monitor zeigt mir das auch so an, das der Zustand von dem Task wieder geändert wird.
Ich weiss, das ist für Aussenstehende schwer zu verstehen, bzw. ich weiss nicht, wie ich es erklären soll.
Ich stelle mal einen Code-Abschnitt und einen Teil der Ausgabe am seriellen Monitor (mit jeweils ein paar Kommentaren meinerseits) zum hoffentlich besseren Verständnis mit ein.
Der Ausschnitt aus dem Programmcode
void alarm_an(unsigned char zimmer)
{
Serial.println("*** alarm_an ***");
/*
Serial.print("alarm_zimmer_1: ");
Serial.println(alarm_zimmer_1);
Serial.print("alarm_zimmer_2: ");
Serial.println(alarm_zimmer_2);
*/
if (zimmer == Zimmer_1)
{
// zimmer_1_btn.initButton(&tft, 175, 70, 300, 40, WHITE, RED, WHITE, "Alarm 1 aus", 2);
// zimmer_1_btn.drawButton(false);
alarm_zimmer_1 = ON;
alarm_tft_anzeige(Zimmer_1, "alarm1");
}
else if (zimmer == Zimmer_2)
{
zimmer_2_btn.initButton(&tft, 175, 130, 300, 40, WHITE, RED, WHITE, "Alarm 2 aus", 2);
zimmer_2_btn.drawButton(false);
alarm_zimmer_2 = ON;
}
alarm_status = 1;
Wire.beginTransmission(8);
Wire.write(alarm_status);
Wire.endTransmission();
relay_SetStatus(zimmer, ON); // Relais für alarmauslösendes Zimmer an
}
Task alarm_tft_anzeige(unsigned char zimmer, char alarm_taste_status[])
{
Serial.println("*** alarm_tft_anzeige ***");
Serial.print ("zimmer: ");
Serial.println (zimmer);
Serial.print ("alarm_taste_status: ");
Serial.println (alarm_taste_status);
Serial.print ("alarm_taste_tft_has_to_be_changed: ");
Serial.println (alarm_taste_tft_has_to_be_changed);
Serial.print ("countdown: ");
Serial.println (countdown);
taskBegin();
while (1)
{
if (zimmer == Zimmer_1)
{
if (alarm_taste_status == "ok")
{
if (alarm_taste_tft_has_to_be_changed == true)
{
zimmer_1_btn.initButton(&tft, 175, 70, 300, 40, WHITE, GREEN, BLACK, "Zimmer 1 OK", 2);
zimmer_1_btn.drawButton(false);
alarm_taste_tft_has_to_be_changed = false;
return;
}
}
else if (alarm_taste_status == "alarm1")
{
if (alarm_taste_tft_has_to_be_changed == true)
{
zimmer_1_btn.initButton(&tft, 175, 70, 300, 40, WHITE, RED, WHITE, "Alarm 1 aus", 2);
zimmer_1_btn.drawButton(false);
alarm_taste_tft_has_to_be_changed = false;
return;
}
}
else if (alarm_taste_status == "alarm2")
{
if (alarm_taste_tft_has_to_be_changed == true)
{
zimmer_1_btn.initButton(&tft, 175, 70, 300, 40, WHITE, RED, WHITE, "Alarm 1", 2);
zimmer_1_btn.drawButton(false);
alarm_taste_tft_has_to_be_changed = false;
return;
}
}
else if (alarm_taste_status == "warten")
{
if (countdown > 14)
{
alarm_taste_tft_has_to_be_changed = true;
// alarm_taste_status = "alarm2";
alarm_tft_anzeige(Zimmer_1, "alarm2");
return;
}
if (keycard_status == true)
{
keycard_check = false;
alarm_aus(Zimmer_1); //<-- hier springt er zu der Funktion, welche ich im ersten Posting gemeint habe
/* alarm_taste_status = "ok";
alarm_taste_tft_has_to_be_changed = true;
alarm_tft_anzeige(Zimmer_1, "ok");*/
return; //<-- hier sollte er den Task dann verlassen und gut is, aber er überspringt diese Anweisung bzw. er sollte nie hier landen, da der alarm_taste_status eigentlich "ok" sein sollte
}
zimmer_1_btn.initButton(&tft, 175, 70, 300, 40, WHITE, RED, BLACK, text[countdown], 2);
zimmer_1_btn.drawButton(true);
countdown++;
taskPause(1000);
}
else
{
zimmer_1_btn.initButton(&tft, 175, 70, 300, 40, WHITE, RED, WHITE, "ERROR", 2);
zimmer_1_btn.drawButton(false);
}
}
else if (zimmer == Zimmer_2)
{
zimmer_2_btn.initButton(&tft, 175, 130, 300, 40, WHITE, RED, WHITE, "Alarm 2 aus", 2);
zimmer_2_btn.drawButton(false);
alarm_zimmer_2 = ON;
}
}
taskEnd();
}
void alarm_aus(unsigned char zimmer)
{
Serial.println("*** alarm_aus ***");
Serial.print("alarm_zimmer_1: ");
Serial.println(alarm_zimmer_1);
Serial.print("alarm_zimmer_2: ");
Serial.println(alarm_zimmer_2);
if (zimmer == Zimmer_1)
{
if (alarm_zimmer_1 == ON)
{
alarm_zimmer_1 = OFF;
if (menue_flag == true)
{
menue_flag = false;
display_change = true;
}
else
{
alarm_taste_tft_has_to_be_changed = true;
alarm_tft_anzeige(Zimmer_1, "ok");
// zimmer_1_btn.initButton(&tft, 175, 70, 300, 40, WHITE, GREEN, BLACK, "Zimmer 1 OK", 2);
// zimmer_1_btn.drawButton(false);
display_change = false;
// alarm_taste_tft_has_to_be_changed=true;
}
}
}
else if (zimmer == Zimmer_2)
{
if (alarm_zimmer_2 == ON)
{
alarm_zimmer_2 = OFF;
if (menue_flag == true)
{
menue_flag = false;
display_change = true;
}
else
{
zimmer_2_btn.initButton(&tft, 175, 130, 300, 40, WHITE, GREEN, BLACK, "Zimmer 2 OK", 2);
zimmer_2_btn.drawButton(false);
display_change = false;
}
}
}
Serial.print("display_change: ");
Serial.println(display_change);
if (alarm_zimmer_1 == OFF && alarm_zimmer_2 == OFF)
{
alarm_status = 2;
keycard_check = 0;
Wire.beginTransmission(8);
Wire.write(alarm_status);
Wire.endTransmission();
countdown = 0;
}
relay_SetStatus(zimmer, OFF); // Relais für alarmauslösendes Zimmer aus
}
Und hier der Ausschnitt aus dem seriellen Monitor
*** alarm_tft_anzeige ***
zimmer: 24
alarm_taste_status: warten
alarm_taste_tft_has_to_be_changed: 1
countdown: 2
*** keycard_access ***
Authorize with access card or Chip
Authorized access chip
keycard_status: 1
keycard_card: 0
keycard_chip: 1
menue_flag: 0
alarm_status: 1
keycard_check: 0
*** keycard_alarm_aus ***
*** alarm_aus ***
alarm_zimmer_1: 1
alarm_zimmer_2: 0
*** alarm_tft_anzeige ***
zimmer: 24
alarm_taste_status: ok //<-- an der Stelle ist alles ok
alarm_taste_tft_has_to_be_changed: 1
countdown: 3
display_change: 0
*** alarm_aus ***
alarm_zimmer_1: 0
alarm_zimmer_2: 0
display_change: 0
*** alarm_tft_anzeige *** //<-- hier sieht man, das er in den Task zurückkehrt, also auch noch ok
zimmer: 24
alarm_taste_status: warten //<-- hier setzt er eigenwillig seinen alten Zustand (vor Verlassen des Task) wieder ein (So ein pösser Pursche ;-))
alarm_taste_tft_has_to_be_changed: 1
countdown: 0
*** keycard_access ***
Authorize with access card or Chip
*** alarm_tft_anzeige ***
zimmer: 24
alarm_taste_status: warten
alarm_taste_tft_has_to_be_changed: 1
countdown: 0
Hoffentlich habe ich jetzt endgültig alle Klarheiten beseitigt
Tom