Hi, ich habe mal eine allgemeine Frage zu Umsetzung eines Regelalgorithmus in einem Mikrocontroller. Und zwar, wie setze ich die Abtastzeit des Reglers, die Berechnungsdauer des Algorithmus und das Zusammenspiel von beiden, in einem Controller exakt um? Angenommen wir haben einen sehr komplizierten Regelalgorithmus, der sich nicht über ein paar Zeilen Code beschreiben lässt. Nun könnte ich diese Berechnung komplett in einem Timer-Interrupt durchführen um die Abtastzeit zu garantieren. Allerdings verbringe ich dann viel Zeit in einem Interrupt, was in der Embedded Software Entwicklung nicht gerade gut ist. Wie löse ich so ein Problem? Dabei möchte ich keinen Scheduler verwenden. Ich hoffe die Frage ist vertsändlich gestellt und nicht dumm. :) Gruß Sebastian
Die Frage ist absolut nicht dumm und ist so interessant, dass sich sogar viele Universitäten mit dieser Thematik beschäftigen! Einen generellen Masterplan gibt es also dafür noch nicht und die Lösung des Problems ist Anwendungsspzifisch. Je nachdem was du regeln willst, ist es jedoch extrem wichtig, dass das Abtasten streng äquidistant durchgeführt wird, da es es sonst zur Instabilität kommen kann!
Sebastian B. schrieb: > Nun könnte ich diese > Berechnung komplett in einem Timer-Interrupt durchführen um die > Abtastzeit zu garantieren. Dafür gibt es keinen Grund. Lediglich die Abtastung muß durch den Timer gesteuert werden. Die Berechnung kann im Hauptprogramm stattfinden und die geänderte Steuergröße wieder Timersynchronisiert ausgegeben werden.
Martin schrieb: > Sebastian B. schrieb: >> Nun könnte ich diese >> Berechnung komplett in einem Timer-Interrupt durchführen um die >> Abtastzeit zu garantieren. > > Dafür gibt es keinen Grund. Lediglich die Abtastung muß durch den Timer > gesteuert werden. Die Berechnung kann im Hauptprogramm stattfinden und > die geänderte Steuergröße wieder Timersynchronisiert ausgegeben werden. Und jetzt nehmen wir mal an, dass das System vorgibt alle X s/ms/µs eine Stellgröße zu benötigen, dann muss auch der Regler garantieren alle X s/ms/µs eine Stellgröße zu liefern. Wenn in der Hauptschleife auch noch Kommunikation mit anderen Controllern, Tastenhandling, Displayansteuerung etc. durchgeführt wird, also man das Programm belibig komplex macht, wie soll man dann garantieren, dass der Regelalgorithmus auch die Stellgröße zur geforderten Zeit liefert?
Hallo Sebastian, wie oben schon geschrieben wurde ist die Umsetzung hier sehr stark von der Anwendung, d.h. der Dynamik des Systems abhängig. Wenn Du z.B. eine langsame Temperaturregelung implementierten möchtest ist es aus meiner Sicht völlig ok alles in einer Hauptschleife zu regeln. Da ist es auch egal wenn die Temperatur mal 100ms früher oder später gemessen wird und dann die neue Stellgröße 100ms früher oder später gesetzt wird. Bei sehr dynamischen Regelungen sieht das Ganze schon anders aus. Wenn Du z.B. einen Servoantrieb regeln musst. Dann berechnet man die Regelung direkt im Interrupt. Hier geht man normalerweise so vor, dass die AD-Wandlung mittels Timer gesteuert wird. Danach wird dann ein Interrupt ausgelöst, der Regelalgorithmus im Interrupt berechnet und die neuen Stellgrößen geschrieben. Diese neuen Stellgrößen werden aber nicht sofort ausgegeben sondern auch wieder automatisch per Timer übernommen. Damit ist dann in Summe gewährleistet, dass die Zeit zwischen Abtastung und Ausgabe der neuen Stellgrößen immer die gleiche ist und Latenzzeiten der SW keinen Einfluss haben. Viele Grüße, Ralf
Sebastian B. schrieb: > Und jetzt nehmen wir mal an, dass das System vorgibt alle X s/ms/µs eine > Stellgröße zu benötigen, dann muss auch der Regler garantieren alle X > s/ms/µs eine Stellgröße zu liefern. Wenn in der Hauptschleife auch noch > Kommunikation mit anderen Controllern, Tastenhandling, > Displayansteuerung etc. durchgeführt wird, also man das Programm belibig > komplex macht, wie soll man dann garantieren, dass der Regelalgorithmus > auch die Stellgröße zur geforderten Zeit liefert? Indem man die Rechenleistung so groß wählt, daß nie 100% Auslastung über eine komplette Abtastrate vorkommen kann. Ansonsten muss man Sorge tragen daß periphere Arbeiten wie z.B. UART nicht alle gleichzeitig durchgeführt werden und so zuwenig Zeit für die wichtige Arbeit übrigbleibt. Ansonsten gibts evt. Bruch wie fast bei Apollo 11 bei der Landung des Eagle auf dem Mond passiert. Ist ne interessante Geschichte.
Udo Schmitt schrieb: > Sebastian B. schrieb: >> Und jetzt nehmen wir mal an, dass das System vorgibt alle X s/ms/µs eine >> Stellgröße zu benötigen, dann muss auch der Regler garantieren alle X >> s/ms/µs eine Stellgröße zu liefern. Wenn in der Hauptschleife auch noch >> Kommunikation mit anderen Controllern, Tastenhandling, >> Displayansteuerung etc. durchgeführt wird, also man das Programm belibig >> komplex macht, wie soll man dann garantieren, dass der Regelalgorithmus >> auch die Stellgröße zur geforderten Zeit liefert? > > Indem man die Rechenleistung so groß wählt, daß nie 100% Auslastung über > eine komplette Abtastrate vorkommen kann. > Ansonsten muss man Sorge tragen daß periphere Arbeiten wie z.B. UART > nicht alle gleichzeitig durchgeführt werden und so zuwenig Zeit für die > wichtige Arbeit übrigbleibt. > Ansonsten gibts evt. Bruch wie fast bei Apollo 11 bei der Landung des > Eagle auf dem Mond passiert. Ist ne interessante Geschichte. Natürlich ist es auch alles kein großes Problem mehr wenn man die Rechenleitung belibig erhöht. Aber mal angnommen wir haben einen High-End Controller, welcher mit 80MHz läuft. Sprich, ein schnellerer Controller ist keine Lösung. Ralf schrieb: > Hallo Sebastian, > > wie oben schon geschrieben wurde ist die Umsetzung hier sehr stark von > der Anwendung, d.h. der Dynamik des Systems abhängig. Wenn Du z.B. eine > langsame Temperaturregelung implementierten möchtest ist es aus meiner > Sicht völlig ok alles in einer Hauptschleife zu regeln. Da ist es auch > egal wenn die Temperatur mal 100ms früher oder später gemessen wird und > dann die neue Stellgröße 100ms früher oder später gesetzt wird. > Bei sehr dynamischen Regelungen sieht das Ganze schon anders aus. Wenn > Du z.B. einen Servoantrieb regeln musst. Dann berechnet man die Regelung > direkt im Interrupt. Hier geht man normalerweise so vor, dass die > AD-Wandlung mittels Timer gesteuert wird. Danach wird dann ein Interrupt > ausgelöst, der Regelalgorithmus im Interrupt berechnet und die neuen > Stellgrößen geschrieben. Diese neuen Stellgrößen werden aber nicht > sofort ausgegeben sondern auch wieder automatisch per Timer übernommen. > Damit ist dann in Summe gewährleistet, dass die Zeit zwischen Abtastung > und Ausgabe der neuen Stellgrößen immer die gleiche ist und Latenzzeiten > der SW keinen Einfluss haben. > > Viele Grüße, > Ralf Genau von so einem sehr dynamischen System spreche ich. Es ist also durchaus üblich eine Regelung komplett im Interrupt durchzuführen bzw. in mehreren oder einen Scheduler/Betriebssytsem zu verwenden? Gruß Sebastian
Sebastian B. schrieb: > Genau von so einem sehr dynamischen System spreche ich. Es ist also > durchaus üblich eine Regelung komplett im Interrupt durchzuführen bzw. > in mehreren oder einen Scheduler/Betriebssytsem zu verwenden? In einem solch komplexen Fall wirst du nicht mehr drum herum kommen irgendein übergeordnetes Steuer/Kontroll-System zu implementieren oder zu nutzen, mit dem du verschiedene Teile prioritätsgesteuert ablaufen lassen kannst. Da man das Rad nicht jedesmal neu erfinden sollte wäre also ein multitasking Betriebssystem dann durchaus eine Überlegung wert.
Nach meiner Erfahrung ist es durchaus überlich eine Regelung komplett im Interrupt zu berechnen wenn man nur so die Timingvorgaben einhalten kann. An dieser Stelle ist auch eine Priorisierung der Tasks sehr wichtig wie Udo auch schon geschrieben hat. Ein RTOS macht an der Stelle evtl. auch Sinn. Hiermit habe ich aber noch relativ wenig Erfahrung. Prinzipiell könnte man es aber so machen, dass der ADC per Timer getriggert wird und dann nach der AD Wandlung im EOC Interrupt ein hochpriorer Task gestartet wird der dann den Regelalgorithmus berechnet. Ob die Latenzzeiten die durch das RTOS verursacht werden immer ok sind muss man von Fall zu Fall entscheiden. Ggf. macht es dann Sinn die Regelung ausserhalb des RTOS komplett im Interrupt zu rechnen und nur die anderen Tasks wie z.B. Kommunikation & Anzeige mit Hilfe des RTOS zu bearbeiten. Gruß, Ralf
Sebastian B. schrieb: > ... dass der Regelalgorithmus auch die Stellgröße zur > geforderten Zeit liefert? so: Martin schrieb: > ... und die geänderte Steuergröße wieder timersynchronisiert > ausgegeben wird
Udo Schmitt schrieb: > Da man das Rad nicht jedesmal neu erfinden sollte wäre > also ein multitasking Betriebssystem dann durchaus eine Überlegung wert. Und damit kommst du vonm Regen in die Traufe... Das Stichwort lautet eher Echtzeitbetriebssystem. Ob es dann ein "hartes" sein muß, hängt von den Anforderungen ab. Ansonsten ist alles relativ, auch solche Forderungen wie "sofort" und "unbedingt". Allerdings nutzt das alles nur was, wenn es überhaupt Rechenzeit zu verteilen gibt. Wenn der Regelalgorithmus 100% der erlaubten Zeit erfordert, hilft alles nichts, dann kann der Prozessor während dessen halt nichts anderes ausführen. Ob der dann in einer un-unterbrechbare ISR läuft, oder in einer un-unterbrechbare Task, ist im Endeffekt egal. Oliver
Martin schrieb: > Sebastian B. schrieb: >> ... dass der Regelalgorithmus auch die Stellgröße zur >> geforderten Zeit liefert? > > so: > > Martin schrieb: >> ... und die geänderte Steuergröße wieder timersynchronisiert >> ausgegeben wird Und wenn der Regelalgorithmus nicht zwischen den Timer-Interrupts in der Hauptschleife berechnet werden kann? Sprich, der Hauptschleifendurchlauf zu lange dauert. Einen veralteten Wert als Steuergröße auszugeben, ist keine Alternative.
Sebastian B. schrieb: > Und wenn der Regelalgorithmus nicht zwischen den Timer-Interrupts in der > Hauptschleife berechnet werden kann? Sprich, der Hauptschleifendurchlauf > zu lange dauert. Dann ist die ALU zu schwach. Oder was ist denn noch alles in der Hauptschleife?
Man kann das System in der Tat aufblasen und es so auch langsamer machen. Wichtig ist eher dann man groessere Aufgaben de Bentuzerinterfaces nicht auf's mal erledigen will, sondern mit einer Zustandsmaschine zerscheibelt. Man kann zb zwischen den wichtigen Dingen die genau erfolgen muessen jeweils ein Digit einer Zahl von Integer nach BCD wandeln. Bei 8 Digits sind das dann eben 8 zyklen, macht ja nichts. Oder auch wenn ein String zu einer Zahl gewandelt werden muss, jeweils ein Char davon pro Durchgang.
Du könntest ja alles was neben der Rechnung noch in der Hauptschleife passiert über einen Low-Priority-Interrupt machen, welcher aber nur dann aktiviert ist, wenn gerade nicht gerechnet wird und der sofort über einen High-Priority-Interrupt wieder abgeschaltet wird, wenn die nächste "Berechnung" ansteht. Allerdings kannst du dann natürlich genauso deine Berechnung in einen Interrupt packen. Und es ist schon eine Alternative einen alten Wert auszugeben, wenn noch kein neuer Wert da ist... Aber wenn du so nah an den Leistungsgrenzen bist, dann ist es vielelicht wirklcih besser einen schnellern µC bzw. einen µProzessor (ARM9 oder nen A8...was weiß ich) mit einem OS zu verwenden. Was willst du denn regeln?
Oliver schrieb: > Allerdings nutzt das alles nur was, wenn es überhaupt Rechenzeit zu > verteilen gibt. Wenn der Regelalgorithmus 100% der erlaubten Zeit > erfordert, hilft alles nichts, dann kann der Prozessor während dessen > halt nichts anderes ausführen. Ob der dann in einer un-unterbrechbare > ISR läuft, oder in einer un-unterbrechbare Task, ist im Endeffekt egal. Der Controller kann die Berechnung in der erlaubten Zeit durchführen. Meine Frage bezog sich eher darauf, dass es schlecht ist 10ms oder ähnlich im Interrupt zu stehen. Andi Ü. schrieb: > Sebastian B. schrieb: >> Und wenn der Regelalgorithmus nicht zwischen den Timer-Interrupts in der >> Hauptschleife berechnet werden kann? Sprich, der Hauptschleifendurchlauf >> zu lange dauert. > > Dann ist die ALU zu schwach. Oder was ist denn noch alles in der > Hauptschleife? Jetzt kommen wir vom Thema ab. Natürlich ist der ALU stark genug, die Annahme war, dass es sich um einen High-End Controller mit 80MHz CPU Clock handelt. In der Hauptschleife werden, wie auch oben geschrieben, ja auch Kommunikation, Display, Tasten, Datenspeicherung, etc. abgehandelt und diese Funktionen haben meist unterschiedliche Durchlaufzeiten, je nachdem wie viel sie zutun haben. Ein hoch dynamischer Regler, muss allerdings zu einer definierten Zeit starten, damit auch Werte zum gewünschten Zeitpunkt vorhanden sind.
Trotzdem glaube ich nicht, dass Du 10ms in der ISR bleiben darfst, ausser Du hättest genügend HW-Puffer für die Kommunikations-Schnittstellen.
StinkyWinky schrieb: > Trotzdem glaube ich nicht, dass Du 10ms in der ISR bleiben darfst, > ausser Du hättest genügend HW-Puffer für die > Kommunikations-Schnittstellen. 10ms war auch nur ein Beispiel, aber genau da sind wir eben beim Thema.
Wie schon geschrieben wurde, wie lange du eine Task blockieren darfst, hängt von der Anwendung ab. Dein Prozessor kann nur eine Sache zur Zeit erledigen, egal, was er gerade auch macht, es muß dafür etwas anderes unterbrechen. Die zu lösende Aufgabe ist es, das so zu machen, daß es die Anforderungen der Anwendung erfüllt. Um beim Beispiel der Kommunikations-Schnittstellen zu bleiben: Irgenwann ist der HW-Puffer voll, dann muss man vor Eintreffen des nächsten Zeichens die Daten abholen, wenn keine verloren gehen dürfen. Das Abholen selber ist aber recht schnell erledigt, es werden da ja nur ein paar Bytes kopiert. Wenn ich jetzt eine sehr wichtige Task (den Regler) habe, die 5ms nach Start Daten liefern muß, und eine Kommnunikationsschnittstelle, die alle 0,01ms Daten liefert, könnte sich das bei sehr großem Kommunikationsaufkommen durch die immer wieder dazwichenfunkenden Datenabholaktionen auf 5,1ms verlängern. Würde das die Regelqualität unzulässig verschlechtern? Wenn ja, bleibt dir nichts anderes übrig, als die Kommunikation während der Reglertask z.B. per Protokoll zu anzuhalten. Und so weiter... Oliver
Sieht so aus als bräuchtest du vier Prioritäten: - Regler-Interrupt - sonstige Interrupts (Tastenentprellung, UART,...) - Regler-Berechnungen - sonstiges (Benutzerinteraktion, Kommunikation,...) Wohl dem, der ein RTOS hat! Ohne RTOS... naja, ein guter Interruptcontroller kann helfen, aber das ist ja das gleiche wie ein RTOS, nur in Hardware. Wenn die "sonstigen" Aufgaben überschaubar sind, kann man sie mittels Zustandsmaschinen in Teilaufgaben mit begrenzter Rechenzeit zerlegen, so daß die Hauptschleife garantiert schnell genug ist. Aber schon die Bezeichnung "sonstiges" deutet ja auf einen Mangel an Übersicht hin... Dann bleibt noch, die Regler-Berechnungen in Teilaufgaben zu zerlegen, die dann im Interrupt stattfinden dürfen. Angenommen der Regler läuft alle 100ms und braucht 10ms Rechenzeit, der UART-Interrupt darf aber maximal 2ms verzögert werden, weil sonst die FIFO überläuft. Dann zerlegt man die Berechnungen in Teile zu je max. 1ms, die in einzelnen Timer-Interrupts, z.B. alle 5ms aufgerufen werden. Dann ist die Gesamtberechnung immer noch rechtzeitig fertig, findet im Interrupt (und damit mit höchster Priorität) statt, und läßt trotzdem noch eine hinreichend schnelle Reaktion der anderen Interrupts zu.
Hallo Allerseits! Das ist wirklich ein sehr interessantes Thema mit ich mich selbst sehr gern beschäftige. Vielleicht helfen die folgenden Stickworte bei einer Google-Suche weter: Single-Rate Multi-Rate/Single-Task Multi-Rate/Multi-Task. Viel Spaß beim Lesen! Gruß Martin
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.