Chia sẻ Điều khiển động cơ bằng phương pháp PID với PIC

daotruongpro

http://vtechpro.vn
#1
Thấy có mấy bạn cứ thích dùng PIC không thích AVR cho đề tài PID này lắm. Mình chuyển code cho bạn nào dùng PIC nhé !
PID.png


Mã:
/******************************************************************************
Project : DKDC PP PID
Version : V2.0
Date    : 21/02/2013
Update  : 19/09/2013
Author  : Dao Xuan Truong
Company : vtechpro.vn
Comments:

Chip type               : PIC16F88
Program type            : Application
Clock frequency         : 10,000000 MHz

******************************************************************************/
#include "PID1.h"
//Dinh nghia cac duong dieu khien motor
#define Sampling_time        50     //thoi gian lay mau (ms)
#define inv_Sampling_time    20     // 1/Sampling_time
#define PWM_Period           1023

unsigned int16 Pulse=0,pre_Pulse=0;
signed long rSpeed=0,Err=0 , pre_Err=0; //thanh phan PID
float Kp=5, Kd=0.6, Ki=2.4; //thanh phan PID
float pPart=0, iPart=0, dPart=0; //thanh phan PID
unsigned long Ctrl_Speed=10;     //van toc can dieu khien (desired speed)
unsigned int16 Output;// absrSpeed;
unsigned char sample_count=0;
void Motor_Speed_PID(long int des_Speed);

#int_EXT
void  EXT_isr(void)
{
if(!input(PIN_B0))Pulse++;
else Pulse--;
}

#int_TIMER1
void  TIMER1_isr(void)
{
    Set_timer1(3035);//25ms
    sample_count++;
    Motor_Speed_PID(Ctrl_Speed);
}
 
void Motor_Speed_PID(unsigned long des_Speed){
   
    rSpeed=Pulse-pre_Pulse;     //tinh van toc (trong sampling time)
    pre_Pulse=Pulse;
    Err=des_Speed-abs(rSpeed);  //tinh error (loi)
    pPart=Kp*Err;
    dPart=Kd*(Err-pre_Err)*inv_Sampling_time;
    iPart+=Ki*Sampling_time*(Err+pre_Err)/2000;
    Output +=pPart+dPart+iPart;     //cong thuc duoc bien doi vi la dieu khien van toc
    if (Output >PWM_Period) Output=PWM_Period-1;
    if (Output <=0) Output=1;
    set_pwm1_duty((int16)Output); //gan duty cycle cho CCP1 update PWM   
    pre_Err=Err;  //luu lai gia tri error 
}

void main()
{
   set_tris_a(0xff);
   //set_tris_b(0x01);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
   setup_timer_2(T2_DIV_BY_16,255,1);
   setup_ccp1(CCP_PWM);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_EXT);
   ext_int_edge( H_TO_L );   // Sets up EXT
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   while(true)
   {
   ;
   }
}[CODE]
 

Đính kèm

Sửa lần cuối:

tiennp

Học sinh phổ thông
#2
Chào bạn, mình đang làm mạch này bằng con 16f887 , dùng IC l298 làm mạch cầu H thì các chân EN,PWM,DIR nối vào các chân nào của Vđk?
 
#3
Hey, anh không hiểu chỗ này:
Em khai báo biến Output là unsigned int16:
aa.JPG


Nhưng trong hàm Motor_Speed_PID():

aa.JPG

Điều kiện Output < 0 sẽ không xảy ra. Thay vào đó nó sẽ tràn qua unsigned int16.
Và khi đó Output của em còn đúng?
Liệu có khi nào nó chạy quá nhanh và Output được tính lại nên mình không thấy được?
 

daotruongpro

http://vtechpro.vn
#4
Hey, anh không hiểu chỗ này:
Em khai báo biến Output là unsigned int16:
Xem đính kèm 12711

Nhưng trong hàm Motor_Speed_PID():

Xem đính kèm 12712
Điều kiện Output < 0 sẽ không xảy ra. Thay vào đó nó sẽ tràn qua unsigned int16.
Và khi đó Output của em còn đúng?
Liệu có khi nào nó chạy quá nhanh và Output được tính lại nên mình không thấy được?
hi a.
Biến Output ở đây là một biến đệm để so sánh rồi update vào hàm set PWM(); thôi
Output ở đây luôn luôn <1023 và lớn hơn 0; không có trường hợp khác. nếu muốn debug các biến này có thể in ra UART tuy nhiên phải chú ý set tốc độ baud nếu không sẽ bị lỗi font khi in ra.
 

NguyenTin

Học sinh phổ thông
#5
anh cho e hỏi về động cơ bước :Giả sử mạch yêu cầu giữ dòng ổn định thì phần cứng mình sẽ phải thiết kế như thế nào. Tức là phần đo dòng phản hồi từ động cơ bước về.
 

tiennp

Học sinh phổ thông
#6
cho mình hỏi sao tính vận tốc lại là
rSpeed=Pulse-pre_Pulse;
giá trị này là số xung encoder đọc dc trong thời gian sampling time.
 

mta_cdt

Super Moderator
Thành viên BQT
#7
cho mình hỏi sao tính vận tốc lại là
rSpeed=Pulse-pre_Pulse;
giá trị này là số xung encoder đọc dc trong thời gian sampling time.
Quãng đường đi được trong 1 đơn vị thời gian là vận tốc mà bạn.
 

daotruongpro

http://vtechpro.vn
#8
Đề tài PID sử dụng Nhiệt độ làm phần tử điều khiển
Nhận tín hiệu điều khiển từ cảm biến nhiệt độ và điều khiển động cơ, Phần tử điều khiển có thể là Lò nhiệt OVEN hay cái gì đó, thuật toán thì tương tự chỉ thay đổi 1 chút ít là xong.
PID Temp.jpg
 

Đính kèm

Nguyenxxx

Học sinh phổ thông
#9
cho e hỏi quan hệ giữa giá trị Output sau khi tính dc với việc điều chỉnh xung pwm là như thế nào, vì đầu vào là giá trị xung encoder còn đầu ra là điều chỉnh duty pwm, em đang băn khoăn chuyện này, a chỉ giúp em với, thanks nhiều nhiều :D
 

daotruongpro

http://vtechpro.vn
#10
cho e hỏi quan hệ giữa giá trị Output sau khi tính dc với việc điều chỉnh xung pwm là như thế nào, vì đầu vào là giá trị xung encoder còn đầu ra là điều chỉnh duty pwm, em đang băn khoăn chuyện này, a chỉ giúp em với, thanks nhiều nhiều :D
- Output được tính như sau:
+. Nếu tốc độ của hệ thống thấp hơn tốc độ đặt -> Tăng giá trị Output -> Tăng PWM lên.
+. Nếu tốc độ của hệ thống cao hơn tốc độ đặt -> Giảm giá trị Output -> Giảm PWM xuống.
- Encoder để đọc xung -> tính được tốc độ.
Chỉ có vậy thôi:):):)
Tham khảo thêm tại đây: Chia sẻ - Điều khiển động cơ bằng phương pháp PID hiển thị LCD | Cộng đồng cơ điện tử Việt Nam | Mechatronics
 

Quảng cáo Google