Forum: Mikrocontroller und Digitale Elektronik PI-Regler für GS-Motor


von Kartoffel (Gast)


Lesenswert?

Hi Leute,
also ich bin grad dabei, einen PI Regler zu programmieren.
Möchte nämlich die Geschwindigkeit regeln, die aktuelle Drehzahl lässt 
sich nicht ohne eure Hilfe schon sehr gut bestimmen.
Also wie der Regler funktioniert, weiß ich, hab aber bezüglich 
Realisierung noch ein paar Fragen und zwar:
1) Begrenzung der Stellgröße:
Die Stellgröße ist ja der Reglerausgang und Regelstrecke-Eingang.
Stimmt es, dass die die maximale Geschwindigkeit meines Motors 
darstellt?
Also wenn ich max. Drehzahl von 3000 hab, muss die Stellgröße einfach 
auf
int-Wert 3000 begrenzen?
2) Was ist mit dem Windup? Das ist doch dafür da, damit mir mein 
I-Anteil nicth abhaut, oder? Wie begrenze ich denn den I-Anteil?
3) Offset beim P-Anteil, brauch ich den?

txs

von Michael K. (mmike)


Lesenswert?

Kartoffel wrote:
> Hi Leute,
> also ich bin grad dabei, einen PI Regler zu programmieren.
> Möchte nämlich die Geschwindigkeit regeln, die aktuelle Drehzahl lässt
> sich nicht ohne eure Hilfe schon sehr gut bestimmen.
> Also wie der Regler funktioniert, weiß ich, hab aber bezüglich
> Realisierung noch ein paar Fragen und zwar:
> 1) Begrenzung der Stellgröße:
> Die Stellgröße ist ja der Reglerausgang und Regelstrecke-Eingang.

jep.

> Stimmt es, dass die die maximale Geschwindigkeit meines Motors
> darstellt?

Kommt drauf an was Deine Steuergröße und Deine Regelgröße ist ! Ich 
denke mal die Drehzahl soll geregelt werden, dann ist die Eingangsgröße 
bespielsweise das PWM Tastverhältnis.

> Also wenn ich max. Drehzahl von 3000 hab, muss die Stellgröße einfach
> auf
> int-Wert 3000 begrenzen?

s.o.

> 2) Was ist mit dem Windup? Das ist doch dafür da, damit mir mein
> I-Anteil nicth abhaut, oder? Wie begrenze ich denn den I-Anteil?

jep. Schalte die "Integration" einfach in Bereichen ab, die weit von der 
Sollgröße weg sind (denn da ist der P - Anteil schon groß genug, 
Beispiel: Aktuelle Drehzahl 1000 U/min .... neuer Sollwert: 2500 U/min 
... Die Integration darf aber erst "loslegen", wenn der Absolutbetrag 
von (Soll - Ist) eine bestimmten Wert unterschreitet. Z.B. 500)

> 3) Offset beim P-Anteil, brauch ich den?

Mir ist nicht ganz klar, was Du mit Offset meinst, aber normalerweise 
macht der integrelle Anteil ja den stationären Regelfehler weg ...

> txs


Grüße,

Michael

von Kartoffel (Gast)


Lesenswert?

