PIC Vietnam

Go Back   PIC Vietnam > Robotics > Điều khiển

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Tìm Kiếm Bài Trong Ngày Ðánh Dấu Ðã Ðọc Vi điều khiển

Điều khiển Lý thuyết điều khiển và ứng dụng lý thuyết điều khiển trong những trường hợp thực tế

 
 
Ðiều Chỉnh Xếp Bài
Prev Previous Post   Next Post Next
Old 07-04-2009, 12:53 PM   #1
mrnumb2010
Nhập môn đệ tử
 
Tham gia ngày: Mar 2009
Bài gửi: 2
:
Question xin giúp đỡ về chương trình PID cho pic 16f877a

Hiện mình đang gặp vấn đề về chương trình điều khiển điều khiển cho mô hình đồ án. Đồ án của mình như sau : Sử dụng vi điều khiển để điều khiển nam châm điện hút một vật (có gắn nam châm vĩnh cửu) treo "lơ lửng " theo phương đứng với 1 khoảng cách cho trước.Vị trí của vật được xác định nhờ 1 cảm biến từ trường.Cảm biến này đưa về giá trị áp (tuyến tính)
tùy theo vị trí của vật dựa trên hiệu ứng hall.Khi không có từ trường thì điện áp của chân ra luôn là 50% điện áp cấp cho nó (với vdd= 5v thì áp ra là 2.5v).Khi có từng trường (nam châm vĩnh cửu gắn trên vật) thì điện áp ra sẽ thay đổi tuyến tính. Phần cứng của mình như sau:
-Mạch điều khiển : gồm có vi điều khiển pic 16f877a và các chân in/out đưa ra : chân an0 đọc giá trị analog từ cảm biến xác định khoảng cách. chân an1 đọc điện áp so sánh(là vdd của pic = 5v) .Từ việc so sánh giá trị áp này có thể xác định khoảng cách của vật cần điều khiển.
-Mạch công suất mình sử dụng con LM18200 với 3 chân điền khiển
chân brake(thắng) nối với pin 15 của pic
chân pwm nối với pin 16 (ccp2) của pic
chân direction nối với pin 18 của pic
Mình sắp xếp sao cho khi đưa vật lại gần thì áp ra của cảm biến giảm theo (giảm từ 2.5v ->0v)
Vị trí cân bằng mình set là v=1.4v (khi vật ở khoảng 1.5cm thì điện áp của cảm biến bắt đều thay đổi, nhưng do giới hạn của lực từ do nam châm điện tạo ra nên mình đặt ở khoảng cách gần hơn- nam châm điện cấp nguồn 12v)
Giải thuật của mình như sau: khi điện vật ở vị trí set thì tắt nam châm, khi vật ở xa (phía dưới) thì cho nam châm hút, khi vật lại gần thì cho nam châm đẩy.
Mình đã viết chương trình chạy thừ (dạng on/off) thì chỉ có thể treo được khoảng 2s và mất ổn định rất nhanh( vật dao động liên tục và rớt xuống) .
Vậy các bác ai có từng làm về điều khiển (theo mình nghĩ phải dùng pid) thì cho mình xin ý kiến với.Hiện giờ mình chưa làm được nên rất lo lắng.
Đây là chương trình mình đã viết bằng ccsc


Code:
#include <16F877A.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#device  ADC=8
#use delay(clock=20000000)
#use fast_IO(B)
#define max_pwm 1023
#define min_pwm 128

float k ;

float analog;

float vref;
float target;

float e;
int16 value1;
signed int16 pw_duty;


unsigned long kp =10; //he so ti le
 
void adc();
void pwm2(int16 value1);
void pid();

void convert();

void main()
{
   
   while (true)
     {  
       
        adc();
           //doc adc
         // xet dieu kien
       convert ();

         
       if ( k==0.28) // nam cham tat neu o vi tri can bang
            {
              output_high(PIN_C0);
              output_high(PIN_C3);
              pwm2(pw_duty);
              
            }
        else if (k<0.28)//nam cham day 
            {
              output_low(PIN_C0);
              output_high(PIN_C3);
               pwm2(pw_duty);
               
         }
       else if (k>0.28) //nam cham hut
       {
              output_low(PIN_C0);
              output_low(PIN_C3);
                pwm2(pw_duty);
                      }
    
                        }
     
     }
void pwm2(int16 value1)
{
   setup_ccp2(CCP_PWM);
   setup_timer_2(T2_DIV_BY_16,255,1);
   set_pwm2_duty(value1);
}

void adc()
{
   Setup_ADC(ADC_clock_DIV_8);
   Setup_ADC_ports(all_analog); 
   set_adc_channel(0);      
   delay_us(10);            
   analog=(float)read_adc();
   
   set_adc_channel(1);      
   delay_us(10);            
   vref=(float)read_adc();  //doc gia tri ap tham khao = vdd cua pic
   target = vref/2; //vi tri set
   k=(analog/vref);
   e = target - analog ; //sai so  cua vi tri
   
       if    (e<0)
         pw_duty =-kp*e;
       else if  (e>0) 
         pw_duty = (kp*e);
       else
         pw_duty = 0;
}
  void convert()
     
     {  if       (pw_duty<min_pwm)
              
              pw_duty = min_pwm  ;
              
       else if   (pw_duty> max_pwm)
              
              pw_duty = max_pwm ;
       else 
              
              pw_duty = pw_duty;
     }

Rất monh nhận đượcc sự giúp đỡ của các bác.

thay đổi nội dung bởi: namqn, 07-04-2009 lúc 03:16 PM. Lý do: định dạng code
mrnumb2010 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
 

Ðiều Chỉnh
Xếp Bài

Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 01:03 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam