Funktionsaufruf aus Interrupt

Guten Abend!

Ich verzweifle an einem in meinen Augen sehr eigenartigen Problem :confused:

Ich versuche aus dem "Interrupt-Rumpf" eine Funktion aufzurufen. Sollte ja eigentlich kein Problem sein, solange man in dieser Funktion nicht auf die Serielle Schnittstelle, i2c oder Ähnliches zugreift.
In meinem Fall bleibt der Arduino aber komplett hÀngen.
Wenn ich die selbe Funktion nicht aus dem Interrupt, sondern aus der Loop-Iteration aufrufe, lÀuft es Problemlos durch.
Es ist mir aber sehr wichtig, dass meine Funktion in möglichst konstanten und kurzen ZeitabstÀnden aufgerufen wird.

Die Funktion befindet sich in einer selbstgebauten Library und berechnet den Schnittpunkt zweier Strecken (GPS).
Die Parameter der Funktion bestehen aus zwei ebenfalls selbstgebauten Vektor-Objekten, welche jeweils aus 6 longs und 2 bools bestehen.
(Info: Ich stelle einen 3D Vektor dar, also brauche ich 2 Punkte, deshalb so viele longs)

Nachdem ich die Ursache eingrenzen konnte, warum der ”C hĂ€ngen bleibt, dachte ich dass es vllt. an den riesigen ĂŒbergabeparametern liegt und habe mein Programm wie folgt umgebaut:

Die Parameter werden nun nicht ĂŒber call by value sondern ĂŒber call by reference ĂŒbergeben.
Bedeutet dass die Parameter der Funktion eigentlich nur 2 Pointer sind.

Nun geht es aber trotzdem nicht :frowning:

Noch als Hintergrundinformation, der ISR wird mithilfe des Timer aufgerufen. Ich verwenden den Arduino MEGA.

Habt ihr vllt eine Idee warum sich die Funkion aus dem Loop problemlos aufrufen lÀsst und aus dem Interrupt nicht?

Mit freundlichen GrĂŒĂŸen

ok, jetzt sollen wir Kristallkugeln beschwöhren, aus dem Kaffeesatz lesen oder uns in Telepatie ĂŒben?? :wink: :wink: :wink: :wink: :wink:
Oder wie kommen wir zu Deinem Sketch?
GrĂŒeß Uwe

Andy__:
Nun geht es aber trotzdem nicht smiley-sad

Hast Du daran gedacht, dass ALLE VARIABLEN, auf die sowohl vom normalen Programm als auch von einer Interrupt-Behandlung zugegriffen werden sollen, als "volatile" deklariert sein mĂŒssen?

Im ĂŒbrigen mĂŒssen Interrupt-Behandlungsroutinen extrem kurze Laufzeiten haben. Wenn Interrupt-Routinen lange Laufzeiten haben und oft aufgerufen werden, also das Produkt aus "Laufzeit in Mikrosekunden" mal "Anzahl Aufrufe pro Sekunde" ĂŒber die Anzahl der Mikrosekunden in einer Sekunde hinauswĂ€chst, dann kann es sein, dass Du Dein Programm damit bis zum Stillstand ausbremst, weil dann nur noch Deine Interrupt-Routine lĂ€uft und sonst nichts mehr.

Programme, bei denen die Interrupts zu lange laufen, sind falsch konzipiert.

Kann man den Sketch dazu hier reinstellen? Glaskugel v1.0 lÀuft nicht auf dem Uno :stuck_out_tongue:

Kann es sein, dass du mit deinem loop / while(1) zuviele delays eingebaut hast? Denn normal sollte jeder Durchlauf nur eine sehr geringe Zeit betragen.

Vielen Dank fĂŒr die schnellen Replys :slight_smile:

@sschultewolter: sollte nicht sein, hab alle anderen Aufrufe auskommentiert, sollte also wirklich nur der Funktionsaufruf laufen und loop(), von wo aus etwas an ein LCD geprinted wird. Aber keine keine while(1) oder delays :slight_smile:

Jurs und sschultewolter, ihr hattet trotzdem den richtigen Hinweis gegeben, dass der Durchlauf zu lange dauert. Ich wusste nicht, dass das Produkt aus der Anzahl der Aufrufe und der Durchlaufdauer unter einer Sekunde sein muss. (Warum ist das so?)

Ich hab jetzt den Teiler grob höher gesetzt und das Programm lÀuft nun :)).

@ALL: Entschuldigung dass ich den Code nicht reingestellt habe. Ich habe mein Programm auf mehrere Dateien und Bibliotheken aufgeteilt, und es sind nicht nur ein paar hundert Zeilen. MĂŒsste es also wieder mĂŒhselig zusammenkopieren -> wĂ€re die letztere Option. Wenn keine schnelle Lösung gefunden worden wĂ€re. Deshalb hab ich den Aufruf auch möglichst genau beschrieben.
Mir ist selbstverstÀndlich auch klar, dass man mit Hilfe der Glaskugel nicht viel helfen kann :slight_smile:
@Uwe: das mit dem Kaffeesatz hab ich wirklich noch nirgendwo gelesen :D:D

Mit freundlichen GrĂŒĂŸen

Andy__:
Ich wusste nicht, dass das Produkt aus der Anzahl der Aufrufe und der Durchlaufdauer unter einer Sekunde sein muss. (Warum ist das so?)

Auf einem Single-Core Prozessor hast Du pro Sekunde exakt EINE SEKUNDE Rechenzeit zur VerfĂŒgung.

Wenn Du versuchst, in einer Sekunde schon mehr Zeit als eine Sekunde in Interrupt-Routinen zu verbringen, dann startet immer nach Ende des Interrupts gleich wieder der nĂ€chste Interrupt. Der Controller reiht dann Interrupt an Interrupt an Interrupt, und die loop-Funktion wird ĂŒberhaupt nicht mehr ausgefĂŒhrt, weil dafĂŒr keine Zeit mehr ĂŒbrig ist. Interrupts haben PrioritĂ€t vor normalem Code.

Stimmt, an das Aneinanderreihen der Interrupts hab ich jetzt nicht gedacht, sollte eig. logisch sein :D. Dankeschön!
Ich glaube, ich sitze schon zuu lange am PC heute :smiley:

War da dann doch jemand besser im Fehlerraten. :wink: :wink: :wink: :wink:
GrĂŒĂŸe Uwe