Forum: Mikrocontroller und Digitale Elektronik Stellgröße bei P-Regler


von Kartoffel (Gast)


Lesenswert?

Hallo Leute,

ich programmier immer noch an meinem PI-Regler für nen GS-Motor. Hab vor 
ner Zeit meinen Regelalgorithmus hier reingestellt gehabt. Jetzt bin ich 
der Meinung, dass der falsch war.
Hab mir gedacht, dass ich es am Anfang mir P-Regler versuche, den Kp 
herausfinde und dann den I-Anteil dazu tue.
Ich regel die GEschwindigkeit mittels PWM (µC ist ein XC167).
Die Breite des PWM wird mit einem Register der Capcom eingestellt. Da 
sich der Motor in beide Richtungen dreht, hab ich bei
CC2 = 65135 (FE6F) eine Geschwindigkeit von 0 U/min
und bei
CC2 = 65535 (FFFF) die max. Geschwindigkeit von 3000 U/min.

Die Stellgröße wird so berechnet :  y = Kp*e, wobei e = Sollgeschw.- 
Istgeschw. ist.

Mein Problem ist, dass ich nicht drauf komme, wie ich die Stellgröße 
dann auf diesen Registerwert umrechne.

Also die aktuelle Geschwindigkeit ist der aktuelle Registerwert von CC2.
Wenn e = 0 ist, dann ist auch y=0, dann brauch ich zum aktuellen Wert 
von CC2 nichts dazu zählen, wenn nicht....wie mach ich es dann?

von Matthias L. (Gast)


Lesenswert?

>CC2 = 65135 (FE6F) ....0 U/min
>und bei
>CC2 = 65535 (FFFF) ... 3000 U/min.


Halte ich für eine sehr schlechte Skalierung...

von Dipl. Ing. (depr.) (Gast)


Lesenswert?

Auch wenn es nicht direkt Deine Frage betrifft möchte ich Dich darauf 
hinweisen, dass das empirische ermitteln von Regelparametern in den 
meisten Fällen sehr aufwendig, bis geradezu unmöglich ist. In der Regel 
nimmt man eine Sprungantwort vom System auf und kann dann schon recht 
einfach die Regelparameter nach Chien/Hrones/Reswick bestimmen. Evtl. 
muß man dann die einzelnen Werte noch leicht korrigieren.

http://www.roboternetz.de/wissen/index.php/Regelungstechnik

Ziemlich in der Mitte "Dimensionierung nach Einstellregeln"

Die Parameter für einen GS-Motor lassen sich so eigentlich recht einfach 
herausfinden.

von Kartoffel (Gast)


Lesenswert?

