Hallo,
Sowas lässt sich auch mit Interrupts ganz gut behandeln.dazwischen immer den Sensor abfragen (z.B. den Bumper ob ich wo angestossen bin)
Da braucht man nicht gleich einen Multitask-Kernel dazu.
Gruß Jan
Hallo,
wie fragt ihr eure Sensoren ab? Mit Multitasking oder immer wieder im Hauptprogramm?
Ohne Multitasking muss ich ja mein Programm in kleine Schritte zerlegen
und dazwischen immer den Sensor abfragen (z.B. den Bumper ob ich wo angestossen bin). Ist aber mehr als blöd zu programmieren.
Mit Multitasking kann ich mein Hauptprogramm einfach runterprogrammieren, der Sensor Task schläft und unterbricht mein
Hauptprogramm wenn er aktiviert wird. Der nachteil hier ist das Multitasking auf dem µController.
Wie macht ihr das so auf eurem Kontroller? Welche Reaktionszeiten braucht man für einen Roboter?
Fancan
Hallo,
Sowas lässt sich auch mit Interrupts ganz gut behandeln.dazwischen immer den Sensor abfragen (z.B. den Bumper ob ich wo angestossen bin)
Da braucht man nicht gleich einen Multitask-Kernel dazu.
Gruß Jan
Hallo!
Bei einem Bumper mag das ja funktionieren, aber wenn es um komplexe Signale geht (zum Beispiel Analogsignal), kommst du mit deinen Interrupts nicht weit (oder irre ich mich?).
Ich verwende ja die CC2, die standardmäßig mit Multitasking ausgestattet ist.
Ich würde sehr ungern darauf verzichten.
Geschwindigkeitsprobleme hatte ich bis jetzt keine.
MfG ACU
http://www.roboterbastler.de
endlich wieder online
Auch der AD-Wandler liefert einen Interrupt,
wenn er mit der Wandlung fertig ist.
Da kann man dann entsprechend reagieren.
Ich behaupte nicht, das Interrupts das alleinseligmachende sind.
Aber je nach Aufgabenstellung kann Multitasking auch mit Kanonen
auf Spatzen geschossen sein.
Oder es frisst einem dringend benötigte Ressourcen weg.
Meist Rechen- oder Reaktionszeit, aber auch Speicherplatz.
Wenn du auf einem kleinen AVR mit 2KFlash und 128Byte RAM noch
mit Multitasking anfängst...
Wie gesagt, kommt darauf an was man womit machen will.
Gruß Jan
Wo ist das Problem?Zitat von ACU
Der ADC löst nach jeder Wandlung einen Interrupt aus, dann kann man die Daten erstmal irgendwie verarbeiten und danach läuft das Programm normal weiter.
Interrupts sind ein sehr wichtiges Werkzeug das einem der Prozessor bietet, und sie nicht zu benutzen ist Verschwendung.
Multitasking kann Interrupts nicht ersetzen!
Für die meisten Anwendungen würde ich empfehlen, zeitkritische und unvorhersehbare Sachen per Interrupt zu machen (dafür sind die ja da), und alle übrigen Funktionen einfach zyklisch aufzurufen.
So viele Treppen und so wenig Zeit!
Hallo,
Interrupts lösen das Problem nicht. Es ist richtig auch eine AD Wandlung kann einen Interrupt auslösen wenn sie fertig ist. Das ist aber nur die halbe Miete. Jetzt will ich ja z.B. beim Bumper eine Ausweichroutine fahren lassen (1sec zurück, 1sec mit einem Motor zur Kurve). Diese ganze Aktion (2 sec) kann ich aber nicht in der Interruptroutine laufen lassen ...
Fancan
natürlich nicht, aber dafür braucht man noch lange kein Multitasking.
wie gesagt...
zeitkritische Sachen in Interrupts (und in den Interruptroutinen wirklich nur das notwendigste)
und den Rest ruft man bei Bedarf mit einer Art "ultra-primitiv-Taskmanager" auf.
Angenommen man kriegt über den ADC irgendein Signal das man zunächst mal filtern möchte um es dann irgendwie weiter zu verarbeiten.
Dann schreibt man in der ADC-Interruptroutine nur den gemessenen Wert irgendwo hin, und setzt dann ein Flag das signalisiert, daß ein neuer Wert da ist.
Im Hauptprogramm steht dann im Extremfall nurnoch eine Endlosschleife, in der die verschiedenen Funktionen aufgerufen werden.
(FlagXY gesetzt? -> Flag löschen und Funktion XY aufrufen)
In diesem Beispiel wäre dann halt das Flag das wir uns vorher für den ADC definiert haben gesetzt,
also würde bei der entsprechenden IF-Anweisung zunächst mal das Flag wieder gelöscht, und dann die Funktion aufgerufen die das Filter implementiert.
Ich behaupte mal, daß dieses Verfahren für die meisten Anwendungen absolut ausreichend ist. (und teilweise besser geeignet als echtes Multitasking)
So viele Treppen und so wenig Zeit!
@felix: so wie ich das gerad verstanden hab, meinst du, dass wenn ein interrupt erfolgt, im hauptprogramm eine schleife aufgerufen wird, die eine bestimmte aktion aufruft (wenn nicht, dann vergiss diesen beitrag). aber ich glaube gerade das will FancanTeik vermeiden. also wenn der prozessor erst dem motortreiber die ausweichen-signale geben muss, wartet der hauptprozess natürlich erstmal, bis der bot ausgewichen ist. ne möglichkeit wäre dann, nen zweiten mini-prozessor mit der motorsteuerung zu betrauen. hauptprozessor bekommt interrupt und sagt dem motorprozessor: "weich ma aus!". und dann kann der hauptprozessor in aller ruhe seine sachen machen während der motorprozessor ausweicht.
-> MEIN PROJEKTBLOG <-
Wenn das Programm (oder die Funktion oder der Thread) so programmiert wäre, würde auch Multithreading nicht helfen!also wenn der prozessor erst dem motortreiber die ausweichen-signale geben muss, wartet der hauptprozess natürlich erstmal, bis der bot ausgewichen ist.
Blockierende Programmteile, wie etwa "Sleep" oder "Wait", die einfach den Prozessor zu NOPs zwingen, darf es nicht geben. Die Idee von felix ist doch: warte auf ein Ereignis, unterbreche alles andere, mache nur das notwendige (AD-Wert abfragen und speichern) und setze einen Event (oder Flag), gib den Prozessor sofort wieder frei.
Da ein Prozesser ja nicht NICHTS tun kann, muß es irgendwo ein main-Programm geben, dass nichts weiter macht, als alle Events (oder Flags) ständig reihum abzufragen. War eins gesetzt, wird die dazu passende Funktion (gespeicherten AD-Wert umrechnen, skalieren, verarbeiten, ...) aufgerufen. Nach dem Ende der Funktion geht es zum main-Programm zurück, das die nächsten Flags abfragt.
Das "Komplizierte" an so einem Programmaufbau ist, sich Events zu schaffen, die den Beginn und/oder das Ende einer Handlung signalisieren. Das können Interrupts (auch Timer) sein, oder einfach auch nur irgendwelche Flags, die irgendwer zu irgendeinem Zeitpunkt setzt.
Bitte kein "Sleep" oder "Wait" verwenden, sondern einen Timer starten und die Funktion verlassen (oder mit was anderem weiterarbeiten). Der Timer kommt später in einer Interrupt-Routine zurück, die jetzt dort weitermacht, was nach "Sleep" oder "Wait" stehen würde.
Blackbird
@Goblin:
nein, ich meinte das so wie Blackbird es beschrieben hat.
Der Prozessor wird auf die Art nie länger als absolut notwendig blockiert.
Im Hauptprogramm läuft eine Endlosschleife (ist doch normalerweise eh so)
in der der Reihe nach alle Funktionen aufgerufen werden die gerade aufgerufen werden sollen.
Diese Schleife läuft immer, d.h. sie wird nicht vom Interrupt aus aufgerufen (was ziemlich schwachsinnig wäre),
sondern nur durch den Interrupt unterbrochen
So viele Treppen und so wenig Zeit!
Lesezeichen