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