mikrocontroller.net

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


Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:

//****************************************************************************
// @Function      void CC2_vInit(void) 
//
//----------------------------------------------------------------------------
// @Description   This is the initialization function of the CAPCOM2 function 
//                library. It is assumed that the SFRs used by this library 
//                are in its reset state. 
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    None
//
//----------------------------------------------------------------------------
// @Date          21.11.2007
//
//****************************************************************************

// USER CODE BEGIN (Init,1)

// USER CODE END

void CC2_vInit(void)
{
  // USER CODE BEGIN (Init,2)

  // USER CODE END

  ///  -----------------------------------------------------------------------
  ///  Configuration of CAPCOM2 Control:
  ///  -----------------------------------------------------------------------
  ///  - the contents of the port register is changed by the CAPCOM2 unit
  ///  - staggered mode is disabled

  CC2_IOC        =  0x0004;      // load CAPCOM2 I/O control register

  ///  -----------------------------------------------------------------------
  ///  Configuration of CAPCOM2 Timer 7:
  ///  -----------------------------------------------------------------------
  ///  - timer 7 works in timer mode
  ///  - prescaler factor is 1
  ///  - timer 7 run bit is set

  ///  -----------------------------------------------------------------------
  ///  Configuration of CAPCOM2 Timer 8:
  ///  -----------------------------------------------------------------------
  ///  - timer 8 works in timer mode
  ///  - prescaler factor is 1
  ///  - timer 8 run bit is reset


  CC2_T78CON     =  0x0000;      // load CAPCOM2 timer 7 and timer 8 
                                 // control register

  CC2_T7         =  0xFCE0;      // load CAPCOM2 timer 7 register

  CC2_T7REL      =  0xFCE0;      // load CAPCOM2 timer 7 reload register

  CC2_T8         =  0x0000;      // load CAPCOM2 timer 8 register

  CC2_T8REL      =  0x0000;      // load CAPCOM2 timer 8 reload register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Timer Port Pins:
  ///  -----------------------------------------------------------------------


  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Timer Interrupts:
  ///  -----------------------------------------------------------------------
  ///  Tmr7 service request node configuration:
  ///  - Tmr7 interrupt priority level (ILVL) = 10
  ///  - Tmr7 interrupt group level (GLVL) = 1
  ///  - Tmr7 group priority extension (GPX) = 0

  CC2_T7IC       =  0x0069;     



  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 16:
  ///  -----------------------------------------------------------------------
  ///  - channel 16 is disabled

  CC2_CC16       =  0x0000;      // load CAPCOM2 channel 16 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 17:
  ///  -----------------------------------------------------------------------
  ///  - channel 17 is disabled

  CC2_CC17       =  0x0000;      // load CAPCOM2 channel 17 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 18:
  ///  -----------------------------------------------------------------------
  ///  - channel 18 is disabled

  CC2_CC18       =  0x0000;      // load CAPCOM2 channel 18 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 19:
  ///  -----------------------------------------------------------------------
  ///  - channel 19 is disabled

  CC2_CC19       =  0x0000;      // load CAPCOM2 channel 19 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 20:
  ///  -----------------------------------------------------------------------
  ///  - channel 20 is disabled

  CC2_CC20       =  0x0000;      // load CAPCOM2 channel 20 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 21:
  ///  -----------------------------------------------------------------------
  ///  - channel 21 is disabled

  CC2_CC21       =  0x0000;      // load CAPCOM2 channel 21 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 22:
  ///  -----------------------------------------------------------------------
  ///  - channel 22 is disabled

  CC2_CC22       =  0x0000;      // load CAPCOM2 channel 22 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 23:
  ///  -----------------------------------------------------------------------
  ///  - channel 23 is disabled

  CC2_CC23       =  0x0000;      // load CAPCOM2 channel 23 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 24:
  ///  -----------------------------------------------------------------------
  ///  - channel 24 is disabled

  CC2_CC24       =  0x0000;      // load CAPCOM2 channel 24 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 25:
  ///  -----------------------------------------------------------------------
  ///  - channel 25 is disabled

  CC2_CC25       =  0x0000;      // load CAPCOM2 channel 25 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 26:
  ///  -----------------------------------------------------------------------
  ///  - channel 26 is disabled

  CC2_CC26       =  0x0000;      // load CAPCOM2 channel 26 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 27:
  ///  -----------------------------------------------------------------------
  ///  - channel 27 is disabled

  CC2_CC27       =  0x0000;      // load CAPCOM2 channel 27 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 28:
  ///  -----------------------------------------------------------------------
  ///  - compare mode 2:  interrupt only
  ///  - CC28 allocated to CAPCOM2 timer 7
  ///  - single event mode is disabled


  CC2_CC28       =  0xFF00;      // load CAPCOM2 channel 28 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 29:
  ///  -----------------------------------------------------------------------
  ///  - channel 29 is disabled

  CC2_CC29       =  0x0000;      // load CAPCOM2 channel 29 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 30:
  ///  -----------------------------------------------------------------------
  ///  - compare mode 2:  interrupt only
  ///  - CC30 allocated to CAPCOM2 timer 7
  ///  - single event mode is disabled


  CC2_CC30       =  0xFE00;      // load CAPCOM2 channel 30 register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel 31:
  ///  -----------------------------------------------------------------------
  ///  - channel 31 is disabled

  CC2_CC31       =  0x0000;      // load CAPCOM2 channel 31 register

  CC2_M4         =  0x0000;      // load CAPCOM2 mode register 4
  CC2_M5         =  0x0000;      // load CAPCOM2 mode register 5
  CC2_M6         =  0x0000;      // load CAPCOM2 mode register 6
  CC2_M7         =  0x0606;      // load CAPCOM2 mode register 7

  CC2_DRM        =  0x0000;      // load CAPCOM2 double-register mode register

  CC2_SEM        =  0x0000;      // load CAPCOM2 single event mode register

  CC2_SEE        =  0x0000;      // load CAPCOM2 single event enable register

  CC2_OUT        =  0x0000;      // load CAPCOM2 compare output register

  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channel Port Pins:
  ///  -----------------------------------------------------------------------


  ///  -----------------------------------------------------------------------
  ///  Configuration of the used CAPCOM2 Channels Interrupts:
  ///  -----------------------------------------------------------------------
  ///  CC28 service request node configuration:
  ///  - CC28 interrupt priority level (ILVL) = 10
  ///  - CC28 interrupt group level (GLVL) = 2
  ///  - CC28 group priority extension (GPX) = 0

  CC2_CC28IC     =  0x006A;     


  ///  CC30 service request node configuration:
  ///  - CC30 interrupt priority level (ILVL) = 10
  ///  - CC30 interrupt group level (GLVL) = 3
  ///  - CC30 group priority extension (GPX) = 0

  CC2_CC30IC     =  0x006B;     



  CC2_T78CON_T7R    = 1;    // set CAPCOM2 timer 7 run bit

  // USER CODE BEGIN (Init,3)

  // USER CODE END

} //  End of function CC2_vInit


