Thông báo

Collapse
No announcement yet.

PID trên PSoC

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • PID trên PSoC

    Tui đang viết một đoạn mã PID trên PSoC để điều khiển DC servo motor, nhưng thấy vất quá. Xin hỏi võ lâm đồng đạo có cao kiến gì xin chỉ giúp.
    Đại khái là tui dùng PWM16 để điều khiển tốc độ động cơ, sau đó thu lấy tín hiệu về từ tachometer,đo cái ni để suy ra tốc độ quay của động cơ.
    Giờ tui muốn đặt cho nó quay ở một tốc độ cố định (giả sử là 3000 rpm chẳng hạn). Thuật toán hiệu chỉnh là dùng PID (mềm-tất nhiên rùi !).
    Tui đã có tốc độ của động cơ (đo từ tín hiệu tachometer)-cũng đo luôn bằng PSoC 27443. Và muốn dùng cái này điều khiển ngược lại sao cho động cơ luôn quay ở một tốc độ cố định.
    Tui cũng ghép với PC để vẽ cái đáp ứng tần số của nó, ghép qua COM9 và vẽ bằng LABVIEW, gửi dữ liệu đi dưới dạng ký tự (sao cho vẽ được cái đường cong dạng "tắt dần" trên PC-tất nhiên tắt càng nhanh càng tốt).
    BUT tui chưa biết viết một thuật toán PID mềm bằng C trên PSoC như thế nào (niewbie mà), vậy nay có vài lời thô thiển xin võ lâm đồng đạo (nhất là mod WINTER) điểm chỉ vài chiêu để được vén mây mù trông thấy cao sơn.
    P/S: ai có pid mềm viết bằng C cho tui xin một đoạn code để ngõ hầu học lấy vài chiêu cơ bản.
    (Giờ tại hạ đang mong tin của các cao nhân như nắng hạn chờ mưa !)
    Ở đời khác thường, làm sự nghiệp phi thường...Cùng thì tự tốt lấy ta, đạt thì đem hạnh phúc cho thiên hạ.---(Gia Cát Khổng Minh)

  • #2
    Cái của bạn làm là PID vận tốc, có lẽ nó cũng giống với cái PID vị trí tôi có tham gia làm hồi xưa.
    Công việc đo và truyền qua 233 dùng PSoC thì ko có gì khó cả. Và cả việc hiên thị trên PC nữa. Nói tóm lại nó khó ở thuật toán của bạn đưa ra, Hàm PID, hệ số Kp,Ki,Kd, và tối ưu hóa các hệ số này.

    Comment


    • #3
      Đúng rồi bác Bình Anh ạ. Tui cũng không có sợ mấy cái kia mà chỉ sợ thằng PID thôi. Bác xem có gì giúp em vớiiiiiiiiiiiiiiiiiiiiiiiii
      Ở đời khác thường, làm sự nghiệp phi thường...Cùng thì tự tốt lấy ta, đạt thì đem hạnh phúc cho thiên hạ.---(Gia Cát Khổng Minh)

      Comment


      • #4
        Dạo này mình hơi bận tý, nên chưa tập trung được vào câu hỏi của bạn, hơn nữa hệ của bạn là điều khiển động cơ, còn mình lại điều khiển nhiệt.

        Mình sẽ nhờ Falleaf trả lời cho bạn. Vì F có làm về chính cái này

        Comment


        • #5
          Code:
          ////////////////////////////////
          // Chuong trinh tinh toan PID //
          ////////////////////////////////
          
          signed int velo_error_perfect;                  // dung de tinh dao ham bac 2
          signed int velo_error_past;                     // tinh dao ham bac nhat
          signed int velo_error_present;                  // gia tri sai so hien tai
          signed int daoham1;
          signed int daoham2;
          signed int16 Proportion;
          signed int16 Integration;
          signed int16 Derivation;
          signed int16 delta_duty;
          signed int16 duty_temp;
          
          #define Kp  10
          #define Ki  10
          #define Kd  4
          
          
          void PID_calculation (signed int velo_current, signed int velo_target)
          {
          
             velo_error_present = velo_target - velo_current;
             daoham1 = velo_error_present - velo_error_past;
             daoham2 = velo_error_present - 2*velo_error_past + velo_error_perfect;
          
             Proportion = Kp * daoham1;
             Integration = Ki * velo_error_present;
             Derivation = Kd * daoham2;
          
          
             delta_duty = (signed int16) (Proportion + Integration + Derivation);      // ep kieu
             //printf(" delta_duty = %ld", delta_duty);
          
             // ham chan gia tri van toc dieu khien de chong soc dong co
             if (delta_duty > 60)                                  // han che gia toc dieu khien
             {
                delta_duty = 60;
             }
             if (delta_duty < -60)
             {
                delta_duty = -60;
             }
          
             duty_temp = pwm_duty + delta_duty;        // dung bien tam de tranh bi sai
          
             if (duty_temp > 1023)
             {
                duty_temp = 1023;
             }
             if (duty_temp <-1023)
             {
                duty_temp = -1023;
             }
          
             if (duty_temp <0)                          // kiem tra dau cua pwm_duty
             {
                pwm_direction = 0;                      // gan vao pwm_direction la bien toan cuc
                pwm_duty = - duty_temp;                 // gan vao pwm_duty la bien toan cuc
             }
             else
             {
                pwm_direction = 1;
                pwm_duty = duty_temp;
             }
          }
          Bạn xem thử đoạn code mẫu này để hiểu sơ về cách viết pid cho động cơ.

          Mình sẽ giải thích kỹ hơn sau.
          Falleaf
          Công ty TNHH Thương mại và Giao nhận R&P
          58/57 Nguyễn Minh Hoàng - Phường 12 - Quận Tân Bình - TP.HCM
          mail@falleaf.net - VP: (04) 36408561 - (08) 38119870

          Comment


          • #6
            Code:
            //////////////////////////////
            // Dieu khien servo         //
            //////////////////////////////
            
            signed int velocity_expected;                     // van toc mong muon
            signed int velocity_temp=0;
            signed int32 delta=0;
            signed int32 delta1=0;
            signed int32 delta2=0;
            signed int32 delta3=0;
            float alfa = 0;
            
            int1 profile;
            
            // Nhan ngo vao la vi tri va van toc yeu cau co dau
            // Tra ra profile va van toc mong muon
            // Neu profile = 1 thi van toc mong muon la van toc max
            // Neu profile = 0 thi phai tra ra van toc mong muon
            
            void motion_profile(signed int16 pos_motion, signed int velo_motion)
            {
               if (velo_motion < 0)
               {
                  velo_motion = - velo_motion;           // gan gia tri duong vao de tinh toan
                  pwm_direction = 0;                     // cho quay theo chieu nguoc
               }
               else
               {
                  pwm_direction = 1;                     // quay theo chieu thuan
               }
            
               // Phuong trinh co dang nhu sau
               // v_expected^2 - (pos_commanded*acceleration/velo_commanded)*v_expected + pos_commanded*acceleration = 0
               //delta = (((pos_motion*acceleration)/velo_motion)*((pos_motion*acceleration)/velo_motion)) - (4*pos_motion)*acceleration;
               // lam giam bo nho phat sinh bang cach chia nho cong thuc tinh
               delta1 = pos_motion*acceleration;          // chia truoc de lam giam nho so
               delta1 = delta1/velo_motion;            //
               //printf("delta1 = %ld",delta1);
               delta3 = delta1*delta1;                   // delta1^2
               //printf("pos_motion =%ld",delta1);
               
               delta2 = (4*pos_motion);
               //printf("delta21 = %ld", delta2);
               delta2 = delta2*acceleration;
               //printf("delta2 = %ld", delta2);
               delta = delta3 - delta2;
            
               //delta = ((pos_motion*acceleration/velo_motion)*(pos_motion*acceleration/velo_motion) - 4*pos_motion*acceleration;
               // tinh delta
               // don vi o day la [xung^2/sampling_time^2]
            
               //printf("delta = %ld",delta);
               
               if (delta<0)
               {
                  //printf("delta am");
                  profile = 1;
                  velocity_expected = velocity_max;
               }
            
            // Phuong trinh vo nghiem khi van toc cao va khoang cach di chuyen ngan
            // Khi do khong the dap ung duoc van toc yeu cau, bat buoc phai dieu khien de sao cho qua trinh la nhanh nhat
            
            // motion profile co dang nhu sau
            //
            // v             /\
            //              /  \
            //             /    \
            //            /      \
            //           /        \
            //          /          \
            // ________/____________\____________t
            ////////////////////////////////////////////
            
            // Neu phuong trinh co nghiem
            // Se luon co hai nghiem duong phan biet
            // Cau hoi dat ra se la, neu cho chieu chuyen dong la chieu am thi sao?
            // Ta khong giai quyet o day, neu vi tri la am, thi co nghia la chieu chuyen dong am
            // Tat ca cac tinh toan o day khong thay doi
            // Viec nay se duoc tinh toan boi may tinh
            
               else
               {
                  //printf("delta duong");
                  profile = 0;
            
            // motion profile trong truong hop co nghiem co dang sau
            //
            //  v
            //              ------------------   v_mong muon >> voi gia toc xac dinh, tinh ra van toc mong muon
            //             /                  \
            //            /____________________\    v_max >> van toc lon nhat cua dong co
            //        ___/______________________\___   v_commanded >> tinh van toc trung binh toan bo quang duong
            //       |  /                        \  |
            //       | /                          \ |
            //       |/                            \|      t
            //------------------------------------------------
            //
            // Neu van toc mong muon lon hon van toc toi da
            // phai dieu khien o van toc toi da
            // Neu van toc mong muon nho hon van toc toi da
            // thi dieu khien o van toc mong muon
            //////////////////////////////////////////////////////////////
            
                  //velocity_temp = (((pos_motion*acceleration)/velo_motion) - sqrt(delta))/2;
                  alfa = (float) delta;
                  //printf ("alfa = %f", alfa);
                  alfa = sqrt(alfa);
                  //printf ("alfa* = %f", alfa);
                  delta = (signed int32) alfa;
                  //printf ("delta = %ld", delta);
                  velocity_temp = delta1 - delta;
                  //printf("delta1 = %ld", delta1);
                  //printf("delta_sqrt = %d", velocity_temp);
                  // chon nghiem nho vi nghiem lon co the luon lon hon velocity_max
                  // nghiem la so thuc
                  //printf("velocity_temp = %ld", velocity_temp);
            
            
                  if (velocity_temp > velocity_max)      // neu van toc lon hon van toc gioi han
                  {
                     velocity_expected = velocity_max;   // don vi xung/sampling_time
                  }
                  else                                   // neu van toc nho hon van toc gioi han
                  {
                     velocity_expected = velocity_temp;      // ep kieu ve signed long
                  }
               }
               printf("velocity_expected = %d", velocity_expected);
            }
            Falleaf
            Công ty TNHH Thương mại và Giao nhận R&P
            58/57 Nguyễn Minh Hoàng - Phường 12 - Quận Tân Bình - TP.HCM
            mail@falleaf.net - VP: (04) 36408561 - (08) 38119870

            Comment


            • #7
              Xin cảm ơn đồng đạo đã hỗ trợ nhiệt tình, tại hạ đang cố công học hỏi, có gì sẽ bắn tin sau. Mong có nhiều thêm bàn tay vỗ nước để tạo nên sóng công thành.
              Ở đời khác thường, làm sự nghiệp phi thường...Cùng thì tự tốt lấy ta, đạt thì đem hạnh phúc cho thiên hạ.---(Gia Cát Khổng Minh)

              Comment


              • #8
                Bác Falleaff ơi, help help, help me !

                Xin hỏi bác Falleaf tý chút:
                - Tui điều khiển động cơ DC bằng cách phát ra các xung PWM từ PSoC.Thu về tốc độ động cơ để làm PID. Vậy làm cách nào để ánh xạ giữa Tần số thu về và Độ rộng xung (0-65535). Tức là khi tính eror trên PSoC bằng PID thì đó là các dung sai về tốc độ, vậy làm cách nào để từ đó ta suy ra được độ rộng xung tương ứng cần PSoc phát ra để chỉnh cho sai số này về 0.Phải chăng cái này chỉnh bằng hệ số tỷ lệ Kp và chỉnh bằng phương pháp thực nghiệm (thử và sai)
                -Phương pháp nào để mô hình hóa một động cơ DC 12V, điều khiển bằng PSoc thông qua một mạch cầu công suất H để có thể từ đó viết hàm truyền đạt của hệ thống hòng áp dụng thuật toán PID (Tui dùng phương pháp thứ hai của Nichols-Ziegle, phương pháp xác định tham số PID bằng thực nghiệm )
                Ở đời khác thường, làm sự nghiệp phi thường...Cùng thì tự tốt lấy ta, đạt thì đem hạnh phúc cho thiên hạ.---(Gia Cát Khổng Minh)

                Comment


                • #9
                  Xin lỗi vì không có thời gian trả lời, chắc bạn cũng giải quyết xong vấn đề mất tiêu rồi, vì diễn đàn quá rộng, tôi không thể nhớ đã viết gì và trả lời gì cho ai. Mong bạn thông cảm. Nếu bạn còn cần, chúng ta vẫn có thể tiếp tục thảo luận.

                  Các bạn cứ viết bài lên diễn đàn, nếu cần chỉ đích danh tôi xem bài thì các bạn cứ nhắn vào tin nhắn cá nhân và đưa link của diễn đàn. Đừng viết bài vào tin nhắn cá nhân vì tôi sẽ không trả lời vấn đề kỹ thuật trên tin nhắn cá nhân (vì không có thời gian).

                  Mong các bạn thông cảm.

                  PS> không phải câu nào tôi cũng biết trả lời (đơn giản tôi là Falleaf, chẳng phải súp pờ men)

                  Chúc vui.
                  Falleaf
                  Công ty TNHH Thương mại và Giao nhận R&P
                  58/57 Nguyễn Minh Hoàng - Phường 12 - Quận Tân Bình - TP.HCM
                  mail@falleaf.net - VP: (04) 36408561 - (08) 38119870

                  Comment

                  Về tác giả

                  Collapse

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

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

                  Collapse

                  Đang tải...
                  X