millis()-Glaubensfrage

Hallo,

ist es lediglich eine Glaubensfrage, was "man" verwenden sollte? :roll_eyes:

if(millis()-intervall>letzter_zeitpunkt)

if(millis()>letzter_zeitpunkt+intervall)

Gruß Chris

Meiner Meinung nach ist das keine Glaubensfrage sondern eine Kenntnisfrage. Wenn Du Dich besser auskennst, dann ist die Antwort weder noch. Ich sag nur "msTimer2 und Freunde".

Chris72622:
ist es lediglich eine Glaubensfrage, was "man" verwenden sollte? :roll_eyes:

if(millis()-intervall>letzter_zeitpunkt)

if(millis()>letzter_zeitpunkt+intervall)

Was sind denn das für Alternativen, wenn Du die Wahl zwischen Pest und Cholera anbietest?

Korrekt natürlich:

if(millis()-letzter_zeitpunkt>=intervall)

[quote author=Udo Klein link=topic=195429.msg1442155#msg1442155 date=1382710102]Ich sag nur "msTimer2 und Freunde".
[/quote]

Läuft laut Spezifikationen nicht auf dem Mega, oder? Worin bestehen denn die großen Vorteile?

http://playground.arduino.cc/Main/MsTimer2

Gruß Chris

msTimer2 löst dann aus wenn der Interrupt kommt und nicht dann wen der Code drankommt.
Weiterhin trennt das Design dann sauberer zwischen der eigentlichen Arbeit und der Zeitbehandlung.

Nachteilig ist, daß man dazu zumindest rudimentär verstehen muß was es bedeutet nebenläufigen Code zu haben. Deshalb hatte ich ja gesagt, daß es eine Kenntnisfrage ist. Die msTimer2 auf einen anderen Controller zu portieren ist nicht schwierig.

Wenn Du die Vorteile nicht siehst, kannst Du auch die andere Lösung verwenden. Allerdings ist die Detailfrage auf welcher Seite des Vergleichs man rechnen soll von untergeordneter Bedeutung. Ich würde die Konstante auf eine Seite alleine sortieren. Im Zweifelsfall gibt das infinitesimal kompakteren und schnelleren Code. An dieser Stelle zu optimieren ist aber weniger wirkungsvoll als den Nummernschildhalter am Auto abzuschrauben um Sprit zu sparen.

Ich glaube, das ist kein Unterschied, würde das aber eher so machen:

if(millis()>naechster_zeitpunkt){
  naechster_zeitpunkt = millis()+intervall;
  // sonstige Befehle
}

dann muß die Summe nur einmal berechnet werden.

[quote author=Udo Klein link=topic=195429.msg1442196#msg1442196 date=1382711138]An dieser Stelle zu optimieren ist aber weniger wirkungsvoll als den Nummernschildhalter am Auto abzuschrauben um Sprit zu sparen.
[/quote]

Alles klar- werd dann mal den Schraubendreher rausholen. :zipper_mouth_face:

Gruß Chris

Wenn Du dabei bist kannst Du auch noch gleich die Fußmatten saugen. Das bringt nochmal zusätzliche Gewichtsersparnis :wink:

guntherb:
Ich glaube, das ist kein Unterschied, würde das aber eher so machen:

Es macht beim Timen von Intervallen mit Hilfe der millis() Funktion keinen Unterschied bei Programmen, die weniger als 25 oder 50 Tage am Stück laufen, bevor sie resettet werden.

Wenn man Programme schreibt, die korrekte Intervalle auch bei Sketch-Laufzeiten von mehr als 50 Tagen am Stück einhalten sollen, und zwar bei allen Intervallen, auch über den Überlauf des Timers hinweg, der muß sich an bestimmte Standards halten.

Und Aschenbecher ausleeren XD

Gruß,
Ralf

guntherb:
Ich glaube, das ist kein Unterschied, würde das aber eher so machen:

if(millis()>naechster_zeitpunkt){

naechster_zeitpunkt = millis()+intervall;
 // sonstige Befehle
}



dann muß die Summe nur einmal berechnet werden.

Der Unterschid ist ob bei einem Überlauf der Intervall korrekt berechnet wird oder nicht.
Nehmen wir mal an daß der Überlauf bei 9 auftritt und nach 9 0 kommt.
Annahme millis() ist 7 und intervall ist 3 und naechster_zeitpunkt war am anfang 6
Daraus laut Deine Rechnung ergibt sich:

if(7>naechster_zeitpunkt){  // 7 ist > 6 
  naechster_zeitpunkt = 7+3; = 0
  // sonstige Befehle
}

Nächster Durchlauf nach 1 Millisekunde:

if(7>0){   / bedingung ist wahr obwohl nur 1 Milliskunde vergangen ist und nicht 3 wie intervall.
  naechster_zeitpunkt = 7+3; = 0
  // sonstige Befehle
}

Der Überlauf wird falsch gehandhabt.
Grüße Uwe

Schachmann:

[quote author=Udo Klein link=topic=195429.msg1442216#msg1442216 date=1382711777]
Wenn Du dabei bist kannst Du auch noch gleich die Fußmatten saugen. Das bringt nochmal zusätzliche Gewichtsersparnis :wink:

Und Aschenbecher ausleeren XD

Gruß,
Ralf
[/quote]
Dann muß mann auch doppelt fleißig die Insektenkadaver von der Windschutzscheibe kratzen (wegen Gewicht und Verschlechterung des cw-Wertes durch Unebenheit). :wink: :wink:
Grüße Uwe

jurs:
Wenn man Programme schreibt, die korrekte Intervalle auch bei Sketch-Laufzeiten von mehr als 50 Tagen am Stück einhalten sollen, und zwar bei allen Intervallen, auch über den Überlauf des Timers hinweg, der muß sich an bestimmte Standards halten.

Welche sind das?

Gruß Chris

Chris72622:

jurs:
Wenn man Programme schreibt, die korrekte Intervalle auch bei Sketch-Laufzeiten von mehr als 50 Tagen am Stück einhalten sollen, und zwar bei allen Intervallen, auch über den Überlauf des Timers hinweg, der muß sich an bestimmte Standards halten.

Welche sind das?

Gruß Chris

Das hat ja jurs im Reply #2 schon beschrieben:

Korrekt natürlich:

if(millis()-letzter_zeitpunkt>=intervall)

Grüße Uwe

Na wenn das alles ist. :*

Gruß Chris

Chris72622:
Na wenn das alles ist. :*

Fast alles, es wäre auch zu berücksichtigen, dass letzter_zeitpunkt als "unsigned long" deklariert werden muß und keinesfalls nur als "long".

Da kommt Donald Knuths Aussage "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil" wieder zum Tragen.

Übertriebene und vorauseilende Optimierung ist nicht immer gut, da sich dadurch auch wieder leicht Fehler einschleichen können oder der Code schlechter lesbar wird.

Wenn es unbedingt mit millis() sein muß, dann würde ich das wenigstens wegkapseln. Ähnlich wie im Lighthouses Experiment (Lighthouses | Blinkenlight).

typedef void (*command)();

template <unsigned long wait_ms, command c>
void repeat() {
    static unsigned long start = millis();
    if (millis()-start >= wait_ms) {
        start += wait_ms;
        c();
    }
}

void task1() {
    Serial.println(F("1 second elapsed"));
}

void task2() {
    Serial.println(F("2 seconds elapsed"));
}

void task3() {
    Serial.println(F("3 seconds elapsed"));
}


void setup() {
    Serial.begin(115200);
}


void loop() {
    repeat<1000, task1>();
    repeat<2000, task2>();  
    repeat<3000, task3>();  
}

Dann ist wenigstens das Timergefrickel vom Rest sauber getrennt.

Habt ihr euch ja nun genug wegen millis() um die Ohren gehauen. :smiley:
Eher "pille-palle" - oder ? (bei Überlauf mal abgesehen - aber auch das ist meistens mit/in der [längeren] Loop automatisch kompensiert).
Leute ... das ist dann doch schon OK, wenn wenigstens kein delay verwendet wird. 8)
Wirklich kaum jemand hat es bei normalen Abfragen in der Loop so was von genau eilig - wer doch, muss eben auf Timer oder Interrupts zurückgreifen.

.... nu kommt jemand wegen micros() mit der gleichen Frage um die Ecke ?!
Die sind beteff der Genauigkeit eh schon mal 4 Ticks ungenau.

Der Ball ist wieder zur Duskussion im Feld zur weiteren Bespielerei. :grin:

Eure Sorgen will ich haben... 8)