Guten Abend, ich habe bei einer Steuerung für eine Maschine das Problem, dass zeitkritisch Ausgänge geschaltet werden müssen. Zeitkritisch heißt in diesem Fall maximal 4-5ms Ungenauigkeit. Ich schreibe nebenbei Werte auf ein I2C Display, und hier liegt das Problem: Die Steuerung empfängt Interrupts von einem Inkrementalgeber und fängt bei einem bestimmten Ereignis an die Impulse zu zählen. In der ISR inkrementiere ich entsprechend eine Variable. Wenn diese Variable >= einem definierten Wert ist, soll der Ausgang geschaltet werden. Das alles funktioniert genau genug, bis das Display ins Spiel komm. Durch das Schreiben wird die loop Schleife so langsam, dass ich meine zeitliche Genauigkeit nicht mehr einhalten kann, da die Bedingung zum schalten des Ausganges im worst case erst nach einem kompletten loop-Zyklus erkannt wird. Wie kann man das besser lösen? Gibt es die Möglichkeit einen Interrupt auszulösen, wenn 2 Variablen gleich sind? Viele Grüße rbcn
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
rbcn schrieb: > Gibt es die Möglichkeit einen Interrupt > auszulösen, wenn 2 Variablen gleich sind? Nein, normalerweise nicht. Aber es weiß ja auch keiner, was für einen Controller du verwendest. rbcn schrieb: > Zeitkritisch heißt in diesem Fall > maximal 4-5ms Ungenauigkeit. Jetzt mach hier mal nicht so eine Hektik. Das ist ein Zeitbereich, in dem der lahmste Controller der Welt noch nebenbei Primzahlen und Mondphasen berechnen kann. Zeig dein Programm, erklär genau, was du vorhast, dann sehen wir schon weiter.
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
Ich erwähnte den Controller nicht, weil ich der Meinung war ich habe hauptsächlich ein strategisches Problem. Es ist ein Atmega 328P. Den kompletten Code werde ich nicht posten, weil es total unübersichtlich wäre. Die relevanten Dinge sind wie oben geschrieben, dass das Schreiben aufs LCD mittels einer Library zu lange dauert und deshalb ein Vergleich nicht immer rechtzeitig ausgewertet wird. Und nein ich schreibe nicht in jedem Schleifendurchlauf aufs LCD, sondern nur wenn ein zweiter externer Interrupt dieses auslöst.
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
> In der ISR inkrementiere ich entsprechend eine Variable. > Wenn diese Variable >= einem definierten Wert ist, soll der > Ausgang geschaltet werden. Wo ist das Problem??? Warum kannst du den Ausgang nicht gleich in der ISR schalten??? Eine Display-Bearbeitung, die den Programmablauf für >= 4 ms aufhält, kann aber auch nur suboptimal (vulgo: beschissen) programmiert sein: Da kriegt das träge menschlische Auge ja schon den Bildaufbau mit...
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
Jacko schrieb: > Warum kannst du den Ausgang nicht gleich in der ISR schalten??? Weil das gleiche auch noch mit drei weiteren Vergleichen und unter Einbezug von anderen Korrekturwerten passiert. Da hatte ich die Sorge, dass die Interrupts bei höheren Drehzahlen zu schnell kommen würden. Aber danke, guter Ansatz, das werd ich ausprobieren! Manchmal sieht man den Wald vor lauter Bäumen nicht
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
rbcn schrieb: > Zeitkritisch heißt in diesem Fall > maximal 4-5ms Ungenauigkeit. Ich schreibe nebenbei Werte auf ein I2C > Display, und hier liegt das Problem: Die Steuerung empfängt Interrupts > von einem Inkrementalgeber und fängt bei einem bestimmten Ereignis an > die Impulse zu zählen. da muss was grundlegend falsch sein in deinem Programm, was für ein Display? mehr als 4x pro Sekunde schreiben lohnt kaum, kann kein Mensch erfassen oder ist es Video, dann ist I2C eh ungünstig. 4x20 Zeichen LCD sind ja auch in wenigen µs erledigt -> i2c 100kHz ca 10k Zeichen/s (PI x Daumen) meist geht auch 400 kHz. Ich frage im ms Raster den Inkrementalgeber ab, zähle bis 250 und aktualisiere das LCD
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
4 ms für ein Display sind OK. Selbst 100ms wären es, wenn man es richtig macht. Man muss die Display-ausgabe dann halt Niederprior machen, z.B: - Rtos nehmen, - Aufteilung in kleine Pakete - verschiedene Interrupt Level und Loop im Interrupt - SW-Interrupt triggern.
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
Sieh es mal so: Wenn die Reaktionszeit < 4...5 ms sein soll und die ISR alles Wichtige (mit Nebenbedingungen, ...) in < 1...2 ms erledigt hat, (schaffst du das?) ist das doch besser, als wenn die Hauptschleife im Programm nur alle 4...5 ms die Bearbeitung drängender Probleme zulässt!
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
Du sollst ja auch nicht den kompletten Code Posten, sondern nur den kritischen Teil. Reduziere das Programm auf eine minimale ausführbare Demo, die das Problem zeigt. So ist es uns allen am liebsten. Also besteht deine erste Aufgabe darin, diesen Teil zu bestimmen. Wenn du das nicht kannst, helfen wir gerne, aber dann brauchen wir doch den kompletten Code.
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
5 ms wären bei 8Mhz Taktfrequenz ca. 40.000 Maschinen-Befehle. Wenn wir pi mal Daumen 10 Maschinenbefehle pro C Codezeile annehmen, komme ich auf 4000 Zeilen Code, die in dieser Zeit ausgeführt werden. Damit kann man eine ganze Menge anstellen.
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
rbcn schrieb: > Weil das gleiche auch noch mit drei weiteren Vergleichen und unter > Einbezug von anderen Korrekturwerten passiert. Da hatte ich die Sorge, ... Sorgen sind da ein schlechter Ratgeber. Gucke dir die Laufzeit an und sorge ggf. durch Interrupt-Freigabe dafür, dass der nächste Interrupt vom Inkrementalgeber heil durchkommt. Noch eine ketzerische Frage: Was machst du eigentlich mit deinem Timing, wenn dein Inkrementalgeber prellt? Kannst du deinen Inkrementalgeber nicht per Timerinterrupt abfragen?
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
Wolfgang schrieb: > Noch eine ketzerische Frage: Was machst du eigentlich mit deinem Timing, > wenn dein Inkrementalgeber prellt? > > Kannst du deinen Inkrementalgeber nicht per Timerinterrupt abfragen? Prellen sehe ich am Oszi keines, es gibt kein Problem damit. Ich stelle es mir auch schwierig vor, wie ein Hallgeber oder ein optischer Geber (eines von beiden ist es) prellen soll. Aber Danke schonmal an alle, gemach gemach, es braucht etwas Zeit das auszuprobieren.
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
Ich muss mich der allgemeinen Meinung: 4-5 ms sind eine "Ewigkeit" anschließen. Also auch wenn ich es für Unsinn halte, ist die Lösung recht einfach. Da der Programmablauf innerhalb einer Interruptroutine etwas anders ist, wie im normalen Programmablauf, sind ein paar Sicherheitsmaßnahmen nötig. 1. Alles, was in der Interruptroutine passieren soll muss in eine Funktion ausgelagert werden. Also eine "leere" Interruptroutine, die nur den Funktionsaufruf enthält. Dadurch wird der Programmablauf unabhängig davon, ob Du die Routine aus der Unterbrechung heraus aufrufst oder aus dem normalen Programmablauf. 2. Du musst dafür Sorge tragen, dass die Routine nicht während sie gerade läuft, sich selber aufruft. Ein Flag als erstes setzen und als letzten Befehl zurück setzen und selbiges innerhalb der Unterbrechung abfragen. In der Routine und in der Unterbrechung. Muss aber nicht sein.
:
Bearbeitet durch User
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
@ rbcn (Gast) >Die Steuerung empfängt Interrupts >von einem Inkrementalgeber und fäng Was schon mal Unsinn ist. Ein Inkrementalgeber wird durch periodisches Abfragen in einem Timer-Interrupt ausgewertet, siehe Drehgeber. Und schwups hast du auch schon einen Timer-Interrupt, der all deine Probleme löst. >Display ins Spiel komm. Durch das Schreiben wird die loop Schleife so Arduino? >langsam, dass ich meine zeitliche Genauigkeit nicht mehr einhalten kann, >da die Bedingung zum schalten des Ausganges im worst case erst nach >einem kompletten loop-Zyklus erkannt wird. >Wie kann man das besser lösen? Indem man die zeitkritischen Dinge in einen Interrupt packt, der hat Priorität und wird immer ausgeführt und die eher langsamen, zeitunkritischen Dinge in der Hauptschleife, aka Arduino-Loop audführt. Siehe Interrupt. Oder hier. Beitrag "Re: Arduino Nano, SD Card, PCM" > Gibt es die Möglichkeit einen Interrupt >auszulösen, wenn 2 Variablen gleich sind? Nö.
:
Bearbeitet durch User
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
rbcn schrieb: > Ich schreibe nebenbei Werte auf ein I2C > Display, und hier liegt das Problem Du hast ein organisatorisches Problem. Wenn du versuchst, langwierige Dinge in Interrupt-Routinen zu erledigen, dann wirst du in jedem System damit scheitern. Da helfen auch keine Pseudo-Tips wie "Was schon mal Unsinn ist. Ein Inkrementalgeber wird durch periodisches Abfragen in einem Timer-Interrupt ausgewertet.." Auch der Ratschlag, aus einer Interruptroutine irgendwelche Funktionen aufzurufen, die du ebenfalls von woanders her aufrufst, ist ein sehr schlechter Ratschlag. Mein Rat: 1. Halte Interrupt-Funktionen stringent und kurz im Durchlauf. Also keine zeitaufwendigen Dinge darin tun, auch nicht warten. 2. Nur solche Reaktionen, die wirklich zeitkritisch sind, machst du in der Interruptroutine selbst. 3. Reaktionen, die sich mehr Zeit lassen können, machst du aus der Grundschleife in main heraus. Dazu richtest du dir einen Ereignis-Puffer ein (fifo), wo du in der Interrupt-Routine lediglich einen Kenner hineinschreibst, der dann später von der Grundschleife wieder herausgelesen und abgearbeitet wird. Wenn's einfacher gehen soll, dann kannst du dir auch einige globale Booleans einrichten, die im Interrupt gesetzt und in der Grundschleife abgearbeitet werden. Zum Beispiel bool SetzeDisplayNeu; oder so ähnlich. W.S.
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
rbcn schrieb: > Ich schreibe nebenbei Werte auf ein I2C Display, und hier liegt das > Problem: Die Steuerung empfängt Interrupts von einem Inkrementalgeber > und fängt bei einem bestimmten Ereignis an die Impulse zu zählen. In der > ISR inkrementiere ich entsprechend eine Variable. Wenn diese Variable >= > einem definierten Wert ist, soll der Ausgang geschaltet werden. Das > alles funktioniert genau genug, bis das Display ins Spiel komm. Das Display ist an dieser Stelle unnötig und insgesamt sowieso das letzte Glied der Nahrungskette, das bedient werden muss. Denn ob ein Wert angezeigt wird oder nicht ist eigentlich völlig uninteressant. Zumindest für die Funktion einer Maschine. Also gehört solch nebenrangiges Zeug wie das Display weg von der eigentlichen Maschninensteuerung. Und das ist jetzt dein Problem: du hast alles miteinander verknotet und vermischt. Das Display wird immer sofort dann angesteuert, wenn eigentlich die Maschine was machen sollte. Du solltest die Hauptarbeit in einer Hauptschleife machen und dafür sorgen, dass diese Hauptschleife durchschnittlich nicht länger als 5..10ms braucht. Dann kannst du nämlich die allermeisten Sachen dort erledigen und die Interruptroutinen kurz und knackig halten. Ich mache es z.B. so, dass ich einen lokalen Display-Puffer habe, in den ich auch aus einem Interrupt sofort reinschreiben kann. Und dann wird pro Hauptschleifendurchlauf 1 einziges Zeichen an das Display ausgegeben. Bei einem 20x2 Textdisplay und einer durchschnittlichen Hauptschleifen-Zykluszeit von 5ms wird das Display also 5x pro Sekunde komplett neu beschrieben. W.S. schrieb: > 2. Nur solche Reaktionen, die wirklich zeitkritisch sind, machst du in > der Interruptroutine selbst. Zeitkritisch bedeutet hier "zeitkritisch für die Maschinenfunktion". Ein Display ist z.B. nicht zeitkritisch (wer kann schon mehr als 3 Werte pro Sekunde ablesen). Eine serielle Schnittstelle auch nicht (dafür gibt es Puffer), die Reaktion auf einen menschlichen Tastendruck auch nicht (die hätte auch 20ms später gedrückt werden können).
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
Man kann das LCD auch per Interrupt im Hintergrund updaten: Beitrag "Formatierte Zahlenausgabe in C" Man kann auch zeitkritische Sachen in einen Interrupt verschieben, ohne den auslösenden Interrupt zu lang werden zu lassen. Der SPM-READY-Interrupt bietet sich dafür an.
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
...und ich frage mich überhaupt, warum der Vergleich von Variablen eine Interrupt-Routine auslösen soll. Je nach Ergebnis des Vergleichs wird einfach ein Unterprogramm ausgeführt...und wie schon mehrfach geschrieben, du mußt selbst Prioritäten für die Abarbeitungen setzen! Das macht weder eine "einfache"- noch eine Interrupt-Routine für dich. Gruß Rainer
Re: "Interrupt" durch Vergleich von Variablen möglich? Timingprobleme durch zu lange Programmlaufzei
Joachim B. schrieb: > Ich frage im ms Raster den Inkrementalgeber ab, zähle bis 250 und > aktualisiere das LCD genau das meinte ich, im IRQ läuft der ms Zähler, wenn bei mir 250 erreicht ist setze ich das flag LCD_up und in der main loop wird es dann irgendwann passieren, schietegal ob +-10ms Lothar M. schrieb: > Zeitkritisch bedeutet hier "zeitkritisch für die Maschinenfunktion". > Ein Display ist z.B. nicht zeitkritisch jj janz jenau Lothar M. schrieb: > Eine serielle Schnittstelle auch nicht (dafür gibt > es Puffer), die Reaktion auf einen menschlichen Tastendruck auch nicht > (die hätte auch 20ms später gedrückt werden können). desgleichen, Tasterabfrage mit Entprellung im IRQ nach Dannegger in der main loop wird es dann irgendwann passieren, schietegal ob +-10ms
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.