You are on page 1of 8

Write code to implement P control.

 In this demo, setpoint, lowplimit and highplimit are programmable.


 Setpoint is set to 35. Kd =1.0, lowplimit = 20, highplimit = 70. Cycle time = 10.
 Setpoint is set using SP key, lowplimit and highplimit are set using Kd key.
           
1) Dùng files đính kèm trong email này cho P control.
2)  Viết lập trình cho Proportional_calculation() trong file.c
     Trong lập trình này, viết 3 công thức cho:
      setpointoutput=  ?
      erroroutput=     ?
       propoutput =     ?
 
    Note:
    Trong main.c, trong while (1) loop, we call Do_pid_control() mỗi  50ms.
     Do_pid_control() => Duty_cycle_calculation() => Proportional_calculation()
Các em tính trị số “propoutput” trong Proportional_calculation(). Trị số này sẽ được
dùng để tính “dutycycle” cho P part of PID control. Integral and Derivative được set to 0
for this test.
 
3) Set Setpoint to 35. lowplimit is 20. highplimit is 70. 
     If temperature is 30 =>
     setpointoutput=(highplimit-setpoint*100/highplimit-lowplimit
                            = (70-35)*100/(70-20) = 70%
     erroroutput= (setpoint-temperature)*100/(highplimit-lowplimit);
                       =  (35-30)*100/(70-20) = 10%
     propoutput = setpointoutput + erroroutput = 70%+10% = 80%
4) Kiểm tra: Với các trị số trên (setpoint=35, lowplimit=20, highplimit=70), output =
80% at 30C, 70% at 35C, 60% at 40C…..
 
   Thí dụ:
   In main.c:
    while (1) { // *** Main loop ***
          while (!tickset) { }  // Wait for 50ms interrupt
       // Do something every 50ms here (when tickset is 1)
       Detect_key_press (); // will set or reset keyinput variable (func_pid.c)
       if (keysetup==0) Do_pid_control(); // Use your code for this function
       Do_tick_service(); // Do this for every 50ms (main_pid.c)
       tickset=0;         // tick flag is reset
  } // while (1) Main loop - Looping forever
 
void Do_pid_control (void) 
{
   count1sec++;  // if count1sec==20 => 1 sec timing
   if (count1sec>=20) { // if 1 second is set: read ADC & update Integral part
       count1sec = 0;
       cyclecount++; //
       Duty_cycle_control(); // turn off relays if time is expired
       Temperature_read();  // will return "temperature"
       Integral_calculation(); // see file.c
       if (cyclecount>=cycletime) { // for every 20 seconds
             cyclecount=0;
             Duty_cycle_calculation(); // in file.c
          }
      phase=0; // Do nothing
   } // if 1 sec is set 
}  
 
In file.c:
 
 void Duty_cycle_calculation (void)
{
   float pval,ival,dval;
   // First, calculate P (proportional) part:
   pval= Proportional_calculation(); // pval=85.3 (0 to 100)
   ival= errorsum; // ival=0 to 100;
   dval= Derivative_calculation(); // dval=0 to 10
 
   pval= pval*kpconstant/10; // verified
   ival= ival*kiconstant/10; // verified
   dval= dval*kdconstant/10; // verified
   output= pval + ival + dval;
   if (output<0) output=0;
   if (output>100) output=100;
   dutycycle= output*cycletime/100; // Verified on 5/22/19
   if (dutycycle>0) { Port_on(PORT1); }
   if (motormode==1) run_step_motor (); 
}
 
float Proportional_calculation (void)
{
   float setpointoutput, erroroutput, propoutput;
  
 //  setpointoutput=  ?
 //  erroroutput=     ?
 //  propoutput =     ?
 
   if (propoutput<0) propoutput=0;  //  minimum 0
   if (propoutput>100) propoutput=100; // maximum 100
  
   return (propoutput);
}
Thầy gửi đính kèm những files cho PI control, các em dùng những files này nhé.

1) Dùng files đính kèm trong email này cho P+I control.
2) Setpoint is set to 35, Kd =1.0, Ki=1.0, lowplimit = 20, highplimit = 70,Cycle time = 10.
3)  Main.c:
     Edit Do_pid_control() like this: thêm temperature = 34;  

void Do_pid_control (void) 


{
   count1sec++;  // if count1sec==20 => 1 sec timing
   if (count1sec>=20) { // if 1 second
          count1sec = 0;
          cyclecount++; //
          Duty_cycle_control(); // turn off relays if time is expired
          Temperature_read();  //  will return temperature
          temperature = 34;     // added for testing with setpoint=35
                                           // %output=72%
          Integral_calculation(); // see file.c
          if (cyclecount>=cycletime) { // for every 20 seconds
          cyclecount=0;
          Duty_cycle_calculation(); // in file.c
   }
     phase=0; // Do nothing
   } // if 1 sec is set 
}  
 
4)  Viết lập trình cho Integral_calculation() trong file.c
     Trong lập trình này, tính “errorsum”. Errorsum chính là integral part            of PI
