PI-Regler für GS-Motor

Gast #724667
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
#724776
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
Gast #724791
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.....
Gast #724795
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.
Gast #724824
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?
#724877
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
Gast #724943
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 :-(
#725274
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
(Firma: 4CKnowLedge) Persönliche Seite #725302
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren