[Bericht] Der (Millis) Ueberlauf im Test

DU erkläre, warum: was ich in #19 nach dem Komma beschrieben habe.

Der Timer hinter millis() läuft auf 1,024ms. Die Nachkommastellen werden gesammelt und wenn die 1ms ergeben, springt millis() halt mal um 2ms weiter.

Modulo schneidet aber alles nach dem Komma ab.
Damit ist Deine Vorlage ungeeignet um das unterschiedliche Verhalten zwischen millis() und % darzustellen.

Du führst in die Irre - siehe oben.

Im Übrigen ist das falsch:

Wie gehts denn dann?

Meine Ausgabe:

22:18:01.804 -> 1
22:18:01.837 -> 2
22:18:01.837 -> 3
22:18:01.837 -> 4
22:18:01.837 -> 5
22:18:01.837 -> 6
22:18:01.837 -> 7
22:18:01.837 -> 8
22:18:01.837 -> 9
22:18:01.837 -> 10
22:18:01.837 -> 11
22:18:01.837 -> 12
22:18:01.837 -> 13
22:18:01.837 -> 14
22:18:01.837 -> 15
22:18:01.837 -> 16
22:18:01.837 -> 17
22:18:01.837 -> 18
22:18:01.837 -> 19
22:18:01.837 -> 20
22:18:01.837 -> 21
22:18:01.837 -> 22
22:18:01.837 -> 23
22:18:01.837 -> 24
22:18:01.837 -> 25
22:18:01.837 -> 26
22:18:01.837 -> 27
22:18:01.837 -> 28
22:18:01.837 -> 29
22:18:01.837 -> 30
22:18:01.837 -> 31
22:18:01.837 -> 32
22:18:01.870 -> 33
22:18:01.870 -> 34
22:18:01.870 -> 35
22:18:01.870 -> 36
22:18:01.870 -> 37
22:18:01.870 -> 38
22:18:01.870 -> 39
22:18:01.870 -> 40
22:18:01.870 -> 41
22:18:01.870 -> 43
22:18:01.870 -> 44
22:18:01.870 -> 45
22:18:01.870 -> 46
22:18:01.870 -> 47
22:18:01.870 -> 48
22:18:01.870 -> 49
22:18:01.870 -> 50
22:18:01.870 -> 51
22:18:01.870 -> 52
22:18:01.870 -> 53
22:18:01.870 -> 54
22:18:01.870 -> 55

Da springt nichts 2ms!
Du verlierst EINE ms.
Und zwar genau die, die Du eigentlich mit Deinem Code bekommst.
Ich weiss, was Du erklären willst. Aber das hast Du nicht gemacht.
Und darauf ist @michael_x reingefallen.

auf die 42 zeig schau mal

2 Likes

Ja,
da wird EINE ms gezählt und EINE ms aufaddiert aus dem Nachkomma.
Da springt nichts 2ms!
Denn wie Du selbst merken wirst, wird irgendwann mal das aufaddieren nicht nach 42ms passieren, weil es eben ein aufaddieren ist. Nicht mehr.

Mit anderen Worten... die Rückgabe von millis() springt da der Rückgabetyp keine Kommazahlen darstellen kann.

Finde den Fehler!
Das tut es nicht.
Egal wie Du das versuchst zu rechtfertigen.
Den Beweis habe ich in #25 erbracht.

42 wird von millis() nicht zurückgegeben. Ist halt nötig um die angestaute "ungenauigkeit" auszugleichen.

Das sind keine 2ms! - Und schon gar nicht eine "angestaute Ungenauigkeit" Das ist beabsichtigt.

Und damit ist das durch.
Deine Rechtfertigungen deiner Uneinsichtigkeit sind ausreichend.

if(millis() == 42) Serial.print("Du hast gewonnen");
void loop() {
  if (millis()%1==0) {
    return;
  }
  Serial.println(millis());
}

Ja!
das geht auch mit %2 ganz gut. Oder mit %3 - oder wie auch immer.

Nirgend springt es um 2ms.
Mehr noch:
Bei %3 wird es schon spannend.

