PID Regler nach Ziegler/Nichols

OP #2697292
Lesenswert?
• ▲
▼
Hallo Zusamen!

Ich arbeite mit dem stm32f103vdt6 und dem uvision von Keil.

Ich möchte die Drehzahl eines EC Motors reglen, Hallsensoren.

Ich setze ein PID Regler ein:
1
float speed_curr;                                         
2
float ctrl_out;  
3
float i_term      = 0.0;
4
float e;
5
float ealt;
6
float speed_last  = 0.0;
7
const  float KS     = 0.218;//10.00;
8
const  float Tg     = 0.027;
9
const  float Tu     = 0.006;
10
float Tv            = 0.5 * Tu;
11
float Tn            = Tg;
12
float       Ta      = 0.005; //(1000 / ITVms_MOTSPD_CTRL) / 1000;
13
float       KP      = (0.6 / KS)*(Tg / Tu);
1
void tsk_Motor_speed_ctrl(float speed_cmd)  
2
{
3
  const int   ctrl_out_max  = 4095;
4
  const int   ctrl_out_min  = 0;
5
  static int  errcnt        = 0;          
6
  float       KI            = KP / Tn;
7
  float       KD            = KP / Tv;
8
  
9
  speed_curr = get_Motor_speed(); 
10
  if(get_MotRun())                
11
  {
12
    e = speed_cmd - speed_curr;   
13
    i_term += e;                  
14
    if(i_term > Setup.PIDpar.iMax)
15
      i_term = Setup.PIDpar.iMax; 
16
    if(i_term < Setup.PIDpar.iMin)
17
      i_term = Setup.PIDpar.iMin; 
18
  
19

20
    ctrl_out  = (KP * e) + (KI * Ta * i_term) + (KD / Ta * (e - ealt));
21

22
    if(ctrl_out < ctrl_out_min)     
23
    {
24
      set_MotorEnPinAlwaysOff(true);
25
      ctrl_out = ctrl_out_min;      
26
    }
27
    else
28
    {
29
      set_MotorEnPinAlwaysOff(false);
30
    }
31
    if(ctrl_out > ctrl_out_max)     
32
    {  
33
      ctrl_out = ctrl_out_max;      
34
    }
35

36
    if(speed_curr < 1)              
37
    {
38
      errcnt ++;
39
      if(errcnt >= (1000 / ITVms_MOTSPD_CTRL))
40
      {
41
        Motor_STOP();                         
42
        iStopp = true;                        
43
      }
44
    }
45

46
    speed_last = speed_curr;
47
    ealt = e;
48

49
  }
50
  else
51
  {
52
    ctrl_out = 0;         // reset the DAC value                   
53
    i_term = 0.0;         // reset the deviation of the speed value
54
    errcnt = 0;           // reset the error counterregister       
55
  }
56

57
  DAC_MotI = ctrl_out;  // transfers the motor current value to the DAC   
58
                                                      
59
}

Das KS ergibt sich aus 152/700.
152 ist der Maximale Istwert der Sprungantwort.
700 ist der Maximale Stromwert (digits), den der Regler zulassen kann.

Der Antrieb fährt nicht immer an, sieht jemand noch etwas oder hat 
verbesserungsvorschläge?!

Danke und Gruss!
Gast #2699278
Lesenswert?
• ▲
▼
Hi,

gut wenn du deinen code am laufen hast?
Beim ansehen hätte ich auf den D-Anteil getippt.

>ctrl_out  = (KP * e) + (KI  Ta  i_term) + (KD / Ta * (e - ealt));

Wie ist die bindung der Operatoren * und /? Die haben in C doch die 
selbe Prio? Werden die von Links nach rechts ausgeführt oder ist das 
compiler abhänig?

ctrl_out  = (KP * e) + (KI  Ta  i_term) + ( KD * (e – ealt)/Ta));

Sorry wenn ich Mist schreibe? Ich habe noch nich so die Ahnung

gruß sebastian

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.