Forum: Mikrocontroller und Digitale Elektronik millis denkproblem


von pascal (Gast)


Lesenswert?

Hallo , ich habe meine Code fast fertig, mit delay geht auch alles.

nun will ich aber in bestimmten fällen 2 sachen gleichzeitig schalten 
und nicht im delay hängen.

mit
if ((hilfausloesen == 1) && (currentMillis - previousMillis) <= magzeit)

komme ich im loop in meine schleife, aber das ist ja nicht was ich will.
in dem fall oben komme ich ja nur alle (magnetzeit) in die schleife

Ich möchte dass im loop die Bedingung immer wahr ist solange wie die 
magnetzeit ist .
Also angenommen die magnetzeit ost 100ms dann soll die bedinung 100ms 
wahr sein.
.

while will ich nicht verwenden weil ich dann ja wieder festhänge.


hat da jemand einen lösungsvorschlag?

Nach 3 stunden googlen dachte ich frag hier mal.

: Gesperrt durch Moderator
von jo mei (Gast)


Lesenswert?

Code-Übermittlung in Prosa ist scheisse.

Zeige dein Programm und versuche nochmal genauer zu beschreiben
was du wann erreichen willst.

Beachte: längere Code (als eine Bildschirmseite) als Anhang posten.

von pascal (Gast)


Lesenswert?

ich möchte mit millis eine funktion eine zeit ausführen, mehr eigentlich 
nicht.

z.b. führe 1000ms ein befehl aus.

Eigentlich das selbe wie delay macht nur ohne festhängen.

von Mth (Gast)


Lesenswert?

Dann Timerinterrupt

von Wolfgang (Gast)


Lesenswert?

pascal schrieb:
> Eigentlich das selbe wie delay macht nur ohne festhängen.

Dann setze beim Start eine Variable auf den Startzeitpunkt und frage in 
deiner Hauptschleife immer ab, ob die aktuelle Zeit minus der Startzeit 
größer als die Dauer ist. Wenn das der Fall ist, ist dein "Delay" 
abgelaufen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

pascal schrieb:
> z.b. führe 1000ms ein befehl aus.
Willst du, dass der Befehl 1s "dauert" oder dass während der 1s 
"andauernd" der selbe Befehl wiederholt wird?

> Eigentlich das selbe wie delay macht nur ohne festhängen.
Im Ernst: du musst einfach nochmal ein wenig über die Möglichkeiten der 
Abfrage von millis() nachdenken. "Ein wenig" kann schon mal 1-2 Tage 
dauern. Aber millis() wird dein Problem lösen.


Wenn ich eine Schleife hätte und während 1s irgendwas ausführen wollte, 
dann würde ich mir die Startzeit merken:
1
   if (startknopf_gedrueckt())
2
      startzeit = millis();
und dann prüfen, ob die aktuelle Zeit schon 1s weiter ist. Ist die 
aktuelle Zeit kleiner als startzeit+1000ms, dann tue ich das, was für 
eine Sekunde zu tun ist:
1
   if (millis() < startzeit+1000)
2
      tu_das_was_eine_sekunde_lang_zu_tun_ist();
Und weil bei dieser Abfrage das übliche Überlaufproblem passieren kann, 
stelle ich die Rechung um, dass das nicht mehr passiert:
1
void loop() {
2
   if (startknopf_gedrueckt())
3
      startzeit = millis();
4
5
   if (millis()-startzeit < 1000) 
6
      tu_das_was_eine_sekunde_lang_zu_tun_ist();
7
}

Wenn du konkrete Hilfe willst, dann poste genau den Code, der dir 
Probleme bereitet. Nicht nur Ausschnitte, wo nichts nirgends passt:
> magzeit .... magnetzeit
Was jetzt?
Und wie gesagt: ruhig mal 1-2 Tage über die Verwendung von millis() 
nachdenken. Sonst hast du laufend solch simple Probleme damit.

: Bearbeitet durch Moderator
von Wolfgang (Gast)


Lesenswert?

Lothar M. schrieb:
> if (millis() < startzeit+1000)

So geht's nicht ...

Spätestens nach einem Überlauf des millis()-Zählers geht dies Art der 
Abfrage gnadenlos schief und man sucht sich einen Wolf.

Beitrag "Re: Arduino frage zu Serial.print"

von Random .. (thorstendb) Benutzerseite


Lesenswert?

pascal schrieb:
> nun will ich aber in bestimmten fällen 2 sachen gleichzeitig schalten
> und nicht im delay hängen.
Schonmal Richtung RTOS geschaut? Ein Scheduler hilft dir hier und 
entzerrt dein Programm. In der Zeit des Delay kannst schonmal andere 
Sachen machen.
Wenn es sehr präzise sein muss, dann wäre ein Timer Interrupt von 
Vorteil, welcher natürlich unabhängig läuft.

> mit
> if ((hilfausloesen == 1) && (currentMillis - previousMillis) <= magzeit)
Bei diesem Denglisch-Konstrukt bekomme ich aber auch Denkprobleme ;-)

von Mth (Gast)


Lesenswert?

Wolfgang schrieb:
> Lothar M. schrieb:
>> if (millis() < startzeit+1000)
>
> So geht's nicht ...
>
> Spätestens nach einem Überlauf des millis()-Zählers geht dies Art der
> Abfrage gnadenlos schief und man sucht sich einen Wolf.

Aber als uint32 geht zB ((millis() - Start) < 1000)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> So geht's nicht ...
Genaus das habe ich zum Glück sofort gleich im Satz danach 
geschrieben. Und einen Hinweis zum Nachdenken über das "übliche 
Überlaufproblem" geliefert.

> So geht's nicht ...
Lustigerweise "geht's" so doch. Aber es "spinnt" halt mal alle paar 
Tage. Vielen ist das "gut genug".

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Lothar M. schrieb:
>> So geht's nicht ...
> Lustigerweise "geht's" so doch. Aber es "spinnt" halt mal alle paar
> Tage. Vielen ist das "gut genug".

Ohje ...
Ich will daran glauben können, dass für einen Aufzug oder PKW alle 
Kriterien der Sicherheit eingehalten wurden und solche Konstrukte dort 
nicht existieren ...
:-)

von Wolfgang (Gast)


Lesenswert?

Lothar M. schrieb:
> Genaus das habe ich zum Glück sofort gleich im Satz danach
> geschrieben.
Dann schreib solchen Unfug gar nicht erst als Programmzeile hin. Das 
Konstrukt funktioniert nämlich genau nicht. Grund ist, dass du in C 
nicht die Menge der ganzen Zahlen zur Verfügung hast.

> Aber es "spinnt" halt mal alle paar Tage.
Genau solche Software braucht die Welt nicht. Das meinte ich mit "man 
sucht sich einen Wolf".

Mth schrieb:
> Aber als uint32 geht zB ((millis() - Start) < 1000)
Genau das steht im verlinkten Post, danke.

von Philipp G. (geiserp01)


Lesenswert?

pascal schrieb:
> magnetzeit

[E] = N/C * t = V/m * t

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> Dann schreib solchen Unfug gar nicht erst als Programmzeile hin.
Ich vertraue darauf, dass einer nicht völlig verblödet die erstbeste 
Codezeile kopiert, die er im Internet findet, sondern wenigstens den 
Text drumrum anschaut.
Und wenn er sowas trotzdem ohne Verständnis und unkontrolliert tut, dann 
darf er sich von mir aus ruhig den Wolf suchen. Vielleicht lernt er es 
auf diese Art. Und wenn nicht, dann liegt das eigentliche Problem 
nicht daran, dass diese Zeile dort steht.
Das war die Ansage zum Freitag.

> Das Konstrukt funktioniert nämlich genau nicht. Grund ist, dass du in C
> nicht die Menge der ganzen Zahlen zur Verfügung hast.
Und deshalb ein unsigned long verwendet wird und damit der millis() 
Timer nach 2**32 ms = 49 Tagen überläuft. Und genau dann gibt es ein 
Problem, denn nach millis() == 4294967296 kommt eine Millisekunde später 
millis() == 0.
Die Suche zu den Stichworten "millis" und "49 Tage" bringt dann auch ein 
Füllhorn an Informationen:
https://www.google.com/search?q=millis+49+tage

von Nick M. (Gast)


Lesenswert?

Zwei statemachines die hintereinander laufen (in einer Mainloop) wäre 
die Lösung die dem ursprünglichen Ansatz am nächsten kommen.

Edit:
Kann man natürlich in zwei Tasks zerlegen, jede eine state machine und 
die zwei tasks werden in der mainloop aufgerufen.

von Philipp G. (geiserp01)


Lesenswert?

Dann mach es halt so:

