Forum: Mikrocontroller und Digitale Elektronik Regelalgorithmus in Mikrocontrollern


von Sebastian B. (m0nkey)


Lesenswert?

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

von Dominik R. (domy)


Lesenswert?

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!

von Martin (Gast)


Lesenswert?

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.

von Sebastian B. (m0nkey)


Lesenswert?

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?

von Ralf (Gast)


Lesenswert?

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

von Udo S. (urschmitt)


Lesenswert?

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.

von Sebastian B. (m0nkey)


Lesenswert?

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

von Udo S. (urschmitt)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

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

von Martin (Gast)


Lesenswert?

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

von Oliver (Gast)


Lesenswert?

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

von Sebastian B. (m0nkey)


Lesenswert?

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.

von Andi Ü. (and0riz0r)


Lesenswert?

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?

von Purzel H. (hacky)


Lesenswert?

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.

von Andi Ü. (and0riz0r)


Lesenswert?

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?

von Sebastian B. (m0nkey)


Lesenswert?

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.

von StinkyWinky (Gast)


Lesenswert?

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.

von Sebastian B. (m0nkey)


Lesenswert?

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.

von Oliver (Gast)


Lesenswert?

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

von Nosnibor (Gast)


Lesenswert?

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.

von Martin (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.