Mach mal.
:wink:

[code]
  if ((millis() / 3000) % 2 == 1)//LCD alle 3Sek umschalten
  {
    if (temp < 10){
      LCD.setCursor(0, 1);
      LCD.print(F("In   "));
      LCD.print (temp - 1, 1);
    }
    else {
      LCD.setCursor(0, 1);
      LCD.print(F("In   "));
      LCD.print (temp - 1, 1);
    }
  }
  else
  {
    if (tempaus < 10) {
      LCD.setCursor(0, 1);
      LCD.print(F("Aus  "));
      if (tempaus == -127.0)LCD.print("    ");
      else LCD.print (tempaus, 1); //DS18B20
    }
    else {
      LCD.setCursor(0, 1);
      LCD.print(F("Aus  "));
      LCD.print (tempaus, 1); //DS18B20
    }
  }

[/code]

das funktioniert bei mir sehr gut.
ich Wage sogar Behaupten das es gibt keinen Menschen der unter 10 millis irgend was wahrnehmt

Deine beiden returns sorgen dafür das die Hauptprogrammschleife urplötzlich verlassen wird. Es gibt keinen vernünftigen Grund sowas jemals zu tun. Bei dem Programmierstil wird nachfolgender Code holprig bis gar nicht abgearbeitet. Formuliere die if Bedingung so das nur was ausgeführt wird wenn erforderlich. Ansonsten soll nachfolgender Code abgearbeitet werden soweit vorhanden.

Nach Prüfung verlassen. Natürlich kann man den Code auch so schreiben:

unsigned long last;

void setup() {
  Serial.begin(115200);
  last = millis();
}

void doIt() {
  auto now = millis();
  if (now != last) {
    if ((now - 1) == last) {
      last = now;
    } else {
      Serial.println(now);
      last = now;
    }
  }
}

void loop() {
  doIt();
}

Aber ob das einfacher zeigt, das man bei millis() keinen X == Y -vergleich machen sollte, wage ich zu bezweifeln.

Ich glaube ich kann mich glücklich schätzen, das da keine Ressourcen allokiert wurden, die am Ende wieder freigegeben werden müssen, da du sonst noch ein paar gotos gesehen hättest...

Hallo,

ist das sinnvoll? :face_with_monocle:

if ((now - 1) == last) {
  last = now;
} else {
  last = now;
}

Es ging um das return!
Die aufgerufene Funktion kann man mittels return verlassen. Da spricht nichts dagegen.

Kann ich auch nicht nachvollziehen. Mit now wird auch Speicher belegt der
automatisch wieder freigegeben wird. last würde ich übrigens lokal machen. Aber wofür der Aufwand wenn das ganze Kontrukt sowieso Verkompliziert und Unsinn ist ...
Wenn du das Rad unbedingt neu erfinden möchtest meinetwegen. Zum nachahmen aber nicht empfohlen.

Nachdem du die hälfte gelöscht hast, nicht mehr.

Das merkst du jetzt selber oder?

Heap und Stack funktionieren da ein wenig unterschiedlich.

Zeig mal bitte.

Du hast nach einer Variante ohne Return gefragt...

Es soll zeigen, das millis() und X==Y-Vergleiche nicht gut zusammengehen, aber wenn du das nicht siehst...

Wozu? Mehr als das millis() springt wird da nicht bei rauskommen.

Hallo,

Ich habe es auf das Wesenliche reduziert ohne die Funktionalität von deinem if else zu ändern. Normalerweise solltest du auf Grund dessen sehen was daran sinnlos ist, weil es ins Auge sticht. Wenn du es komplett benötigst dann eben so. Ändert daran nichts.

void doIt() {
  auto now = millis();
  if (now != last) {
    if ((now - 1) == last) {
      last = now;
    } else {
      last = now;
    }
  }
}

Wer etwas von Heap und Stack erzählt der wird wohl Grundkenntnisse haben wie man eine lokale Variable anlegt. Dazu musst du mich sicherlich nicht fragen.