1
// constants won't change. Used here to set a pin number:
2
const int ledPin =  LED_BUILTIN;// the number of the LED pin
3
4
// Variables will change:
5
int ledState = LOW;             // ledState used to set the LED
6
7
// Generally, you should use "unsigned long" for variables that hold time
8
// The value will quickly become too large for an int to store
9
unsigned long previousMillis = 0;        // will store last time LED was updated
10
11
// constants won't change:
12
const long interval = 1000;           // interval at which to blink (milliseconds)
13
14
void setup() {
15
  // set the digital pin as output:
16
  pinMode(ledPin, OUTPUT);
17
}
18
19
void loop() {
20
  // here is where you'd put code that needs to be running all the time.
21
22
  // check to see if it's time to blink the LED; that is, if the difference
23
  // between the current time and last time you blinked the LED is bigger than
24
  // the interval at which you want to blink the LED.
25
  unsigned long currentMillis = millis();
26
27
  if (currentMillis - previousMillis >= interval) {
28
    // save the last time you blinked the LED
29
    previousMillis = currentMillis;
30
31
    // if the LED is off turn it on and vice-versa:
32
    if (ledState == LOW) {
33
      ledState = HIGH;
34
    } else {
35
      ledState = LOW;
36
    }
37
38
    // set the LED with the ledState of the variable:
39
    digitalWrite(ledPin, ledState);
40
  }
41
}

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Philipp G. schrieb:
> Dann mach es halt so:
Wie soll dieser kommentarlos dahinkopierte Code dem TO helfen? Dieses 
Beispiel findet man zigfach an jeder Ecke des Internets. Wenigstens die 
Quelle hättest du noch nennen können:
https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing

: Bearbeitet durch Moderator
von Einer K. (Gast)


Lesenswert?

Philipp G. schrieb:
> // if the LED is off turn it on and vice-versa:
>     if (ledState == LOW) {
>       ledState = HIGH;
>     } else {
>       ledState = LOW;
>     }
Sowas finde ich immer irgendwie unfassbar, unfasslich...

ledState = not ledState;

von Joachim B. (jar)


Lesenswert?


: Bearbeitet durch User
von wendelsberg (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Sowas finde ich immer irgendwie unfassbar, unfasslich...
>
> ledState = not ledState;

Wobei sicher schon viele die Erfahrung gemacht haben, dass man nach 
einigen Jahren denkt: Was ist das, was hast Du da gemacht?*
Wenn man da den notwendigen Kommentar anhaengt, kann man es auch gleich 
so schreiben:
>     if (ledState == LOW) {
...
Das erschliesst sich ohne Kommentar.

wendelsberg

*mich selbst ausdruecklich eingeschlossen

von Wolfgang (Gast)


Lesenswert?

Lothar M. schrieb:
> Und genau dann gibt es ein Problem, denn nach millis() == 4294967296
> kommt eine Millisekunde später millis() == 0.

Wenn man es richtig formuliert, gibt es eben kein Problem, solange die 
Zeitdifferenz nicht zu groß wird - auch nicht beim Überlauf des 
millis()-Zählers.

von Kollege (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Philipp G. schrieb:
>> // if the LED is off turn it on and vice-versa:
>>     if (ledState == LOW) {
>>       ledState = HIGH;
>>     } else {
>>       ledState = LOW;
>>     }
> Sowas finde ich immer irgendwie unfassbar, unfasslich...
>
> ledState = not ledState;

Was du vorschlägst kann man bei einer Boolschen Variablen machen, aber 
nicht bei einer Definition, die du nicht unter deiner Kontrolle hast.

In Arduino.h ist LOW und HIGH wie folgt definiert:

#define HIGH 0x1
#define LOW  0x0

Mit 'int ledState' ergibt dein Vorschlag beim Wechsel LOW->HIGH ein 
ledState = 0xFFFF, und damit würde eine möglicherweise im Code 
nachfolgende Abfrage auf 'if (ledState == HIGH') nicht mehr 
funktionieren. So ein Fehler ist auch nicht mehr auf den ersten Blick 
erkennbar.

von beo bachta (Gast)


Lesenswert?

Kollege schrieb:
> Was du vorschlägst kann man bei einer Boolschen Variablen machen, aber
> nicht bei einer Definition, die du nicht unter deiner Kontrolle hast.

Ja so ist er, der Fanboy. Bringt die wildesten C++ Ausdrücke
daher (ich meine jetzt nicht unbedingt diesen not Operanden)
und wirft sie den Arduino-Anfängern vor die noch keine einzige
Zeile C-Code erfolgreich geschrieben haben. Beispiele dafür
hab ich gesehen sonst würde ich nicht so daher reden.

Sehr einfühlsam und didaktisch wertvoll.

Aber Hauptsache: besser Wissen, protzen, ich bin ich ....

von Philipp K. (philipp_k59)


Lesenswert?

ich würde so oft man Zeit brauch diesen abschnitt immer in eine 
beschreibende Funktion kopieren.. das macht die Sache übersichtlicher.

z.B.: https://pastebin.com/2RU4GKyS

von Einer K. (Gast)


Lesenswert?

wendelsberg schrieb:
> kann man es auch gleich so schreiben:
Interessant!

Du bist der Erste, welcher mir sagen möchte, dass Verzweigungsblöcke 
leichter zu lesen sind, als Zuweisungen.
In meiner kleinen Welt, gehören "Verschachtelungstiefen" zu den bösen 
Dingen. Je tiefer, und je komplizierter die Bedingung, desto böser. 
Sogar exponentiell zunehmend böse.

von Einer K. (Gast)


Lesenswert?

Kollege schrieb:
> Mit 'int ledState' ergibt dein Vorschlag beim Wechsel LOW->HIGH ein
> ledState = 0xFFFF, und damit würde eine möglicherweise im Code
> nachfolgende Abfrage auf 'if (ledState == HIGH') nicht mehr
> funktionieren. So ein Fehler ist auch nicht mehr auf den ersten Blick
> erkennbar.

Iss klar.
Da hasste aber einen schönen Traum.

Vielleicht mal nachschauen, was der not Operator so tut.
Und was die impliziten Casts so machen.
Beides sollte man schon wissen, wenn man andere kritisiert, denke ich 
mal.

Kollege schrieb:
> Was du vorschlägst kann man bei einer Boolschen Variablen machen, aber
> nicht bei einer Definition, die du nicht unter deiner Kontrolle hast.
In einem hast du recht!
Wenn man eine Variabel hat, welche nur 2 Zustände kennt, sollte man sie 
zu einem bool machen.
Das wäre konsequent, aber nicht unbedingt nötig, in C hat das ja 
schließlich auch ca 30 Jahre so geklappt.

von Schlaumaier (Gast)


Lesenswert?

Ich hatte ein ähnliches Problem.

Hab das über ein Timer gelöst.

In deinen Fall :
Beim Start der Schleife = Timer.on
Einziger Befehl des Timers = Timer.off (bei mir noch eine Varible 
umschalten da ich den Status den Timers nicht abfragen konnte).

Mag vielleicht ein wenig ungenau sein. Aber diese Ungenauigkeit kann man 
wenn man muss logisch berechnen und angleichen. Mich haben 3-4 millis 
mehr oder weniger nicht gejuckt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> Wenn man es richtig formuliert, gibt es eben kein Problem, solange die
> Zeitdifferenz nicht zu groß wird
Welche "nicht zu große" Zeit würde dir da so vorschweben?

Ich biete 49kommaeinpaarzerquetschte Tage. Mehr kann man mit dieser 
"millis()-startzeit > dauer" Methode nicht erreichen, weil dann ja die 
"dauer" nicht mehr in einem unsigned long Platz hat.

Allerdings ist das auch ein arg fraglicher Ansatz, wenn jemand mit einem 
Millisekundentimer etwas verwaltet, das länger als einen Monat 
braucht...

von Schlaumaier (Gast)


Lesenswert?

Lothar M. schrieb:
> Allerdings ist das auch ein arg fraglicher Ansatz, wenn jemand mit einem
> Millisekundentimer etwas verwaltet, das länger als einen Monat
> braucht...

na und. Dann muss man nur an der richtigen Stelle die "Rücksetzung" 
berücksichtigen.  Auch nicht so weltbewegend.

von Schlaumaier (Gast)


Lesenswert?

Nachtrag :

Solange man keine Operationen hat die länger als die genannten 49 Tage 
dauert macht man das ganz einfach. Man legt sich eine public-Variable 
Zeit an. Nun einfach die Variable mit den akt. millis-wert füllen. Bei 
der nächsten Abfrage einfach vorher fragen ob millis kleiner sind als 
der aktuelle Wert.

Einzige Fehlerquelle. Wenn die nächste Abfrage > 49 Tage ist. Falls das 
eintritt sollte man vielleicht 3 Euro opfern und sich ein Uhr-Modul 
kaufen. ;)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Schlaumaier schrieb:
> Dann muss man nur an der richtigen Stelle die "Rücksetzung"
> berücksichtigen.
Welche "Rücksetzung" denn? Und an welcher Stelle?
Zeig das mal mit einer LED, die per millis() im 100-Tage-Takt "blinkt", 
also 50 Tage on und 50 Tage off.
50 Tage = 50*24*60*60*1000 ms = 4320000000 ms = 0x1017DF800 ms