Also meine Regelstrecke ist ein Motor mit einem Encoder. Der Motor wird 
mittels PWM angetrieben, PWM erzeuge ich selbst, ich poste einfach 
meinen Code:
1
//****************************************************************************
2
// @Function      void CC2_vInit(void) 
3
//
4
//----------------------------------------------------------------------------
5
// @Description   This is the initialization function of the CAPCOM2 function 
6
//                library. It is assumed that the SFRs used by this library 
7
//                are in its reset state. 
8
//
9
//----------------------------------------------------------------------------
10
// @Returnvalue   None
11
//
12
//----------------------------------------------------------------------------
13
// @Parameters    None
14
//
15
//----------------------------------------------------------------------------
16
// @Date          21.11.2007
17
//
18
//****************************************************************************
19
20
// USER CODE BEGIN (Init,1)
21
22
// USER CODE END
23
24
void CC2_vInit(void)
25
{
26
  // USER CODE BEGIN (Init,2)
27
28
  // USER CODE END
29
30
  ///  -----------------------------------------------------------------------
31
  ///  Configuration of CAPCOM2 Control:
32
  ///  -----------------------------------------------------------------------
33
  ///  - the contents of the port register is changed by the CAPCOM2 unit
34
  ///  - staggered mode is disabled
35
36
  CC2_IOC        =  0x0004;      // load CAPCOM2 I/O control register
37
38
  ///  -----------------------------------------------------------------------
39
  ///  Configuration of CAPCOM2 Timer 7:
40
  ///  -----------------------------------------------------------------------
41
  ///  - timer 7 works in timer mode
42
  ///  - prescaler factor is 1
43
  ///  - timer 7 run bit is set
44
45
  ///  -----------------------------------------------------------------------
46
  ///  Configuration of CAPCOM2 Timer 8:
47
  ///  -----------------------------------------------------------------------
48
  ///  - timer 8 works in timer mode
49
  ///  - prescaler factor is 1
50
  ///  - timer 8 run bit is reset
51
52
53
  CC2_T78CON     =  0x0000;      // load CAPCOM2 timer 7 and timer 8 
54
                                 // control register
55
56
  CC2_T7         =  0xFCE0;      // load CAPCOM2 timer 7 register
57
58
  CC2_T7REL      =  0xFCE0;      // load CAPCOM2 timer 7 reload register
59
60
  CC2_T8         =  0x0000;      // load CAPCOM2 timer 8 register
61
62
  CC2_T8REL      =  0x0000;      // load CAPCOM2 timer 8 reload register
63
64
  ///  -----------------------------------------------------------------------
65
  ///  Configuration of the used CAPCOM2 Timer Port Pins:
66
  ///  -----------------------------------------------------------------------
67
68
69
  ///  -----------------------------------------------------------------------
70
  ///  Configuration of the used CAPCOM2 Timer Interrupts:
71
  ///  -----------------------------------------------------------------------
72
  ///  Tmr7 service request node configuration:
73
  ///  - Tmr7 interrupt priority level (ILVL) = 10
74
  ///  - Tmr7 interrupt group level (GLVL) = 1
75
  ///  - Tmr7 group priority extension (GPX) = 0
76
77
  CC2_T7IC       =  0x0069;     
78
79
80
81
  ///  -----------------------------------------------------------------------
82
  ///  Configuration of the used CAPCOM2 Channel 16:
83
  ///  -----------------------------------------------------------------------
84
  ///  - channel 16 is disabled
85
86
  CC2_CC16       =  0x0000;      // load CAPCOM2 channel 16 register
87
88
  ///  -----------------------------------------------------------------------
89
  ///  Configuration of the used CAPCOM2 Channel 17:
90
  ///  -----------------------------------------------------------------------
91
  ///  - channel 17 is disabled
92
93
  CC2_CC17       =  0x0000;      // load CAPCOM2 channel 17 register
94
95
  ///  -----------------------------------------------------------------------
96
  ///  Configuration of the used CAPCOM2 Channel 18:
97
  ///  -----------------------------------------------------------------------
98
  ///  - channel 18 is disabled
99
100
  CC2_CC18       =  0x0000;      // load CAPCOM2 channel 18 register
101
102
  ///  -----------------------------------------------------------------------
103
  ///  Configuration of the used CAPCOM2 Channel 19:
104
  ///  -----------------------------------------------------------------------
105
  ///  - channel 19 is disabled
106
107
  CC2_CC19       =  0x0000;      // load CAPCOM2 channel 19 register
108
109
  ///  -----------------------------------------------------------------------
110
  ///  Configuration of the used CAPCOM2 Channel 20:
111
  ///  -----------------------------------------------------------------------
112
  ///  - channel 20 is disabled
113
114
  CC2_CC20       =  0x0000;      // load CAPCOM2 channel 20 register
115
116
  ///  -----------------------------------------------------------------------
117
  ///  Configuration of the used CAPCOM2 Channel 21:
118
  ///  -----------------------------------------------------------------------
119
  ///  - channel 21 is disabled
120
121
  CC2_CC21       =  0x0000;      // load CAPCOM2 channel 21 register
122
123
  ///  -----------------------------------------------------------------------
124
  ///  Configuration of the used CAPCOM2 Channel 22:
125
  ///  -----------------------------------------------------------------------
126
  ///  - channel 22 is disabled
127
128
  CC2_CC22       =  0x0000;      // load CAPCOM2 channel 22 register
129
130
  ///  -----------------------------------------------------------------------
131
  ///  Configuration of the used CAPCOM2 Channel 23:
132
  ///  -----------------------------------------------------------------------
133
  ///  - channel 23 is disabled
134
135
  CC2_CC23       =  0x0000;      // load CAPCOM2 channel 23 register
136
137
  ///  -----------------------------------------------------------------------
138
  ///  Configuration of the used CAPCOM2 Channel 24:
139
  ///  -----------------------------------------------------------------------
140
  ///  - channel 24 is disabled
141
142
  CC2_CC24       =  0x0000;      // load CAPCOM2 channel 24 register
143
144
  ///  -----------------------------------------------------------------------
145
  ///  Configuration of the used CAPCOM2 Channel 25:
146
  ///  -----------------------------------------------------------------------
147
  ///  - channel 25 is disabled
148
149
  CC2_CC25       =  0x0000;      // load CAPCOM2 channel 25 register
150
151
  ///  -----------------------------------------------------------------------
152
  ///  Configuration of the used CAPCOM2 Channel 26:
153
  ///  -----------------------------------------------------------------------
154
  ///  - channel 26 is disabled
155
156
  CC2_CC26       =  0x0000;      // load CAPCOM2 channel 26 register
157
158
  ///  -----------------------------------------------------------------------
159
  ///  Configuration of the used CAPCOM2 Channel 27:
160
  ///  -----------------------------------------------------------------------
161
  ///  - channel 27 is disabled
162
163
  CC2_CC27       =  0x0000;      // load CAPCOM2 channel 27 register
164
165
  ///  -----------------------------------------------------------------------
166
  ///  Configuration of the used CAPCOM2 Channel 28:
167
  ///  -----------------------------------------------------------------------
168
  ///  - compare mode 2:  interrupt only
169
  ///  - CC28 allocated to CAPCOM2 timer 7
170
  ///  - single event mode is disabled
171
172
173
  CC2_CC28       =  0xFF00;      // load CAPCOM2 channel 28 register
174
175
  ///  -----------------------------------------------------------------------
176
  ///  Configuration of the used CAPCOM2 Channel 29:
177
  ///  -----------------------------------------------------------------------
178
  ///  - channel 29 is disabled
179
180
  CC2_CC29       =  0x0000;      // load CAPCOM2 channel 29 register
181
182
  ///  -----------------------------------------------------------------------
183
  ///  Configuration of the used CAPCOM2 Channel 30:
184
  ///  -----------------------------------------------------------------------
185
  ///  - compare mode 2:  interrupt only
186
  ///  - CC30 allocated to CAPCOM2 timer 7
187
  ///  - single event mode is disabled
188
189
190
  CC2_CC30       =  0xFE00;      // load CAPCOM2 channel 30 register
191
192
  ///  -----------------------------------------------------------------------
193
  ///  Configuration of the used CAPCOM2 Channel 31:
194
  ///  -----------------------------------------------------------------------
195
  ///  - channel 31 is disabled
196
197
  CC2_CC31       =  0x0000;      // load CAPCOM2 channel 31 register
198
199
  CC2_M4         =  0x0000;      // load CAPCOM2 mode register 4
200
  CC2_M5         =  0x0000;      // load CAPCOM2 mode register 5
201
  CC2_M6         =  0x0000;      // load CAPCOM2 mode register 6
202
  CC2_M7         =  0x0606;      // load CAPCOM2 mode register 7
203
204
  CC2_DRM        =  0x0000;      // load CAPCOM2 double-register mode register
205
206
  CC2_SEM        =  0x0000;      // load CAPCOM2 single event mode register
207
208
  CC2_SEE        =  0x0000;      // load CAPCOM2 single event enable register
209
210
  CC2_OUT        =  0x0000;      // load CAPCOM2 compare output register
211
212
  ///  -----------------------------------------------------------------------
213
  ///  Configuration of the used CAPCOM2 Channel Port Pins:
214
  ///  -----------------------------------------------------------------------
215
216
217
  ///  -----------------------------------------------------------------------
218
  ///  Configuration of the used CAPCOM2 Channels Interrupts:
219
  ///  -----------------------------------------------------------------------
220
  ///  CC28 service request node configuration:
221
  ///  - CC28 interrupt priority level (ILVL) = 10
222
  ///  - CC28 interrupt group level (GLVL) = 2
223
  ///  - CC28 group priority extension (GPX) = 0
224
225
  CC2_CC28IC     =  0x006A;     
226
227
228
  ///  CC30 service request node configuration:
229
  ///  - CC30 interrupt priority level (ILVL) = 10
230
  ///  - CC30 interrupt group level (GLVL) = 3
231
  ///  - CC30 group priority extension (GPX) = 0
232
233
  CC2_CC30IC     =  0x006B;     
234
235
236
237
  CC2_T78CON_T7R    = 1;    // set CAPCOM2 timer 7 run bit
238
239
  // USER CODE BEGIN (Init,3)
240
241
  // USER CODE END
242
243
} //  End of function CC2_vInit
244
245
246
//****************************************************************************
247
// @Function      void CC2_viTmr7(void) 
248
//
249
//----------------------------------------------------------------------------
250
// @Description   This is the interrupt service routine for the CAPCOM2 timer 
251
//                7. It is called when overflow of the timer 7 register 
252
//                occurs.
253
//                Please note that you have to add application specific code 
254
//                to this function.
255
//
256
//----------------------------------------------------------------------------
257
// @Returnvalue   None
258
//
259
//----------------------------------------------------------------------------
260
// @Parameters    None
261
//
262
//----------------------------------------------------------------------------
263
// @Date          21.11.2007
264
//
265
//****************************************************************************
266
267
// USER CODE BEGIN (Tmr7,1)
268
269
// USER CODE END
270
271
void CC2_viTmr7(void) interrupt CC2_T7INT using RB_LEVEL10
272
{
273
  // USER CODE BEGIN (Tmr7,2)
274
  P7_P4=0;
275
  P7_P5=1;
276
  P7_P6=0;
277
  P7_P7=1;
278
  // USER CODE END
279
280
} //  End of function CC2_viTmr7
281
282
283
//****************************************************************************
284
// @Function      void CC2_viCC28(void) 
285
//
286
//----------------------------------------------------------------------------
287
// @Description   This is the interrupt service routine for the CAPCOM2 
288
//                register CC28. If the content of the corresponding compare 
289
//                timer (configurable) equals the content of the 
290
//                capture/compare register CC28 or if a capture event occurs 
291
//                at the associated port pin, the interrupt request flag is 
292
//                set and an interrupt is triggered (only if enabled).
293
//                Please note that you have to add application specific code 
294
//                to this function.
295
//
296
//----------------------------------------------------------------------------
297
// @Returnvalue   None
298
//
299
//----------------------------------------------------------------------------
300
// @Parameters    None
301
//
302
//----------------------------------------------------------------------------
303
// @Date          21.11.2007
304
//
305
//****************************************************************************
306
307
// USER CODE BEGIN (CC28,1)
308
309
// USER CODE END
310
311
void CC2_viCC28(void) interrupt CC2_CC28INT using RB_LEVEL10
312
{
313
  // USER CODE BEGIN (CC28,2)
314
  P7_P4=1;
315
  P7_P5=0;
316
317
  // USER CODE END
318
319
} //  End of function CC2_viCC28
320
321
322
//****************************************************************************
323
// @Function      void CC2_viCC30(void) 
324
//
325
//----------------------------------------------------------------------------
326
// @Description   This is the interrupt service routine for the CAPCOM2 
327
//                register CC30. If the content of the corresponding compare 
328
//                timer (configurable) equals the content of the 
329
//                capture/compare register CC30 or if a capture event occurs 
330
//                at the associated port pin, the interrupt request flag is 
331
//                set and an interrupt is triggered (only if enabled).
332
//                Please note that you have to add application specific code 
333
//                to this function.
334
//
335
//----------------------------------------------------------------------------
336
// @Returnvalue   None
337
//
338
//----------------------------------------------------------------------------
339
// @Parameters    None
340
//
341
//----------------------------------------------------------------------------
342
// @Date          21.11.2007
343
//
344
//****************************************************************************
345
346
// USER CODE BEGIN (CC30,1)
347
348
// USER CODE END
349
350
void CC2_viCC30(void) interrupt CC2_CC30INT using RB_LEVEL10
351
{
352
  // USER CODE BEGIN (CC30,2)
353
  P7_P6=1;
354
  P7_P7=0;
355
356
  // USER CODE END
357
358
} //  End of function CC2_viCC30
359
360
361
362
363
// USER CODE BEGIN (CC2_General,10)
364
365
// USER CODE END

