Guten Abend,
ich habe einen Sensor am analogen Anschluss des Arduinos angelegt und
mit den abgetasteten Werten führe ich eine knappe Berechnung durch. Das
resultierende Ergebnis gebe ich dann über die serielle Schnittstelle an
den Computer aus. Gibt es eine Möglichkeit die Echtzeitfähigkeit für
diesen Prozess zu beurteilen?
Grüße
Echtzeit bedeutet nur, daß auf ein Ereignis eine Reaktion in einer
garantierten Zeit erfolgt, die üblicherweise niedrig sein soll. Was
niedrig bedeutet, ergibt sich aus der Anwendung. Bei der Beobachtung von
Schneckenwanderungen können das auch Minuten sein.
Für das vorliegende Problem wirst Du dann eine worst-case-Analyse machen
müssen. Beispielsweise:
Wandlung im Timer-Interrupt: einmal das Timer-Intervall.
Berechnung: maximale Dauer (Oszilloskop). Wahrscheinlich
vernachlässigbar.
RS232: rüberkopieren der Daten (vernachlässigbar), Starten des
TX-Prozesses. Abhängig von Datenvolumen und Baudrate (Start/Stopbits und
Parity mit einberechnen!) ergibt das die Übertragungszeit.
Auswertung am anderen Ende: andere Baustelle.
Dirk_Geber schrieb:> Gibt es eine Möglichkeit die Echtzeitfähigkeit für> diesen Prozess zu beurteilen?
Erstmal musst du beurteilen, was für deine Anwendung "Echtzeitfähigkeit"
bedeutet. Lunochod 1 und 2 wurden bei Signallaufzeiten von über einer
Sekunde in Echtzeit gesteuert.
>Gibt es eine Möglichkeit die Echtzeitfähigkeit> für diesen Prozess zu beurteilen?
Ja, Du kannst eine "Bremsfunktion" mit Hilfe der Zeitmessfunktion
"millis" in die "loop" einbauten. Mit der Funktion kannst Du dann die
Ausführung der Schleife auf eine genau definierte "Sekunde" herunter
bremsen und die Messwerte mit "genau definierter Echtzeit" von einer
Sekunde übertragen.
chris_ schrieb:> "Bremsfunktion"
Hilft alleine nicht, du musst immer das Gesamtsystem betrachten.
Wenn z.B. ein anderer Task einmal pro Tag die Best-Of-Arduino-Trollposts
aus dem Forum über die Serielle schieben soll, hilft es dir nichts, wenn
dann zwar die Messung exakt zum richtigen Zeitpunkt stattgefunden hat,
der Messwert aber irgendwo im Sendebuffer vergammelt.
Also: Alle Tasks, ISRs, gemeinsam genutzten Resourcen usw. betrachten.
Das ist im Arduino-Framework aufwendig, weil vieles vor'm Programmierer
versteckt wird.
Planlos schrieb:> Also: Alle Tasks, ISRs, gemeinsam genutzten Resourcen usw. betrachten.> Das ist im Arduino-Framework aufwendig, weil vieles vor'm Programmierer> versteckt wird.
Ich programmiere ohne die Arduino Libraries. Also den A/D-Wandler, die
Schnittstelle sowie die Zeitfunktion habe ich selber programmiert.
Ich nutze nur Arduino als billigen USB-Seriell-Wandler.
Programmiren tue ich auf PIC... Okay ist ja jetzt das gleiche.
Und die Echtzeitfähigkeit ist da FOSC/4 und man kann am Oszi die
verarbeiteten Befehle mit zählen.
@ Dirk_Geber (Gast)
>Ich programmiere ohne die Arduino Libraries. Also den A/D-Wandler, die>Schnittstelle sowie die Zeitfunktion habe ich selber programmiert.
Dann solltest du ja wissen, wie lange deine Funktion arbeitet und ob sie
echtzeitfähig ist. In einem anderen Thread wollte jemand mit dem AVR und
ADC Daten mit 10 kHz abtasten und per UART verschicken. Das hat
funktioniert. Wie schnell willst du das tun?
Falk B. schrieb:> Dann solltest du ja wissen, wie lange deine Funktion arbeitet und ob sie> echtzeitfähig ist. In einem anderen Thread wollte jemand mit dem AVR und> ADC Daten mit 10 kHz abtasten und per UART verschicken. Das hat> funktioniert. Wie schnell willst du das tun?
Mein ADC arbeitet auch mit etwa 10kHz. SO schnell würde ich die Daten
auch gerne verschicken, aber das macht der UART bestimmt nicht mit.
Serielle Schnittstelle zum Computer heißt:
Kein deterministisches Zeitverhalten - der PC bekommt das "irgendwann"
mal mit, aber nicht in einem definierten Zeitfenster.
Damit nicht echtzeitfähig. Es harkt am Betriebssystem. Man bräuchte ein
echtzeitfähiges.
Mit dem Arduino kann man generell gut echtzeitfähig programmieren. z.B:
mit einem Timerinterrupt oder ähnlichen Geschichten. Hängt einfach davon
ab, wie schnell die Echtzeit denn sein soll.
PS:
Die Sache mit der seriellen Schnittstelle ist kein Witz. Ich habe mich
damit schon herumärgern müssen. Wenn man auf ein enges Timing angewiesen
ist, kann einem der Windows-scheduler schon einen Strich durch die
Rechnung machen, und ein paar Byte eines Paketes um zig ms verzögern.
Bei meinem ersten Bootloader (Funk, mit ACK-Paketen) war nicht der
8MHz-µC der Flaschenhals, sondern der 4-Kern-Core I5 - PC...
Hmmhmm schrieb:> Mit dem Arduino kann man generell gut echtzeitfähig programmieren. z.B:> mit einem Timerinterrupt oder ähnlichen Geschichten. Hängt einfach davon> ab, wie schnell die Echtzeit denn sein soll.
SO schnell wie möglich ;). Gibt es denn eine Möglichkeit die Dauer zu
bestimmen?
Hmmhmm schrieb:> Serielle Schnittstelle zum Computer heißt:> Kein deterministisches Zeitverhalten - der PC bekommt das "irgendwann"> mal mit, aber nicht in einem definierten Zeitfenster.
Irgendwann reicht völlig aus, sofern keine Daten verloren gehen. Bei 10
kHz Abtastfrequenz haben die Werte immer 100 µs Abstand. Ein Ringpuffer
bei der Ausgabe und eine hinreichend hohe Baudrate sind aber notwendig.
Abhängig von der Auswertung und dem Ausgabeformat würde ich wohl einen
schnelleren µC einsetzen.
> Damit nicht echtzeitfähig. Es harkt am Betriebssystem. Man bräuchte ein> echtzeitfähiges.
.. oder einen Haken ;-)
@ Dirk_Geber (Gast)
>Mein ADC arbeitet auch mit etwa 10kHz. SO schnell würde ich die Daten>auch gerne verschicken, aber das macht der UART bestimmt nicht mit.
Nun ja, Ingenieure und ähnlich logisch veranlagte Wesen (z.B. Vulkanier,
nicht zu verwechseln mit Vulkaniseuren) würden da mal rechnen.
Beitrag "Re: Atemega328p - schaffst du das?"
Auch eine ADC Wandlung ist doch nicht in festen Schritten messbar oder?!
Er misst doch, und gibt dann im Register frei wann er mit der Messung
fertig ist. Also nicht Echtzeit. Also man kann ja nicht sagen: "Er
braucht genau 10 Takte und ist dann fertig". Sondern diese Zeit
differenziert doch auch?! Oder täusche ich mich?
Draco schrieb:> Auch eine ADC Wandlung ist doch nicht in festen Schritten messbar> oder?!> Er misst doch, und gibt dann im Register frei wann er mit der Messung> fertig ist. Also nicht Echtzeit. Also man kann ja nicht sagen: "Er> braucht genau 10 Takte und ist dann fertig". Sondern diese Zeit> differenziert doch auch?! Oder täusche ich mich?
Mit dem freilaufenden Modus ist das möglich.
Dirk_Geber schrieb:> SO schnell wie möglich ;). Gibt es denn eine Möglichkeit die Dauer zu> bestimmen?
Im Arduino?
Kenne ich mich nicht gut aus. Was aber gehen sollte, ist z.B. einen ADC
in einer Timer-ISR auszuwerten.
Wie schnell das aufdrehen kannst, hängt von deinem Code ab. Die ISR
kannst du jedenfalls quasi beliebig schnell takten. 100kHz sind da kein
Problem.
Nur muss dein Code halt auch in 10µs (für 100kHz) fertig werden. Ob das
so ist, musst du wohl selber herausfinden. Dazu gibts diverse
Möglichkeiten, bis hin zum Takte zählen (schwierig bei der
Arduino-IDE...). Im Einfachsten Fall einfach einen Ausgang toggeln und
mit dem scope prüfen.
Dann wäre da noch DMA. Ob der AVR des Arduino eine hat weiß ich nicht.
Aber DAMIT kannst du den ADC zu 100% ausfahren.
@ Hmmhmm (Gast)
>> SO schnell wie möglich ;). Gibt es denn eine Möglichkeit die Dauer zu>> bestimmen?
Ja, mit einem Oszilloskop. Am Anfang der ISR ein Pin auf HIGH schalten,
am Ende auf LOW. Oder im Simulator des Atmelstudios.
>Wie schnell das aufdrehen kannst, hängt von deinem Code ab. Die ISR>kannst du jedenfalls quasi beliebig schnell takten. 100kHz sind da kein>Problem.
Unsinn. Nichts kann man beliebig schnell takten.
>Möglichkeiten, bis hin zum Takte zählen (schwierig bei der>Arduino-IDE...).
Unmöglich, denn dafür ist sie gar nicht gemacht.
>Dann wäre da noch DMA. Ob der AVR des Arduino eine hat weiß ich nicht.
Hat er nicht, dann nur die ATXmegas haben DMA. Und bisher gibt es keinen
Arduino mit ATXmegas.
Planlos schrieb
>Hilft alleine nicht, du musst immer das Gesamtsystem betrachten.>Wenn z.B. ein anderer Task einmal pro Tag
Bei den meisten Arduinos ( Uno.. DUE ) gibt es keine Tasks.
Falk B. schrieb:>>Möglichkeiten, bis hin zum Takte zählen (schwierig bei der>>Arduino-IDE...).>> Unmöglich, denn dafür ist sie gar nicht gemacht.
Nunja.....
Meine Arduino IDE spuckt bei jeder Kompilierung auch ein Assemblerdump
aus. (musste ich ihr erst beibiegen, war aber problemlos)
Das erleichtert das Zählen, wenn es denn sein muss.
Außerdem ist es sicherlich nicht die IDE welche dir da im Magen liegt,
sondern das Gedöns, was standardmäßig mit kompiliert wird. Z.B. die
Timer0 Belegung. Aber darauf zu verzichten ist ein leichtes. Den Auftrag
erfüllt die IDE mit links.
Dirk_Geber schrieb:> Mein ADC arbeitet auch mit etwa 10kHz. SO schnell würde ich die Daten> auch gerne verschicken, aber das macht der UART bestimmt nicht mit.
Der UART im AVR schafft 2 MBit bei 16 MHz, da ist nur die Frage, ob die
andere Seite da mitspielt und ob man das sauber übertragen bekommt.
Ich hatte letztes Jahr ein Projekt bei dem ich mit einem AVR 24
AD-Kanäle von drei externen SPI ADC in 12 Bit und 2kS/s eingelesen und
per 2 MBit UART->RS485->USB an den PC geschickt habe.
Inklusive ID, Zeitstempel und CRC32 in jedem Datenrahmen, mit durch das
Protokoll unterschiedlicher Länge für den Datenrahmen von mindestens 51
Byte.
War schwer grenzwertig, das Ding hat aber exakt alle 500µs einen
Datenrahmen raus geworfen und lief mit der Test-Software am PC
stundenlang ohne CRC Fehler.
Und dann fing der Kollege auf der PC Seite an sein Programm dafür in
Java zu entwickeln und musste erstmal feststellen, dass er die Daten
nicht mal ansatzweise so schnell empfangen konnte wie sie rein kamen.
:-)
Dirk_Geber schrieb:> ich habe einen Sensor am analogen Anschluss des Arduinos angelegt und> mit den abgetasteten Werten führe ich eine knappe Berechnung durch. Das> resultierende Ergebnis gebe ich dann über die serielle Schnittstelle an> den Computer aus. Gibt es eine Möglichkeit die Echtzeitfähigkeit für> diesen Prozess zu beurteilen?
Was den Arduino betrifft: Ja, natürlich. Du brauchst bloss den erzeugten
Assemblercode kompetent zu analysieren.
Allerdings: Wenn da auch noch ein PC in "diesem Prozess" mitmischt, dann
wird es schwierig bis unmöglich. Bei diesem Teil hängt es einfach davon
ab, welches Betriebssystem auf dem PC verwendet wird.
Hmmhmm schrieb:> Mit dem Arduino kann man generell gut echtzeitfähig programmieren. z.B:> mit einem Timerinterrupt oder ähnlichen Geschichten. Hängt einfach davon> ab, wie schnell die Echtzeit denn sein soll.
Nein, so einfach ist das nicht. Es kommt auch drauf an, mit welcher
Latenz der Timerinterrupt durch kommt. Wenn also andere Sachen im
Interrupt laufen, sind Interruptprioritäten und ggf. Laufzeiten gleich
oder höher priorisierter Interruptroutinen relevant.
Draco schrieb:> W.A. schrieb:>> Laufzeiten gleich>> oder höher priorisierter Interruptroutinen relevant.>> Beim Atmega gibt es keine priorisierten Interrupts.
Keine, deren Priorität man umschalten kann. Wenn aber mehrere
gleichzeitig anstehen, dann werden sie in der Reihenfolge der
Interruptvektoren abgearbeitet. Das ist auch eine Priorität, wenn auch
eine Fixe.
Wenn z.B. (bei M48/88/168/328 ExtInt0- und ADC-Int "ausgelöst" sind,
dann muß der ADC warten.
chris_ schrieb:> Bei den meisten Arduinos ( Uno.. DUE ) gibt es keine Tasks.
Natürlich. Es gibt loop(). Alles, was daraus mehr oder weniger
periodisch ausgeführt wird, ist ein Task.
>Natürlich. Es gibt loop(). Alles, was daraus mehr oder weniger>periodisch ausgeführt wird, ist ein Task.
Ohje, jetzt geht die Diskussion los, was ein Task ist. Normalerweise
wird der Begriff immer im Zusammenhang mit "Multitasking" Systemen
verwendet. Die beiden genannten Arduino-Varianten haben keins und damit
im Sinne des Multitasking Begriffs auch keinen Task.
Man kann natürlich jetzt spitzfindig sein und sagen, jedes
Mikrocontrollersystem hat mindestens einen Task, sonst macht es nix. Das
wird aber allgemein nicht so gehandhabt.
Oder man könnte eine Interruptroutine einfach in "Task"-Routine
umbenennen.
Carl D. schrieb:> Wenn z.B. (bei M48/88/168/328 ExtInt0- und ADC-Int "ausgelöst" sind,> dann muß der ADC warten.
Ich weiß was du meinst, aber das kann auch nicht passieren, weil jede
Interruptauslösung ja in das INTVECT geschrieben wird bevor er auslößt,
das bedarf ja mindestens ein Cycle - also nacheinander - es kann nicht
passieren das zwei Interrupts gleichzeitig auslösen. Zumindest nicht im
Ablauf, Problem dabei ist jedoch - solange es nicht Atomic ist - das
dann der niedere Interrupt den höheren Interrupt unterbricht (Also in
der Int Tabelle), das ist richtig.
Joachim B. schrieb:> kann man aber einbauen> Beitrag "Wartezeiten effektiv (Scheduler)"
Falsch, damit nutzt man die Leerlaufzeit, aber es können keine "Tasks"
gleichzeitig abgearbeitet werden. Er macht schön eins nach dem anderen,
auch in diesem Scheduler.
Naja...
Was man auf einem Arduino gut hin bekommt ist sowas wie kooperatives
Multitasking.
Aber Echtzeit?
Eine garantierte Reaktionszeit bekommt man nur über den WDT. z.B. Reset
und Notabschaltung.
Das gilt im Grunde auch für RTOS.
Kein Speicherschutz. An jedem Ende des Codes können die Interruptflags
manipuliert werden.
Nee...
So einfach ist das mit der "Echtzeit" auf AVRs nicht.
Draco schrieb:> aber es können keine "Tasks"> gleichzeitig abgearbeitet werden. Er macht schön eins nach dem anderen,> auch in diesem Scheduler.
Multi-Tasking beschreibt ja auch nicht, dass mehrere Tasks gleichzeitig
parallel abgearbeitet werden.
Multi-Processing oder Parallel-Computing ist auch lange nicht so alt wie
Multi-Tasking.
Amiga, 1985, ein Prozessor-Kern, keine MMU oder MPU, Multi-Tasking.
Wie ausgefeilt und sicher das ist, das ist doch eine andere Frage.
c-hater schrieb:> Was den Arduino betrifft: Ja, natürlich. Du brauchst bloss den erzeugten> Assemblercode kompetent zu analysieren.>> Allerdings: Wenn da auch noch ein PC in "diesem Prozess" mitmischt, dann> wird es schwierig bis unmöglich. Bei diesem Teil hängt es einfach davon> ab, welches Betriebssystem auf dem PC verwendet wird.
Also auf dem Computer ist Win-7 installiert und als Terminalprogramm
verwende ich HTerm. Wie genau könnte ich dies denn für den PC
beurteilen?
Draco schrieb:> Carl D. schrieb:>> Wenn z.B. (bei M48/88/168/328 ExtInt0- und ADC-Int "ausgelöst" sind,>> dann muß der ADC warten.>> Ich weiß was du meinst, aber das kann auch nicht passieren, weil jede> Interruptauslösung ja in das INTVECT geschrieben wird bevor er auslößt,> das bedarf ja mindestens ein Cycle - also nacheinander - es kann nicht> passieren das zwei Interrupts gleichzeitig auslösen. Zumindest nicht im> Ablauf, Problem dabei ist jedoch - solange es nicht Atomic ist - das> dann der niedere Interrupt den höheren Interrupt unterbricht (Also in> der Int Tabelle), das ist richtig.
Vielleicht gibt es durchaus einen Unterschied zwischen "kann nicht" und
"ist unwahrscheinlich", oder?
Draco schrieb:> Problem dabei ist jedoch - solange es nicht Atomic ist - das> dann der niedere Interrupt den höheren Interrupt unterbricht (Also in> der Int Tabelle), das ist richtig.
Nö. Standardmässig wird bei Eintritt in eine ISR das globale I-Bit
gelöscht und somit eine Unterbrechung der ISR verhindert. Erst ein RETI
setzt das globale I-Bit wieder und gibt damit Interrupts wieder frei.
Wenn man weiss, was man tut, kann man in der ISR das I-Bit setzen und
damit eine Unterbrechung ermöglichen, aber die Hardware macht das nicht
von alleine.
Dein PC kann mit Sicherheit kontinuierlich serielle Daten mit 115200
Baud empfangen. Eventuell auch schneller.
Allerdings sorgt das Windows OS dafür, dass die Daten nicht
kontinuierlich an das Programm (in deinem Fall HTerm) übergeben werden.
Du musst mit Pausen Rechnen, wo mal nichts ankommt und danach kommen die
bis dahin angesammelten Daten am Stück ganz schnell rein.
Unregelmäßiger Verzögerungen im einstelligen ms Bereich sind die Regel.
Darüber Hinaus kommt es gelegentlich aber auch zu Verzögerungen, die
durchaus mehrere Sekunden dauern können.
Deswegen ist Windows nicht Echtzeit-tauglich.
Deswegen werden von Windows gesteuerte Maschinen typischerweise durch
echtzeitfähige Mikrocontroller unterstützt. Zum Beispiel:
1) Grafikchip + Bildschirm arbeiten mit einem exakt definiertem Timing
zusammen, um ein Ruckelfreies und stehendes Bild zu erzeugen.
2) Die Maus erfasst mit einem µC die Bewegungen und überträgt sie danach
zum PC.
3) Der Drucker moduliert den Laser genau passend zur
Rotationsgeschwindigkeit der Walzen. Der Tintendrucker spritzt Tinte
synchron zur Laufgeschwindigkeit des Druckkopfes.
4) Das CD Laufwerk und die Festplatte liest Daten mit der
Rotationsgeschwindigkeit des Mediums und liefert sie dann in dem Tempo
und Intervall ab, wie das Betriebsystem es gerne hätte.
All diese Geräte Puffern Datenströme, damit die Verzögerungen durch das
OS kein Problem darstellen. Ich kenne noch Heimcomputer, da war das noch
nicht so. Da war das OS Echtzeitfähig und die ganze Peripherie erheblich
primitiver.