Schlaumaier schrieb:
> Man legt sich eine public-Variable Zeit an. Nun einfach die Variable mit
> den akt. millis-wert füllen. Bei der nächsten Abfrage einfach vorher
> fragen ob millis kleiner sind als der aktuelle Wert.
Welcher "aktuelle Wert" ist hier gemeint?

: Bearbeitet durch Moderator
von Schlaumaier (Gast)


Lesenswert?

If millis > alt_millis then
  ' hier ist die Rücksetzung
  ' Wenn Millis "überlaufen fangen sie wieder bei 0 an".
end if
 alt_millis = millis


Fertig. Muss halt nur in jede Abfrage rein oder durch einen sehr 
großzügig dimensionierten Timer erfolgen.

Wo ist das Problem ???

von Nick M. (Gast)


Lesenswert?

Hier wurde der Käse mit dem uint32 doch schon durchgekaut.
Beitrag "Sekunden,Minuten zählen mit der Funktion Millis()"
Das ist broken by design, egal wie oft man es ignorieren will. Arduino 
halt.

Mit uint64 ist das erledigt für die nächsten 584 Jahre.
Einmal ordentlich drüber nachgedacht und danach muss man nie wieder 
irgendwelche Fallstricke beachten. OK, ausser man plant 
ausserplanetarische Reisen.

von Schlaumaier (Gast)


Lesenswert?

Schlaumaier schrieb:
> If millis > alt_millis then
>   ' hier ist die Rücksetzung
>   ' Wenn Millis "überlaufen fangen sie wieder bei 0 an".
> end if
>  alt_millis = millis

Fehler im code. Zu spät gesehen
es muss heissen.

If millis < alt_millis then

KLEINER. Weil der Wert ja bei 0 neu startet nach den 49 Tagen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Nick M. schrieb:
> Mit uint64 ist das erledigt für die nächsten 584 Jahre.
Da hast du 1. noch einen argen Rechenfehler drin. Ich komme auf 
annähernd 590 Millionen Jahre.
Und 2. kann man mit solchen völlig unpassenden und von Hilflosigkeit 
zeugenden Datentypen einen 8-Bit-Rechner ganz schön in die Knie zwingen.

Schlaumaier schrieb:
> Wo ist das Problem ???
Das Problem ist, dass man es einfach mal kapieren muss, dass diese ganze 
"Verwaltung" schon die Vergleichsrechnung "millis-startzeit" so nebenher 
mitmacht:
1
if (millis() - startzeit > dauer) {
2
   zeitdauer_abgelaufen();
3
}
Das geht gut solange dauer maximal 0xffffffff = 49,7 Tage ist. Da 
braucht man keine zusätzlichen Vergleich auf einen millis()-Überlauf 
samt Sonderbehandlung. Und es ist auch schnurzegal, ob millis() bei der 
Zuweisung der an die startzeit 0xffffffff oder 0x00000000 war.

: Bearbeitet durch Moderator
von Nick M. (Gast)


Lesenswert?

Lothar M. schrieb:
> Da hast du 1. noch einen argen Rechenfehler drin. Ich komme auf
> annähernd 590 Millionen Jahre.

Oh, mit Brille: Ich auch.

> Und 2. kann man mit solchen völlig unpassenden und von Hilflosigkeit
> zeugenden Datentypen einen 8-Bit-Rechner ganz schön in die Knie zwingen.

Passend ist er wohl schon, weil das Problem dann weg ist. Hilflos ist 
eher die Diskussion hier und im verlinkten Thread.
Und der Rechenaufwand ist verglichen mit uint32 nicht so immens größer, 
da Überläufe in die oberen 32 Bit nur alle 50 Tage auftreten. Es geht 
hier nur um ein +1. Ein bisschen weiter zu denken hilft also auch hier.

if (millis() - startzeit > dauer) {
   zeitdauer_abgelaufen();
}

Der Ansatz ist halt auch nicht wirklich schlau. Rechne die Zeit aus, 
wenn sie abgelaufen ist und mach dann:
if (uin64ticker <= targetTime) ...

Aber diskutiert ruhig weiter ... :-)

von Schlaumaier (Gast)


Lesenswert?

Lothar M. schrieb:
> if (millis() - startzeit > dauer) {
>    zeitdauer_abgelaufen();
> }

Millis = 10.000
Startzeit = 1000
Dauer = 500