Ich versteh irgendwie nicht, was meine Stellgröße in diesem Fall ist und 
wohin ich mit der soll.....

von sechsminuszwei (Gast)


Lesenswert?

Die Stellgroesse ist die Zahl, die ausm Regler kommt und ins Stellglied 
reingeht. Beim PWM-Stellglied ist das demnach die Pulsbreite. Die 
maximale Stelgroesse ist daher die Zahl, bei der der anschlag erreicht 
wird. Das ist bei einem 8Bit PWM 255, bei einem 10bit PWM 1023 usw. Ich 
hab den code nicht angeschaut.

von Kartoffel (Gast)


Lesenswert?

@sechsminuszwei:
also meine Pulsantwort wird so bestimmt:
am Anfang ist das PWM-Signal =1, ein Timer läuft mit. Wenn der Inhalt 
des Timers mit dem Inhalt des Compare-Registers übereinstimmt, setz ich 
PMW auf "0", wenn der Timer abgelaufen ist, wieder auf "1" usw.

Also um die Pulsbreite zu beeinflussen, könnte ich so vorgehen:
Pulsbreite= Registerinhalt des Compare_Registers -Startwert vom Timer
Pulsbreite= Stellgröße
Registerinhalt des Compare_Registers= Stellgröße+Startwert vom Timer

