Hallo um Timerfunktionen z.b für ein Blinken, in der Arduino Umgebung (Software) zu nutzen gibt es die delay Funktion, mit allen ihren Problemen wenn das Programm ein wenig mehr machen soll. Das ist selbst den Arduinoentwicklern klar und deshalb gibt es auch eine Funktion millis, auf die ich aber auch gerne verzichten würde. Wieso, weshalb, warum steht nicht zu Diskussion, und zwar bezüglich meines Wunsch auf Verzicht als auch (!) warum ich die Arduino Entwicklungsumgebung nutze obwohl ich teilweise Hardware nah arbeiten möchte - Glaubenskrieger und Missionare können sich woanders austoben -Danke. Jetzt findet Google zwar 1001 Tutorials zu "Arduino without delay" aber bei "Arduino without delay and millis" und Ähnliches erhalte ich keine brauchbaren Treffer sondern letztendlich die gleichen Tutorials, Fragen, Hinweise... wie bei der reinen "... without delay..." Suche. Deutschsprachige Suche bringt eher noch weniger. Ich möchte aber in der Arduinoumgebung (und nicht in reinen C, Assembler...) Hardwarenah den ATMega328 bezüglich den Timer (sowohl "Timer" in der Bedeutung beim µC als auch wie sie im Allgemeinen Sprachgebrauch verwendet wird)verstehen und nutzen. Dafür gibt es doch mit hoher Wahrscheinlichkeit schon Tutorials - nur ich finde diese nicht da die gefühlt Millionen Tutorials zum Ersatz der Delay Funktion das Auffinden unmöglich machen. Wer kann helfen (Link, genialer Suchbegriff, eigene Worte...)? Ardu Ino
Wie ist denn die Blink-Frequenz? Im Idealfall gibt es in der Loop() kein einzigen Aufruf der eine Wartezeit verursacht. Sodas die Loop() mit einer sehr hohen Frequenz durchlaufen ist. Um ein Blinken ohne Nutzung einer Delay-Funktion zu erzeugen, muss du in der Loop die vergangene Zeit messen. Ist die gewünschte Zeit (z.B. 0,5 Sekunden) abgelaufen, schaltest du den Ausgang um und startest eine neue Zeitmessung, so bekommst du eine Blinkfrequenz von z.B. 1Hz
> Wer kann helfen (Link, genialer Suchbegriff, eigene Worte...)?
Suchbegriff: "pferd von hinten aufzäumen". Verabschiede Dich von der
Arduinolaufzeitarchitektur oder von genauen Timings. In ersterem Falle:
Herzlichen Glückwunsch, als nächstes bitte das Datenplatt zum
Mikrocontroller lesen und verstehen.
Ardu Ino schrieb: > ... obwohl ich teilweise Hardware nah arbeiten möchte Es hindert dich keiner daran, eigene Funktionen für hardwarenahen Anwendungen zu verwenden. > ... und deshalb gibt es auch eine Funktion millis, auf die ich > aber auch gerne verzichten würde. Selber schuld - warum? > -Danke. Bitte Ardu Ino schrieb: > Wer kann helfen (Link, genialer Suchbegriff, eigene Worte...)? Geniale Suchbegriffe wären z.B. "Timer" und "Interrupt". Wenn du dem Timer-Interrupt, der hinter millis() steht, nicht traust, setze doch einen eigenen Timer auf. Die Registerbezeichnungen stehen im Datenblatt und sind auch in der Arduino IDE verfügbar. Wenn du das nicht kannst/möchtest nutze die Arduino Umgebnung oder lese dir Grundlagen an, z.B. https://www.robotshop.com/letsmakerobots/arduino-101-timers-and-interrupts Wasch mir den Pelz, aber mach mich nicht nass funktioniert hier nicht, wenn Copy&Paste schon an elementaren Suchbegriffen scheitert
Ardu Ino schrieb: > Ich möchte aber in der Arduinoumgebung (und nicht in reinen C, > Assembler...) Hardwarenah den ATMega328 bezüglich den Timer (sowohl > "Timer" in der Bedeutung beim µC als auch wie sie im Allgemeinen > Sprachgebrauch verwendet wird)verstehen und nutzen. Schreibe deine Funktion int main (void) { ..... } in deiner Arduino IDE und vermeide die Implementierungen Setup(); und Loop(); Damit bist du Herr über alles ohne auch nur eine Mikrosekunde deines Controllers hergeschenkt zu haben. Und alle Hardware, auch die Timer, ist/sind frei verfügbar.
Ardu Ino schrieb: > Ich möchte aber in der Arduinoumgebung (und nicht in reinen C, > Assembler...) Hardwarenah den ATMega328 bezüglich den Timer (sowohl > "Timer" in der Bedeutung beim µC als auch wie sie im Allgemeinen > Sprachgebrauch verwendet wird)verstehen und nutzen. Schon mal drüber nachgedacht, das Datenblatt zu studieren? Da steht alles drin, was man so wissen muss.
Hallo, auch in der Arduino-IDE niemand hindert Dich niemand eigene Timerinterrups einzubauen. https://github.com/esp8266/Arduino/blob/master/libraries/Ticker/Ticker.h ist möglicher Weg. Das stammt aus einer Scrollroutine eines meiner Displays:
1 | #include <Ticker.h> // Bibliothek einbinden |
2 | |
3 | Ticker scroll_display; // Instanz anmelden |
4 | |
5 | int scrollpos = 0; // aktuelle Scrollposition |
6 | int scrolltime = 250; // Zeit in ms zwischen den Scrollschritten |
7 | |
8 | |
9 | void scrollen() // Scrollroutine die vom Ticker-Interrupt aufgerufen wird |
10 | { |
11 | scrollpos++; |
12 | if (disp_buf[scrollpos] == 0) // Stringende |
13 | { |
14 | scrollpos = 0; |
15 | } |
16 | |
17 | int aktpos = scrollpos; |
18 | |
19 | for (int i = 0; i < 16; i++) |
20 | { |
21 | if (disp_buf[aktpos] == 0) // Stringende |
22 | { |
23 | aktpos = 0; // von vorne |
24 | } |
25 | displayWriteChar(i, disp_buf[aktpos]); |
26 | aktpos++; |
27 | } |
28 | } |
Im loop dann eben mit scroll_display.attach_ms(scrolltime, scrollen); und mit scroll_display.detach(); ausschalten. Gruß aus Berlin Michael
Ich verstehe das Problem nicht. Warum sollte auf millis() verzichtet werden? Das ist doch einfach zu benutzen und man kann überprüfen ob eine Zeit schon abgelaufen ist. Was ist das Problem mit millis() ?
> Was ist das Problem mit millis() ? Verstehe ich auch nicht. Jedes PC Betriebssystem hat das, jedes Smartphone und ARM Kerne haben dazu sogar einen extra Timer integriert. Wie willst du sonst Zeiten messen? Etwa mit Kondensatoren?
@Ardu Ino (Gast) >Jetzt findet Google zwar 1001 Tutorials zu "Arduino without delay" aber >bei "Arduino without delay and millis" und Ähnliches erhalte ich keine >brauchbaren Treffer sondern letztendlich die gleichen Tutorials, Fragen, >Hinweise... wie bei der reinen "... without delay..." Suche. >Deutschsprachige Suche bringt eher noch weniger. Dann suchst du falsch. >Ich möchte aber in der Arduinoumgebung (und nicht in reinen C, >Assembler...) Hardwarenah den ATMega328 bezüglich den Timer (sowohl >"Timer" in der Bedeutung beim µC als auch wie sie im Allgemeinen >Sprachgebrauch verwendet wird)verstehen und nutzen. Das ist leicht, denn Arduino ist nicht sooo isoliert wie manche meinen. Es ist "nur" eine Sammlung von Bibliotheken, die man nutzen KANNN (und meist auch sollte), der Rest des AVRs ist aber genauso verfügbar und zugreifbar wie in reinem C ohne Arduino. >Dafür gibt es doch mit hoher Wahrscheinlichkeit schon Tutorials Jaja, die ganze Welt als Tutorial. Nerd 2.0 >ich finde diese nicht da die gefühlt Millionen Tutorials zum Ersatz der >Delay Funktion das Auffinden unmöglich machen. Ich schon. Siehe Multitasking. Einen Interrupt kann man beim Arduino genauso leicht nutzen wie ohne. Beitrag "Re: Arduino Nano, SD Card, PCM"
millis() ist genau das, was der TO braucht, unabhängig davon, was er will. Den millis() arbeitet ja mit einem Timer und dessen Interrupt. Ich vermute sehr, der TO weiß nur nicht, wie man diese Funktion am besten einsetzt und zyklisch mit Zustandsautomaten programmiert (Stichwort Mainloop). Und deshalb versucht er, seinen Schopf über ein Programm, das direkt im Timerinterrupt läuft, aus der Schlinge zu ziehen. Dass er sich damit ganz andere Probleme an die Backe klebt, weiß er allerdings auch nicht (Stichworte Semaphorenproblem und Racecondition).
Ardu Ino schrieb: > Ich möchte aber in der Arduinoumgebung (und nicht in reinen C, > Assembler...) Hardwarenah den ATMega328 bezüglich den Timer (sowohl > "Timer" in der Bedeutung beim µC als auch wie sie im Allgemeinen > Sprachgebrauch verwendet wird)verstehen und nutzen. tue es doch ich kam vom nackten Atmel AVR mit AVR Studio 4.18 zum Arduino, nutze eigene C-Module die ich einbinde als *.ino als auch LIBs der Arduinio wahlweise nach Bedarf. Mich stört weder setup(), noch loop() auch nicht millis() oder eigene Timerinterrupts, alles kooperiert nach meinen Wunsch und wenn mal nicht schaue ich wo ich ändern muss, z.B. mal einen anderen Timer wählen.
zur erhellung ohne delay ... #ifndef PERIODIC_H #define PERIODIC_H //usage: // PERIODIC(100) //{ // digitalWrite(PIN, HIGH/LOW) // } //create an unique name from given parameter and line number #define UNIQUE(name) __CONCAT(name,__LINE__) //creates an unique timer for each instance, ms period in milli-seconds #define WAITBLOCK(ms) \ static uint32_t UNIQUE(timer) = millis(); \ if (millis() - UNIQUE(timer) >= ms) { //creates an unique timer for each instance, ms period in milli-seconds #define PERIODIC(ms) \ static uint32_t UNIQUE(timer) = millis(); \ if (millis() - UNIQUE(timer) >= ms) { \ UNIQUE(timer) = millis(); //XPERIODIC(ms,1) = WAITBLOCK but takes more program code space! //XPERIODIC(ms,0) = PERIODIC //creates an unique timer for each instance, x: repeats 0-255, 0=endless #define XPERIODIC(ms, x) \ static uint32_t UNIQUE(timer) = millis(); \ static uint8_t UNIQUE(xRepeats) = x; \ static uint8_t UNIQUE(lock); \ if (millis() - UNIQUE(timer) >= ms) { \ if (!UNIQUE(lock)) { \ if ((UNIQUE(xRepeats)==0) || (--UNIQUE(xRepeats))) \ UNIQUE(timer) = millis(); \ else UNIQUE(lock)=1; \ } #endif //PERIODIC_H
@Lothar Miller (lkmiller) (Moderator) Benutzerseite >millis() ist genau das, was der TO braucht, Nein, denn diese Funktion liefert nur einen Timerwert, welche in einem 1ms Timer-Interrupt hochgezählt wird. Die nützt rein gar nichts, wenn andere Funktionen, warum auch immer, den Programmablauf längere Zeit "blockieren". > unabhängig davon, was er >will. Den millis() arbeitet ja mit einem Timer und dessen Interrupt. Dort kommt man aber so direkt nicht ran, sprich, man kann sich NICHT in den 1ms Timer einklinken! Dazu müßte es eine Funktion geben, die der Anwender erstellen kann, welche dann vom Arduino-Framework im 1ms Interrupt aufgerufen wird. So etwas gibt es nicht, u.a. weil es dem Konzept der Vereinfachung deutlich widerspricht. >Ich vermute sehr, der TO weiß nur nicht, wie man diese Funktion am >besten einsetzt und zyklisch mit Zustandsautomaten programmiert >(Stichwort Mainloop). Das ist nur ein Würg-Around mit begrenzter Leistung. Siehe oben. >Und deshalb versucht er, seinen Schopf über ein Programm, das direkt im >Timerinterrupt läuft, aus der Schlinge zu ziehen. Genau DAS ist aber die Lösung der allermeisten Probleme dieser Art! Außerdem hat der OP ganz sicher sehr wenig Plan von AVRs und Interrupts, denn ich wette 1 Kasten Bier, daß er für seine Drehgeberauswertung die rudimentäre Interrupt-Funktionalität des Arduinos nutzt. https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/ >Dass er sich damit ganz andere Probleme an die Backe klebt, weiß er >allerdings auch nicht (Stichworte Semaphorenproblem und Racecondition). Jaja, und schon wieder sind am Sonntag Morgen die Reichsbdenkenträger voll dabei, die Welt zur retten. ODer zumindest viel Staub aufzuwirblen! :-( Siehe Anhang!!!
@majortom (Gast)
>zur erhellung ohne delay ...
Du hast eine merkwürdige Vorstellung von "Erhellung".
>> millis() ist genau das, was der TO braucht, > Nein, denn diese Funktion liefert nur einen Timerwert, welche in einem > 1ms Timer-Interrupt hochgezählt wird. Die nützt rein gar nichts, wenn > andere Funktionen, warum auch immer, den Programmablauf längere Zeit > "blockieren". Die millis() Funktion ist ideal, um innerhalb eines Zustandsautomaten Aktionen zu einem bestimmten Zeitpunkt auszuführen. Das Abwarten einer Zeitspanne zählt auch dazu. > wenn andere Funktionen... den Programmablauf längere Zeit "blockieren". Das ist in vernünftigen Multi-Task fähigen Anwendungen ohnehin nicht zulässig. Größere Aktionen müssen ggf. in kleinere zerlegt werden. Zustandsautomaten ist das Stichwort zum lernen, sobald man die Grenzen von delay() und anderen blockierenden Aktionen erkannt hat.
@Stefan Us (stefanus) >>> millis() ist genau das, was der TO braucht, >> Nein, denn diese Funktion liefert nur einen Timerwert, welche in einem >> 1ms Timer-Interrupt hochgezählt wird. Die nützt rein gar nichts, wenn >> andere Funktionen, warum auch immer, den Programmablauf längere Zeit >> "blockieren". >Die millis() Funktion ist ideal, um innerhalb eines Zustandsautomaten >Aktionen zu einem bestimmten Zeitpunkt auszuführen. Das Abwarten einer >Zeitspanne zählt auch dazu. FALSCH! Auch du hast das Problem NICHT verstanden! >> wenn andere Funktionen... den Programmablauf längere Zeit "blockieren". >Das ist in vernünftigen Multi-Task fähigen Anwendungen ohnehin nicht >zulässig. Größere Aktionen müssen ggf. in kleinere zerlegt werden. Jaja, soweit die Theorie. Dumm nur, daß das selbt für Profis bisweilen nicht möglich ist, weil bestimmte Funktionen bzw. Bibliotheksfunktionen schlicht länger dauern und nicht teilbar sind. Hier geht es um das gleiche Problem. Und besonders dort ist millis() fehl am Platz. Der schelle, zeitkritische Kram gehört in die Timer-ISR, der langsame LCD-Kram in die Hauptschleife. Beitrag ""Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzeit" >Zustandsautomaten ist das Stichwort zum lernen, sobald man die Grenzen >von delay() und anderen blockierenden Aktionen erkannt hat. Eben dafür braucht es KEINE gottverdammte millis() Funktion, die nur ein Arduino-Würg-Around ist! Denn in den allermeisten Fällen will man diverse State Machines mit einer definierten, konstanten Frequenz aufrufen, damit ergibt sich das Timing von allein und diverse Verzögerungen werden in den FSMs per Zustand und Zähler gemacht. Un komm mir jetzt nicht mit der 101 Ausnahme, welche die Regel bestätigt!
> millis() Funktion, die nur ein Arduino-Würg-Around ist! Dann schau Dir mal Java an, oder Windows, oder Linux, oder Android, oder ARM Kerne. Die haben alle einen Millisekunden-Zähler mit mehr oder weniger ähnlichem Namen. > weil bestimmte Funktionen bzw. Bibliotheksfunktionen > schlicht länger dauern und nicht teilbar sind Diese Funktionen würde ich als Designfehler bezeichnen. Mit einem OS das aktiv Threads unterbricht könnte man sie verwenden, aber auf µC wären sie fehl am Platz. Blockierende Warteschleifen dürfen meiner Meinung nach nur wenige Nano- bis Mikrosekunden dauern.
@ Stefan Us (stefanus) >> millis() Funktion, die nur ein Arduino-Würg-Around ist! >Dann schau Dir mal Java an, oder Windows, oder Linux, oder Android, oder >ARM Kerne. Die haben alle einen Millisekunden-Zähler mit mehr oder >weniger ähnlichem Namen. Du Nase! Wer hat denn die Existenz dieser Sache abgestritten? Es ging um die Frage, wie man sinnvoller, bzw. optimalerweise ein minimales Multitasking auf einem uC gestaltet. Und schau dir mal diverse Java-Anwendungen an, dann weißt du, warum die Mist sind (Performance, was ist das?) Ob das an den schlechten Konzepten der mittelmäßigen Programmierer und dernen millis() Funktion liegt?
@Stefan Us (stefanus) > >> weil bestimmte Funktionen bzw. Bibliotheksfunktionen >> schlicht länger dauern und nicht teilbar sind >Diese Funktionen würde ich als Designfehler bezeichnen. Mit einem OS das >aktiv Threads unterbricht könnte man sie verwenden, aber auf µC wären >sie fehl am Platz. Schon wieder Unsinn. Heute nicht dein Tag, oder? Beispiel. Das VORZÜGLICHE FATfs vom Meister Elm Chan aus dem fernen Osten hat diverse Funktion, die halt mal länger und mal kürzer dauern. Willst du daraus schließen, daß dFATfs Mist ist? NEIN! Denn wenn man damit was performantes auf die Beine stellen will, muss man halt "nur" wissen wie das geht. Mein schon mehrfach zitierter DMX Rekorder macht das mit 22kB/s. Totz daß diverse FATfs Funktionen eher Millisekunden brauchen.
Wie kann denn etwas ein Arduino-Würg-Around sein, was in praktisch allen anderen Programmiersprachen und Betriebssystemen ebenso vorhanden ist? > in den allermeisten Fällen will man diverse State Machines > mit einer definierten, konstanten Frequenz aufrufen Ich kenne das als eine mögliche Lösung. Ich habe aber schon wesentlich mehr State Machines gesehen, deren hauptschleife einfach nur schnellstmöglich ausgeführt wird. Unter anderem in Arduino, µC Projekte die auf LwIp und µIP basieren (somit auch ESP8266), fast alle meine eigenen µC Projekte, zahlreiche Windows Programme, die Event-Loop vom QT Framework, ... Vielleicht beginnst du mal zu akzeptieren, dass viele Wege zum Ziel führen und deiner nicht der einzig richtige ist.
In Sachen millis() und delay(), bin ich schon fast eine Fachkraft. Zumindest eine eingewiesene Person, mit fundiertem Halbwissen. Die Hierarchie des ArduinoZeitHändlings: Einfache Dinge ruhig mit delay(). Solange, bis es einem auf die Füße fällt.... Dann das BlinkWithoutDelay Konzept anwenden. Damit kann man eigentlich alles erschlagen. Ja, wenn es einen nicht stört, dass dauernd millis() aufgerufen und verglichen wird. Wird dann schlußendlich ein exaktes Timing gebraucht, kann man ja noch immer die HardwareTimer zur Hilfe nehmen. Ein UNO hat 3 davon, wobei Timer0 vom Core belegt wird. Da ist man dann an dem Punkt, wo es ohne Datenblatt nicht weiter geht. ---- Auch gibt es die Chance den Arduino Core abzuändern. In dessen Timer0 ISR eine Weak Funktion rein zu klemmen ist eine Kleinigkeit von 3 oder 4 Zeilen. Dieser Interrupt kommt alle, ca. 1ms. Er ist nicht ganz exakt. Damit millis() korrekt läuft wird da im Core noch rumkorrigiert.
Arduino F. schrieb: > Dieser Interrupt kommt alle, ca. 1ms. Er ist nicht ganz exakt. Damit > millis() korrekt läuft wird da im Core noch rumkorrigiert. Warum? 16MHz:1KHz geht doch im CTC-Mode glatt auf. Oder benutzen sie den Timer als Atmega8-Gedächtnis-Timer nur im OVF?
millis() Zeite 65 https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring.c ISR => Zeile 45
Ich kann mich nicht für die Jungs und Mädels rechtfertigen.... Das lohnt nicht. Der Timer wird auch für PWM genutzt. Und er hat eben nur 8 Bit. Vielleicht fehlte da einfach der Hut, um da beides drunter zu bekommen. https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM https://playground.arduino.cc/Main/TimerPWMCheatsheet
Ich kopier's mal raus:
1 | // the prescaler is set so that timer0 ticks every 64 clock cycles, and the
|
2 | // the overflow handler is called every 256 ticks.
|
3 | #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
|
4 | |
5 | // the whole number of milliseconds per timer0 overflow
|
6 | #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
|
7 | |
8 | // the fractional number of milliseconds per timer0 overflow. we shift right
|
9 | // by three to fit these numbers into a byte. (for the clock speeds we care
|
10 | // about - 8 and 16 MHz - this doesn't lose precision.)
|
11 | #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
|
12 | #define FRACT_MAX (1000 >> 3)
|
13 | |
14 | volatile unsigned long timer0_overflow_count = 0; |
15 | volatile unsigned long timer0_millis = 0; |
16 | static unsigned char timer0_fract = 0; |
17 | |
18 | #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
|
19 | ISR(TIM0_OVF_vect) |
20 | #else
|
21 | ISR(TIMER0_OVF_vect) |
22 | #endif
|
23 | {
|
24 | // copy these to local variables so they can be stored in registers
|
25 | // (volatile variables must be read from memory on every access)
|
26 | unsigned long m = timer0_millis; |
27 | unsigned char f = timer0_fract; |
28 | |
29 | m += MILLIS_INC; |
30 | f += FRACT_INC; |
31 | if (f >= FRACT_MAX) { |
32 | f -= FRACT_MAX; |
33 | m += 1; |
34 | }
|
35 | |
36 | timer0_fract = f; |
37 | timer0_millis = m; |
38 | timer0_overflow_count++; |
39 | }
|
40 | |
41 | unsigned long millis() |
42 | {
|
43 | unsigned long m; |
44 | uint8_t oldSREG = SREG; |
45 | |
46 | // disable interrupts while we read timer0_millis or we might get an
|
47 | // inconsistent value (e.g. in the middle of a write to timer0_millis)
|
48 | cli(); |
49 | m = timer0_millis; |
50 | SREG = oldSREG; |
51 | |
52 | return m; |
53 | }
|
Beitrag #5238637 wurde vom Autor gelöscht.
Falk B. schrieb: > @Lothar Miller (lkmiller) (Moderator) Benutzerseite >> millis() ist genau das, was der TO braucht, > Nein, denn diese Funktion liefert nur einen Timerwert, welche in einem > 1ms Timer-Interrupt hochgezählt wird. Das reicht für übliche zeitliche Abläufe völlig aus. > Die nützt rein gar nichts, wenn andere Funktionen, warum auch immer, > den Programmablauf längere Zeit "blockieren". Dann haben wir das Problem ja schon erkannt: der Programmablauf der Hauptschleife darf schlicht und einfach nicht blockiert werden. Das wars. Wenn man sich daran hält, dann kann man ganz einfach wartbare und erweiterbare und vor allem portierbare Programme schreiben. Die wichtigste (Überwachungs-)Funktion meiner Hauptschleife ist der Abschnitt, wo die minimale, maximale und durchschnittliche Zykluszeit berechnet wird. Und wenn ein durch die Anwendung bestimmter Grenzwert der maximalen Zykluszeit überschritten wird, dann habe ich gerade eben einen Fehler reinprogrammiert. Merke: der am einfachsten erkennbare Programmierfehler ist ein delay_ms(). Falk B. schrieb: > Das VORZÜGLICHE FATfs vom Meister Elm Chan aus dem fernen Osten hat > diverse Funktion, die halt mal länger und mal kürzer dauern. Willst du > daraus schließen, daß dFATfs Mist ist? Doch. Genau das ist es: wenn es mir wegen irgendwelcher Warterei auf irgendwelche Hardware das Timing verhagelt, dann ist das Murks. Und ich muss dann auf die eine oder andere Art einen Workaroud drumrum basteln. Falk B. schrieb: >> Dass er sich damit ganz andere Probleme an die Backe klebt, weiß er >>>allerdings auch nicht (Stichworte Semaphorenproblem und Racecondition). > Jaja, und schon wieder sind am Sonntag Morgen die Reichsbdenkenträger > voll dabei, die Welt zur retten. ODer zumindest viel Staub aufzuwirblen! Falk, du lenkst ab. Hier schlagen doch laufend Anfänger auf, die sich wundern, warum ihre volatile Variable, die im Interrupt und im Huptprogramm verwendet wird, ab&zu "spinnt". Und ich kenne einige Fälle, wo Anfänger um genau solche Fälle dann mit "Dreifach-Abfragen mit anschließendem Vergleich" übel um genau dieses Semaphoren-Problem herumflicken. Denn das ist nichts, was einem Angst machen soll, sondern man muss es einfach wissen um daraus entstehende Probleme zu vermeiden. So wie du es weißt und auf diese Art Probleme vermeidest. Falk B. schrieb: > Du Nase! Falk, könntest du bitte die Antworten OHNE solche absolut vollkommen unnötigen persönlichen Angriffe und Beleidigungen schreiben? Den Rest meiner Antwort spare ich mir!
:
Bearbeitet durch Moderator
@Stefan Us (stefanus) >Wie kann denn etwas ein Arduino-Würg-Around sein, was in praktisch allen >anderen Programmiersprachen und Betriebssystemen ebenso vorhanden ist? Falsch! Du verwechselst die Verfügbarkeit einer Methode mit deren optimalem Einsatz. >> in den allermeisten Fällen will man diverse State Machines >> mit einer definierten, konstanten Frequenz aufrufen >Ich kenne das als eine mögliche Lösung. Na immerhin. >Ich habe aber schon wesentlich mehr State Machines gesehen, deren >hauptschleife einfach nur schnellstmöglich ausgeführt wird. Unter >anderem in Arduino, WOW! Was für eine Referenz! Vor allem was die Performance angeht! > µC Projekte die auf LwIp und µIP basieren (somit >auch ESP8266), Hmm. >fast alle meine eigenen µC Projekte, Naja. > zahlreiche Windows >Programme, die Event-Loop vom QT Framework, ... Sinngemäßes Zitat von Bertrand Russel "Nur weil eine Meinung von der Mehrheit vertreten wird, ist kein Beweis, daß es nicht vollkommener Unsinn ist." Mein letztes Plädoyer zum Thema. Man KANN mit einer Funktion ala millis() diverse Statemachine betreiben, die ggf. auch nur so schnell wie möglich oder auch langsamer aufgerufen werden. Für einige Anwendungen ist das ausreichend. Manchmal MUSS man es machen, weil es nicht besser geht und ggf. mit den daraus folgenden Einschränkungen leben. ABER!!!!! Wenn möglich, versucht man bei einer Problemlösung von vorn herein erstmal KEINE Kompromisse zu schließen und eine schnelle, leistungsfähige Lösung anzustreben. Das bedeutet hier, eine Statemachine mittels Timer oder gar ISR im festen Zeitraster aufzurufen, ohne sonstige Kompromisse. Und genau DAS will und braucht der OP!!! OK, es war der andere Thread, die Diskussion ist aber praktisch die Gleiche, weil das grundlegende Problem das Gleiche ist! Beitrag ""Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzeit" >Vielleicht beginnst du mal zu akzeptieren, dass viele Wege zum Ziel >führen und deiner nicht der einzig richtige ist. Das habe ich nie behauptet. Siehe oben.
@ Lothar Miller (lkmiller) (Moderator) >>> millis() ist genau das, was der TO braucht, >> Nein, denn diese Funktion liefert nur einen Timerwert, welche in einem >> 1ms Timer-Interrupt hochgezählt wird. >Das reicht für übliche zeitliche Abläufe völlig aus. Nö. Definiere mal "übliche zeitliche Abläufe". >> Die nützt rein gar nichts, wenn andere Funktionen, warum auch immer, >> den Programmablauf längere Zeit "blockieren". >Dann haben wir das Problem ja schon erkannt: der Programmablauf der >Hauptschleife darf schlicht und einfach nicht blockiert werden. Das >wars. Wenn man sich daran hält, dann kann man ganz einfach wartbare und >erweiterbare und vor allem portierbare Programme schreiben. Bla! Auch das ist, wie bereits geschrieben, in einigen Fällen nicht möglich, vor allem bei Einsatz von Fremdsoftware oder Bibliotheken. >> Das VORZÜGLICHE FATfs vom Meister Elm Chan aus dem fernen Osten hat >> diverse Funktion, die halt mal länger und mal kürzer dauern. Willst du >> daraus schließen, daß dFATfs Mist ist? >Doch. Genau das ist es: wenn es mir wegen irgendwelcher Warterei auf >irgendwelche Hardware das Timing verhagelt, dann ist das Murks. Pure Arroganz und Ignoranz! Beschäftige dich mal mit der Software, dann kannst du ggf. einen fundierten Kommentar abgeben! >Und ich muss dann auf die eine oder andere Art einen Workaroud drumrum >basteln. Jain. Eine vergleichbare Software, die beliebig multitaskingfähig ist, braucht entweder ein echtes, prääemtives Multitasking oder einen deutlich anderen Softwareansatz. Beides ist ziemlich aufwändig. Der Kompromiss der bestehenden Lösung ist IMO optimal. Natürlich muss man des Öfteren Kompromisse und manchmal auch Workarounds machen. Die Frage ist aber, ob man ohne Not gleich damit anfängt. Und meine Antwort darauf ist: NEIN! Falk B. schrieb: >> Dass er sich damit ganz andere Probleme an die Backe klebt, weiß er >>>allerdings auch nicht (Stichworte Semaphorenproblem und Racecondition). > Jaja, und schon wieder sind am Sonntag Morgen die Reichsbdenkenträger > voll dabei, die Welt zur retten. ODer zumindest viel Staub aufzuwirblen! >Falk, du lenkst ab. Hier schlagen doch laufend Anfänger auf, die sich >wundern, warum ihre volatile Variable, die im Interrupt und im >Huptprogramm verwendet wird, ab&zu "spinnt". Ja und? Das Problem ist mit einem volatile lösbar. Und die Grundlagen dazu sind im Artikel Interrupt zu finden. >Und ich kenne einige Fälle, wo Anfänger um genau solche Fälle dann mit >"Dreifach-Abfragen mit anschließendem Vergleich" übel um genau dieses >Semaphoren-Problem herumflicken. Auch das ist ein lösbares Problem. millis() macht es nicht wirklich besser. Du willst nicht die Stützräder am Fahrrad abschrauben sondern bunt anmalen. Das klingt sehr fürsorglich, entmündigt aber nur. >> Du Nase! >Falk, könntest du bitte die Antworten OHNE solche absolut vollkommen >unnötigen persönlichen Angriffe und Beleidigungen schreiben? Nö, manchmal geht es einfach nicht anders. > Den Rest meiner Antwort spare ich mir! Ist auch besser so, moralinsaure Gardinenpredigten sind sowieso sinnlos, in meinem Alter erst recht ;-)
Hallo danke für die diversen Links und auch für die sich entwickelnde Diskussion die meist interessant und teilweise sogar hilfreich für mich ist. Aber bitte: Es handelt sich um ein Technisches Thema - da sollte eine vernünftige Diskussionskultur doch möglich sein? Das sich hier einige Leute herumtreiben die erkennbar richtig viel Wissen und Erfahrung in anspruchsvollen Technischen Bereichen haben, aber gleichzeitig wie ein Holligan oder ein 18 jähriger besoffener am Samstagmorgen um 4:00Uhr in der Partymeile einer Großstadt "argumentieren" ist nur noch als beschämend zu bezeichnen. Mensch Leute, seid Nett zueinander, akzeptiert andere Meinungen, Vorgehensweisen und das nicht alle genauso viel fachlich Wissen wie man selbst. Ardu Ino
Ardu Ino schrieb: > deshalb gibt es auch eine > Funktion millis, auf die ich aber auch gerne verzichten würde. > Wieso, weshalb, warum steht nicht zu Diskussion Sollte es aber. "millis" gibt Dir nur einen Zeitstempel zurück, ist also überhaupt nicht böse. Es gibt daher keinen Grund darauf verzichten zu wollen. Der Unterschied, ob man CPU-Leistung verschwendet oder nicht, liegt allein an Dir, wie Du "millis" anwendest. Eine bequeme Lösung für parallele Tasks mit verschiedenen Verzögerungen kann dann ein Scheduler sein, der z.B. in 1ms oder 10ms Schritten aufgerufen wird: Beitrag "Wartezeiten effektiv (Scheduler)"
Ich verstehe den Aufruhr nicht. Hat doch bei Heise alles schon mal gestanden. Man nimmt einen Timer Interrupt und gut: https://www.heise.de/developer/artikel/Timer-Counter-und-Interrupts-3273309.html
@Matthias Melcher (Firma: privat) (quadraturencoder) >Ich verstehe den Aufruhr nicht. Hat doch bei Heise alles schon mal >gestanden. Man nimmt einen Timer Interrupt und gut: Na wenn das bei heise steht, MUSS es ja die reine Wahrheit sein ;-) Naja, die Begründung, warum ein delay() schlecht ist, ist aber auch eher schlecht 8-0 Daß dabei die CPU steht und zum Nichtstun verdonnert wird, kommt dort nicht wirklich rüber! Außerdem ist die Ungenauigkeit der Funktion das kleinste der Probleme, mal ganz davon abgesehen, daß sie gar nicht so ungenau ist, sondern mit einer Auflösung und Genauigkeit von wenigen CPU-Takten arbeitet. Naja, das übliche IT-Fastfood von heute . . .
:
Bearbeitet durch User
Falk B. schrieb: > @Matthias Melcher (Firma: privat) (quadraturencoder) > >>Ich verstehe den Aufruhr nicht. Hat doch bei Heise alles schon mal >>gestanden. Man nimmt einen Timer Interrupt und gut: > > Na wenn das bei heise steht, MUSS es ja die reine Wahrheit sein ;-) Auch wenn das gleiche bei Falk B. steht? ;-) Falk B. schrieb: > Das bedeutet hier, eine Statemachine > mittels Timer oder gar ISR im festen Zeitraster aufzurufen, ohne > sonstige Kompromisse. Und genau DAS will und braucht der OP!!! Warum machst du dich jetzt über heise lustig, obwohl dort die gleiche Meinung vertreten wird, wie du sie vertrittst?
@Krull (Gast) >Warum machst du dich jetzt über heise lustig, obwohl dort die gleiche >Meinung vertreten wird, wie du sie vertrittst? Weil die Begründung eher schlecht ist. Man kann das richtige meinen aber schlecht ausdrücken.
Falk B. schrieb: > mal ganz davon abgesehen, daß sie gar nicht so > ungenau ist, sondern mit einer Auflösung und Genauigkeit von wenigen > CPU-Takten arbeitet. Naja, das übliche IT-Fastfood von heute . . . ...aber (fast) jedes µC-Programm arbeitet auch mit Interrupts. Und diese Interrupts unterbrechen logischerweise auch ein delay(). Damit (und das ist eigentlich der Normalfall) wird das delay() auf jeden Fall nicht mit der Genauigkeit von wenigen CPU-Takten arbeiten!
@Krull (Gast) >> mal ganz davon abgesehen, daß sie gar nicht so >> ungenau ist, sondern mit einer Auflösung und Genauigkeit von wenigen >> CPU-Takten arbeitet. Naja, das übliche IT-Fastfood von heute . . . >...aber (fast) jedes µC-Programm arbeitet auch mit Interrupts. Viele. Die Arduino-Welt nahezu ohne, vom "unsichtbaren" 1ms Timer mal abgesehen. >Und diese >Interrupts unterbrechen logischerweise auch ein delay(). Damit (und das >ist eigentlich der Normalfall) wird das delay() auf jeden Fall nicht >mit der Genauigkeit von wenigen CPU-Takten arbeiten! Nö, du konstruierst schon wieder eine Sachlage, die so gar nicht existiert. So nach dem Motto, wenn ich ein 10m Maßband nur zu Hälft ausrolle, kann ich keine 10m messen. ;-) Wer des Lesens und vor allem des sinnerfassenden Lesens mächtig ist, wird in der Doku davor gewarnt. Und dann kann man mit delay() recht genaue Zeiten erreichen, z.B. einfache Pulsgeneratoren. Für einige Anwendungen ist das OK, wenn die CPU so oder so nix besseres zu tun hat. In vielen Fällen hat sie das aber.
@Jens Grabner (jensg) >Das hier könnte sehr interessant sein: >http://www.avdweb.nl/arduino/libraries/virtualdelay.html Naja, das ist auch nur eine aufgezuckerte Variate der millis() Nutzung.
Falk B. schrieb: > Nö, du konstruierst schon wieder eine Sachlage, die so gar nicht > existiert. So nach dem Motto, wenn ich ein 10m Maßband nur zu Hälft > ausrolle, kann ich keine 10m messen. ;-) Und wenn ich mein Maßband in 1µm kleine Teile schneide, kann ich sogar sehr genau messen ;-) Ich frage mich, wer hier etwas konstruiert, nur damit er recht behält. Willst du allen ernstes behaupten, daß ein delay(), wenn es tausendmal durch einen Interrupt unterbrochen wird, der selbst ja logischerweise auch Zeit braucht, dann genauso lang ist wie ein delay(), was ganz allein und ungestört läuft? Ein delay() weiß doch nicht, wie lange ein Interrupt dauert, oder? Vor allem, weil ja innerhalb der isr noch Verzweigungen auftreten können, die auch von externen Ereignissen bestimmt werden können...
@Krull (Gast) >Willst du allen ernstes behaupten, daß ein delay(), wenn es tausendmal >durch einen Interrupt unterbrochen wird, der selbst ja logischerweise >auch Zeit braucht, dann genauso lang ist wie ein delay(), was ganz >allein und ungestört läuft? Keine Sekunde, nicht mal delay(1) ;-) Mein Gott, willst du mich nicht verstehen oder kannst du mich nicht verstehen oder willst du nur schwätzen um des Schwätzens willen? >Ein delay() weiß doch nicht, wie lange ein >Interrupt dauert, oder? Jaja, also doch nur Schwätzen! >Vor allem, weil ja innerhalb der isr noch >Verzweigungen auftreten können, die auch von externen Ereignissen >bestimmt werden können... BlaBlaBla!
Krull schrieb: > Ein delay() weiß doch nicht, wie lange ein > Interrupt dauert, oder? Vor allem, weil ja innerhalb der isr noch > Verzweigungen auftreten können, die auch von externen Ereignissen > bestimmt werden können... Bitte "Non-blocking Virtual Delay" anschauen - es wird ein Vergleich mit dem internen 1ms-Timer gemacht -- der Fehler der dabei entsteht ist .. 1ms -- was häufig ausreichen sollte. Wie lang andere Abläufe dauern ist dabei nicht wichtig.
@ Jens Grabner (jensg) >Bitte "Non-blocking Virtual Delay" anschauen Hab ich gemacht. >- es wird ein Vergleich mit >dem internen 1ms-Timer gemacht Stimmt. > -- der Fehler der dabei entsteht ist .. >1ms Stimmt nicht! > -- was häufig ausreichen sollte. Dito! > Wie lang andere Abläufe dauern ist dabei nicht wichtig. Falsch! Es wird nur festgestellt, ob die vorgegebene Wartezeit erreicht wurde oder nicht. Ob die um 1, 10, oder 1.000.000 ms überschritten wurde wird weder geprüft, noch gemeldet noch könnte man was dagegen tun! Zumindest nicht direkt. Denn wenn die anderen Abläufe zu lange brauchen, erfolgt die Prüfung und damit ggf. die Reaktion auch zu spät. Und wenn man dann periodisch den virtuellen Timer wieder starten will, akkumuliert sich der Fehler! Ganz toll! Mal ganz abgesehen davon, daß auch die Beispiele dort Mist sind. So lernt niemand eine gescheite Programmierung und Struktur von Programmen, sondern nur den allgegenwärtigen Arduino-Murks. Ergo. Gute Tutorials fallen nicht vom Himmel und sind eher rar.
Falk B. schrieb: > @ Jens Grabner (jensg) > >>Bitte "Non-blocking Virtual Delay" anschauen > > Hab ich gemacht. Ich auch.... Selbst wenn ich ähnliche Verfahren anwende, muss ich sagen, dass das Tutorial/Code nicht schön ist. z.B. static in Makros. Darauf reagiere ich mittlerweile recht allergisch. Das kann die Wiederverwendung von Funktionen und Klassen/Objekten derbe einschränken.
Könntest du bitte mal meine Fragen beantworten? Deine drei letzten "Antworten" sind dafür nicht geeignet. Ich frage dich, ob ein delay, das durch Interrupts ständig unterbrochen wird, genauso lang ist ist, wie ein "ungestörtes" delay? Und du antwortest darauf: > "keine Sekunde" ---??? Ich frage dich, ob ein delay weiß, wie lange Interrupts brauchen? Deine Antwort: > Jaja, also doch nur Schwätzen! --??? Ich stelle fest, daß innerhalb der isr noch Verzweigungen auftreten können und damit die Ausführungsdauer einer isr nicht bestimmbar ist. Deine Antwort: > BlaBlaBla! Also bitte gib mir jetzt die richtigen Antworten, ja?
Falk Brunner -- Besten dank für die genaue Beschreibung -- ein RealTimeOS oder auch nur ein Sytem zur Zeitsteuerung ist für viele "Anfänger" einfach schon eine Hürde -- Arduino ist auf der anderen Seite auch nie für professionelle Dinge gedacht gewesen -- weshalb hier sehr heftig unterschiedliche Denkmuster zusammenlaufen. aber gut -- delay() und die Beispiele dazu hätten "nie" Standard werden dürfen -- ohne delay() vermeidet man viele Probleme.
@Jens Grabner (jensg) >RealTimeOS oder auch nur ein Sytem zur Zeitsteuerung ist für viele >"Anfänger" einfach schon eine Hürde Sicher. >-- Arduino ist auf der anderen >Seite auch nie für professionelle Dinge gedacht gewesen -- weshalb hier >sehr heftig unterschiedliche Denkmuster zusammenlaufen. Mag sein. >aber gut -- delay() und die Beispiele dazu hätten "nie" Standard werden >dürfen -- ohne delay() vermeidet man viele Probleme. Mag auch sein. delay() hat schon seine Berechtigung, sei es für einfach(ste) Arduino-Sachen oder wo es halt unkritisch ist. Ebenso die Funktion millis() und deren Anwendung. Man sollte aber dennoch in einer vernünftigen, anschaulichen Art und Weise zeigen, wie man es besser machen kann, wenn es denn nötig ist. Nicht mehr und nicht weniger wollte ich sagen.
Jens G. schrieb: > delay() und die Beispiele dazu hätten "nie" Standard werden > dürfen Schwachsinn! Ein delay() ist leicht zu verstehen, und tut genau das, wofür es vorgesehen ist. Außerdem kan man während eines delay() noch tausend andere feine Dinge tun, nur nicht das delay() vorzeitig abbrechen.
Vielleicht habe ich ja auch Aussagen oder Anforderungen überlesen: Aus Prinzip alles in eine isr zu packen ist sicher kurzsichtig und blöd. Falk B. sprach vom Drehgeber. Klar Stich gemacht, aber man weiß doch gar nicht, WAS der TO eigentlich machen will. Ein Dogma erarbeiten ist da nun auch nicht zielführend. Eine Statemachine die millis() benutzt hat von mir auch quasi jedes Programm. Zugegebenermaßen neben härteren Echtzeit-Geschichten. Wenn ich alle 10s einen Feuchtigkeitswert angucken will, mache ich da keinen Timer für, sondern vergleiche mit der Systemzeit. Mit delay_ms() operieren zu wollen ist an sich (fast) immer unklug. ich sage fast, weil man damit auch ein Programm schreiben kann, welches gut damit funktionieren kann wenn man das im Vorfeld weiß. Werkzeug zum Problem wählen.
@Falk: Könntest du bitte mal meine Fragen beantworten? Deine drei letzten "Antworten" sind dafür nicht geeignet. Ich frage dich, ob ein delay, das durch Interrupts ständig unterbrochen wird, genauso lang ist ist, wie ein "ungestörtes" delay? Und du antwortest darauf: > "keine Sekunde" ---??? Ich frage dich, ob ein delay weiß, wie lange Interrupts brauchen? Deine Antwort: > Jaja, also doch nur Schwätzen! --??? Ich stelle fest, daß innerhalb der isr noch Verzweigungen auftreten können und damit die Ausführungsdauer einer isr nicht bestimmbar ist. Deine Antwort: > BlaBlaBla! ---??? Also bitte gib mir jetzt die richtigen Antworten, ja?
Krull schrieb: > Ich frage dich, ob ein delay, das durch Interrupts ständig unterbrochen > wird, genauso lang ist ist, wie ein "ungestörtes" delay? > Und du antwortest darauf: Ein bisschen verspannt heute? Weißt du es wirklich nicht, oder willst du nur Streit?
Arduino F. schrieb: > Krull schrieb: >> Ich frage dich, ob ein delay, das durch Interrupts ständig unterbrochen >> wird, genauso lang ist ist, wie ein "ungestörtes" delay? >> Und du antwortest darauf: > > Ein bisschen verspannt heute? > > Weißt du es wirklich nicht, oder willst du nur Streit? Ich suche absolut keinen Streit. Ich habe dem Falk ein paar Fragen gestellt. Seine "Antworten" kannst du selbst lesen. Aber vielleicht kannst du mir die Fragen beantworten? Falk will es offensichtlich nicht.
Wichtig ist zu erkennen ob Delay das Projekt nun "zerstört" oder hinreichend ist. Im ersteren Falle muss man einen einfachen Workaround schaffen, da brauch man nicht diskutieren und lange Sinnlos Schwafeln. Wenn Du alles unbedingt mit einem Timer umsetzen möchtest, geht das auch.. Die Frage ist nur, reichen Deine Fähigkeiten dazu aus das ohne Delay/Millis zu machen oder nicht. Millis ist schonmal ein guter Ansatz das Delay zu umgehen.. das ist mehrschichtig auch nicht "Super einfach" und verlangt auch schon Grips. (Bei einem siehts einafch aus.. mach mal nen BlinkWithoutDelay mit 3 LEDS, und 3 IF/FOR) Wenn man das mit Millis kann braucht es nur noch eine Timerinitialisierung und ein "Suchen/ersetzen" um es auf einen Timer umzumünzen.
Krull schrieb: > Aber vielleicht kannst du mir die Fragen beantworten? Sicher! Es liegt ganz an der Implementierung! 1: Das AVR Lib (util/delay.h) Delay wird von jedem ISR Ereignis verlängert. 2: Bein Arduino delay() verlängert, schlimmstenfalls, die letzte ISR die Pause. Jetzt alle Klarheiten beseitigt?
Arduino F. schrieb: > Krull schrieb: >> Aber vielleicht kannst du mir die Fragen beantworten? > > Sicher! > > Es liegt ganz an der Implementierung! > > 1: Das AVR Lib (util/delay.h) Delay wird von jedem ISR Ereignis > verlängert. > > 2: Bein Arduino delay() verlängert, schlimmstenfalls, die letzte ISR die > Pause. > > Jetzt alle Klarheiten beseitigt? Alle noch nicht, aber damit kann ich auf jeden Fall wesentlich mehr anfangen als mit der "Gesprächskultur" von Falk. Danke dir dafür. Der erste Punkt (AVR-Delay) war mir bekannt, deshalb habe ich dem Falk die Fragen gestellt. Der zweite Punkt ist mir neu. Da werde ich mich mal damit auseinandersetzen und versuchen den Grund herauszufinden, warum nur die letzte ISR das Delay verlängert. Allein daß das so ist, wußte ich nicht. Das ist aber (meiner Meinung nach) kein Grund für Falk, mir nur mit "blabla" zu antworten. Ist er so abgehoben, daß er sich nicht vorstellen kann, daß es noch Leute gibt, die weniger wissen als er? Ich für meinen Teil finde das einfach arrogant. Sorry :-( Auf jeden Fall danke ich dir für deine Antworten :-)
Krull schrieb: > arrogant Ich halte es für recht schwierig, Arroganz und Kompetenz auseinander zu halten, wenn ich die Person nicht kenne. Auch kommen soziale und fachliche Kompetenz nicht immer in Personalunion vor. PS: Auch du zeigst hier ein irritierendes Verhalten. (ein mich irritierendes)
Liegt wohl heute am Wetter. Ich hoffe es sind keine Psychopathen oder/und Soziopathen unter uns.
Arduino F. schrieb: > Krull schrieb: >> arrogant > > Ich halte es für recht schwierig, Arroganz und Kompetenz auseinander zu > halten, wenn ich die Person nicht kenne. > > Auch kommen soziale und fachliche Kompetenz nicht immer in Personalunion > vor. Das mag ja sein, aber wenn ich kompetent bin, gibt mir das nicht das Recht, jemandes Frage einfach mit "blabla" zu beantworten. Das ist dann der Punkt, wo sich die fachliche Kompetenz von der sozialen Kompetenz gründlich verabschiedet hat. Tut mir auch leid für Falk. Ich hoffe, er hatte nur einen "schlechten Tag" und ist nicht immer so :-)
BlaBla schrieb: > Liegt wohl heute am Wetter. Ich hoffe es sind keine Psychopathen > oder/und Soziopathen unter uns. Da mache dir mal keine zu großen Hoffnungen. Meiner Schätzung nach tragen ca 2% der Weltbevölkerung eine neurotische Fehlanpassung mit sich rum. Ob die sich hier rudeln, ka, manchmal kommt es mir so vor.
Arduino F. schrieb: > PS: > Auch du zeigst hier ein irritierendes Verhalten. > (ein mich irritierendes) Darf ich mal fragen, was genau dich irritiert? Kommt es nicht so häufig vor, daß man Antworten einfordert, wenn man Fragen gestellt hat? Oder was ist es?
Krull schrieb: > Kommt es nicht so häufig vor, daß man Antworten einfordert, wenn man > Fragen gestellt hat? Z.B.: Wenn in Fragen schon die gewünschte Antwort vorgegeben wird, empfinde ich das als provokant. Als unangenehm. Oft wird sowas (unbewusst?) als subtile Methode genutzt, um eine Eskalationsspirale zu starten, oder zu fördern. Und das ist etwas, woran ich nur selten Spaß habe.
Arduino F. schrieb: > 2: Bein Arduino delay() verlängert, schlimmstenfalls, die letzte ISR die > Pause. Das würde ich etwas relativieren. Das Arduino-Delay (ms) basiert auf den "Standard-Millis". Wenn da mehrere Interrupts hintereinander kommen (incl. der Millis ...) dann wartet das Arduino-Delay diese alle ab (soweit mein Verständnis). Wenn ein Spassvogel die "Millis" deaktiviert, dann gibt es gar ein St. Nimmerlein-delay. Das (Arduino-Delay (µs) ) arbeitet mit "NOP" und kann gleichfalls beliebig durch ISR unterbrochen und verzögert werden.
Das halte ich für einen konstruierten Sonderfall. Wenn die ISR so dicht aufeinander folgen, dass noch nicht mal ein delay() sein Ende (recht pünktlich) findet, dann ist was ganz anderes faul. Mindestens ein Maschinenbefehl, des Hauptprogramms, wird zwischen 2 ISR ausgeführt!?! Also findet das delay() sein Ende.
Arduino F. schrieb: > Das halte ich für einen konstruierten Sonderfall. Das ist Dein gutes Recht:-) - aber der "schlimmste Fall" Arduino F. schrieb: > 2: Bein Arduino delay() verlängert, schlimmstenfalls, die letzte ISR die > Pause. ist nunmal oft ein Sonderfall. Arduino F. schrieb: > Mindestens ein Maschinenbefehl, des Hauptprogramms, wird zwischen 2 ISR > ausgeführt!?! So sei es. Die "Arduino-Delay (ms)"-Routine besteht aus einigen "Maschinenbefehlen" - oder?
1 | void delay( uint32_t ms ) |
2 | {
|
3 | if ( ms == 0 ) |
4 | {
|
5 | return ; |
6 | }
|
7 | |
8 | uint32_t start = _ulTickCount ; |
9 | |
10 | do
|
11 | {
|
12 | yield() ; |
13 | } while ( _ulTickCount - start < ms ) ; |
14 | }
|
chris schrieb: > Warum nicht direkt in den Code schauen? : Wessen - von wann? Wir schreiben das Jahr 2017 ...
Arduino F. schrieb: > Außerdem kan man während eines delay() noch tausend andere feine Dinge > tun, nur nicht das delay() vorzeitig abbrechen. Das würde ich gerne erklärt bekommen. Nach meinem Verständnis ist delay blockierend, während dieser Zeit kann kein weiterer Code ausgeführt werden.
>Wessen - von wann? Wir schreiben das Jahr 2017 ...
Genau so ist es. Im Jahr 2017 gibt es GitHub. Und dort befindet sich das
aktuelle Arduino Repository. Und darauf habe ich verlinkt. Sogar auf's
richtige File mit Angabe der Zeilennummer.
Zu schwer?
> Das würde ich gerne erklärt bekommen. Nach meinem Verständnis ist delay > blockierend, während dieser Zeit kann kein weiterer Code ausgeführt > werden. Interrupts können delay() unterbrechen. Ich schätze, du hast den Thread nicht mitverfolgt, oder?
Manfred schrieb: > Das würde ich gerne erklärt bekommen. Nach meinem Verständnis ist delay > blockierend, während dieser Zeit kann kein weiterer Code ausgeführt > werden. Testprogramm:
1 | unsigned long counter; |
2 | |
3 | void yield(void) |
4 | {
|
5 | counter++; |
6 | }
|
7 | |
8 | |
9 | void setup(void) |
10 | {
|
11 | Serial.begin(9600); |
12 | }
|
13 | |
14 | void loop(void) |
15 | {
|
16 | delay(1000); |
17 | Serial.print("Counter: "); Serial.println(counter); |
18 | }
|
Ausgabe:
1 | Counter: 185875 |
2 | Counter: 371726 |
3 | Counter: 557577 |
4 | Counter: 743427 |
5 | Counter: 929278 |
6 | Counter: 1115129 |
7 | Counter: 1300979 |
8 | Counter: 1486828 |
9 | Counter: 1672677 |
10 | Counter: 1858528 |
11 | Counter: 2044379 |
12 | Counter: 2230230 |
13 | Counter: 2416081 |
14 | Counter: 2601932 |
15 | Counter: 2787783 |
16 | Counter: 2973634 |
17 | Counter: 3159485 |
18 | Counter: 3345336 |
19 | Counter: 3531186 |
chris schrieb: > Genau so ist es. Im Jahr 2017 gibt es GitHub. Und dort befindet sich das > aktuelle Arduino Repository. Und darauf habe ich verlinkt. Sogar auf's > richtige File mit Angabe der Zeilennummer. > > Zu schwer? Scheinbar ... 2005 - 2006 war einmal (von wem auch immer ...)
1 | /*
|
2 | wiring.c - Partial implementation of the Wiring API for the ATmega8. |
3 | Part of Arduino - http://www.arduino.cc/ |
4 | Copyright (c) 2005-2006 David A. Mellis |
Neu ist
1 | /*
|
2 | Copyright (c) 2015 Arduino LLC. All right reserved. |
3 | |
4 | ..
|
5 | |
6 | |
7 | void delay( uint32_t ms ) |
8 | {
|
9 | if ( ms == 0 ) |
10 | {
|
11 | return ; |
12 | }
|
13 | |
14 | uint32_t start = _ulTickCount ; |
15 | |
16 | do
|
17 | {
|
18 | yield() ; |
19 | }
|
Arduino F. schrieb: > Manfred schrieb: >> Das würde ich gerne erklärt bekommen. Nach meinem Verständnis ist delay >> blockierend, während dieser Zeit kann kein weiterer Code ausgeführt >> werden. Außer ISR - und das kannst Du nachlesen :-)
man lernt hier immer noch dazu, danke an alle wie ist das mit Serial.event und Serial.available() mit Serial.read(); unterbricht das delay_ms()? Das ich eigene ISR nutzen kann weiss ich schon.
Joachim B. schrieb: > wie ist das mit Serial.event und Serial.available() mit Serial.read(); > > unterbricht das delay_ms()? Nein! Aber der von Serial genutzte Interrupt tut das. Also: JA! ööhmmmm... Ein kleines Jain, auf die Frage, weil sie in sich einen logischen Fehler hat.
Das paradoxe an Frameworks ist: Sie sollen die Arbeit erleichtern. Doch früher oder später kommen Detailfragen auf, zu deren Beantwortung man in den Quelltext schauen muss. Spätestens, wenn das Framework darüber hinaus nicht genau das tut, was man braucht, muss man sich fragen, warum man überhaupt ein Framework verwendet hat. Ich wollte diese Erkenntnis als Java Enterprise Entwickler viele Jahre lang nicht akzeptieren, doch mittlerweile wurde ich mehrfach auf die harte Tour (durch negative Erfahrung) eines besseren belehrt.
>Das paradoxe an Frameworks ist: Sie sollen die Arbeit erleichtern...
Ja, heutzutage kämpft man eigentlich nur noch mit den Frameworks.
Ich neige dazu, alles selber schreiben zu wollen. Aber am Ende bleibt
einem halt doch nur, Frameworks nutzen zu müssen.
Bei den Arduinosachen hat man zumindest die Möglichkeit bis auf die
unterste Ebene rein zu schauen und notfalls kann man da was ändern.
Bei den STM-HAL Sachen kann das aber richtig übel werden und eigentlich
helfen da nur Workarrounds.
Arduino F. schrieb: > ööhmmmm... > Ein kleines Jain, auf die Frage, weil sie in sich einen logischen Fehler > hat. wo? ich habe void serialEvent(void) erst spät entdeckt ist ja eine Interruptnutzung somit müsste void serialEvent(void) { while (Serial.available()) { char incomingByte = (char)Serial.read(); auch delay_ms unterbrechen wo soll der logische Fehler sein?
Stefan U. schrieb: > Interrupts können delay() unterbrechen. Allerdings würde ich in einer ISR nicht Arduino F. schrieb: > noch tausend andere feine Dinge tun.
Autor: Dieter F. (jim_quakenbush)
>Scheinbar ... 2005 - 2006 war einmal (von wem auch immer ...)
Oha, ich dachte mein Link sei das Main-Arduino-Repository.
Falls jemand das von 2015 findet, würde mich ein Link stark
interessieren.
Joachim B. schrieb: > ich habe void serialEvent(void) erst spät entdeckt ist ja eine > Interruptnutzung Ist es nicht. serialEvent() wird in der main() Loop aufgerufen. Ein Schritt vor, oder nach, dem Aufruf von loop(). Also im ganz normalen Programmkontext. Nicht in einem Interrupt.
Rolf M. schrieb: > Stefan U. schrieb: >> Interrupts können delay() unterbrechen. > > Allerdings würde ich in einer ISR nicht > > Arduino F. schrieb: >> noch tausend andere feine Dinge > > tun. Ein drohendes Darama bei dem yield() ist, dass rekursive Aufrufe stattfinden könnten. Das wird man (durch Disziplin?) unterbinden müssen.
chris schrieb: > Falls jemand das von 2015 findet, würde mich ein Link stark > interessieren. Google kennst Du? Die Welt hat sich weiter gedreht :-)
Stefan U. schrieb: > Nach meinem Verständnis ist delay >> blockierend, während dieser Zeit kann kein weiterer Code ausgeführt >> werden. > > Interrupts können delay() unterbrechen. Das ist mir klar, aber ich sehe diese eher als Sonderform zeitkritischer Anwendungen denn im Tagesgeschäft. > Ich schätze, du hast den Thread nicht mitverfolgt, oder? Aber doch! Bei solchen Themen schaue ich immer, ob ich ein paar Informationen oder Anregungen für mich mitnehmen kann.
Manfred schrieb: > Das ist mir klar, aber ich sehe diese eher als Sonderform zeitkritischer > Anwendungen denn im Tagesgeschäft. Was hast Du denn für ein Tagesgeschäft mit AVR-Mikrocontrollern?
Autor: Dieter F. (jim_quakenbush) >Google kennst Du? Die Welt hat sich weiter gedreht :-) Bei mir wirft Google dieses: https://github.com/arduino Aber Google ist ja schlau und präsentiert Userabhängige Ergebnisse. Vielleicht will's mich ärgern, weil ich kein Android-Handy habe. Jetzt zeig mal den Link den Google Dir zeigt.
chris schrieb: > Jetzt zeig mal den Link den Google Dir zeigt. Ich wusste gar nicht, dass dafür ein Kurs erforderlcih ist :-) https://github.com/arduino-org/arduino-core-nrf52/blob/master/cores/arduino/delay.c
Arduino F. schrieb: >> Das würde ich gerne erklärt bekommen. Nach meinem Verständnis ist delay >> blockierend, während dieser Zeit kann kein weiterer Code ausgeführt >> werden. > Testprogramm: Oops, da hast Du etwas gemacht, was mir vollkommen unbekannt ist. Mit einer Internetsuche lande ich auf einer Bachelorarbeit an der Uni Hamburg und finde "yield" als Scheduler beschrieben. Heisst also, mit "void setup(void) und void loop(void)" springst Du jedesmal durch void yield(void)? Das muß ich erstmal sacken lassen :-) Danke Dir!
chris schrieb: > Vielleicht will's mich ärgern, weil ich kein Android-Handy habe. Dann müsste Google mich noch mehr ärgern, weil ich gar kein Schei..-Handy/-Schmartphone habe :-) (auch kein Fatzebook und kein Whatsapp etc. ) habe
Dieter F. schrieb: > weil gar kein > Schei..-Handy/-Schmartphone habe :-) (auch kein Fatzebook und kein > sonstwas Ich bin ja doch nicht alleine.
Dieter F. schrieb: > chris schrieb: >> Jetzt zeig mal den Link den Google Dir zeigt. > > Ich wusste gar nicht, dass dafür ein Kurs erforderlcih ist :-) > > https://github.com/arduino-org/arduino-core-nrf52/... Arduino.org ist ein toter Ast in der Arduinowelt. Und der nrf52 ist kein typischer Arduino. Dein Link zeigt also ins Gebüsch.
Arduino F. schrieb: > Dein Link zeigt also ins Gebüsch. Na, dann zeig doch mal den aktuellen Link (von welcher Arduino-Fraktion auch immer)
Dieter F. schrieb: > Willkommen im Club der Ignoranten Wer weiß, vielleicht sind wir ja noch mehr. Arduino F. schrieb: > Arduino.org ist ein toter Ast in der Arduinowelt. Und wo wachsen die Blätter? Arduino.org hört sich für mich nach oberster Instanz an. Oder ist das jetzt Alduino.cn?
Arduino.cc ist die aktuelle Seite. Zumindest war das gestern noch so.
Manfred schrieb: > und finde "yield" als Scheduler beschrieben. Über die Geschichte weiß ich nichts... Aber irgendwo in den Tiefen der Arduino Doku findet sich ein Spruch dazu: > yield() ist für Entwickler von Libraries bestimmt, > um Kooperative Scheduler zu implementieren. (möglichst sinngemäß wiedergegebeben) Manfred schrieb: > Heisst also, mit "void setup(void) und void loop(void)" > springst Du jedesmal durch void yield(void)? yield() wird in delay() aufgerufen. Halt um die Wartezeit sinnvoll nutzen zu können.
Thomas E. schrieb: > Und wo wachsen die Blätter? Arduino.org hört sich für mich nach oberster > Instanz an. Oder ist das jetzt Alduino.cn? Der Arduino.cc Trupp hat sich in die Wolle bekommen. Arduino.org hat sich abgespalten. Kürzlich war die Wiedervereinigung. Damit ist Arduino.org weg vom Fenster. Das war ein Prozess über ca. 2 Jahre.
Dieter F. schrieb: > Na, dann zeig doch mal den aktuellen Link (von welcher Arduino-Fraktion > auch immer) Such mal schön selbst ...
Dieter F. schrieb: > Arduino F. schrieb: >> Dein Link zeigt also ins Gebüsch. > > Na, dann zeig doch mal den aktuellen Link (von welcher Arduino-Fraktion > auch immer) Wurde hier schon gezeigt! https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring.c
Arduino F. schrieb: > yield() Ist irgendwie seit dem ESP ... erfunden worden (soweit mir bekannt) aber ihr könnt mich auch einfach ignorieren :-)
Arduino F. schrieb: > Wurde hier schon gezeigt! > https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring.c Copyright (c) 2005-2006 David A. Mellis lol - aber vergiss es, ich lasse euch jetzt in Ruhe :-)
Dieter F. schrieb: >> Das ist mir klar, aber ich sehe diese eher als Sonderform zeitkritischer >> Anwendungen denn im Tagesgeschäft. > Was hast Du denn für ein Tagesgeschäft mit AVR-Mikrocontrollern? Mein Tagesgeschäft im beruflichen Erwerbsleben hat leider keine Hardware mehr, früher war ich dort mal mit 2MHz-Taktfrequenz und Assembler unterwegs. Arduino setze ich im Hobbybereich ein, für überschaubare Steuerungs- / Meßaufgaben. Meist renne ich da in einer Schleife herum und vergleiche diverse Millisekunden, um dann in einer Unterroutine etwas zu tun. Diese Unterroutine kann auch mal blockierend sein oder einige Dutzend Millisekunden dauern. Interrupt habe ich eingesetzt, um auf eine Eingabe in akzeptabler Zeit zu reagieren. Als nächstes will ich Entladekurven von Akkus auf eine SD-Karte schreiben, das wird aus Sicht des Prozessors im Prinzip unendlich langsam ablaufen.
Arduino F. schrieb: > Ist es nicht. > serialEvent() wird in der main() Loop aufgerufen. nö, nicht bei mir
1 | my_delay(100); |
2 | } // loop() |
3 | |
4 | |
5 | void serialEvent(void) |
sitzt definitiv ausserhalb der loop
> Copyright (c) 2005-2006 David A. Mellis >lol - aber vergiss es, ich lasse euch jetzt in Ruhe :-) Die letzte Änderung im File ist aber vom Dez.2015: https://github.com/arduino/Arduino/commit/b1231c39e9fa6d8602ac24305b07f074c1145633 Es sieht so aus, als wenn sie das Datum im Header nicht aktualisiert haben. Das ist aber auch lästig, wenn man wegen jeder kleinen Änderung im File den Copyright Header ändern muss.
Joachim B. schrieb: > sitzt definitiv ausserhalb der loop Außerhalb von loop(), ja. Aber innerhalb der Schleife, welche sich typischer weise in main() befindet. Und damit eben nicht in einem Interrupt. Es verlängert nicht das delay_ms() Das Gegenteil ist der Fall: Ein delay_ms() verzögert den serialEvent() Aufruf. Siehe: https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/main.cpp Dort wird serialEventRun() aufgerufen, welches wiederum dann die diversen serialEvent() aufruft.
Beitrag #5240298 wurde von einem Moderator gelöscht.
Arduino F. schrieb: > yield() wird in delay() aufgerufen. > Halt um die Wartezeit sinnvoll nutzen zu können.
1 | void yield(void) |
2 | {
|
3 | delay(-1); |
4 | }
|
Und was macht er damit?
Thomas E. schrieb: > Und was macht er damit? Habe ich eben schon beschrieben: Arduino F. schrieb: > Ein drohendes Darama bei dem yield() ist, dass rekursive Aufrufe > stattfinden könnten. > Das wird man (durch Disziplin?) unterbinden müssen.
Arduino F. schrieb: > Außerhalb von loop(), ja. > Aber innerhalb der Schleife, welche sich typischer weise in main() > befindet. > Und damit eben nicht in einem Interrupt. > Es verlängert nicht das delay_ms() das wiederum hatte ich nirgens behauptet, es wurde behauptet das während delay_ms nichts abgearbeitet wird, das war meine Frage, aber egal ich nutze mein eigenes my_delay_ms() und da wird nebenbei anderes abgearbeitet. D.h. während my_delay wartet wird dort weitergearbeitet. Arduino F. schrieb: > Ist es nicht. > serialEvent() wird in der main() Loop aufgerufen. hört sich nach Ausrede an, in der Arduinowelt gibts nur loop() klar liegt noch eine main loop drüber, dann schreibe das doch deutlicher, wenn in Arduino von loop gesprochen wird dann ist doch loop() gemeint und nicht while(1);
:
Bearbeitet durch User
Dabei habe ich doch extra "main() Loop" geschrieben! Die Klammern mit Bedacht gesetzt. Merksatz: > Ich bin für das verantwortlich, was ich sage. > Nicht für das, was du verstehst. Und von deinem_delay() weiß ich natürlich nichts... Aber das könntest du gerne mal zeigen. Joachim B. schrieb: > in der Arduinowelt gibts nur loop() Das ist übrigens auch nicht richtig. Ein korrektes Arduino Programm kann auch so aussehen:
1 | int main() |
2 | {
|
3 | for(;;); |
4 | return 0; |
5 | }
|
Man wird dann aber auch auf die ganzen Arduino Features verzichten müssen.
Arduino F. schrieb: > Ein korrektes Arduino Programm kann stimmt, nur dann brauchts auch nicht mehr die IDE Arduino F. schrieb: > Merksatz: >> Ich bin für das verantwortlich, was ich sage. >> Nicht für das, was du verstehst. kenne ich schon, ist aber auch nur platt Arduino F. schrieb: > Aber das könntest du gerne mal zeigen. dazu bin ich ein zu schlechter progger, das hilft niemanden hier und Häme gibts ja genug, das brauche ich nicht, für mich reichts eben :)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.