> if (millis() - startzeit > dauer) {
 if 10.000 - 1000 > 500 then

  'Gut - solange millis nicht überläuft

 end if

'*************************

Millis = 100 ' gerade übergelaufen
Startzeit = 1000
Dauer = 500

 if 100 - 1000 > 500 then
 ' Startzeit NICHT Abgelaufen
' grund : Millis ist viel zu klein gegenüber Startzeit, ergo gibt es 
fast immer ein - Wert und da Dauer im + ist .......

 end if


Das würde im Endeffekt bedeutet dein Prg. spinnt nach den 49 Tagen.

von Einer K. (Gast)


Lesenswert?

Schlaumaier schrieb:
> Das würde im Endeffekt bedeutet dein Prg. spinnt nach den 49 Tagen.
Nein!
Solange die interval Zeit kleiner als 49 Tage ist, läuft das sauber 
durch.
Alle Überläufe werden zur genau der richtigen Zeit durch Unterläufe 
kompensiert.

Es ist ok, wenn du und auch von Nick M. (muellernick) das nicht 
verstehen wollen.

Und wenn man wirklich Intervalzeiten größer als 49 Tage benötigt, muss 
man eben eine Extrawurst backen.
Aber meist, reichen die 32 Bit völlig aus.
1
uint64_t wideMillis()
2
{
3
  union
4
  {
5
    struct
6
    {
7
      uint32_t lo;
8
      uint32_t hi;
9
    };
10
    uint64_t zeit;
11
      } static daten;  
12
  uint32_t jetzt = millis();
13
  if(jetzt < daten.lo) daten.hi++;
14
  daten.lo = jetzt;
15
  return daten.zeit;
16
}
Die Funktion geht von einem stetig wachsenden millis() Wert aus.
Den dürfte man in der Praxis immer so haben.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Schlaumaier schrieb:
> Das würde im Endeffekt bedeutet dein Prg. spinnt nach den 49 Tagen.
Denk nochmal drüber nach. du

Schlaumaier schrieb:
> ' grund : Millis ist viel zu klein gegenüber Startzeit
Nein, der Grund ist der, dass die Zeitdauer, die du abfragen wolltest ja 
schon ewig vorbei ist und die Reaktion darauf schon lange stattgefunden 
hat und somit eigentlich in der Vergangenheit und vergessen ist.

Das ist so, wie wenn du dieses Jahr einen Zettel schreibst: "am 22.01. 
Brot kaufen!" und du findest den Zettel nächstes Jahr wieder. Dann 
kaufst du am 23.01. Brot, obwohl du eigentlich keines brauchst. Du musst 
den Zettel nach dem Einkaufen also vernichten. Oder die Jahreszahl 
dazuschreiben.

Und genau das selbe musst du mit der Bearbeitung von solchen Aktionen 
natürlich auch machen. Wenn du die Startzeit einfach unverändert lässt, 
dann klappert es natürlich nach 49 Tagen. Muss ja.

: Bearbeitet durch Moderator
von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Es ist ok, wenn du und auch von Nick M. (muellernick) das nicht
> verstehen wollen.

Da haut einer arg aufs Blech ...

> Und wenn man wirklich Intervalzeiten größer als 49 Tage benötigt, muss
> man eben eine Extrawurst backen.

und führt dann uint64 ein. Und denkt, er ist schlau wie Harry! Wisch dir 
doch die Kagge aus dem Gesicht!

von Einer K. (Gast)


Lesenswert?

Lothar M. schrieb:
> Zeig das mal mit einer LED, die per millis() im 100-Tage-Takt "blinkt",
> also 50 Tage on und 50 Tage off.
> 50 Tage = 50*24*60*60*1000 ms = 4320000000 ms = 0x1017DF800 ms
1
//#include "INTERVAL.h"
2
3
const byte LED = LED_BUILTIN;
4
5
6
uint64_t wideMillis()
7
{
8
  union
9
  {
10
    struct
11
    {
12
      uint32_t hi;
13
      uint32_t merker;
14
    };
15
    uint64_t zeit;
16
  } static daten;  
17
  uint32_t jetzt {millis()};
18
  if(jetzt < daten.merker)
19
  {
20
    daten.hi++;
21
  }
22
  daten.merker = jetzt;
23
  return daten.zeit;
24
}
25
26
//// ----------------------------------
27
uint64_t zeitmerker;
28
const uint64_t interval = 4320000000ULL;
29
30
void setup() 
31
{
32
  pinMode(LED,OUTPUT);
33
}
34
35
void loop() 
36
{
37
   if(wideMillis()-zeitmerker > interval)  
38
   {
39
     digitalWrite(LED,!digitalRead(LED));
40
     zeitmerker += interval;
41
   }
42
}

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> und führt dann uint64 ein.
Richtig!
Und zwar genau dann, wenn es nötig ist!
Keine Sekunde vorher.

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> if(wideMillis()-zeitmerker > interval)

Und hier auch wieder:
Eine unnötige Rechenoperation, aber jammern wie langsam uint64 sei.
Rechne einmal aus zu welchen Zeitpunkt das nächste Ereignis ist 
(nextEvent = now + interval) und überprüf mit:
if (wideMilli() >= nextEvent)

Jämmerlich.

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Und zwar genau dann, wenn es nötig ist!
> Keine Sekunde vorher.

Genau das gleiche macht die Addition schon für dich (hab ih oben schon 
geschrieben). Wenn es keinen Überlauf gibt, ist die Addition beendet. 
Schön dass du genau das nachstellst.

Fans sind schon reichlich verblendet!

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Jämmerlich.
Du!

von W.S. (Gast)


Lesenswert?

pascal schrieb:
> komme ich im loop in meine schleife, ...
> ...
> Also angenommen die magnetzeit ost 100ms dann soll die bedinung 100ms
> wahr sein.
>
> Nach 3 stunden googlen dachte ich frag hier mal.

Du schreibst derart wirr, daß unsereiner nicht versteht, was du denn 
eigentlich machen willst.

Ich mache mal ein paar Annahmen:

1. du willst deinen Programmablauf nicht mit elend langen Warteschleifen 
konstruieren. OK, das ist löblich, denn dann kann dein µC in der 
Zwischenzeit etwas anderes machen.

2. Du hast irgend einen Magneten, der offenbar so um die 100 ms 
angesteuert werden sollte und dann wieder auszuschalten ist.

3. aus irgend einem sonstigen Grunde ergibt sich gelegentlich, daß 
dieser Magnet einzuschalten ist, danach soll er dann nach Ablauf der 
o.g. Zeit wieder ausgeschaltet werden.

4. in der Zwischenzeit willst du tatsächlich mit deinem µC noch etwas 
anderes tun.

Ist das so korrekt dargestellt?

Wenn ja, dann empfehle ich dir, deine Firmware ereignisgesteuert 
aufzubauen.

1. Dazu richtest du dir erst mal eine Systemuhr ein. So alle 1ms oder 10 
ms sollten ausreichen, ist aber nach deinem Gusto.

2. Als zweites richtest du dir eine Liste ein, die zu erledigende 
Arbeiten und deren Zeitpunkt speichern kann. Der Zeitpunkt kann als 
unsigned long gemacht werden, der die Millisekunden des Tages zählt und 
die zu erledigende Arbeit kann durch irgend etwas (irgend ein Kenner, 
ein Byte, ein Word oder so) gemacht werden.
Diese Liste braucht nicht lang zu sein, nur soviele Einträge, wie du an 
Vorhaben brauchst.

3. Du schreibst dir eine kleine Routine zum Eintragen eines Vorhabens in 
diese Liste. Die kriegt dann 2 Argumente: was zu tun ist und um wieviel 
Millisekunden in der Zukunft es zu tun ist. Daraus macht sie einen 
Eintrag in obiger Liste mit dem Kenner was zu tun ist und aktuelle 
Uhrzeit plus zu wartende Millisekunden.

4. Deine ISR der Systemuhr sieht die obige Liste durch und guckt, ob da 
etwas dabei ist, wo die Zeit grad abgelaufen ist. Wenn sie etwas findet, 
dann schreibt sie die Aktion was zu tun ist in eine 
Ereigniswarteschlange (ein simpler Ringpuffer) und löscht den EIntrag in 
obiger Liste.

5. deine Grundschleife in main testet immer wieder, ob in der 
Ereigniswarteschlange etwas drinsteht - und wenn ja, dann holt sie es 
heraus und startet die betreffende Aktion gemäß dem Kenner.

So. Sowas ist ein Konzept, mit dem man Aktionen in seiner Firmware 
zeitlich planbar realisieren kann UND zugleich keinerlei Warteschleifen 
oder anderes blockierendes Zeugs benötigt. Das Ganze ist auch viel 
einfacher und übersichtlicher als ein echtes RTOS.

W.S.

von Schlaumaier (Gast)


Lesenswert?

Lothar M. schrieb:
> Und genau das selbe musst du mit der Bearbeitung von solchen Aktionen
> natürlich auch machen. Wenn du die Startzeit einfach unverändert lässt,
> dann klappert es natürlich nach 49 Tagen. Muss ja.

Ja im Prinzip schon.

Nur nicht wenn zwischen der Startzeit und der Abfrageroutine ein 
Überlauf von Millis vorkommt und dadurch mills genullt werden. ;)

Je kleiner die Laufzeit desso geringer die Gefahr. Aber frei nach 
"Murphys Gesetz" .... es passiert. Und man wundert sich warum.

Um das Problem zu lösen musst du nur einfach eine Abfrage extra machen.
Ich persönlich würde das über eine Funktion lösen.

If millis <= Startzeit then
 dort einfach die Startzeit neu berechnen und dann normal durch das Prg.
end if

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Fans sind schon reichlich verblendet!

Nick M. schrieb:
> Jämmerlich.

Nick M. schrieb:
> Wisch dir
> doch die Kagge aus dem Gesicht!

Der arme muellernick ....
Da argumentiert er hier rum, für seine 64 Bit, die man sowieso nie nicht 
braucht.
Keiner interessiert sich für den Quatsch, bzw. stimmt ihm zu....
Dann kann er nicht anders, dann muss er persönlich werden, bis zu 
Beleidigungen.

Naja..
Eigentlich ist es ja schön wenn er für sich eine Lösung gefunden hat.
Aber dieses dogmatische dulle und verblendete Priestertum, das nervt 
etwas.

Erinnert mich irgendwie an die Erlebniswelt des Don Quichotte.

-------------

Und jetzt zu den fachlichen Dingen.

 millis umbauen oder einen 64Bit Zähler einzubauen, in den Arduino Core, 
dauert ca 5 Minuten!
Das ist also keine Hürde.
Die Hürde ist: Man wird zum restlichen Arduino Universum inkompatibel.

Wieder etwas persönlicher:
Es kann natürlich sein, dass dir das Arduino Universum am Arsch vorbei 
geht..
Dann ist das allerdings gar nicht deine Baustelle.
Also: Gehe woanders Kaggen, da wo es mehr Sinn macht.

Alternative Sichtweise:
In diesem Thread dreht es sich um millis() und nicht um deine Kagge.

Übrigens:
Der Vorschlag wurde, von mir, zur Kenntnis genommen und abgelehnt.
Seit dem ist dein Verhalten das eines trotzigen Kindes, welches seinen 
Lieblingslutscher nicht bekommt.

von leo (Gast)


Lesenswert?

Schlaumaier schrieb:
> Um das Problem zu lösen musst du nur einfach eine Abfrage extra machen.
> Ich persönlich würde das über eine Funktion lösen.

Nein. Was hast du an unsigned int nicht verstanden? Nimm dir einen 
passenderen Nick und vergiss dein Basic.

leo

von Einer K. (Gast)


Lesenswert?

Schlaumaier schrieb:
> Je kleiner die Laufzeit desso geringer die Gefahr. Aber frei nach
> "Murphys Gesetz" .... es passiert. Und man wundert sich warum.

Nach 49 Tagen gibts einen Überlauf...
Na und?

Wenn die Interval Zeit kleiner ist, gibts auch keinen "Murphy".
Denn dann tuts das, immer, Jahre lang, ohne jeden Aussetzer.
> while(not stromausfall) allesGut();

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Da argumentiert er hier rum, für seine 64 Bit, die man sowieso nie nicht
> braucht.

Hast du doch selbst verwendet. Hmm ...
Zumindest bist du in der Lage eine uint64 Addition fast so schnell wie 
jeder Compiler nachzuprogrammieren. Toll!
Aber wie man die Vergleiche ordentlich macht hast du bis jetzt noch 
nicht kapiert. Aber das erklärt dann folgendes besser:

