PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : NodeMCU 8662: CountDown erstellen



mjovi
04.12.2018, 11:57
Hallo. Ich mal wieder ;)
Mein erstes Projekt ist nun erledigt und nun geht's gleich ans zweite:
Ich möchte für unseren Bogensportverein eine Schießtimer bauen.
Als Ausgabe hab ich eine LED Matrix.
Steuerung soll über einen ESP8266WebServer erfolgen.
Ziel ist das der Client einen Start Request schickt und dann der Countdown 20 Sekunden herunterzählt. Das ist die Vorbereitungszeit.
Dann zählt er 120 Sekunden herunter. Schießzeit.
20 Sekunden vor ende der Schießzeit wird der Hintergrund des Displays GELB um anzuzeigen das es gleich vorbei ist.
Dann wird der Display wieder rot. Schießzeit zu ende.


Alles soweit kein Problem aber wie gehe ich mit der korrekten zeit um?
delay(1000) ist unschön und man kann dann ja auch die Verarbeitung nicht abbrechen.
In Java gibt's das Object Timer() und TimerTask()

gibt's sowas auch hier?

Vielen Dank und Viele Grüße
Michael

HaWe
04.12.2018, 12:05
hallo,
such mal nach dem Beispiel (Arduino example) "Blink without delay()"

mjovi
04.12.2018, 12:58
Hallo.
hab ich versucht aber das läuft ja dann immer in einer endlosschleife und ich habe keine Möglichkeit die schleife zu unterbrechen. Das ganze müsste in einem Thread laufen. Gibt es sowas?

Sorry.. Hier mein Code:


void runTime(int mytime, uint16_t myColor){
unsigned long previousMillis = 0;
unsigned long actTime = mytime;
setBGColor(myColor);
doRun = true;
while(doRun){
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// do something
if(actTime >= 0){
displayTime(String(actTime));
actTime--;
} else {
doRun = false;
}
}
}
}

HaWe
04.12.2018, 13:25
nein, auf dem esp8266 gibt es von offizieller Seite keine threads für multithreading (ist wohl auch nicht vorgesehen), bis auf manche experimentelle Versuche einzelner Privatleute, ansonsten nur multithreading auf den normalen Arduinos (z.B. über Scheduler libs).

Ich könnte mir aber vorstellen, dass man aus den timer-Schleifen ausbrechen könnte, per semaphor

if(semaphor==x) return ()

Du springst andernfalls von loop aus die timer Funktion wiederholt an, lässt sie checken, und dann einen Wert zurückgeben, den du weiter verarbeitest (oder machst alles in loop).

HaWe
04.12.2018, 16:03
so in dieser Art:




uint32_t starttime;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(3000);
Serial.println("Serial started");

starttime=millis(); // start countdown
}


void setBGColor(uint32_t myColor){ } // eigene Funktion verwenden!


void setcolor(uint32_t timesec) {
uint32_t myColor2, myColor1, myColor0; // Color-Werte definieren!

if(timesec>20) {
setBGColor(myColor2);
Serial.println("myColor2");
}
else
if(timesec<=5 && timesec>=0 ) {
setBGColor(myColor0);
Serial.println("myColor0");
}
else
if(timesec<=20 && timesec>0) {
setBGColor(myColor0);
Serial.println("myColor1");
}

}

uint32_t countdowntime=20; // sec countdown;

void loop() {
static int32_t passedsec, oldpassedsec=0, dtimesec=-1;

passedsec= (millis()-starttime)/1000;

if(oldpassedsec!=passedsec && passedsec<=countdowntime) {
dtimesec=countdowntime-passedsec;
Serial.println(dtimesec);
setcolor(dtimesec);
oldpassedsec=passedsec;
if(dtimesec==0 && countdowntime==20) {
countdowntime=120;
starttime=millis();
}
}


// *SNIP*
// do anything important
// *SNIP*

delay(1); // yield

}

HaWe
05.12.2018, 17:50
hast du den Code mal getestet?

mjovi
13.12.2018, 09:35
Hallo,
Vielen Dank für eure Hilfe.
Ich habe es nun zum laufen gebracht.
Vielen Dank an HaWe.

Jetzt ist es doch etwas grösser geworden.. Jaja.. mit dem essen steigt der Appetit.

Viele grüße
Michael

Moppi
13.12.2018, 10:07
In Java gibt's das Object Timer() und TimerTask()

Sowas wie timer() in anderen Sprachen gibt es auch auf den ATmegas. Dazu muss aber der Timer programmiert werden, ist der dann abgelaufen, kann er einen Interrupt auslösen, so dass man also damit eine Funktion verbinden kann. Soweit meine laienhafte Beschreibung, ich habe das in anderen Zusammenhängen nebenbei mal gesehen, dass das möglich ist.

MfG

HaWe
13.12.2018, 11:27
Sowas wie timer() in anderen Sprachen gibt es auch auf den ATmegas. Dazu muss aber der Timer programmiert werden, ist der dann abgelaufen, kann er einen Interrupt auslösen, so dass man also damit eine Funktion verbinden kann. Soweit meine laienhafte Beschreibung, ich habe das in anderen Zusammenhängen nebenbei mal gesehen, dass das möglich ist.

MfG
ok, ATMegas...
aber nur aus Interesse:
wie funktioniert das auf den hier im Projekt verwendeten nodeMCUs mit den 2 oder 3 benötigten Sekunden-Timern?

Moppi
13.12.2018, 11:47
Auch dort wird es Timer geben, die sich programmieren lassen, davon geh ich aus. Weil das nodeMCU komp. zu ATmega sein soll.

Nachgeschaut: Benutzt werden kann der Timer#1, Auflösung in Microsekunden, der einen Interrupt auslösen kann.
Allerdings weiß ich nicht, wie es beim 8662 ist.

Für den 8266 kann man wohl die Ticker.h verwenden: https://github.com/esp8266/Arduino/tree/master/libraries/Ticker

MfG

HaWe
13.12.2018, 13:25
Auch dort wird es Timer geben, die sich programmieren lassen, davon geh ich aus. Weil das nodeMCU komp. zu ATmega sein soll.

Nachgeschaut: Benutzt werden kann der Timer#1, Auflösung in Microsekunden, der einen Interrupt auslösen kann.
Allerdings weiß ich nicht, wie es beim 8662 ist.

Für den 8266 kann man wohl die Ticker.h verwenden: https://github.com/esp8266/Arduino/tree/master/libraries/Ticker

MfG

ah, danke, also extra Ticker lib, kannte ich noch nicht!
(nodeMCU ist ja gleich ESP8266, und sie sind nicht kompatibel zu AVRs!)

mjovi
14.12.2018, 09:03
Vielen Dank.
Schau ich mir dann mal an.

Viele Grüße
Michael