loop

Hallo

Wie und mit was wird die loop bei meinem Arduino Duemilanove(ATmega328) ausgelöst?

Gruß

der loop startet sich doch automatisch oder?

Ich habe zwar eh noch nicht so viel Ahnung aber ich weiß nichtmal was gemeint ist.

void loop(){ }

Startet doch wenns im Code dran ist

Meißt nach void setup (){ }

Oder sehe ich das falsch?

Jedes C/C++ Programm startet über die Funktion main().
In Arduino Programmen ist sie jedoch nicht vorhanden weil sie automatisch beim compilieren hinzugefügt wird.
Der Inhalt dieser main() Funktion lautet:

int main(void)
{
    init();

    setup();

    for (;;)
        loop();

    return 0;
}

Die loop muss ja irgendwie durch einen Interrupt sprich timer ausgelöst werden. Ich haben mir einen Timer2 zusätzlich programmiert und wollte jetzt wissen wer die loop auslöst. Wäre auch mal interessant zu wissen welcher Interrupt welche Priorität hat bei Arduino oder wo man das nachlesen kann. Auch was für einen "Betriebssystem" schon ab Werk auf dem Atmega läuft.

loop wird nicht ausgelöst, es ist sozusagen das Hauptprogramm was in einer endlosschleife ausgeführt wird.

mit einem interrupt kann man den microcontroller aus "Standby" wecken

(glaube ich)

Timmy: Die loop muss ja irgendwie durch einen Interrupt sprich timer ausgelöst werden. Ich haben mir einen Timer2 zusätzlich programmiert und wollte jetzt wissen wer die loop auslöst. Wäre auch mal interessant zu wissen welcher Interrupt welche Priorität hat bei Arduino oder wo man das nachlesen kann. Auch was für einen "Betriebssystem" schon ab Werk auf dem Atmega läuft.

Hallo Timmy,

nochmal vielleicht zum klarstellen, was beim Start eines Arduino-Programms so passiert (Akrlfix hats ja schon teilweise beschrieben):

Nach dem Reset oder Hochladen des Sketches über den Bootloader wird einmal die Funktion main() aufgerufen. Dort wird dann als erstes einmal die Funktion init() aufgerufen. Der Code dafür steckt in der Datei wiring.c. Dort werden einige Initialisierungen und Vorbelegungen vorgenommen. Da muss man nichts dran machen, die wird automatisch dazugepackt.

Danach wird die Funktion mit dem Namen setup() aufgerufen, die du in deinem Sketch geschrieben hast/schreiben musst. Und zwar genau einmal. Hier hinein gehören deine persönlichen Initialisierungen und Vorbereitungsarbeiten, die einmal ausgeführt werden.

Danach kommt dann diese "komische Konstruktion" mit dem "for( ; ; ) loop();". Das ist eine Endlosschleife, in der die Funktion loop() immer wieder und wieder aufgerufen wird. Und was dabei ausgeführt wird, ist genau der Code, den du in die Funktion loop() reingepackt hast. Immer wieder und wieder... Dafür braucht man keinen Interrupt, sondern die Funktion main() ruft eben die Funktion loop() in der Endlosschleife auf.

Ansonsten gibt es bei einem Mikrocontroller oft/meistens kein Betriebssystem in dem Sinne eines Windows o.ä. Die nötige Funktionalität musst du gegebenenfalls selber schreiben, falls so etwas benötigt wird. Der Arduino hat jedenfalls nichts in dieser Richtung an Bord.

Zu den Prioritäten der Interrupts zitiere ich mal aus dem Datenbuch für den Controller ATMega 2560:

"A flexible interrupt module has its control registers in the I/O space with an additional Global Interrupt Enable bit in the Status Register. All interrupts have a separate Interrupt Vector in the Interrupt Vector table. The interrupts have priority in accordance with their Interrupt Vector position. The lower the Interrupt Vector address, the higher the priority."

Und wo finde ich die "Interrupt Vector position" ? Nun, die Interruptvektor-Tabelle findet sich im Datenbuch des jeweiligen Controllers im Kapitel "Interrupts". Für den ATMega 328 in Kapitel 11. Dort kannst du nachsehen, welcher Interrupt auf welcher Position liegt. Und damit seine Priorität. Da die einzelnen Controller unterschiedliche Hardware mit unterschiedlichen Interrupts haben, sieht die Tabelle bei den einzelnen Controllertypen auch unterschiedich aus.