Arduino Fanboy D. schrieb:
> Die Hürde ist: Man wird zum restlichen Arduino Universum inkompatibel.

Ist schon gut wenn man verbissen an schlechten Dingen festhält. Das gibt 
ein Gefühl der Sicherheit. Dir! Mir nicht!
Aber leider stimmt das mit dem inkompatibel nicht. Der Überlauf den du 
behandelst wird nie passieren, ist also nur toter code. Lediglich 
aufpassen muss man, dass man uint64 verwendet. Aber das würde spätestens 
ein lint dir schon sagen.
Kurz: Du hast schon wieder nicht zu Ende gedacht.

Arduino Fanboy D. schrieb:
> Seit dem ist dein Verhalten das eines trotzigen Kindes, welches seinen
> Lieblingslutscher nicht bekommt.

Fachlich kommt jetzt garnichts mehr von dir?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Schlaumaier schrieb:
> Ja im Prinzip schon.
Und zwar im Prinzip immer.

> Nur nicht wenn zwischen der Startzeit und der Abfrageroutine ein
> Überlauf von Millis vorkommt und dadurch mills genullt werden. ;)
Doch, natürlich. Wegen der unsigned-Arithmetik geht das gut. Denn dann 
ist im Extremfall die startzeit = 0xffffffff und millis = 0 und somit 
die Rechnung (millis() - Startzeit) also 0 - 0xffffffff was unsigned 
gerechnet völlig korrekt wieder 1 ergibt, was genau der dazwischen 
vergangenen 1ms entspricht.

: Bearbeitet durch Moderator
von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Hast du doch selbst verwendet. Hmm ...
Als "Notlösung"...
Ein Einzelfall.

Aber DAS kapierst du ja nicht, dass man eine 64Bit Epoche in aller 
Regel gar nicht benötigt.

Nick M. schrieb:
> man uint64 verwendet
millis() wird an einigen Ecken des Frameworks und der Libraries 
verwendet.
Es ist schlicht unmöglich die 64Bit weltweit durchzusetzen.
Darum: Du hast schon wieder nicht zu Ende gedacht.

Nick M. schrieb:
> Fachlich kommt jetzt garnichts mehr von dir?

Was soll da noch kommen!
Das "Problem" ist so primitiv, und die Lösungen so naiv, da kann man 
nichts mehr zu sagen.
Es wurde alles gesagt.
Vielleicht noch nicht von jedem, aber das wird schon noch.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Arduino Fanboy D. schrieb:
> dass man eine 64Bit Epoche in aller Regel gar nicht benötigt.
Schon 40 Bit reichen für 256* 49 Tage und mit mit den resultierenden 35 
Jahren mit hoher Wahrscheinlichkeit länger als die Schaltung leben wird.

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Es ist schlicht unmöglich die 64Bit weltweit durchzusetzen.
> Darum: Du hast schon wieder nicht zu Ende gedacht.

Das war der Designer der Plattform, nicht ich. Aber der ist wohl dein 
Gott.
Deinen Nickname hast du dir schließlich selbst gewählt.

Arduino Fanboy D. schrieb:
> Was soll da noch kommen!

Nichts mehr. Sinnvolles ist von dir auch schon lange nichts mehr 
gekommen. Schade, aber auch typisch für die Plattform.

von Einer K. (Gast)


Lesenswert?

Lothar M. schrieb:
> Schon 40 Bit reichen
Könnte man sich mit C++ Mitteln basteln...

von Nick M. (Gast)


Lesenswert?

Lothar M. schrieb:
> Schon 40 Bit reichen ...

Wenn es nur ein uint40 gäbe ...

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Das war der Designer der Plattform, nicht ich.

Häää... du nörgelst doch die ganze Zeit.

Ich bin da der falsche Partner, das hast du schon erkannt, aber noch 
nicht in der Tiefe begriffen!

Tipp:
Wende dich an den Designer!
Oder ändere es selber, der Arduino Core liegt öffentlich aus, 
editierbar.
Wenn die Änderungen abgesegnet werden, hast du deinen Sieg errungen.

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Oder ändere es selber, der Arduino Core liegt öffentlich aus,
> editierbar.

Den Ruhm und die Ehre für dein int64-incrememt will ich dir nicht 
nehmem! :-))))

von Stefan F. (Gast)


Lesenswert?

jo mei schrieb:
> Zeige dein Programm

Hast du leider nicht gemacht, schade. Das schränkt unsere Möglichkeiten, 
dir zu helfen, massiv ein.

Du siehst dass hier heiß über alle möglichen Details diskutiert wird, 
nur nicht mehr über deinen konkreten Code. Wie denn auch?

Nick M. schrieb:
> Kann man natürlich in zwei Tasks zerlegen, jede eine state machine und
> die zwei tasks werden in der mainloop aufgerufen.

Das war meiner Meinung nach noch der beste Tipp. Ich habe einen Aufsatz 
dazu geschrieben, der hier wie der Deckel auf den Topf passt:
http://stefanfrings.de/multithreading_arduino/index.html

von Sebastian W. (wangnick)


Lesenswert?

Wenn man uin64_t nimmt dann aber auch gleich Mikrosekunden statt diesen 
ungenauen millis(). Läuft allerdings schon nach 500000 Jahren über und 
nicht erst nach 500 Millionen ... :)

LG, Sebastian

von Nick M. (Gast)


Lesenswert?

Sebastian W. schrieb:
> aber auch gleich Mikrosekunden

LOL! Mein Tip: Mach es nicht! :-))

von Sebastian W. (wangnick)


Lesenswert?

Nick M. schrieb:
> LOL! Mein Tip: Mach es nicht! :-))

Je, nun. Brauchte ich gerade (im Zusammenhang mit der Ermittlung des 
aktuellen Stromverbrauchs aus den Impulsen einer 
Stromzähler-Impuls-LED):
1
static volatile uint64_t usbase; // Initialised to zero
2
static inline void timer1_ovf (void) {
3
  usbase += 0x8000;
4
}
5
ISR(TIMER1_OVF_vect) {timer1_ovf();}
6
static uint64_t micros (void) {
7
  uint8_t oldSREG = SREG;
8
  cli();
9
  uint16_t tcnt = TCNT1;
10
  uint8_t tov = TIFR1&(1<<TOV1); // Has to happen strictly after accessing TCNTn
11
  SREG = oldSREG;
12
  uint64_t us = usbase + tcnt/2;
13
  if (tov && tcnt<0xFFFF) us += 0x8000; // Pending timer_ovf processing for this TCNT not yet executed
14
  return us;
15
}
16
...
17
  TCCR1A = 0;
18
  TCCR1B = (1<<CS11); // Prescaler 8 -> 2 ticks per microsecond @ 16MHz
19
  TCCR1C = 0;
20
  TIMSK1 = (1<<TOIE1); // Overflow interrupt enable
21
...
FWIW.

LG, Sebastian

PS:
Stefan ⛄ F. schrieb:
> Das war meiner Meinung nach noch der beste Tipp. Ich habe einen Aufsatz
> dazu geschrieben, der hier wie der Deckel auf den Topf passt:
> http://stefanfrings.de/multithreading_arduino/index.html

Schön verständlich geschrieben, Stefan!

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Schlaumaier schrieb:
> Millis = 100 ' gerade übergelaufen
> Startzeit = 1000
> Dauer = 500
>
>  if 100 - 1000 > 500 then
>  ' Startzeit NICHT Abgelaufen
> ' grund : Millis ist viel zu klein gegenüber Startzeit, ergo gibt es
> fast immer ein - Wert und da Dauer im + ist .......
>
>  end if

Guck dir einfach noch mal an, wie die Subtraktion von unsigned int 
läuft.
Um die Sache auch für dich überschaubar zu gestalten, probier es dann 
einfach mal 8-Bit Größen und staune.

von Falk B. (falk)


Lesenswert?

Wolfgang schrieb:
> Um die Sache auch für dich überschaubar zu gestalten, probier es dann
> einfach mal 8-Bit Größen und staune.

Das Zauberwort lautet arithmetischer Überlauf und Modulo-Operation.

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Arduino Fanboy D. schrieb:
>> Oder ändere es selber, der Arduino Core liegt öffentlich aus,
>> editierbar.
>
> Den Ruhm und die Ehre für dein int64-incrememt will ich dir nicht
> nehmem! :-))))

Mach die Welt besser!
Dabei kannst du mir nichts nehmen.
(Ganz im Gegenteil)


