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?
>CC2 = 65135 (FE6F) ....0 U/min >und bei >CC2 = 65535 (FFFF) ... 3000 U/min. Halte ich für eine sehr schlechte Skalierung...
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.
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.
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.
@ 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?
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.
@ Karl heinz Buchegger hmm, mein CC2 kann aber max. 65535 werden, wenn ich zu 65135 5000 dazu addier, bin ich weit drüber. Begrenzen?
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
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!
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?
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.
@ 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.
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!
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!!!
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?
@ 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.