Forum: Mikrocontroller und Digitale Elektronik micros() Timer auf Null stellen (Arduino)


von micros (Gast)


Lesenswert?

Gibt es eine sichere Methode ohne Nebeneffekte, den micros() Timer auf 
Null zu stellen? Das würde mir in einem speziellen Fall, laufende 
Differenzzeitbestimmung eines Prozesses, die Arbeit etwas erleichtern.

von my2ct (Gast)


Lesenswert?

micros schrieb:
> Das würde mir in einem speziellen Fall, laufende
> Differenzzeitbestimmung eines Prozesses, die Arbeit etwas erleichtern.

Was für Arbeit hast du bei der Differenzzeitbestimmung.
Die einfachste Rechenoperation dafür ist ein "-".

von Einer K. (Gast)


Lesenswert?

micros schrieb:
> Das würde mir in einem speziellen Fall, laufende
> Differenzzeitbestimmung eines Prozesses, die Arbeit etwas erleichtern.
Das glaube ich nicht!

Warum sollte das so sein?



micros schrieb:
> Gibt es eine sichere Methode ohne Nebeneffekte, den micros() Timer auf
> Null zu stellen?
Ein solcher Eingriff hat Nebenwirkungen (auf alles was micros() und 
millis() nutzt). Selbst die PWM Ausgabe bekommt Hackler.
Sollte man also möglichst unterlassen.

von Michael B. (laberkopp)


Lesenswert?

micros schrieb:
> Gibt es eine sichere Methode ohne Nebeneffekte, den micros() Timer auf
> Null zu stellen?

Nein. Vieles basiert auf timer0_millis.

> Das würde mir in einem speziellen Fall, laufende
> Differenzzeitbestimmung eines Prozesses, die Arbeit etwas erleichtern.

Echt

while(1)
{
  start=millis();
  :
  time=millis()-start;
}

möchtest du durch

void resetmillis(void)
{
  timer0_millis=timer0_fract=0;
}

while(1)
{
  resetmillis();
  :
  time=millis();
}

ersetzen. Klingt aufwändiger.

Das passiert normalerweise in einer Schleife und geht sowieso einfacher

stop=millis();
while(1)
{
  start=stop;
  :
  stop=millis();
  time=stop-start;
}

von Peter D. (peda)


Lesenswert?

micros schrieb:
> Das würde mir in einem speziellen Fall, laufende
> Differenzzeitbestimmung eines Prozesses, die Arbeit etwas erleichtern.

Da geht nichts zu erleichtern:
1
uint32_t start = micros();
2
// do something
3
uint32_t duration = micros() - start;

von micros (Gast)


Lesenswert?

An den Überlauf nach ~ 70 Sekunden dachtet ihr gar nicht?

Gut, in meinem Fall neutralisierte er sich. Wie so oft. Wußte ich aber 
eben noch nicht.

Die Routine ist zeitkritisch, ISR. Wollte die int32-Arithmetik etwas 
verkürzen. Aber es läuft (natürlich) auch so noch schnell genug.

OK. Danke an alle :-)


Frage noch:
timer0_millis hatte ich vorher schon ergoogelt. War aber irgendwie nicht 
ansprechbar, so dass ich dann das Posting hier abgesetzt habe.

Was ist timer0_millis für ein Konstrukt ?
1
void setup() {
2
  Serial.begin(9600);
3
  Serial.println(timer0_millis);
4
}
5
6
void loop() {
7
}

von Einer K. (Gast)


Lesenswert?

micros schrieb:
> timer0_millis hatte ich vorher schon ergoogelt. War aber irgendwie nicht
> ansprechbar, so dass ich dann das Posting hier abgesetzt habe.
>
> Was ist timer0_millis für ein Konstrukt ?
1
extern unsigned long timer0_millis;
2
3
void setup() 
4
{
5
  Serial.begin(9600);
6
  Serial.println(timer0_millis);
7
}
8
9
void loop() 
10
{
11
 Serial.println(timer0_millis);
12
 delay(500);
13
}

Vorsicht!
Das auslesen und beschreiben von timer0_millis sollte (anders, als hier 
gezeigt) atomar erfolgen!



micros schrieb:
> An den Überlauf nach ~ 70 Sekunden dachtet ihr gar nicht?
Warum?
Der ist doch unabwendbar.

micros schrieb:
> Gut, in meinem Fall neutralisierte er sich. Wie so oft. Wußte ich aber
> eben noch nicht.
Siehst du, so schlimm ist der Überlauf doch gar nicht... :-)

von Wolfgang (Gast)


Lesenswert?

micros schrieb:
> An den Überlauf nach ~ 70 Sekunden dachtet ihr gar nicht?

Der  spielt überhaupt keine Rolle, solange man saubere vorzeichenlose 
32bit-Arithmetik benutzt. Guck dir mal die Grundlagen dazu an.

von macros (Gast)


Lesenswert?

micros schrieb:
> An den Überlauf nach ~ 70 Sekunden dachtet ihr gar nicht?

Den Überlauf gibt es übrigens alle 2^32 usec, also 4295 Sekunden oder 71 
Minuten, und nicht alle 70 Sekunden. Aber wie schon in den vorigen 
Beiträgen geschrieben, ist er für die Differenzbildung egal solange 
deine zu messende Zeitspanne unterhalb dieser Grenze liegt.

von micros (Gast)


Lesenswert?

Den atomaren Zugriff hätte ich mir schon gedacht. Aber eins verstehe ich 
noch nicht: Wieso wird long timer0_millis, sobald als Variable 
vorhanden, automatisch bestückt?

>
1
> extern unsigned long timer0_millis;
2
>

von Einer K. (Gast)


Lesenswert?