Eins der Probleme ist, auch hier im Forum, dass die Nörgler nur nörgeln 
wollen. Sie wollen nicht verbessern, denn dann gäbs nix mehr zu nörgeln.
Dass sich ein Nörgler selbst abschafft, damit ist eher nicht zu rechnen.

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> dass die Nörgler nur nörgeln wollen.
> Sie wollen nicht verbessern, denn dann gäbs nix mehr zu nörgeln.

Du willst doch den uint32 um jeden Preis halten. Verbesserungsvorschläge 
gehen an dir vorbei.
Beispiele:
uint64 ist zu langsam, dann machst du aber bei jedem Vergleich eine 
unnötiges Subtrahieren.
Dann "verbesserst" du die uint64-Arithmetik auf grandiose Art und Weise.
Selbst die Tatsache dass es die Frage wohl einmal im Monat gibt, hält 
dich nicht davon ab dich an den Designfehler zu klammer. Google mal nach 
"Arduino millis". Da gehört schon eine gehörige Portion an Starrsinn 
dazu.

Und nörgeln? Wenn du das so auffasst, dann verstehst du mich nicht. Aber 
ist mir auch egal, nachfragen müsstest du.
Der 14 Beitrag, mein erster hier im thread wurde selbst von stefanus 
(Hört hört!) als bester Tip bezeichnet, während ihr euch an dem tollen 
millis() aufgeilt weil ihr wisst wie es als Sonderfall funktioniert.
Aber zwei Minuspunkte hab ich dafür bekommen, also ist die Welt wieder 
in Ordnung! :-))

Ich weiß schon, warum mir der Arduino am Arsch vorbeiget. Es ist das 
Umfeld und dieses unsäglich verkrüppelte C++. Damit kommt dann ein 
Fanboy drauf, dass man ja auch 40 Bit Integer-Arithmetik bauen könnte.

Hält mich aber nicht davon ab, den Leuten bissl die Augen zu öffnen und 
ihnen zu erklären wie man Sachen ordentlich löst.

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Du willst doch

Nick M. schrieb:
> an dir vorbei

Nick M. schrieb:
> dann machst du

Nick M. schrieb:
> "verbesserst" du die

Nick M. schrieb:
> hält dich nicht

Nick M. schrieb:
> Wenn du das so

Nick M. schrieb:
> du mich nicht

Nick M. schrieb:
> müsstest du.

Nick M. schrieb:
> während ihr euch

Nick M. schrieb:
> weil ihr wisst

Merkst du was?

---

Du hast deinen Lieblingsweg gefunden.
Schön!
Nutze ihn, behalte ihn.
Ich gönne ihn dir!

Nick M. schrieb:
> Ich weiß schon, warum mir der Arduino am Arsch vorbeiget.
Hab ich ja gesagt:
Ist nicht deine Baustelle.

Also?
Schaum vorm Mund, wegen nix.

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Schaum vorm Mund, wegen nix.

Ich Schaum? Ich hab eher den Eindruck, dass dein Zitatsgestammle vom 
Bauschaum im Mund kommt.

Edit:
Oder ist der Bauschaum gar im Kopf?

von Stefan F. (Gast)


Lesenswert?

Muss das schon wieder sein Nick?

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> dass dein Zitatsgestammle
Da ist es wieder des dein, du, ihr usw.
Das Gestammel, stammt übrigens von dir, habs nur etwas konzentriert.

Habe die "Message" da raus operiert:
Du bist mit dem Arduino millis Handling nicht zufrieden, es regt dich 
total auf...
Obwohl du doch gar nix damit zu tun hast.
Und der einzige, welcher sich gerade anbietet, bin ich.
.. ok, auf "von Lothar M. (lkmiller) (Moderator) Benutzerseite" könntest 
du auch rumhacken...
Ich weiß nicht ob er das Arduino "Konzept" liebt, aber eine "Billigung" 
glaube ich zu erkennen.

Also, weitermachen!
Wenn es dir Befriedigung verschafft.....
Windmühlen gibt es genug.

von Nick M. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Muss das schon wieder sein Nick?

Frag doch lieber den, der damit begonnen hat. Oder noch besser, erinnere 
dich an deine eigenen Worte. Und schreib den Fanboy auf die Liste mit 
dem Photo. :-))

Arduino Fanboy D. schrieb:
> Nick M. schrieb:
>> dass dein Zitatsgestammle
> Da ist es wieder des dein, du, ihr usw.

Sag bloß, du hast das nicht geschrieben. Auch ich könnte irgendeinen 
Text möglichst dumm zerhackstückelnd zitieren und dann behaupten dass es 
eine intelligente Antwort wäre. Jetzt ist es halt leider nur eine 
minderintelligente Antwort von dir geworden.

Und glaub mir, ich kann beliebig lange auf jeden Schwachsinn von dir 
antworten. Ich muss dabei immer so lächeln.

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Und glaub mir, ich kann beliebig lange auf jeden Schwachsinn von dir
> antworten.

OK, das Angebot nehme ich an ... bin ja kooperativ ... manchmal.

Merke:
Du hast versagt!
Hast dich nicht durchsetzen können.
Looser!

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Merke:
> Du hast versagt!
> Hast dich nicht durchsetzen können.
> Looser!

Du solltest aber bitte nicht aus Facebook reinkopieren was dir geschickt 
wurde!

Und lerne doch lieber wie man Loser schreibt.

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Und lerne doch lieber wie man Loser schreibt.
Geil!

Looooser!

Wie auch immer, du hast versagt!
Offensichtlich niemanden bekehren können.

Tipp:
Das ist ganz normal, wenn man auf fremder Leute Baustellen rum nörgelt.
Quasi sogar fast der beste anzunehmende Fall.

von Einer der im Goldenen Käfig sitzt (Gast)


Lesenswert?


von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Offensichtlich niemanden bekehren können.

Mag sein. Hat aber primär was mit "fruchtbarer Boden" zu tun.
Aber deine Beiträge um die Arduino Fanboys aufs mentale Abstellgleis zu 
stellen sind dafür um so wirkungsvoller.

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Hat aber primär was mit "fruchtbarer Boden" zu tun.
"Ein Falschfahrer?"
"Hunderte!"
;-)

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> "Ein Falschfahrer?"
> "Hunderte!"

Ja, tragisch, kommt halt vor wenn die Arduino Fanboys Ausflug haben.
Darwin regelt das.

von Einer K. (Gast)


Lesenswert?

Genau!
Der letzte 64Bit, auf 8Bit Rechner, Krieger wird dahin siechen.

Nachruf:
Viel hat er genörgelt, aber nix geändert.
Die arme Seele....

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Macht eure kindischen Streitereien bitte per PN aus.

von W.S. (Gast)


Lesenswert?

Lothar M. schrieb:
> Schon 40 Bit reichen

Leute!!!!!

und Lothar!!!

Wozu dieses aufgeregte Gekreische? Der nächste führt 128 Bit Integer 
ein, um auch den Untergang unserer Galaxis noch berechnen zu können.

ALBERN!!!

Ich bemühe mal meinen steinalten HP-Taschenrechner:
24 Stunden = 1440 Minuten = 89400 Sekunden = 86400000 ms

Natürlich reicht ein beliebiger long bequem für mehrere Tage und wenn 
eine Systemuhr in der Firmware ordentlich funktioniert, dann setzt sie 
die Uhrzeit um Mitternacht auf 0 zurück - und wenn sie obendrein auch 
die Ablaufzeiten für vorgemerkte Ereignisse betreut, dann kann sie 
problemlos auch von diesen Ablaufzeiten um Mitternacht besagte 86400000 
ms subtrahieren und fetig ist die Laube.

Ihr alle habt zwar keinen Kaiser vorrätig, aber ihr streitet dennoch um 
dessen Bart.

Fangt doch endlich mal an, rational zu denken.

W.S.

von Nick M. (Gast)


Lesenswert?

W.S. schrieb:
> Natürlich reicht ein beliebiger long

Da kannst du auch "Hurz" ([c] H.P. Kerkele) statt long schreiben, das 
passt auch für alles.

von J. T. (chaoskind)


Lesenswert?

W.S. schrieb:
> Ich bemühe mal meinen steinalten HP-Taschenrechner:
> 24 Stunden = 1440 Minuten = 89400 Sekunden = 86400000 ms

Irgendwie kann dein steinalter HP nicht mehr sauber durch 1000 teilen.
Edit: er kann 1440 nicht mit 60 multiplizieren.

: Bearbeitet durch User
von J. T. (chaoskind)


Lesenswert?

J. T. schrieb:
> W.S. schrieb:
>> Ich bemühe mal meinen steinalten HP-Taschenrechner:
>> 24 Stunden = 1440 Minuten = 89400 Sekunden = 86400000 ms
>
> Irgendwie kann dein steinalter HP nicht mehr sauber durch 1000 teilen.