//****************************************************************************
// @Function      void CC2_viTmr7(void) 
//
//----------------------------------------------------------------------------
// @Description   This is the interrupt service routine for the CAPCOM2 timer 
//                7. It is called when overflow of the timer 7 register 
//                occurs.
//                Please note that you have to add application specific code 
//                to this function.
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    None
//
//----------------------------------------------------------------------------
// @Date          21.11.2007
//
//****************************************************************************

// USER CODE BEGIN (Tmr7,1)

// USER CODE END

void CC2_viTmr7(void) interrupt CC2_T7INT using RB_LEVEL10
{
  // USER CODE BEGIN (Tmr7,2)
  P7_P4=0;
  P7_P5=1;
  P7_P6=0;
  P7_P7=1;
  // USER CODE END

} //  End of function CC2_viTmr7


//****************************************************************************
// @Function      void CC2_viCC28(void) 
//
//----------------------------------------------------------------------------
// @Description   This is the interrupt service routine for the CAPCOM2 
//                register CC28. If the content of the corresponding compare 
//                timer (configurable) equals the content of the 
//                capture/compare register CC28 or if a capture event occurs 
//                at the associated port pin, the interrupt request flag is 
//                set and an interrupt is triggered (only if enabled).
//                Please note that you have to add application specific code 
//                to this function.
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    None
//
//----------------------------------------------------------------------------
// @Date          21.11.2007
//
//****************************************************************************

// USER CODE BEGIN (CC28,1)

// USER CODE END

void CC2_viCC28(void) interrupt CC2_CC28INT using RB_LEVEL10
{
  // USER CODE BEGIN (CC28,2)
  P7_P4=1;
  P7_P5=0;

  // USER CODE END

} //  End of function CC2_viCC28


//****************************************************************************
// @Function      void CC2_viCC30(void) 
//
//----------------------------------------------------------------------------
// @Description   This is the interrupt service routine for the CAPCOM2 
//                register CC30. If the content of the corresponding compare 
//                timer (configurable) equals the content of the 
//                capture/compare register CC30 or if a capture event occurs 
//                at the associated port pin, the interrupt request flag is 
//                set and an interrupt is triggered (only if enabled).
//                Please note that you have to add application specific code 
//                to this function.
//
//----------------------------------------------------------------------------
// @Returnvalue   None
//
//----------------------------------------------------------------------------
// @Parameters    None
//
//----------------------------------------------------------------------------
// @Date          21.11.2007
//
//****************************************************************************

// USER CODE BEGIN (CC30,1)

// USER CODE END

void CC2_viCC30(void) interrupt CC2_CC30INT using RB_LEVEL10
{
  // USER CODE BEGIN (CC30,2)
  P7_P6=1;
  P7_P7=0;

  // USER CODE END

} //  End of function CC2_viCC30




// USER CODE BEGIN (CC2_General,10)

// USER CODE END



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

Autor: sechsminuszwei (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kartoffel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-(

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: JÜrgen Grieshofer (Firma: 4CKnowLedge) (psicom) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: JÜrgen Grieshofer (Firma: 4CKnowLedge) (psicom) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.