oder?

von Kartoffel (Gast)


Lesenswert?

Ach ja, noch ne andere Frage:
da meine Pulsbreite aus der Differenz zweier 16-Bit REgister berechnet 
wird,heißt es für mich, dass ich die Stellgröße auf 65536 begrenzen 
soll?

von Michael K. (mmike)


Lesenswert?

> Pulsbreite= Stellgröße

Richtig. Da die 16bit hat --> 0 - 65535

Du musst aber noch die Größen umrechnen !!

Du hast die Drehzahl als Regelgröße und die Pulsbreite als Stellgröße.

Da die beiden Wertemässig nicht zusammen passen musst Du vorher ein 
sogenanntes Command - Shaping machen:

Mach einfach mal ein paar Testläufe, mit stationären Zuständen, damit Du 
die Größenordungen ein wenig abschätzen kannst !

z.B.

PWM Tastverhältnis --> Drehzahl
10% (6553) --> 400 U/min
20% (13107) --> 600 U/min
30% (19660) --> 900 U/min
...

Du hast oben geschrieben, daß Deine max. Drehzahl rund 3000 U/min ist. 
Somit sind 0 U/min 0% und 3000U/min 100%. Jetzt musst Du nur noch die 
Prozente anpassen (Command Shaping) und die Reglerparameter tunen.