> Edit: er kann 1440 nicht mit 60 multiplizieren.

Im großen und ganzen, irgendwas stimmt da nicht :D

von Carl D. (jcw2)


Lesenswert?

Arduino Fanboy D. schrieb:
>
1
 //// ----------------------------------
2
 uint32_t zeitmerker;
3
 const uint32_t interval = 1000UL;
4
 
5
 void setup()
6
 {
7
   pinMode(LED,OUTPUT);
8
 }
9
 
10
 void loop()
11
 {
12
    if(millis()-zeitmerker > interval)
13
    {
14
      digitalWrite(LED,!digitalRead(LED));
15
      zeitmerker += interval;
16
    }
17
 }
>

zu beachten ist in Zeile 15, daß nicht millis() gelesen wird. Damit wird 
verhindert, daß das (hier) 1s-Raster wegen der Laufzeit des anderen 
loop-Codes wegläuft. Ohne das wird die "Sekunde" immer größer als eine 
Sekunde sein.

Vielleicht interessanter als die wöchentliche (tägliche) Frage, warum 
das mit millis() funktioniert, wo es doch gar nicht sein kann, und ob 
man sich wirklich merken muß, wie sich in C unsigned beim Überlauf 
verhält.

: Bearbeitet durch User
von void (Gast)


Lesenswert?

Bei meinen Arduino Sachen mache ich das immer so (stark vereinfacht).
Für einfache Timer reicht das locker hin. Wenn es präzise sein muss, 
sollte
aber ein Timerinterrupt mit externem Quarz genommen werden.