micros schrieb:
> Wieso wird long timer0_millis, sobald als Variable
> vorhanden, automatisch bestückt?

Falsche Sicht auf die Dinge.

Es ist nur eine extern Deklaration in meinem Beispiel.
Keine Definition.

Die Variable wird vor setup() initialisiert und in einer ISR verändert.
Egal ob du sie nutzt, oder nicht.

von micros (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:

> Die Variable wird vor setup() initialisiert und in einer ISR verändert.
> Egal ob du sie nutzt, oder nicht.

Also die Variable gibt es schon - extern - und es wird nur eine Referenz 
erzeugt, auf die das Prog zugreifen kann. Habe ich es jetzt verstanden?

von Einer K. (Gast)


Lesenswert?

micros schrieb:
> eine Referenz

Der Begriff Referenz ist in C++ schon belegt.
Also nein, das ist keine Referenz.

extern teilt dem Compiler mit, dass sich die Variable in einer anderen 
Übersetzungseinheit befindet.
Der Linker tragt dann Sorge dafür, dass das klappt.

von micros (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:

> extern teilt dem Compiler mit, dass sich die Variable in einer anderen
> Übersetzungseinheit befindet.

OK, alles klar.

Anbei ein Lied. Das hast du dir jetzt wirklich verdient

On The Roth Again
https://www.youtube.com/watch?v=qRKNw477onU

;)

von Einer K. (Gast)


Lesenswert?


von Mario M. (thelonging)


Lesenswert?

micros schrieb:
> An den Überlauf nach ~ 70 Sekunden dachtet ihr gar nicht?

macros schrieb:
> Den Überlauf gibt es übrigens alle 2^32 usec, also 4295 Sekunden oder 71
> Minuten, und nicht alle 70 Sekunden.

Ähm, rechnet noch mal! ?

von micros (Gast)


Lesenswert?


von Einer K. (Gast)


Lesenswert?

Mario M. schrieb:
> Ähm, rechnet noch mal!

Doku lesen würde reichen...
(falls es beim rechnen hapert)
https://www.arduino.cc/reference/en/language/functions/time/micros/

von Mario M. (thelonging)


Lesenswert?

Ja, richtig. Micros gelesen und millis gedacht. Ziehe meinen Kommentar 
zurück.

von Stefan F. (Gast)


Lesenswert?

micros schrieb:
> An den Überlauf nach ~ 70 Sekunden dachtet ihr gar nicht?

Doch. Der Trick liegt in der Subtraktion, denn sie liefert nach einem 
Überlauf immer noch ein korrektes Ergebnis. Nur bei mehr als einem 
Überlauf klappt das nicht mehr, aber dann wäre die Zählvariable so oder 
so zu klein.

Manche Leute versuchen es anders herum mit einer Addition, das klappt 
aber nicht:
1
uint32t timeout=millis()+10000;
2
while (millis()<timeout)
3
{
4
    doSomething();
5
}

Bitte nicht nachmachen!

von Torsten (Gast)


Lesenswert?

Hallo Micros,

schau hier mal vorbei: 
https://forum.arduino.cc/index.php/topic,85706.0.html
Da gehts zwar um millis(), aber das Problem ist ja an sich das gleiche.

Ich denke damit wird klarer, was dir das Forum hier sagen will :-)

von extern (Gast)


Lesenswert?

> extern unsigned long timer0_millis;

>>extern teilt dem Compiler mit, dass sich die Variable in einer anderen
Übersetzungseinheit befindet.


und zwar genau in:
wiring.c
deklariert als
volatile unsigned long timer0_millis = 0;

gefunden über:
1
arduino$ grep -r 'timer0_millis' *
2
hardware/arduino/avr/cores/arduino/wiring.c:  unsigned long m = timer0_millis;
(Linux Bash)(aber über CygwinKannManJaAuch)

von Cyblord -. (cyblord)


Lesenswert?

extern schrieb:
>> extern unsigned long timer0_millis;
>
>>>extern teilt dem Compiler mit, dass sich die Variable in einer anderen
> Übersetzungseinheit befindet.
>
>
> und zwar genau in:
> wiring.c
> deklariert als
> volatile unsigned long timer0_millis = 0;
>
> gefunden über:
>
1
> arduino$ grep -r 'timer0_millis' *
2
> hardware/arduino/avr/cores/arduino/wiring.c:  unsigned long m = 
3
> timer0_millis;
4
>
> (Linux Bash)(aber über CygwinKannManJaAuch)

Wow, in Eclipse drücke ich F3 wenn der Cursor auf dem Variablennamen ist 
und springe direkt zur Definition. Aber klar, man kann auch über bash 
Befehle gehen....

Aber woher sollen Arduinos auch eine ordentliche Entwicklungsumgebung 
kennen. Armselig.

von Stefan F. (Gast)


Lesenswert?

Cyblord -. schrieb:
> Aber woher sollen Arduinos auch eine ordentliche Entwicklungsumgebung
> kennen. Armselig.

Eclipse ist allerdings auch nicht gerade ein leuchtendes Vorbild. Diese 
IDE akzeptiere ich so wie sie ist nur, weil sie kostenlos ist.

von Cyblord -. (cyblord)


Lesenswert?

Stefanus F. schrieb:
> Cyblord -. schrieb:
>> Aber woher sollen Arduinos auch eine ordentliche Entwicklungsumgebung
>> kennen. Armselig.
>
> Eclipse ist allerdings auch nicht gerade ein leuchtendes Vorbild. Diese
> IDE akzeptiere ich so wie sie ist nur, weil sie kostenlos ist.

Egal. IntellIJ und Konsorten können das alle auch. Eclipse war nur ein 
Beispiel. Ist sowieso eine Glaubensfrage. Aber ich mag es.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.