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.
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.
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.
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.
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
voidloop(){
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.
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 ;-)
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)
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".
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 ...
:-)
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.
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
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.
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;
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
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.
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.
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 ....
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
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.
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.
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.
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...
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.
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. ;)
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?
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 ???
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.
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.
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.
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 ... :-)
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.
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_twideMillis()
2
{
3
union
4
{
5
struct
6
{
7
uint32_tlo;
8
uint32_thi;
9
};
10
uint64_tzeit;
11
}staticdaten;
12
uint32_tjetzt=millis();
13
if(jetzt<daten.lo)daten.hi++;
14
daten.lo=jetzt;
15
returndaten.zeit;
16
}
Die Funktion geht von einem stetig wachsenden millis() Wert aus.
Den dürfte man in der Praxis immer so haben.
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.
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!
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
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.
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!
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.
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
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.
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
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();
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?
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.
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.
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.
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.
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.
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! :-))))
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
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
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
staticvolatileuint64_tusbase;// Initialised to zero
2
staticinlinevoidtimer1_ovf(void){
3
usbase+=0x8000;
4
}
5
ISR(TIMER1_OVF_vect){timer1_ovf();}
6
staticuint64_tmicros(void){
7
uint8_toldSREG=SREG;
8
cli();
9
uint16_ttcnt=TCNT1;
10
uint8_ttov=TIFR1&(1<<TOV1);// Has to happen strictly after accessing TCNTn
11
SREG=oldSREG;
12
uint64_tus=usbase+tcnt/2;
13
if(tov&&tcnt<0xFFFF)us+=0x8000;// Pending timer_ovf processing for this TCNT not yet executed
14
returnus;
15
}
16
...
17
TCCR1A=0;
18
TCCR1B=(1<<CS11);// Prescaler 8 -> 2 ticks per microsecond @ 16MHz
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.
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.
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.
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.
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?
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.
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.
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!
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.
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.
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.
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.
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.
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
>
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.
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);
[
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.
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.
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
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.
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
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.
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 :-(
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.
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.
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.
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.
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.
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.
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?
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.
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. :-))