Regeldifferenz DeltaU = (Soll - Ist)

Stellgröße (PWM Tastverhältnis) = Kp * DeltaU + Ki * Integral (DeltaU)

Das Integral kannst Du entweder als Euler vorwärts, oder auch mit Trapez 
rechnen.

Den Anti - Windup kannst du im ersten Versuch wie folgt machen:

if (DeltaU < Limit)
  Stellgröße (PWM Tastverhältnis) = Kp * DeltaU;
else
  Stellgröße (PWM Tastverhältnis) = Kp * DeltaU + Ki * Integral (DeltaU)

Grüße,
Michael

von Kartoffel (Gast)


Lesenswert?

@(mmike)
Also das PWM-Tastverhältnis ist ja das Verhältnis zwischen pos. und neg. 
Periode. Heißt bei 50% dreht sich der Motor überhaupt nicht, weil der 
Mittelwert =0 ist.
Wieso hab ich dann bei 3000U-> 100%? Versteh ich net.

Wieso ich die Umdrehungen in Prozente umwandeln soll, hab ich auch nicht 
verstanden :-(

von Michael K. (mmike)


Lesenswert?

Kartoffel wrote:
> @(mmike)
> Also das PWM-Tastverhältnis ist ja das Verhältnis zwischen pos. und neg.
> Periode.

Wie positiv und negativ ?

PWM sieht bei mir so aus

  -----       -----       -----
_|     |_____|     |_____|     |___
  HIGH  LOW   HIGH  LOW

HIGH + LOW = Periode
bei 50 % => HIGH = LOW = Periode / 2

> Heißt bei 50% dreht sich der Motor überhaupt nicht, weil der
> Mittelwert =0 ist.

??

> Wieso hab ich dann bei 3000U-> 100%? Versteh ich net.

100% ensprechen Deiner Maximaldrehzahl. 0% ist wenn sich nix dreht! Oder 
läuft das Ding auch rückwärts ?

> Wieso ich die Umdrehungen in Prozente umwandeln soll, hab ich auch nicht
> verstanden :-(

Um die Sachen aneinander anzupassen (Command Shaping). Denn Dein PWM 
geht ja von 0 - 65535 und die Drehzahl sicher nicht von 0 - 65535 
sondern z.B. von 0 - 3000

Grüße,
Michael

von JÜrgen G. (Firma: 4CKnowLedge) (psicom) Benutzerseite


Lesenswert?

Wie ich bisher gelesen habe willst du den Motor nur Drehzahlregeln? 
Welche Last soll er denn treiben können?

Das Problem ist, das die Drehzahl auch mit der Belastung abfällt und du 
daher eine U UND I Regelung machen müsstest, ums ganz genau zu haben...

Aber Last und Zweck wären ganz interessant!

von JÜrgen G. (Firma: 4CKnowLedge) (psicom) Benutzerseite


Lesenswert?

Kartoffel wrote:
> Hi Leute,
> also ich bin grad dabei, einen PI Regler zu programmieren.

Wieso neu erfinden? -> Codesammlung

> 1) Begrenzung der Stellgröße:
> Die Stellgröße ist ja der Reglerausgang und Regelstrecke-Eingang.
> Stimmt es, dass die die maximale Geschwindigkeit meines Motors
> darstellt?

jap, bzw. könntest du den Motor auch bis zu einen gewissen Grad 
"schneller" drehen lassen.

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.