control. “errorsum” is positive if temperature>setpoint, và                   ngược lại.
“errorsum” will be reset to 0 if temperature=setpoint.
  
      void Integral_calculation (void)
{
   float error;
   error=setpoint-temperature; //
   if (error==0) errorsum=0;
   else { // if there is error
          if (error>0) { // if error is positive
              if (errorsum<=0) errorsum=error;
              else errorsum=errorsum+error;
              if (errorsum>100) errorsum=100;
              } // if error>0     
         else { // error is negative
              if (errorsum>=0) errorsum=error;
              else errorsum=errorsum+error;
              if (errorsum<-100) errorsum=-100;
              } // if error<0     
        } // else if error 

 
5) Kiểm tra 1: Compile and program. Quan sát %Output. Ouput sẽ               bắt đầu
từ 70% (34C) tăng 10% mỗi 10 seconds (cycle time) cho             tới 100%.
6)  Edit main.c like this:
            void Do_pid_control (void) 
            {
                . . . . . . . . . . . . . . . . . . . . .
                Temperature_read();  //  will return temperature
                temperature = 36;     // added for testing with SP=35
                                                    // %output=67.5%
                Integral_calculation(); // see file.c
                . . . . . . . . . . . . . . . . . . . . .
            }  
7) Kiểm tra 2: Compile and program. Quan sát %Output. Output sẽ             bắt đầu
từ 70% (36C) giảm 10% mỗi 10 seconds (cycle time) cho 
    tới 0%.

Chúc các em thành công tốt đẹp.

Thầy
Chào các em,

Vì thời gian có hạn,  thầy gửi các em files PID control đầy đủ để các em chỉ test chớ
không cần modify. Các em test để biết cách làm việc của PID và thầy sẽ chỉ sơ
firmware thầy viết cho các loại control này.
Buổi làm việc sắp tới, các em dùng những files này để test PI nếu chưa test PI, và PD
nếu chưa test PD. Em nào chưa test On-Off control và P control thì có thể không cần
demo, nhảy qua làm PI cho thầy. Nhóm nào chưa hoàn tất board mạch thì có thể dùng
project của thầy hay của bạn để test PI control. 
Khi test PI, thầy muốn thấy các em thay đổi 2 trị số của nhiệt độ (temperature=34 và
temperature=36) và demo cho thầy coi %output tăng lên 100% hoặc giàm xuống 0%.

Em nào demo xong PI thì coi như hoàn tất.


 
Buổi học tới là buổi cuối cùng nên thầy chỉ chú trọng vào PI vì PI là cốt lỏi. Tuy PD
không cần thiết lắm, nhưng em nào có thời giờ có thể test PD cho biết. 
 
Nếu test PI thì các em set Kd=0; nếu test PD thì set Ki=0.

Đây là thứ tự:

1) Dùng files đính kèm trong email này cho P+I+D control hiện tại và             tương lai.
2) If test PI:
                a) Setpoint is set to 35, Kp =1, Ki=1, Kd=0, lowplimit=20,                          
highplimit=70,Cycle time= 10.
                 b)  Main.c: Edit main.c like this: thêm temperature = 34;  
 
            void Do_pid_control (void) 
            {
                 count1sec++;  // if count1sec==20 => 1 sec timing
                if (count1sec>=20) { // if 1 second is set: read ADC
                        count1sec = 0;
                        cyclecount++; //
                        Duty_cycle_control(); // turn off relays
                         Temperature_read();  //  will return temperature
                         temperature = 34;     // added for testing
                                                             // %output=72%
 
                         Integral_calculation(); // see file.c
                        if (cyclecount>=cycletime) { // for every 20 seconds
                            cyclecount=0;
                            Duty_cycle_calculation(); // in file.c
                      }
                 phase=0; // Do nothing
               } // if 1 sec is set 
            }  
      c) Kiểm tra 1: Output sẽ bắt đầu từ 70% (34C) tăng 10% mỗi 10                 seconds
(cycle time) cho tới 100%.
 
     d)  Edit main.c like this:
            void Do_pid_control (void) 
            {   . . . . . . . . . . . . . . . . . . . . .
                Temperature_read();  //  will return temperature
                temperature = 36;     // added for testing 
                                                    // %output=67.5%
                Integral_calculation(); // see file.c
                . . . . . . . . . . . . . . . . . . . . .
            }  
     e) Kiểm tra 2: Output sẽ bắt đầu từ 70% (34C) giảm 10% mỗi 10                  seconds
(cycletime) cho tới 0%.
 
3) If test PD:
           a) Setpoint is set to 35, Kp =1, Ki=0, Kd=1, lowplimit=20,                            
highplimit=70,Cycle time=20.
                b)  Kiểm tra 1:
          b.1: Để máy sấy tóc off. Đợi nhiệt độ ổn định. Thí dụ 30C.
                 Ở 30C, output sẽ là 80%. Đợi qua 1 chu kỳ (cycle time)                          và verify
output is still 80%?
          b.2: Khi Cycle time=1/20, turn on máy sấy tóc và điều chỉnh                         sao cho
nhiệt độ lên 40C vào cuối cycle time (trước 20                           seconds), vì D part sẽ được
tính vào đầu chu kỳ mới.
               Ở chu kỳ mới:
                Với trị số 40C =>  Proportional (40C) = 60%
                                           Derivative = 40C-30C = 10% 
                                           Output = 60%-10% = 50%.
          b.3: Khi Cycle time=1/20, turn off máy sấy tóc và theo dỏi                              nhiệt độ
cho đến đầu chu kỳ sau. Nhiệt độ sẽ giảm xuống                       T value. Verify new
percent output.
                Ở chu kỳ mới:
                Output = Proportional at T  + (40-T);
                 Thí dụ T=30C => Proportional (30C) =70%
                                          Derivative = 40-30= 10%
                                          Output = 70% + 10% = 80%

Sau này, các em có thể dùng files này cho PID control. Chỉ cần đổi Kp, Ki, Kd, cycle time,
low limit và high limit cho thích hợp với môi trường.

Chúc các em thành công,


Thầy

You might also like