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

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