also ich möchte das schon auch mit der Sprungantwort des Systems 
bestimmen.
Dafür muss der Regler aber erst mal regeln :-(
Das macht er leider nicht. Dann wollte ich mir die Istgeschwindigkeit 
aufzeichnen  und anschauen, ob sie der Sollgeschwindigkeit folgt oder 
wie das Verhältnis ist.

von Karl H. (kbuchegg)


Lesenswert?

Kartoffel wrote:

> Also die aktuelle Geschwindigkeit ist der aktuelle Registerwert von CC2.
> Wenn e = 0 ist, dann ist auch y=0, dann brauch ich zum aktuellen Wert
> von CC2 nichts dazu zählen,

Du brauchst zu CC2 nichts dazuzählen. Dein y ist schon der Wert für
CC2 (mit einer ev. Umrechnung)

Das hat mich am Anfang auch verwirrt. Der springende Punkt ist:
Dein e wird nie 0! Ein P-Regler alleine schafft es nicht den
Istwert auf den Sollwert einzustellen. Es wird immer eine
Regelabweichung e <> 0 geben, die sich so einpendelt, dass der
Istwert immer den gleichen Abstand vom Sollwert hat. Den Rest
macht dann der I-Regler.

von Kartoffel (Gast)


Lesenswert?

@  Karl heinz Buchegger:

also ich habe wirklich keine Ahnung, wie ich die Stellgröße auf den 
Registerwert umrechnen kann.

Sagen wir mal der Motor dreht sich mit der Geschwindigkeit von 500 
U/min. Dies entspricht einem Registerwert von  CC2 = 65201 (FEB1).
Beim Anlaufen hab ich die Istgeschwindigkeit = 0 U/min.

y = Kp*e, also sagen wir mal 10*500 = 5000. Und weiter?

von Karl H. (kbuchegg)


Lesenswert?

Kartoffel wrote:
> @  Karl heinz Buchegger:
>
> also ich habe wirklich keine Ahnung, wie ich die Stellgröße auf den
> Registerwert umrechnen kann.
>
> Sagen wir mal der Motor dreht sich mit der Geschwindigkeit von 500
> U/min. Dies entspricht einem Registerwert von  CC2 = 65201 (FEB1).
> Beim Anlaufen hab ich die Istgeschwindigkeit = 0 U/min.
>
> y = Kp*e, also sagen wir mal 10*500 = 5000. Und weiter?

Das schreibst du ins CC2 rein. (vorher noch 65135 addieren,
weil ja dort dein 0 ist)

Beim nächsten Durchlauf durch die Regelschleife ermittelst du
den Istwert, durch Subtraktion vom Sollwert das e, multiplizierst
mit Kp und das ergibt den nächsten Wert für CC2 (+ 65135)

Und so geht das immer rundum.

Dadurch, dass dein e am Anfang gross ist, wird CC2 am Anfang
gross sein. Dein Motor beschleunigt. Dadurch wird das e im Lauf
der Zeit kleiner und kleiner, bis sich irgendwann ein Gleichgewicht
einstellt, sodass der Motor bei einem bestimmten e eine konstante
Drehzahl (die nicht notwendigerweise 500 beträgt) hält.

Trenn dich von der Vorstellung, dass du mit einem P-Regler eine
bestimmte Drehzahl einstellen kannst! Ein P-Regler stellt die
Stellgröße so ein, dass der e-Wert konstant bleibt, was auch immer
das für die Istgröße bedeutet.
Wird die Stellgröße größer, dann pendelt der P-Regler sich auf ein
neues Gleichgewicht ein und umgekehrt.
Der P-Regler ist nur dafür verantwortlich, dass die Istgröße der
Sollgröße nachgeführt wird. Er gleicht sie aber nicht auf eine
Differenz von 0 aus! Das macht erst der I-Regler.

von Kartoffel (Gast)


Lesenswert?

@  Karl heinz Buchegger

hmm, mein CC2 kann aber max. 65535 werden, wenn ich zu 65135 5000 dazu 
addier, bin ich weit drüber. Begrenzen?

von Helmut L. (helmi1)


Lesenswert?

Wert ausrechnen

y = Kp * e;

Begrenzen auf 400

if (y > 400) y = 400;

+ dein offset von 65135 fuer deine 0 U/min

CC2 = 65135 + y

Versuch das mal .

Gruss Helmi

von Karl H. (kbuchegg)


Lesenswert?

Kartoffel wrote:
> @  Karl heinz Buchegger
>
> hmm, mein CC2 kann aber max. 65535 werden, wenn ich zu 65135 5000 dazu
> addier, bin ich weit drüber. Begrenzen?

Oh Mann.
Dann wird wohl ein Kp von 10 etwas zu viel sein oder du begrenzt
den Wert oder ...

Das sind doch alles keine Dogmen! Sei kreativ!

von Kartoffel (Gast)


Angehängte Dateien:

Lesenswert?

Sodala, bin jetzt wieder voll dabei.

Der Code sieht jetzt so aus:
1
//*************************************************************************************
2
//                     Includes
3
//*************************************************************************************
4
5
#include "MAIN.H"
6
#include <REGLER.h>
7
#include <stdio.h>
8
9
10
11
//*************************************************************************************
12
//                    Defines
13
//*************************************************************************************
14
#define MAX 65535    // untere Grenze
15
#define MIN 65135    // obere Grenze
16
17
18
//*************************************************************************************
19
//                    Variablen
20
//*************************************************************************************
21
22
bit Begrenzung;              //Flag signalisiert, wenn Stellgröße in der Begrenzung ist
23
int Pulsbr = 400;
24
extern unsigned int Solldrehzahl; // Drehzahlvorgabe
25
26
27
//*************************************************************************************
28
//                    Prototypen
29
//*************************************************************************************
30
31
//unsigned long int Regeln (unsigned long int Istdrehzahl); // Funktion zum Aufrufen des Reglers
32
33
34
//*************************************************************************************
35
//                     Funktionen
36
//*************************************************************************************
37
extern int PI_Init(void)
38
{         
39
//pi_r.Kp = 18;   // !!!
40
pi_r.Kp = 1;
41
//pi_r.Ki = 60;
42
pi_r.Ki = 0;
43
44
45
//pi_r.Ki = 125;
46
47
Begrenzung=0;
48
pi_r.I_Anteil=0;
49
pi_r.Regelabweichung = 0;
50
51
return 0;
52
}
53
//*************************************************************************************
54
55
unsigned int Regeln (unsigned int Istdrehzahl)
56
{
57
signed  int Stellwert = 0;       // Bereich zwischen -XXXXXX bis +XXXXXX
58
59
  pi_r.Istwert=Istdrehzahl;
60
61
  printf("pi_r.Istwert: %d",pi_r.Istwert);
62
  printf("\n");
63
64
  pi_r.Sollwert=Solldrehzahl;  
65
  pi_r.Regelabweichung = pi_r.Sollwert-pi_r.Istwert;             // e=w-x
66
67
  printf("Regelabweichung: %d",pi_r.Regelabweichung);
68
  printf("\n");
69
70
71
//********************TEST**************************************************************
72
73
Stellwert = pi_r.Kp*pi_r.Regelabweichung; // Stellwert in U/min
74
75
printf("Stellwert: %d",Stellwert);
76
printf("\n");
77
78
  if(Stellwert< 0)      // Begrenzung nach unten, also auf FE6F
79
  {
80
    Stellwert = 0;
81
    Begrenzung = 1;         // Rergler läuft in der Begrenzung
82
 
83
  } 
84
85
  else if(Stellwert> 400)    // Begrenzung nach oben, also auf FFFF
86
  {  
87
    Stellwert =400;
88
    Begrenzung = 1;            // Regler läuft in der Begrenzung
89
  }
90
91
printf("Stellwert nach Begrenzung: %d",Stellwert);
92
printf("\n");
93
94
pi_r.Stellwert = MIN + Stellwert;
95
96
printf("pi_r.Stellwert: %X",pi_r.Stellwert);
97
printf("\n"); 
98
99
  return pi_r.Stellwert;      // Übergabe Stellgröße
100
}

Bin der MEinung, dass der Code jetzt so passt.
Ich schau mir die Werte dann in einem Textfile an. Hab ich angehängt.
Es passieren komische Sachen. Der Prozess läuft aber mein Motor dreht 
sich nicht. Ich gebe auch die aktuelle Istdrehzahl aus, die ist nicht 0, 
obwohl der Motor im Stillstand ist!!!!
Wenn ich den Motor dann manuell drehe,dann greht er sich wieder für 2s 
und dann gibt es Sprünge in den Werten (hab ich gekennzeichnet). Die 
nähern sich immer mehr der Solldrehzahl.

Woran kann es liegen?

von Karl H. (kbuchegg)


Lesenswert?

Kartoffel wrote:

> Bin der MEinung, dass der Code jetzt so passt.

Wie kommt der Regler wieder aus der Begrenzung raus?
Also: Wie wird die Variable Begrenzung wieder zu 0?
(Ist nicht wirklich wichtig, da du ja mit der Variablen
momentan weiter nichts machst)

> Es passieren komische Sachen. Der Prozess läuft aber mein Motor dreht
> sich nicht. Ich gebe auch die aktuelle Istdrehzahl aus, die ist nicht 0,
> obwohl der Motor im Stillstand ist!!!!

Da würde ich erst mal ansetzen.
Es gibt ein altes Sprichwort: Garbage in, garbage out.

Soll in diesem Fall heissen: Wenn deine Istdrehzahl schon nicht
mit der Realität übereinstimmt, dann wird wohl ein Regler so
seine Schwierigkeiten haben, die in irgendeiner Form zu regeln.

von Kartoffel (Gast)


Lesenswert?

@ Karl heinz Buchegger:
also die Drehzahl, die ich messe, stimmt schon mir der Realität überein, 
aber das nur, wenn ich den Regler nicht aufrufe. Hab es schon überprüft.

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

Kartoffel wrote:
> @ Karl heinz Buchegger:
> also die Drehzahl, die ich messe, stimmt schon mir der Realität überein,
> aber das nur, wenn ich den Regler nicht aufrufe.

Dann wirst du wohl einen Programmfehler bei der Messung haben.

Wenn ich mir deine Werte mal umformatiere, so dass man da auch
was sehen kann (Tip: sowas kann dein Erzeugerprogramm auch
selbst machen, dann hat man im Nachhinein weniger Arbeit), dann
kann ich die Werte nicht glauben:

Istwert  Abw.  Stell  Begrenzt  Stell  CC2_CC30
 0       500    500    400       FFFF FFFF
 0       500    500    400       FFFF FFFF
1795   -1295  -1295      0       FE6F FE6F
2805   -2305  -2305      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F

Nach den ersten beiden Regelzyklen beschleunigt dein Motor, ist
auch richtig so. Aber er beschleunigt innerhalb von 2 Zyklen
von 0 auf 2000 U/min! Danach wird ihm der Strom abgedreht, aber
der Motor wird nicht langsamer?

Nach einigen Zyklen passiert dann folgendes:

2095   -1595  -1595      0       FE6F FE6F
2095   -1595  -1595      0       FE6F FE6F
1356    -856   -856      0       FE6F FE6F
1356    -856   -856      0       FE6F FE6F

Die Drehzahl sackt urplötzlich auf rund die Hälfte ein.

Das riecht doch förmlich danach, dass die Messung der
Istdrehzahl nicht stimmen kann!

von Kartoffel (Gast)


Lesenswert?

also ich denke, dass es an den Interrupts liegt.
der Regler ruft die Fkt. zur Drehzahlbestimmung auf. Die 
Drehzahlbestimmung wird auch über ein Int. realisiert und zwar, wird bei 
jeder pos. Flanke des Encoders ein Int. generiert und die Drehzahl 
bestimmt. Ich denke mal, dass sich das irngedwie überschneidet und es 
nicht mehr zur Drehzahlbestimmung kommt, daher auch der alte Wert, der 
konstant bleibt (2095). Zur Wertänderung kommt es, weil ich ja manuell 
am Motor gedreht hab, dann gibt es auch ne Flanke und nen Interrupt und 
ne richtige Drehzahl.
Also hab ich mich mit den vielen Interrupts in den Wald programmiert:-( 
Kenn mich gar nicht mehr aus..
Auf jeden Fall stimmt die Drehzahlberechnung schon, hab das mit einem 
Drehzahlmesser überprüft: der Wert, der angezeigt wird stimmt mit dem 
gemessenen überein!!!

von Kartoffel (Gast)


Lesenswert?

mal ne andere Frage:

es ist ja jetzt so, dass ich, sobald die Drehzahl 0 ist, was am Anfang 
beim Einregeln oft der Fall ist wegen Begrenzung, die aktuelle Drehzahl 
nicht mehr ermitteln kann. Die Ermittlung erfolgt über ein Interrupt, 
der bei einer pos. Flanke des Encoders ausgelöst wird. Wenn sich auch 
kurzzeitig nichts mehr dreht, gibt es auch keinen Interrupt.
Kann ich das irgedwie umgehen? So dass die Drehzahlermittlung doch statt 
findet?

von Kartoffel (Gast)


Lesenswert?

@ Karl heinz Buchegger:
<Trenn dich von der Vorstellung, dass du mit einem P-Regler eine
bestimmte Drehzahl einstellen kannst! Ein P-Regler stellt die
Stellgröße so ein, dass der e-Wert konstant bleibt, was auch immer
das für die Istgröße bedeutet.>

Kann es auch sein, dass ich bei V_soll von 1000 nur eine V von 520 
erreiche?
Diese Geschwindigkeit stellt sich schon ein und bleibt konstant, aber 
der Unterschied ist schon erheblich......daher meine Bedenken...

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.