void loop()
{
  static uint16 timer = 0;

  if ( timer > 0 )
    timer--;

  if ( TriggerBedingungFuerSchaltvorgang )
  {
    SchalteEin();
    timer = 50; //entspricht 1s bei 20ms Taskraster
  }

  if (timer == 1)
  {
    SchalteAus();
  }

  //um ein genaueres Zeitraster zu bekommen, sollte
  //hier nicht stumpf gewartet werden sondern die Tasklaufzeit
  //dynamisch einkalkuliert werden
  delay(20);
[

von Falk B. (falk)


Lesenswert?

void schrieb:
> //um ein genaueres Zeitraster zu bekommen, sollte
>   //hier nicht stumpf gewartet werden sondern die Tasklaufzeit
>   //dynamisch einkalkuliert werden
>   delay(20);

Blödsinn. Man nutzt dafür keine delay() Funktion sondern einen 
Timer-Interrupt, siehe Multitasking.

von Falk B. (falk)


Lesenswert?

Carl D. schrieb:
> zu beachten ist in Zeile 15, daß nicht millis() gelesen wird. Damit wird
> verhindert, daß das (hier) 1s-Raster wegen der Laufzeit des anderen
> loop-Codes wegläuft. Ohne das wird die "Sekunde" immer größer als eine
> Sekunde sein.

Letztendlich ist dieser Ansatz die Softwarevariane eines Output Compare 
Interrupts.

von Michael D. (nospam2000)


Lesenswert?

Carl D. schrieb:
> Vielleicht interessanter als die wöchentliche (tägliche) Frage, warum
> das mit millis() funktioniert, wo es doch gar nicht sein kann, und ob
> man sich wirklich merken muß, wie sich in C unsigned beim Überlauf
> verhält.

In dem Artikel 
https://www.mikrocontroller.net/articles/High-Speed_capture_mit_ATmega_Timer#Keine_Angst_vor_.C3.9Cberl.C3.A4ufen 
habe ich mal erklärt, wie das mit Überläufen funktioniert und warum das 
ganz einfach ist, wenn man es mal verstanden hat.

Und nein, es passiert dabei keine Katastrophe und man muss den Überlauf 
auch nicht verhindern sondern einfach mit unsigned Zahlen rechen.

  Michael

von Wolfgang (Gast)


Lesenswert?

W.S. schrieb:
> Natürlich reicht ein beliebiger long bequem für mehrere Tage und wenn
> eine Systemuhr in der Firmware ordentlich funktioniert, dann setzt sie
> die Uhrzeit um Mitternacht auf 0 zurück - und wenn sie obendrein auch
> die Ablaufzeiten für vorgemerkte Ereignisse betreut, dann kann sie
> problemlos auch von diesen Ablaufzeiten um Mitternacht besagte 86400000
> ms subtrahieren und fetig ist die Laube.

Jetzt fängt auch noch diese Diskussion an.
Da ist man froh, einen durchlaufenden Zähler zu haben, der unabhängig 
von Erdrotation, Zeitzonen und Schaltsekunden läuft und immerhin die 
direkte Steuerung von Zeitenabläufen mit Abstand der Ereignisse von bis 
zu 49 Tagen erlaubt, und dann kommst du mit einem Vorschlag, bei dem 
alle 23/24/25 Stunden ein Bruch im Ablauf ins System reindesignt ist. 
Willst du unterschiedlich lange Sekunden, damit dein Tag immer "86400000 
ms" hat?
Da ist die nächste Baustelle vorprogrammiert. Gleichmäßiger Ablauf und 
Uhrzeit oder gar gesetzliche Zeiten passen nicht zusammen und man muss 
sich für eins entscheiden.

von void (Gast)


Lesenswert?

Falk B. schrieb:
> Blödsinn. Man nutzt dafür keine delay() Funktion
Naja... eigentlich hast du ja recht. Aus professioneller Sicht würde man 
es anders machen.

Aber: um im Hobby-Bereich auf einem kleinen AVR einfache Zeitabläufe zu 
steuern, und um eine Zeitbasis (hier ca. 20ms) zu haben, ist es für die 
meisten meiner (!) AVR Projekte ausreichend.

Für mich bietet es viele Vorteile:
- einfach in der Handhabung
- verschiedenste Prozesse im round-robin-Prinzip möglich
- viele unabhängige Timer parallel möglich
- globale Variablen kommen ohne Ressourcen-Locking aus

von Falk B. (falk)


Lesenswert?

void schrieb:
> Für mich bietet es viele Vorteile:
> - einfach in der Handhabung
> - verschiedenste Prozesse im round-robin-Prinzip möglich
> - viele unabhängige Timer parallel möglich
> - globale Variablen kommen ohne Ressourcen-Locking aus

Das kann die gescheite Variante mit dem Timer ebenso und ist nicht 
nennenswert aufwändiger oder komplizierter.

von Wolfgang (Gast)


Lesenswert?

void schrieb:
> Aber: um im Hobby-Bereich auf einem kleinen AVR einfache Zeitabläufe zu
> steuern, und um eine Zeitbasis (hier ca. 20ms) zu haben, ist es für die
> meisten meiner (!) AVR Projekte ausreichend.

Du musst es wissen - für deine Projekte mag es ausreichen.
Dein Nick ist Programm :-(

von Nick M. (Gast)


Lesenswert?

void schrieb:
> Falk B. schrieb:
>> Blödsinn. Man nutzt dafür keine delay() Funktion
> Naja... eigentlich hast du ja recht. Aus professioneller Sicht würde man
> es anders machen.

Völlig falscher Denkansatz.
Man macht es so, wie es effizient ist und zuverlässig funktioniert. Wenn 
man etwas einfaches zu programmieren hat (z.B. die "useless machine") 
kann man das locker mit delay() machen. Es gibt nichts, was man 
gleichzeitig zu erledigen hat. Also tut's das.
Und das hat absolut nichts mit professionell oder Hobby zu tun.

Andere Bsp. für ein delay():
Resetgenerator der mehrere reset-Signale zeitversetzt ausgeben muss. In 
einem meiner (defekten) HP-LAs ist da eine äusserst fragwürdige 
Schaltung die ich wohl ersetzen werde. Die schafft das Timing nämlich 
nicht mehr.

Dummer Timer für einen Aqariums-Sprudler. Irgend ein kleiner 
AVR-PIC-China-µC.

Da gibts so viel, dass jedem von euch ein besseres Beispiel einfällt als 
mir.

von Einer K. (Gast)


Lesenswert?

void schrieb:
> Für mich bietet es viele Vorteile:
> - einfach in der Handhabung
> - verschiedenste Prozesse im round-robin-Prinzip möglich
> - viele unabhängige Timer parallel möglich


Das könnte ich dir, oder besser die Verfahren welche ich nutze, dir auch 
bieten.
Ohne die Zeit tot zu warten.
Suche mal nach "Adam Dunkel Protothreads"


> - globale Variablen kommen ohne Ressourcen-Locking aus
Das lässt sich nicht wirklich vermeiden. Jede Art von Multitasking 
benötigt Verriegelungen, hat kritische Bereiche. Kooperatives ist da nur 
etwas gnädiger...


Falk B. schrieb:
> sondern einen Timer-Interrupt
Die Arduinowelt hat schon einen.
Noch einen braucht es nicht.
Über millis() kann man vielleicht streiten, aber ein zweiter Timer 
Interrupt wäre doppelt gemoppelt.
Wenn, dann nur, wenn man unbedingt muss.
z.B. würde sich ein Timer0 Compare anbieten, der kommt dann mit 980Hz 
auf einem UNO.

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Ohne die Zeit tot zu warten.

Kostet das was? Oder warum ist das prinzipiell falsch (siehe meine 
Beispiele oben)?

> Suche mal nach "Adam Dunkel Protothreads"

Die müssen genauso warten. Halt mit mehr Aufwand. Bei einfachen 
Anwendungen Overkill. Nichts gegen die Protothreads per se!

Das wait() ist fast schon plattformübergreifend (auf µC), Timer oder 
Interuptgeschichten aber immer Controllerabhängig.

von Stefan F. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Suche mal nach "Adam Dunkel Protothreads"
Wenn man mit µIP hantiert, kommt damit früher oder später zwangsläufig 
in Kontakt.

Obwohl ich dazu eine sehr stabile Anwendung und einen schönen Aufsatz 
geschrieben habe (http://stefanfrings.de/net_io/protosockets.html) mag 
ich dieses Konstrukt gar nicht.

Denn man verzettelt sich damit ganz schnell bezüglich des Lifecycles von 
Variablen. Da passiert mir zu viel, was nicht mehr offensichtlich ist.

Meiner Meinung nach schreien Web-Anwendungen geradezu nach einem 
Garbage-Collector und den damit verbundenen Möglichkeiten der 
einfacheren Datenhaltung. Gibt es das überhaupt für C? Vermutlich nicht.

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Arduino Fanboy D. schrieb:
>> Ohne die Zeit tot zu warten.
>
> Kostet das was? Oder warum ist das prinzipiell falsch (siehe meine
> Beispiele oben)?
>
>> Suche mal nach "Adam Dunkel Protothreads"
>
> Die müssen genauso warten. Halt mit mehr Aufwand. Bei einfachen
> Anwendungen Overkill. Nichts gegen die Protothreads per se!
>
> Das wait() ist fast schon plattformübergreifend (auf µC), Timer oder
> Interuptgeschichten aber immer Controllerabhängig.

Du hast doch nicht alle Streusel auf dem Kuchen!

Bis eben, war dir das Arduino millis() nicht gut genug, und jetzt 
spielst du den delay() Fanboy.

Nörgeln, nerven. Streitsüchtig.

von Schuppeste (Gast)


Lesenswert?

precF_CPU=timemillisoverflows*256+TCNT0

Duck und weg

von Einer K. (Gast)


Lesenswert?

Schuppeste schrieb:
> precF_CPU=timemillisoverflows*256+TCNT0
Das ist in etwa das, was das Arduino micros() tut.

von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Nörgeln, nerven. Streitsüchtig.

So bist du halt.

Arduino Fanboy D. schrieb:
> Du hast doch nicht alle Streusel auf dem Kuchen!

Wenn du dich besser im Konditoreiwesen auskennst, dann such dir doch ein 
passendes Thema dazu aus. Oder lies die Bäckerblume.


Arduino Fanboy D. schrieb:
> Bis eben, war dir das Arduino millis() nicht gut genug, und jetzt
> spielst du den delay() Fanboy.

Also Fanboy bin ich nicht, nenn ich mich auch nicht. Eine Begründung für 
delay hab ich gegeben.
Jetzt bleibt noch die Frage: Was hast du daran nicht kapiert?
Keine Angst, es gibt keine dummen Fragen.

von Einer K. (Gast)


Lesenswert?

Nick M. schrieb:
> Eine Begründung für
> delay hab ich gegeben.
> Jetzt bleibt noch die Frage: Was hast du daran nicht kapiert?

Dann wollen wir doch mal schauen, wer irgendwas nicht kapiert hat....

Mach mal Eingangsposting lesen....
1. Ihm verwendet offensichtlich Arduino
2. Ihm will weg von delay()
3. Hin zu millis()
4. Nebenläufigkeiten realisieren

Jetzt der Vergleich zu deinen Ergüssen:

Einen 64Bit Timer gibts in der Arduino Welt nicht.
Man kommt auch mit dem gegebenen 32Bit gut klar.

Auf delay() soll verzichtet werden. Also sind deine Lobpreisungen des 
Wartens, gelinde gesagt, etwas deplatziert.

Und Arduino ist sowieso nicht deine Baustelle. Sagste ja selber....
Es geht dir am Arsch vorbei.

Jetzt mal Butter bei die Fische:
Warum machst du hier so die Welle?
Warum gehst du mich so an?

Beitrag #6560561 wurde von einem Moderator gelöscht.
Beitrag #6560568 wurde von einem Moderator gelöscht.
Beitrag #6560616 wurde von einem Moderator gelöscht.
Beitrag #6560636 wurde von einem Moderator gelöscht.
von Nick M. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Du hast doch nicht alle Streusel auf dem Kuchen!

Arduino Fanboy D. schrieb:
> Nörgeln, nerven. Streitsüchtig.

Arduino Fanboy D. schrieb:
> 1. Ihm verwendet offensichtlich Arduino
> 2. Ihm will weg von delay()
> 3. Hin zu millis()
> 4. Nebenläufigkeiten realisieren

Junge, das alles hab ich doch lang vor dir beantwortet. Und zwar so, 
dass er damit tatsächlich weiterkommt. FSM. Such einfach danach. 13. 
Posting, nachdem die vorhergehenden (nicht von mir) sich am millis 
elaboriert haben ohne das Problem zu lösen.

Natürlich will der TO weg von delay() weil es einfach so nicht geht. Ist 
mir schon lange klar. War mir sofort klar wie ich sein posting gelesen 
hab.

Bezüglich delay() hab ich auf die Aussage beantwortet:

void schrieb:
> Falk B. schrieb:
>> Blödsinn. Man nutzt dafür keine delay() Funktion
> Naja... eigentlich hast du ja recht. Aus professioneller Sicht würde man
> es anders machen.
>
> Aber: um im Hobby-Bereich auf einem kleinen AVR einfache Zeitabläufe zu
> steuern, und um eine Zeitbasis (hier ca. 20ms) zu haben, ist es für die
> meisten meiner (!) AVR Projekte ausreichend.

Mit Beispielen!

Aber der void wurde sofort persönlich dafür angegriffen. U.a. von dir.
Auch meine Erklärung warum delay() durchaus sinnvoll sein kann hast du 
versucht pauschal als schlecht hinzustellen. Ohne dann auf meine Frage 
was denn an den Proto-threads besser sei wenn man einfach nur ganz 
stumpf warten will. Aber da flippst du aus und antwortest mit deinen 
Ausfälligkeiten. Mach dir keine Hoffnungen, damit bewirkst du nichts, du 
bekommst dafür eine Retourkutsche.

Arduino Fanboy D. schrieb:
> Warum machst du hier so die Welle?
> Warum gehst du mich so an?

Glaubst du, dass du mich einschüchterst? Ich lass mich nicht 
einschüchtern. Weder im Netz noch auf der Straße. Den Versuch haben 
schon paar bereut. Auch 40 Jahre jüngere, auf der Straße, nicht ein Jahr 
her. Ich bin 64.

Lass es einfach bleiben, red mit mir vernünftig und alles ist gut. Lass 
vor Allem deine Spielchen, die kenn ich.

von Falk B. (falk)


Lesenswert?

Jaja, Glaubens- und Kleinkrieg 2.0.

Habt ihr das WIRKLICH nötig? Zu kleiner Piephahn?

von Nick M. (Gast)


Lesenswert?

Falk B. schrieb:
> Jaja, Glaubens

Ich führe hier keinen Glaubenskrieg. Weil mir es piepegal ist ob AVR, 
Microchip oder ARM oder gar Propeller. Hängt von der Anwendung ab. Und 
danach wähle ich die Plattform. Und die löte ich mir dann auch genau 
passend zusammen.
Solange C drauf läuft ist alles gut. :-))

von 900ss (900ss)


Lesenswert?

Arduino Fanboy D. schrieb:
> Du hast doch nicht alle Streusel auf dem Kuchen!
....

> Nörgeln, nerven. Streitsüchtig.

Merkste was?

von 900ss (900ss)


Lesenswert?

Arduino Fanboy D. schrieb:
> Warum gehst du mich so an?

Wundert dich das wirklich?

von 900ss (900ss)


Lesenswert?

Falk B. schrieb:
> Zu kleiner Piephahn?

LOL :)

Beitrag #6560746 wurde von einem Moderator gelöscht.
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Gut, Schluß jetzt.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.