Giải thích đoạn code điều khiển động cơ DC sử dụng PID giúp mình với !

Collapse
X
 
  • Giờ
  • Show
Clear All
new posts
  • embsys
    Thành viên chính thức
    • Jun 2008
    • 99

    #1

    Giải thích đoạn code điều khiển động cơ DC sử dụng PID giúp mình với !

    Đây là một đoạn code mình viết theo một tài liệu hướng dẫn trên mạng :
    PHP Code:
    void PID_tocdo(void)
    {
        Err_now = V_set - V_real ;   
        Err_sum = Err_now + Err_last ; 
        Err_del = Err_now - Err_last ;
        Err_last = Err_now ;
        
        Duty = Duty + Kp*Err_now + Ki*Err_sum + Kd*Err_del ;
        
        if      ( Duty > 255 ) Duty = 255 ;
        else if ( Duty < 0 ) Duty = 0 ;    
        
    } 
    
    Cho mình hỏi tại sao ở đây sử dụng Duty ( chữ màu đỏ )

    Duty = Duty + Kp*Err_now + Ki*Err_sum + Kd*Err_del ;
    Theo mình nghĩ thì nó phải là giá trị Duty_set ( được thiết đặt để có V_set mong muốn nào đó .) chứ không phải là Duty .
    Như vậy ở đoạn code trên thì Duty thì liên tiếp được cộng dồn có phải không ?

    Ai biết thì chỉ dùm mình với !

    Còn đây là một hướng dẫn trên mạng :
    PHP Code:
    Các biến được sử dụng:    
    - Speed: Tốc độ động cơ, tính bằng số xung đếm được trong một thời gian lấy mẫu Ts(đã định sẵn)
    - Set_Point: Giá trị cài đặt, dùng tham chiếu với Speed nên có cùng đơn vị và công thức chuyển đổi
    - int Error_Acc: Tích lũy sai số.
    - int This_Error: Sai số hiện hành
    - int Last_Error: Sai số lần trước (ngôn ngữ hơi phi kỹ thuật chút)
    - int P_Gain, I_Gain, D_Gain: Độ lợi khâu P, I, D
    - int P_Term, I_Term, D_Term: giá trị khâu P, I, D
    - int Output: giá trị ngõ ra điều khiển, tỷ lệ với giá trị set cho PWM.
    
    
    
    Các bước tính
    
    - Cập nhật sai số:
    This_Error = Set_Point - Speed;
    
    - Tích lũy sai số:
    Error_Acc = Error_Acc + This_Error; 
    
    - Lưu sai số:
    Last_Error  = This_Error; 
    
    - Tính khâu tỷ lệ:
    P_Term = This_error * P_Gain;
    if (P_Term>32767) P_Term=32767; //Correct out of range
    if (P_Term<-32768) P_Term=-32768; //Correct out of range
    
    - Tính khâu tích phân:
    I_Term = Error_Acc * I_Gain;
    if (I_Term>32767) I_Term=32767; //Correct out of range
    if (I_Term<-32768) I_Term=-32768; //Correct out of range
    
    - Tính khâu vi phân:
    D_Term = (This_Error - Last_Error) * D_Gain;
    if (D_Term>32767) D_Term=32767; //Correct out of range
    if (D_Term<-32768) D_Term=-32768; //Correct out of range
    
    - Tính ngõ ra:
    Output = P_Term + I_Term + D_Term;
    if (Output >32767) Output =32767; //Correct out of range
    if (Output < 0) Output = 0; //Correct out of range
    
    - Scale Output để hợp với 10bit- PWM:
    PWM = Output * 1023/32767; 
    
    Mình đọc đoạn này thì thấy khó hiều quá . ko biết đây là PID theo tốc độ hay theo vị trí . Nếu là PID theo tốc độ thì tại sao lại có đoạn :

    PHP Code:
    
    PWM = Output * 1023/32767; 
    
    Nếu vậy thì khi sai lệch Output = 0 thì PWM = 0 à . Đoạn này mình không hiểu .

    Hàm truyền PID :

    PHP Code:
    Phương trình hành động là : 
            Ira = Kp ( e + Ki ∫ edt + Kd de/dt ) + I0
    Với :
        Ira     :  tín hiệu ra khỏi bộ điều khiển khi có một sai lệch e thay đổi với thời gian t .
        I0     :  tín hiệu ra tại thời điểm thiết lập khi không có sai lệch .
        Kp     :  hằng số tỉ lệ 
        Ki     : hằng số tích phân 
    Kd     : hằng số đạo hàm  ( vi phân ) 
    
    Vậy đối với PID theo tốc độ và PID theo vị trí thì giá trị I0 khác nhau thế nào .
    Mình đã đọc một số bài lập trình trên mạng và có đọc qua cơ sở lý thuyết điều khiển PID nhưng không hiểu được phải viết hàm PID theo vị trí và PID theo tốc độ thế nào cả .... Các bài ví dụ trên mạng mỗi người làm một kiểu . mình càng đọc càng băn khoăn khó hiểu .
    Nay viết lên đây mong anh chị em cô bác nào hiểu thấu có thể chỉ giáo cho em chút ít để mở rộng tầm hiểu biết của mình được không ? Cảm ơn mọi người trước nhé ....
  • embsys
    Thành viên chính thức
    • Jun 2008
    • 99

    #2
    Và đây cũng là một bài mà em tham khảo được trên mạng nhưng em có chỗ không hiểu . Mong ai biết chỉ dùm . he he .....

    PHP Code:
    void pid()
    { 
    
    // sp : co gia tri duoc truyen tu may tinh xuong chip Driver
    err=sp-pv; // (err = setpoint - process variable) pv : là số xung Encoder đo được ;
    eht = err + elast; 
    sum_err+=eht; // tinh tong sai so theo cong thuc hinh thang 
    d_err=err-elast; // vi phan sai so = sai so hien tai - sai so truoc do 
    cv=((kp*err)+(ki*sum_err)+(kd*d_err)); // Cong thuc tinh toan PID 
    cv=cv/1000; // Cho nay / 1000 vi tren giao dien ki,kp,kd da * 1000 
    
    // VD: ki=0.01*1000=10 gui xuong VDK - tranh gui dau "." 
    
    if(cv>511) 
    { cv=511; }                 // gioi han PWM 9Bit 
    if(cv<0)
    { cv=0; }                    // chay maximum 
    
    pwm1=(int)cv;            // ep kieu sang so nguyen 
    pwm=511-pwm1;         // xuat pwm(OCR1A) 
    
    //PORTA.4=0; 
    elast=err; // sai so hien tai se tro thanh sai so truoc no khi co sai so moi 
    ok=1;      // bit danh dau da xuat dc pwm 
    
    } 
    
    Có đoạn code mình không hiểu là :
    PHP Code:
    sum_err+=eht;  // tinh tong sai so theo cong thuc hinh thang 
    
    theo đoạn code trên thì được : sum_err = sum_err + err + elast ;
    tác giả bài lập trình có ghi chú là :// tinh tong sai so theo cong thuc hinh thang cái này có nghĩa là gì ?
    và :
    PHP Code:
    pwm=511-pwm1;   // xuat pwm(OCR1A) 
    
    tại sao lại như thế này nhỉ . he he . bạn nào từng làm về cái này chỉ dùm với . tớ thấy băn khoăn , khó hiểu quá ....

    Comment

    • Viet Vinh
      Thành viên chính thức
      • May 2009
      • 62

      #3
      Hi, mình thấy các thuật toán mô phỏng PID của bạn không chuẩn lắm.
      Bạn biết đấy, khối P và khối D là 2 khối tính toán phụ thuộc vào thời gian xử lý dt. Nhưng trong code của bạn không hề đề cập đến vấn đề này.

      Bạn hãy xem thuật toán này chuẩn hơn:

      previous_error = 0
      integral = 0
      start:
      error = setpoint - actual_position
      integral = integral + (error*dt)
      derivative = (error - previous_error)/dt
      output = (Kp*error) + (Ki*integral) + (Kd*derivative)
      previous_error = error
      wait(dt)
      goto start

      Muốn hiểu rõ rơn xin vào link sau:

      Chúc vui

      Comment

      • Viet Vinh
        Thành viên chính thức
        • May 2009
        • 62

        #4
        Sorry mình nhầm, chỉ có khối I và D phụ thuộc thời gian dt

        Comment

        • embsys
          Thành viên chính thức
          • Jun 2008
          • 99

          #5
          Cảm ơn bạn nhiều nhé . Để mình xem xem ....

          Comment

          • embsys
            Thành viên chính thức
            • Jun 2008
            • 99

            #6
            Mình có đoạn code này không hiểu . mong các bạn giải thích giúp mình ?

            PHP Code:
            typedef struct
            {
            
            double dState; // Last position input
            double iState; // Integrator state
            double iMax, iMin; 
            // Maximum and minimum allowable integrator state
            double    iGain, // integral gain
                         pGain, // proportional gain
                         dGain; // derivative gain
            } SPid;
            
            double UpdatePID(SPid * pid, double error, double position)
            {
            double pTerm,dTerm, iTerm;  
            pTerm = pid->pGain * error;   
                                  // calculate the proportional term
                                  // calculate the integral state with appropriate limiting   
            pid->iState += error;
                      if        (pid->iState > pid->iMax) pid->iState = pid->iMax;
                      else if (pid->iState < pid-> iMin) pid->iState = pid->iMin;
            
            iTerm = pid->iGain * iState; // calculate the integral term
            dTerm = pid->dGain * (position - pid->dState);
            pid->dState = position;
            
            return pTerm + iTerm - dTerm;
            
            } 
            
            PHP Code:
            if        (pid->iState > pid->iMax) pid->iState = pid->iMax; 
            
            Viết thế này là thế nào ? mình đọc không hiểu .

            Comment

            • doctorthanh
              Thành viên mới
              • Aug 2009
              • 21

              #7
              cai phương trình điều khiển pid nguyên thủy phải tính đến thời gian liên tục tuy nhiên để có thể điều khiển bằng cách lập trình theo dạng số dĩ nhiên người ta đã số hóa nó và coi một số đk là gần đúng nên không thấy trong chương trình có cái lượng dt, và cái khoảng thời gian này được hiểu là xủ lý trong chương trình ngắt lấy mẫu chẳng hạn.

              Comment

              • LamHong
                Thành viên mới
                • Mar 2009
                • 15

                #8
                Nguyên văn bởi embsys Xem bài viết
                PHP Code:
                if        (pid->iState > pid->iMax) pid->iState = pid->iMax; 
                
                Viết thế này là thế nào ? mình đọc không hiểu .
                Chưa đọc kỹ bài của bạn, nhưng lướt qua tôi thấy PID như thế có vấn đề gì đâu, bạn chú ý số công thức tính PID ra , rồi rút gọn các phép tính cho VĐK tối giản các phép tính nhất.
                Còn riêng dòng lệnh trên chẳng qua giới hạn tín hiệu điều khiển của bạn thôi.
                Last edited by LamHong; 13-08-2009, 13:28.

                Comment

                • embsys
                  Thành viên chính thức
                  • Jun 2008
                  • 99

                  #9
                  Bạn thông cảm nhé . Nói thật là đoạn code đó mình không hiểu lắm . vì mình lập trình cũng tương đối mà chưa nhìn thấy kiểu viết như thế . Bạn hiểu ý mình không nhỉ .
                  PHP Code:
                  if        (pid->iState > pid->iMax) pid->iState = pid->iMax; 
                  
                  Mấy cái dấu " -> " có nghĩa là gì . có thể viết kiểu nào cho dễ hiểu hơn được không ?

                  Comment

                  • Viet Vinh
                    Thành viên chính thức
                    • May 2009
                    • 62

                    #10
                    Toán tử -> dùng để truy xuất thành viên dạng con trỏ (pointer)trong kiểu dữ liệu có cấu trúc như struct, class.
                    Vi du
                    typedef struct _Vivi
                    {
                    int thanhvien_a;
                    nit thanhvien_b;
                    } VIVI,*LPVIVI;
                    //khai báo
                    VIVI a,*pa;
                    //Khởi tạo thành viên
                    a.thanhvien_a=1;
                    a.thanhvien_b=2;
                    //Như vậy việc truy xuất gián tiếp đối tượng a như sau
                    pa=&a;//Con trỏ pa trỏ tới đối tượng a
                    //Truy cập thành viên của đối tượng a
                    int GiaTriThanhVien_a=pa->thanhvien_a;
                    int GiaTriThanhVien_b=pa->thanhvien_b;
                    //Như vậy
                    //GiaTriThanhVien_a=1;
                    //GiaTriThanhVien_b=2;

                    Comment

                    • Viet Vinh
                      Thành viên chính thức
                      • May 2009
                      • 62

                      #11
                      pid là một con trỏ trỏ tới đối tượng SPid nên phải truy xuất bằng toán tử ->
                      Có cách viết dễ hiểu hơn là dùng MACRO nhưng nó làm mất đi tính trực quan của C/C++
                      Chúc vui

                      Comment

                      • embsys
                        Thành viên chính thức
                        • Jun 2008
                        • 99

                        #12
                        Cảm ơn bạn Viet Vinh nhiều lắm ! Mình hiểu rồi ! Đây là lần đâu tiên mình gặp ký tự là này nên rất khó hiểu . Rất vui vì được bạn giúp đỡ ... Cảm ơn nhiều nha

                        Comment

                        • mitomtrung
                          Thành viên mới
                          • Jan 2010
                          • 13

                          #13
                          viet j ma kho hieu the.dieu khien dong co dcservo bang pid ne .nhap toc do can dieu khien bang ban phim luon

                          /************************************************** ***
                          This program was produced by the
                          CodeWizardAVR V2.03.4 Standard
                          Automatic Program Generator
                          © Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
                          CodeVisionAVR C Compiler for Atmel AVR microcontrollers


                          Project :
                          Version :
                          Date : 5/13/2011
                          Author :
                          Company :
                          Comments:


                          Chip type : ATmega32
                          Program type : Application
                          Clock frequency : 8.000000 MHz
                          Memory model : Small
                          External RAM size : 0
                          Data Stack size : 512
                          ************************************************** ***/

                          #include <mega32.h>
                          #include <math.h>
                          #include <delay.h>
                          #include <stdio.h>
                          #include <stdlib.h>
                          #define KEYPAD_PORT PORTA
                          #define KEYPAD_PIN PINA
                          // Alphanumeric LCD Module functions
                          #asm
                          .equ __lcd_port=0x15 ;PORTC
                          #endasm
                          #include <lcd.h>
                          #define MOTOR_DDR DDRD
                          #define MOTOR_PORT PORTD
                          #define MOTOR_DIR 6
                          #define MOTOR_EN 7
                          #define sampling_time 25
                          #define inv_Sampling_time 40
                          #define PWM_Period 8000
                          void motorspeed_pid(long int des_speed);
                          volatile long int pulse,prepulse;

                          volatile long int rspeed,err,pre_err,kp=8,kd=10,ki=1;

                          volatile long int ppart=0 ;

                          volatile long int dpart=0;

                          volatile long int ipart=0;

                          volatile long int ctrl_speed=0;;

                          volatile long int output,pulse;
                          volatile unsigned char sample_count=0;
                          int so(char a) ;
                          volatile long int n,t,c,dv,v1,v2;
                          int nhap();
                          int l=0,j,A1[2],A2[2],chophep=0,k,m,v=0,x,y;
                          char checkpad();
                          int scan_code[4]={0x0E,0x0D,0x0B,0x07};
                          int ASCII_code[4][4]=
                          {'7','8','9','/',
                          '4','5','6','*',
                          '1','2','3','-',
                          'A','0','=','+'
                          };
                          // External Interrupt 2 service routine
                          interrupt [EXT_INT2] void ext_int2_isr(void)
                          {
                          if(PINB.0==1)
                          {
                          pulse=pulse+1;
                          }
                          else
                          {
                          pulse=pulse-1;
                          }


                          }

                          // Timer 2 output compare interrupt service routine
                          interrupt [TIM2_COMP] void timer2_comp_isr(void)
                          {

                          TCNT2=0X3C;
                          sample_count++;
                          motorspeed_pid(ctrl_speed);
                          }

                          // Declare your global variables here
                          char checkpad()
                          {
                          int i,j,keyin;
                          for(i=0;i<4;i++){
                          KEYPAD_PORT=0xFF-(1<<(i+4));
                          delay_ms(1);
                          keyin=KEYPAD_PIN & 0x0F;
                          if(keyin!=0x0F){
                          for(j=0;j<4;j++)
                          if(keyin==scan_code[j])
                          return ASCII_code[j][i];
                          }//else return 0;
                          }
                          }
                          int nhap()
                          {

                          if (checkpad()=='A')
                          l=1;
                          if ((j==0)&&(checkpad()!=0)&&(l==1)&&(checkpad()!='A' )&&checkpad()!='/') ///////////////checkpad()==0co nghia la khong nhan keypad
                          {
                          A1[0]=checkpad() ;
                          lcd_gotoxy(6,1);
                          lcd_putchar(A1[0]);
                          j=1;
                          chophep=1;

                          }
                          if ((checkpad()==0)&&(j==1)) /////////////
                          {
                          j=2;
                          }
                          if ((j==2)&&(checkpad()=='/') )
                          {
                          A1[0]=' ';
                          lcd_gotoxy(6,1);
                          lcd_putchar(A1[0]);
                          j=0;
                          //chophep=1;
                          }

                          if ((j==2)&&(checkpad()!=0)&&(l==1)&&(checkpad()!='A' )&&checkpad()!='/') //////////////
                          {
                          A1[1]=checkpad();
                          lcd_gotoxy(7,1);
                          lcd_putchar(A1[1]);
                          j=3;
                          chophep=1;
                          }
                          if ((checkpad()==0)&&(j==3))
                          {
                          j=4;
                          }
                          if ((j==4)&&(checkpad()=='/'))
                          {
                          A1[1]=' ';
                          lcd_gotoxy(7,1);
                          lcd_putchar(A1[1]);
                          j=5;
                          }
                          if ((checkpad()==0)&&(j==5))
                          {

                          j=2;


                          }
                          if ((j==4)&&(checkpad()!=0)&&(l==1)&&(checkpad()!='A' )&&checkpad()!='/')
                          {
                          A2[0]=checkpad();
                          lcd_gotoxy(8,1);
                          lcd_putchar(A2[0]);
                          j=6;
                          chophep=1;

                          }
                          if ((checkpad()==0)&&(j==6))
                          {
                          j=7;
                          }
                          if ((j==7)&&(checkpad()=='/') )
                          {
                          A2[0]=' ';
                          lcd_gotoxy(8,1);
                          lcd_putchar(A2[0]);
                          j=8;

                          }
                          if ((checkpad()==0)&&(j==8))
                          {
                          j=4;
                          }
                          if ((j==7)&&(checkpad()!=0)&&(l==1)&&(checkpad()!='A' )&&checkpad()!='/')
                          {
                          A2[1]=checkpad();
                          lcd_gotoxy(9,1);
                          lcd_putchar(A2[1]);
                          j=9;
                          // chophep=1;
                          }
                          if ((checkpad()==0)&&(j==9))
                          {
                          j=10;
                          }
                          if ((j==10)&&(checkpad()=='/') )
                          {
                          A2[1]=' ';
                          lcd_gotoxy(9,1);
                          lcd_putchar(A2[1]);
                          j=11;
                          }
                          if ((checkpad()==0)&&(j==11))
                          {
                          j=7;
                          chophep=1;
                          }

                          }
                          void motorspeed_pid(long int des_speed)
                          {
                          rspeed=pulse-prepulse ;
                          prepulse=pulse;

                          if(rspeed<0)
                          {
                          rspeed=rspeed*(-1);
                          }

                          err=des_speed-rspeed;
                          ppart=kp*err;
                          dpart=kd*(err-pre_err)*inv_Sampling_time ;
                          ipart+=ki*sampling_time*(err+pre_err)/1000;
                          output+=ppart+dpart+ipart;
                          //////////////////////////////////////////

                          if(output>=PWM_Period)
                          {
                          output=PWM_Period-1;
                          if(output<0)
                          {
                          output=1;
                          }
                          }


                          OCR1A=output;
                          pre_err=err;
                          }

                          void main(void)
                          { pulse=0;
                          // Declare your local variables here

                          // Input/Output Ports initialization
                          // Port A initialization
                          // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
                          // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
                          PORTA=0x00;
                          DDRA=0xF0;

                          // Port B initialization
                          // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
                          // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
                          PORTB=0x00;
                          DDRB=0x00;

                          // Port C initialization
                          // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
                          // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
                          PORTC=0x00;
                          DDRC=0xFF;

                          // Port D initialization
                          // Func7=In Func6=In Func5=Out Func4=In Func3=In Func2=In Func1=In Func0=In
                          // State7=T State6=T State5=0 State4=T State3=T State2=T State1=T State0=T
                          PORTD=0x00;
                          DDRD=0x20;

                          // Timer/Counter 0 initialization
                          // Clock source: System Clock
                          // Clock value: Timer 0 Stopped
                          // Mode: Normal top=FFh
                          // OC0 output: Disconnected
                          TCCR0=0x00;
                          TCNT0=0x00;
                          OCR0=0x00;

                          // Timer/Counter 1 initialization
                          // Clock source: System Clock
                          // Clock value: 1000.000 kHz
                          // Mode: Fast PWM top=ICR1
                          // OC1A output: Inverted
                          // OC1B output: Discon.
                          // Noise Canceler: Off
                          // Input Capture on Falling Edge
                          // Timer 1 Overflow Interrupt: Off
                          // Input Capture Interrupt: Off
                          // Compare A Match Interrupt: Off
                          // Compare B Match Interrupt: Off
                          TCCR1A=0xC2;
                          TCCR1B=0x1A;
                          TCNT1H=0x00;
                          TCNT1L=0x00;
                          ICR1H=0x1F;
                          ICR1L=0x40;
                          OCR1AH=0x00;
                          OCR1AL=0x00;
                          OCR1BH=0x00;
                          OCR1BL=0x00;

                          // Timer/Counter 2 initialization
                          // Clock source: System Clock
                          // Clock value: 1000.000 kHz
                          // Mode: Normal top=FFh
                          // OC2 output: Disconnected
                          ASSR=0x00;
                          TCCR2=0x07;
                          TCNT2=0x00;
                          OCR2=0x00;

                          // External Interrupt(s) initialization
                          // INT0: Off
                          // INT1: Off
                          // INT2: On
                          // INT2 Mode: Falling Edge
                          GICR|=0x20;
                          MCUCR=0x00;
                          MCUCSR=0x00;
                          GIFR=0x20;

                          // Timer(s)/Counter(s) Interrupt(s) initialization
                          TIMSK=0x80;

                          // Analog Comparator initialization
                          // Analog Comparator: Off
                          // Analog Comparator Input Capture by Timer/Counter 1: Off
                          ACSR=0x80;
                          SFIOR=0x00;
                          OCR1A=1;
                          // LCD module initialization
                          lcd_init(16);

                          // Global enable interrupts
                          #asm("sei")

                          while (1)
                          {
                          PORTD.6=1;
                          PORTD.7=1;
                          nhap();
                          if((chophep==1)&&(checkpad()=='A'))
                          {
                          k=so(A1[0]);
                          m=so(A1[1]);
                          x=so(A2[0]);
                          y=so(A2[1]);
                          v=k*10+m;
                          //chophep=0;
                          }
                          if(sample_count>10)
                          {
                          ctrl_speed=v;
                          n= rspeed/1000;
                          t=(rspeed-n*1000)/100;
                          c=(rspeed-t*100)/10;
                          dv=(rspeed-n*1000-t*100-c*10);
                          lcd_gotoxy(0,0);
                          lcd_putchar(n+48);
                          lcd_gotoxy(1,0);
                          lcd_putchar(t+48);
                          lcd_gotoxy(2,0);
                          lcd_putchar(c+48);
                          lcd_gotoxy(3,0);
                          lcd_putchar(dv+48);
                          sample_count=0;
                          }

                          };
                          }
                          int so(char a)
                          {
                          switch (a)
                          {
                          case '0' :
                          return 0;
                          break;
                          case '1' :
                          return 1;
                          break;
                          case '2' :
                          return 2;
                          break;
                          case '3' :
                          return 3;
                          break;
                          case '4' :
                          return 4;
                          break;
                          case '5' :
                          return 5;
                          break;
                          case '6' :
                          return 6;
                          break;
                          case '7' :
                          return 7;
                          break;
                          case '8' :
                          return 8;
                          break;
                          case '9' :
                          return 9;
                          break;

                          }
                          }

                          Comment

                          • kevotinh_163
                            Thành viên mới
                            • Mar 2011
                            • 6

                            #14
                            duty = duty + ..... là vì cái này phải cộng dồn. vì nếu khi động có đã ổn định tốc độ rồi thì giá trị duty lúc đó sẽ = 0, nếu vậy động cơ sẽ dừng. nên phải cộng dồn cả duty trước đó

                            Comment

                            Về tác giả

                            Collapse

                            embsys Tìm hiểu thêm về embsys

                            Bài viết mới nhất

                            Collapse

                            Đang tải...