www.mikrocontroller.net

Forum: Compiler & IDEs PID & Overflow ?


Autor: FrageMan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

sollte man bei PID-Regler die Zwischenergebnisse auf Overflow prüfen?

z.B. ist der I-Anteil:

i = iAlt + Regelabweichung;
iAlt = i;

Und da kann die i Variable schnell in Überlauf bzw. Unterlauf kommen.
Wie managet ihr das?

Vielleich hat jemand ein PID-Regler-Code in C zeigen? Wäre echt lieb..

Danke!

Autor: Gerhard M. (ggcode)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if(i > x) i = x

Autor: FrageMan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
beim Überlauf kann man das nicht anwenden!

Autor: Gerhard M. (ggcode)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
why?

Autor: Gerhard M. (ggcode)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (sixi > 255)           // Begrenzung I-Anteil
      sixi = 255;

   if (sixi < -255)
      sixi = -255;


sixi --> signed integer 16Bit

Autor: Peter Diener (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wenn die Varieble bei einer Addition überläuft, wird sie nicht mehr 
größer sein als ein Grenzwert, sondern eventuell sogar negativ. Man 
sollte besser das Overflowflag der ALU der CPU abfragen. Dort wird ein 
Overflow festgehalten. Wenn das passiert ist, kann man den Maximalwert 
der Variable setzen.

Grüße,

Peter

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Man sollte besser das Overflowflag der ALU der CPU abfragen.

Aha...
Und wie geht das in C ........??

Autor: Peter Diener (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo  Matthias,

in C geht das genauso, wie in Assembler. Normalerweise steht das 
Overflow Bit im Satusregister der CPU. Man kann mit C genauso auf alle 
Register der CPU zugreifen wie mit Assembler, so auch auf das 
Statusregister. Dort muss man dann nur noch prüfen, ob das OF Bit 
gesetzt ist. Man nenne mir den Controllertyp und ich zeig dir, wie das 
geht.

Es kann sein, dass im Headerfile des Comlipers nicht definiert ist, wo 
das Statusregister liegt, das ist aber mit einer kleinen Definition 
erledigt. Dann kann man mit C darauf zugreifen.

Beim AVR (Beispiel AtMega16) etwa so:
#define SREG    _SFR_IO8(0x3F)
#define C    0
#define Z    1
#define N    2
#define V    3
#define S    4
#define H    5
#define T    6
#define I    7

if (SREG & (1 << V)) ... //twos complement overflow occured
if (SREG & (1 << C)) ... //carry flag has been set


Was man braucht, steht in C und V.


Grüße,

Peter

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist mir soweit bekannt, war mir nur nicht sicher, dass das in der 
Hochsprache C auch korrekt funktioniert...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas macht man nicht!
Es kann funktionieren, muss aber nicht, da der Compiler Codeblöcke 
umsortieren kann und somit die Abfrage möglicherweise keinen Sinn mehr 
ergibt, da sie an einer falschen Stelle ausgeführt wird.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Sowas macht man nicht!

Aus diesem Grund meine skeptische Frage....

Autor: Peter Diener (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

man muss sich auf jeden Fall nachher den Assemblercode davon ansehen. 
Wenn der Compiler das nicht so umsetzt, dass es funktioniert, muss man - 
ansonsten rate ich dazu, dass man - sowohl die Addition als auch die 
Overflowabfrage in Inlineassembler hinschreibt.

Aber prinzipiell lassen sich die Satusbits auch in C abfragen und in der 
Regel wird der Compiler auch die Reihenfolge nicht vertauschen.

Dennoch besteht die Gefahr, dass eine Optimierung dafür sorgt, dass das 
nicht mehr geht. Wobei ein guter Compiler auch erkennt, dass die 
Statusflags der letzten Operation abgefragt werden und deshalb die 
Reihenfolge nicht getauscht werden dürfen. Davon kann man beim gcc aber 
nicht ausgehen.


Peter

Autor: Peter Diener (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eleganter geht es in C, also ohne sich die Mühe machen zu müssen, den 
Code nachher zu prüfen, wenn man als i und iAlt 16 bit Werte nimmt und 
als Regelabweichung 8 bit Werte. Dann hat man dafür gesorgt, dass 
maximal 128 als Regelfehler auftreten kann. So kann man Grenzwerte von i 
angeben, ab denen man abschneidet, bei denen sicher noch kein Überlauf 
passiert.

i = iAlt + Regelabweichung;

if ((i < 32639) && (i > -32639))
  iAlt = i;
else
  i = iAlt;

Wenn man aber darauf angewiesen ist, dass i und Regelabweichung vom 
gleichen Typ sind, sollte man tatsächlich den Overflow der ALU 
auswerten, andernfalls wird die Berechnung, ob ein Überlauf auftreten 
wird, recht aufwendig.

Man müsste dazu erst ausrechnen, wieviel Platz noch in i nach oben und 
unten ist bis zum Überlauf und dann abfragen, ob die Regelabweichung 
größer ist, als dieser Wert. Das ganze mit Fallunterscheidung für 
positive und negative Werte.

Auf DSPs hat man dieses Problem im Übrigen meist nicht, denn die meisten 
können saturiert addieren, d.h. das Register läuft nicht über, sondern 
wird nur auf den Maximalwert gesetzt, wenn man zu viel draufaddiert.

Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.