Forum: Compiler & IDEs PID & Overflow ?


von FrageMan (Gast)


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!

von Gerhard M. (ggcode)


Lesenswert?

if(i > x) i = x

von FrageMan (Gast)


Lesenswert?

beim Überlauf kann man das nicht anwenden!

von Gerhard M. (ggcode)


Lesenswert?

why?

von Gerhard M. (ggcode)


Lesenswert?

if (sixi > 255)           // Begrenzung I-Anteil
      sixi = 255;

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


sixi --> signed integer 16Bit

von Peter Diener (Gast)


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

von Matthias L. (Gast)


Lesenswert?

>Man sollte besser das Overflowflag der ALU der CPU abfragen.

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

von Peter Diener (Gast)


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:
1
#define SREG    _SFR_IO8(0x3F)
2
#define C    0
3
#define Z    1
4
#define N    2
5
#define V    3
6
#define S    4
7
#define H    5
8
#define T    6
9
#define I    7
10
11
if (SREG & (1 << V)) ... //twos complement overflow occured
12
if (SREG & (1 << C)) ... //carry flag has been set

Was man braucht, steht in C und V.


Grüße,

Peter

von Matthias L. (Gast)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


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.

von Matthias L. (Gast)


Lesenswert?

>Sowas macht man nicht!

Aus diesem Grund meine skeptische Frage....

von Peter Diener (Gast)


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

von Peter Diener (Gast)


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

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.