Ansonsten muss ich immer wieder auf das Datenbuch für den Controller verweisen, wenn du in diese Einzelheiten einsteigen willst: http://www.atmel.com/dyn/resources/prod_documents/doc8271.pdf

Gruß Wolfgang

Die Datenblätter der Microcontroller findest Du bei der Beschreibung der jeweiligen Arduinis http://arduino.cc/en/Main/Hardware oder für nicht mehr aktuelle Arduinis: http://arduino.cc/en/Main/Boards oder eben beim Hersteller: http://www.atmel.com Grüße Uwe

Hallo,

wenn die Funktion loop() aber immer wieder aufgerufen wird, kann es dann nicht sein, dass es dann zu Problemen kommt? Z.B.: loop() { warte 10 Sekunden; LED 1 an; }

Dann wird doch immer wieder loop() aufgerufen und es wird angefangen zu warten. Die LED 1 leuchtet also nie. Oder wo ist der Denkfehler?

omthomas

Warum sollte die LED in dem Fall nicht angehen? Der loop-Bereich umfasst alles, was in der geschweiften Klammer steht und dieser Inhalt wird nacheinander ausgeführt:

---> 10 Sekunden warten ---> LED einschalten ---> 10 Sekunden warten ---> LED einschalten ---> ... usw.

Wie du siehst, wird die LED nie ausgehen.

naja, aber wenn die loop()-Funktion immer neu aufgerufen wird - was ja sehr schnell geht - dann wird doch immer wieder von vorne angefangen, die Anweisungen abzuarbeiten; bis zur "LED 1 an" kämme es doch garnicht wegen dem "warte".

T.

Der führt nicht einfach so zwischendurch denn loop neu aus.

führe loop aus
   void loop(){   
      mache was
      mache was
      mache was oder auch nicht
   }
oh loop ist fertig hui springe zu Anfang von loop

er wird abgearbeitet und dann neu angefangen

Also nochmal.

Das ist die main() Funktion:

int main(void)
{
    init();

    setup();

    for (;;)
        loop();

    return 0;
}

Das entscheidende ist dieser Teil:

    for (;;)
        loop();

In einer Endlosschleife wird immer wieder die Funktion loop() aufgerufen. Da das Programm aber nur sequentiell abgearbeitet werden kann, kommt es an diesen Punkt erst wieder zurück wenn die Funktion loop() verlassen wird.

  • loop() wird aufgerufen
  • loop() wird bis zum Ende oder bis zu einem "return" durchlaufen
  • loop() wird verlassen
  • durch die Endlosschleife wird loop() sofort wieder aufgerufen
  • und wenn er nicht gestorben ist...

Das ist eine sehr gute Erklärung!!

loop() wird in der main()-Funktion aufgerufen (das läuft im Hintergrund ab) loop() wird immer einmal abgearbeitet dann Rücksprung in die main()-Funktion und gleich wieder Aufruf von loop() durch die Endlosschleife for;; (das läuft auch im Hintergrund ab)

Also wird loop() immer einmal komplett durchlaufen und fängt wieder vorne an. Das passt!

Vielen Dank Thomas

omthomas:
naja, aber wenn die loop()-Funktion immer neu aufgerufen wird - was ja sehr schnell geht - dann wird doch immer wieder von vorne angefangen, die Anweisungen abzuarbeiten; bis zur “LED 1 an” kämme es doch garnicht wegen dem “warte”.
T.

Das “warte” hält die Ausführung des Programms an. Das Programm wird der Reihe nach abgearbeitet und erst wenn es fertig ist wird loop() wieder aufgerufen.
Das gilt für (fast) alle Funktionen. Eine Funktion wird aufgerufen, abgearbeitet und wenn sie fertig ist wird das Programm weiter abgearbeitet.

Einzige Ausnahme ist die Interruptfunktion. Diese wird aufgerufen wenn ein “Auslöser” eintritt; es sind mehrere “Auslöser” oder Ereignisse auswählbar (Timer, UART, externe Signale). Ein Interrupt unterbricht das normale Programm und arbeitet die Interruptfunktion ab. Wenn diese fertig ist wird das unterbrochene Programm fortgeführt. Interrrups werden verwendet, wenn auf ein Ereignis sofort reagiert werden muß oder wenn zeitkritische Aufgaben zu machen sind.

Grüße Uwe