Kann man millis() auf Null stellen? Im Sinne von:
if (miillis() > 1000 ){
millis(0)
}
Kann man millis() auf Null stellen? Im Sinne von:
if (miillis() > 1000 ){
millis(0)
}
Ich würde mir eher die Startzeit merken und von der aktuellen abziehen
start = millis();
...
if( (millis() - start) > Wartezeit) {
machwas
}
Ich glaube nicht, dass das möglich ist, aber welchen Sinn hat es, millis() auf Null zu setzen?
Ich habe das noch nie gebraucht. Um die verstrichene Zeit zu bestimmen, liest millis() den Wert ein, speichert ihn in einem vorzeichenlosen Long-Wert und vergleicht ihn, um die verstrichene Zeit zu berechnen.
Du musst nur die interne Zählvariable auf 0 setzen.
Beim Uno R3 wäre das
extern volatile unsigned long timer0_millis;
Hört sich nach einem Anfängerproblem an.
Hunderttausende Arduino Anwender kommen ohne das aus.
Kann man tun!
Ist aber meist/immer eine dumme Idee.
Was willst du "wirklich" erreichen?
Ja. Braucht man aber nur in (sehr seltenen) Ausnahmefällen.
Dein Glaube wird erschüttert ![]()
Du könntest deinen Arduino resetten. Statt den internen Zähler zurückzusetzen - beschreibe besser was du wirklich machen willst. Es gibt sicher einen überschaubaren Weg dafür.
unsigned long start;
void resetMillis() { start = millis(); }
unsigned long myMillis() { return millis() - start;}
Das funktioniert auf jeder Plattform, die die Arduino-Funktion millis() zur Verfügung stellt.
Unabhängig davon, ob es die interne Variable timer0_millis gibt oder nicht.
Und man ist sicher, dass keine Nebeneffekte auftreten, da man an keiner undokumentierten internen Variable rumfummelt.
Aber alle Vorredner haben auch recht: "Warum willstn das wissen" ?
Mir kämme die Idee zu fragen. Wieso willst Du das machen / Wozu brauchst Du das.
Grüße Uwe
Welche wären das?
Ich habs doch oben gezeigt. selten. Aber nützlich um die Auswirkungen zu testen.
Vermutlich alles aus der Kategorie "Wenn du es siehst weißt du es".
Selbst beim Testen der Überlaufs könnte bereits ein Timing losgelaufen sein das du jetzt störst und andere Fehler nach sich zieht.
Danke für eure Hinweise.
Warum die Frage aufkam:
Ich suchte nach einer Möglichkeit delay() zu umgehen. millis() ist die Lösung.
Ich habe es jetzt so gelöst:
if (millis() >= delayEndTime){
delayEndTime = millis() + delayTime;
tu was
...
Das Problem ist, wenn sich der Timer nach 49 Tagen auf 0 setzt, wird die Bedingung nicht mehr erfüllt.
Wer das braucht, braucht evtl. auch mehrere davon.
Das geht so:
class myMillis {
unsigned long start;
public:
myMillis() {start = 0;}
void reset() { start = millis(); }
unsigned long get() { return millis() - start;}
};
// ...
myMillis millis1, millis2; // können unabhängig voneinander rückgesetzt werden
void setup() {
pinMode(2, INPUT_PULLUP); // Test-Taster
Serial.begin(112500);
}
void loop() {
if (!digitalRead(2)) { millis1.reset(); return;}
Serial.print(millis()); Serial.print(": "); Serial.println(millis1.get());
delay(500);
}
@combie würde dazu noch ein paar Operatoren überladen, damit auch Sachen wie
Serial.println(millis1());
gehen.
Nachtrag: ist nicht für den TO, aber das wäre nur
unsigned long operator()() {return get();}
im public - Teil der class
Nachtrag2: Puristen schreiben
unsigned long get() const { return millis() - start;}
unsigned long operator()() const {return get();}
weil diese zwei Methoden das myMillis Objekt nicht verändern
... und die Methode get könnte man auch ganz durch den Operator ersetzen...
Bei der Addition gibt's Probleme mit dem Überlauf.
Mach's doch wie in #2.
Oder Du überlädst einfach die millis() Funktion
using Millis_t = decltype(millis());
Millis_t millis(Millis_t timestamp) {
return millis()-timestamp;
}
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.println(millis(millis()));
delay(1000);
Serial.println(millis());
}
Sicher, aber es gibt eine sehr gängige Methode dafür.
Wie bereits erwähnt, verwendet man zur Bestimmung der verstrichenen Zeit die Funktion millis(), um den Wert auszulesen, speichert ihn in einem vorzeichenlosen long-Wert und vergleicht ihn anschließend, um die verstrichene Zeit zu berechnen:
unsigned long tmrStart;
unsigned long delayInterval = 1000;
...
if (millis() - tmrStart >= delayInterval){
tmrStart = millis();
...
Diese Verwendung von millis() ermöglicht es Ihnen, das gewünschte Intervall festzulegen (in diesem Beispiel "delayInterval", das ich auf 1 Sekunde gesetzt habe) und behandelt auch einen Überlauf des "unsigned long" Werts nach 49 Tagen korrekt.
Glauben Sie mir, es funktioniert in 99,99 % der Fälle; Sie müssen millis() nicht zurücksetzen.
Die Addition ist das Problem.
Eine Subtraktion würde den Überlauf kompensieren.
Immer gerne!
Mein Basis Timer sieht so aus:
class SimpleTimer
{
private:
uint32_t timeStamp; // Zeitmerker
bool reached; // default Status: timer abgelaufen
public:
SimpleTimer():timeStamp(0),reached(true){}
void start()
{
timeStamp = millis();
reached = false;
}
void reset()
{
reached = true;
}
bool operator()(const uint32_t interval)
{
if(!reached) reached = millis() - timeStamp >= interval;
return reached;
}
};
Davon sind dann alle anderen Timer abgeleitet.
Entstehungsgeschichte: [Projekt] INTERVAL Ersatzstoff