Ich komme bei einem Code nicht recht weiter. Eigentlich ganz einfach, der Code soll Text1 alle 2 Sek., Text2 alle 4 Sek. anzeigen, aber nicht wenn Text3 aktiv ist. Text3 wird alle 20 Sek. aktiv für 10 Sek., danach das ganze wieder von vorne.
Code:
const int TEXT1_INTERVAL = 2000; // show "text1" every 3 seconds
const int TEXT2_INTERVAL = 4000; // show "text2" every 5 seconds
const int TEXT3_INTERVAL = 20000; // show "text3" every 20 seconds
const int TEXT3_DURATION = 10000; // show "text3" for 15 seconds
unsigned long previousText1Millis = 0;
unsigned long previousText2Millis = 0;
unsigned long previousText3Millis = 0;
unsigned long text3StartMillis = 0;
bool text3Active = false;
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long currentMillis = millis();
// check if it's time to show "text1"
if (currentMillis - previousText1Millis >= TEXT1_INTERVAL && !text3Active) {
Serial.println("text1");
previousText1Millis = currentMillis;
}
// check if it's time to show "text2"
if (currentMillis - previousText2Millis >= TEXT2_INTERVAL && !text3Active) {
Serial.println("text2");
previousText2Millis = currentMillis;
}
// check if it's time to show "text3"
if (currentMillis - previousText3Millis >= TEXT3_INTERVAL) {
Serial.println("text3");
previousText3Millis = currentMillis;
text3StartMillis = currentMillis;
text3Active = true;
}
// check if it's time to stop showing "text3"
if (text3Active && currentMillis - text3StartMillis >= TEXT3_DURATION) {
text3Active = false;
}
}
Nach einschalten ist alles ok, Text1 + 2 sind ok, Text3 kommt nach 20 Sek. für 10 Sek.
Aber danach wird Text3 immer alle 10 Sek. für 10 Sek. aktiv.
Was mache ich falsch?
const int TEXT1_INTERVAL = 2000; // show "text1" every 3 seconds
const int TEXT2_INTERVAL = 4000; // show "text2" every 5 seconds
const int TEXT3_INTERVAL = 20000; // show "text3" every 20 seconds
const int TEXT3_DURATION = 10000; // show "text3" for 15 seconds
unsigned long previousText1Millis = 0;
unsigned long previousText2Millis = 0;
unsigned long previousText3Millis = 0;
unsigned long text3StartMillis = 0;
bool text3Active = false;
void setup()
{
Serial.begin(9600);
}
void loop()
{
unsigned long currentMillis = millis();
// check if it's time to show "text1"
if (currentMillis - previousText1Millis >= TEXT1_INTERVAL && !text3Active)
{
Serial.println("text1");
previousText1Millis = currentMillis;
}
// check if it's time to show "text2"
if (currentMillis - previousText2Millis >= TEXT2_INTERVAL && !text3Active)
{
Serial.println("text2");
previousText2Millis = currentMillis;
}
// check if it's time to show "text3"
if (currentMillis - previousText3Millis >= TEXT3_INTERVAL && !text3Active)
{
Serial.println("text3");
previousText3Millis = currentMillis;
text3StartMillis = currentMillis;
text3Active = true;
}
// check if it's time to stop showing "text3"
if (currentMillis - text3StartMillis >= TEXT3_DURATION && text3Active)
{
text3Active = false;
}
}
text1 und text2 werden einmal ausgegeben und das Wartezeit-Intervall wird neu gestartet.
Wie oft soll text3 geschrieben werden? Wie soll TEXT3_INTERVALL und TEXT3_DURATION zusammenspielen? Das ist mir an deiner Aufgabenstellung unklar, und dein Code ist mir zu kompliziert. Wenn er eh nicht das tut,was er soll, brauch ich ihn ja auch nicht zu verstehen
Im Prinzip zwei Funktionen (Text1 + 2) die im Loop laufen, aber nur wenn die dritte Funktion Text3 nicht aktiv ist. Diese Funktion Text3 soll alle 20 Sek. für 10 Sekunden aktiv sein und danach soll alles wieder von vorne beginnen.
Ich weiss nicht wie ich das noch anders beschrieben soll:)
const int TEXT1_INTERVAL = 2000; // show "text1" every 3 seconds
const int TEXT2_INTERVAL = 4000; // show "text2" every 5 seconds
const int TEXT3_INTERVAL = 20000; // show "text3" every 20 seconds
const int TEXT3_DURATION = 10000; // show "text3" for 15 seconds
unsigned long previousText1Millis = 0;
unsigned long previousText2Millis = 0;
unsigned long previousText3Millis = 0;
unsigned long text3StartMillis = 0;
bool text3Active = false;
void setup()
{
Serial.begin(9600);
}
void loop()
{
unsigned long currentMillis = millis();
if (!text3Active)
{
// check if it's time to show "text1"
if (currentMillis - previousText1Millis >= TEXT1_INTERVAL)
{
Serial.println("text1");
previousText1Millis = currentMillis;
}
// check if it's time to show "text2"
if (currentMillis - previousText2Millis >= TEXT2_INTERVAL)
{
Serial.println("text2");
previousText2Millis = currentMillis;
}
// check if it's time to show "text3"
if (currentMillis - previousText3Millis >= TEXT3_INTERVAL)
{
Serial.println("text3");
previousText3Millis = currentMillis;
text3StartMillis = currentMillis;
text3Active = true;
}
}
else
{
// check if it's time to stop showing "text3"
if (currentMillis - text3StartMillis >= TEXT3_DURATION)
{
text3Active = false;
}
}
}
Was ist denn gleich?
Du willst, das Text 1 alle 2 sekunden kommt und Text 2 alle 4 Sekunden.
Das solange, bis Text 3 nach 20 Sekunden kommt.
Dann 10 Sekunden Pause
Dann wieder anfangen mit Text 1.
Genau das passiert.
17:18:30.280 -> text1
17:18:30.280 -> text2
17:18:32.278 -> text1
17:18:32.278 -> text3 -- 20 sekunden sind um
17:18:42.273 -> text1 -- Pause ende
17:18:42.273 -> text2 -- siehe text
17:18:44.272 -> text1
Nach der Pause sind die 4 sekunden als auch die 2 sekunden um.
Ja, die erste Ausführung ist ok. Aber danach wird Text3 nur noch alle 10 Sek. aktiv, anstatt alle 20 Sek.
17:25:49.374 -> text3
17:25:59.359 -> text1, nächster Start nach 10 Sek. Pause
17:25:59.359 -> text2
17:26:01.368 -> text1
17:26:03.364 -> text1
17:26:03.364 -> text2
17:26:05.363 -> text1
17:26:07.349 -> text1
17:26:07.349 -> text2
17:26:09.379 -> text1
17:26:09.379 -> text3, zweite Ausführung nach 10 Sek. anstatt 20 Sek.
Die 20 Sek. sollen ja erst nach der 10 Sek. Pause anfangen zu zählen.
Wenn Text3 aktiv, sollen die beiden Text1+2 Funktionen nicht ausgeführt werden.
Nach Aktivierung Text3 soll 10 Sek. Pause sein, danach wieder weiter mit Text1+2
Im Normalfall rechnet man millis nicht vorwärts, sondern vergleicht die abgelaufene Zeit.
if (aktuelleMillis - abgelaufeneZeit >= intervall)
Im Code oben rechne ich vorwärts:
previousText3Millis+=TEXT3_DURATION;
Das kann ich da aber auch machen.
Denn ich rechne nicht vorwärts, sondern setze previousText3Millisnur mit der aktuellen Zeit.
Alternativ hätte ich auch schreiben können:
previousText3Millis=millis();
Ich war hier nur mit dem Code weiter.
Es gibt einen kleinen Unterschied, der aber wichtig ist.
const int TEXT1_INTERVAL = 2000; // show "text1" every 3 seconds
const int TEXT2_INTERVAL = 4000; // show "text2" every 5 seconds
const int TEXT3_INTERVAL = 20000; // show "text3" every 20 seconds
const int TEXT3_DURATION = 10000; // show "text3" for 15 seconds
unsigned long previousText1Millis = 0;
unsigned long previousText2Millis = 0;
unsigned long previousText3Millis = 0;
unsigned long text3StartMillis = 0;
bool text3Active = false;
void setup()
{
Serial.begin(9600);
}
void loop()
{
unsigned long currentMillis = millis();
if (!text3Active)
{
// check if it's time to show "text1"
if (currentMillis - previousText1Millis >= TEXT1_INTERVAL)
{
Serial.println("text1");
previousText1Millis += TEXT1_INTERVAL;
}
// check if it's time to show "text2"
if (currentMillis - previousText2Millis >= TEXT2_INTERVAL)
{
Serial.println("text2");
previousText2Millis += TEXT2_INTERVAL;
}
// check if it's time to show "text3"
if (currentMillis - previousText3Millis >= TEXT3_INTERVAL)
{
Serial.println("text3");
previousText3Millis += TEXT3_INTERVAL;
text3StartMillis = currentMillis;
text3Active = true;
}
}
else
{
// check if it's time to stop showing "text3"
if (currentMillis - text3StartMillis >= TEXT3_DURATION)
{
text3Active = false;
previousText3Millis += TEXT3_DURATION;
}
}
}
Du wirst merken, das die Abweichung bei den Ausgaben nicht so groß ist.
Durch das aufrechnen mit den intervallen wird der Fehler des Durchlaufs kompensiert.
Nachtrag:
Du könntest sogar auf die Variable text3StartMillis verzichten und dafür previousText3Milliskomplett verwenden.
zum probieren:
if (currentMillis - previousText3Millis >= TEXT3_INTERVAL)
{
Serial.println("text3");
previousText3Millis += TEXT3_INTERVAL;
// text3StartMillis = currentMillis;
text3Active = true;
}
}
else
{
// check if it's time to stop showing "text3"
// if (currentMillis - text3StartMillis >= TEXT3_DURATION)
if (currentMillis - previousText3Millis >= TEXT3_DURATION)
{
text3Active = false;
previousText3Millis += TEXT3_DURATION;
}
}
In dem Zusammenhang ist die += Rechnung schon ok.
Ja!
Aber dann ist der Bezeichner falsch/unsauber.
Ein semantischer Fehler.
previous Millis == vorheriger millis wert
Es ist aber kein vorhergehender Wert, kein Mensch weiß, ob es diesen millis Wert je gegeben hat.
Es ist, nach der Addition sogar ein Zeitpunkt, der sicherlich meistens in der Zukunft liegen wird.
Also eher das Gegenteil von "vorherigem millis Wert"