MİKRODENETLEYİCİLER 13.HAFTA
Doç.Dr. Serdar KÜÇÜK
Doç. Dr. Serdar Küçük
PID KONTROL NEDİR?
Kontrol Nedir?
• Kontrol: Bir sistemin istenilen davranışları göstermesini sağlamaktır.
• Kontrol sinyali sisteme uygulanır.
• Sistemin kontrol sinyaline göre davranışları ölçülerek sistemin ilk başlangıcına geri dönüt olarak gönderilir.
• Bu sisteme kapalı çevrim kontrollü sistem diyoruz.
SK-2011 3
Kapalı Çevrim Sistemler
• Sistem, özel bir niceliğin kontrol edildiği herhangi bir mekanizma, süreç veya tesisattır.
• Kontrolör, hata değerine göre sisteme uygun giriş sağlayan düzenektir.
• Geri besleme, sistem çıkışlarının ölçüldüğü birimdir.
SK-2011 4
PID Kontrol Nedir?
• PID kontrol sistemi Oransal, İntegral ve Türevsel (Proportional‐Integral‐
Derivative) kazançların toplam etkisiyle oluşturulan bir kontrol sistemidir.
• PID Kontrol yönteminin alt basamakları olarak P Kontrol, PI Kontrol, PD Kontrol yöntemleri de mevcuttur.
• Sistemin davranışını en iyi şekilde düzenleyen PID kontrol yöntemidir.
SK-2011 5
PID Kontrol Yöntemi
• Günümüzde çok çeşitli kontrol yöntemleri kullanılmaktadır. Fakat bunlar içerisinde en köklü olan ve en yaygın kullanım alanına sahip olan PID kontrol yöntemidir.
• Yaygın olmasına rağmen hala parametreleri belirleyen standart bir tanımlama yoktur denilebilir.
• PID denetimi daha çok doğrusal ve basit yapıda tek döngülü sistemlere uygulanır.
• Doğrusal olmayan ve özellikle ölü zaman gecikmesi sistem zaman gecikmesi yanında çok büyük olan sistemlerde uygulanması zordur.
SK-2011 6
PID Kontrol Matematiksel İfadesi
• r(t) : Referans sinyali
• y(t) : Çıkış sinyali
• e(t) : Hata sinyali
• u(t) : Kontrol sinyali
• K
p: Oransal kazanç (Proportional Gain)
• K
i: Integral kazancı (Integral Gain)
• K
d: Türev kazancı (Derivative Gain)
PID Kontrol Denklemi
• Burada K
p– K
i– K
dPID kontrol parametreleridir. Denklemi sadeleştirdiğimizde;
• denklemi elde edilir. Kontrol sinyalininin oransal etkisi P(t), integral etkisi I(t), türevsel etkisi D(t) olacaktır.
• Birim geribeslemeli kapalı çevrim sistem blok diyagramı
PID Parametrelerinin Belirlenmesi
• Mevcut sistem üzerinde PID kontrol yöntemi uygulandığında temelde sistemin iki farklı cevabı olabilir.
• Ya sistem kararlı bir hale geçecek, ya da kararsızlık oluşacak ve sistem hiçbir zaman referans değerine oturmayacaktır.
• Bunu belirleyen PID kontrol yöntemi parametreleridir.
SK-2011 9
PID Parametreleri
• PID kontrolörden alınan kontrol sinyaline sistemin verdiği etkilerde şu durumlar gözlenir:
– Yükselme zamanı
• Rise time – Üst aşım miktarı
• Overshoot – Oturma zamanı
• Settling time – Kalıcı durum hatası
• Steady‐State Error
SK-2011 10
PID Parametrelerinin Etkileri
• Oransal denetleyicilerin (K p ), yükselme zamanını azaltmada etkisi vardır ve azaltır, ama asla tamamen yok etmez (kararlı hal hatası).
• İntegral denetleyicinin (K i ) kararlı hal hatasının çıkarılmasında etkisi vardır ancak bu geçici tepkinin daha kötü olmasına sebep olabilir.
• Türevsel denetleyicinin (K d ) sistemin kararlılığının artmasında etkisi vardır, aşmayı azaltır ve geçici tepkiyi düzeltir.
SK-2011 11
PID Parametrelerinin Etkisi
• Kapalı döngülü bir sistemde, her bir denetleyicinin etkisi K p , K d ve K i aşağıdaki tabloda özet olarak gösterilmiştir.
• Tabloda verilen bu düzeltmeler tek başına tam olarak geçerli değildir.
• Çünkü K p , K i ve K d birbirlerine bağımlıdırlar. Yani değişkenlerden birinin değişimi diğer ikisinin etkisini değiştirebilir.
• Bu yüzden tablo K i , K p ve K d değerlerinin belirlenmesinde sadece bir referanstır.
SK-2011 12
Kapalı Çevrim Cevabı
Yükselme Zamanı (Rise Time)
Üst Aşım (Overshoot)
Oturma Zamanı (Settling Time)
Kalıcı Dur. Hata (SS‐Error)
Kp Azalır Artar Az değişir Azalır
Ki Azalır Artar Artar Yok olur
Kd Az değişir Azalır Azalır Az değişir
CCS C İLE
PIC PROGRAMLAMA
UYGULAMA 13_01
• Bir DC Motorun pozisyon kontrolü çalışması yapılmak istenmektedir.
• Bunun için pid kontrol algoritması kullanılacaktır.
• MATLAB ortamında hazırlanan arayüz programı ile seri port üzerinden haberleşecek olup veri transferi ve parametre ayarları yapılmasına izin verilecektir.
• Aynı zamanda veriler PORTD’ye bağlı 4*20 Text LCD ile görüntülenecektir.
• Gerekli CCS C pic programlama kodunu yazınız.
• Uygulama devresini kurarak çalışmasını sağlayınız.
• PID kontrol için uygun parametre seçimini belirleyiniz.
SK-2011 14
Servo Motor Tanımı
• Servo kelimesi Servant ‐ serv den gelir, hizmet eden demektir.
• Aslında servo motor diye bir alet yoktur. Bir motora yaptığı işi kontrol edebileceğiniz bir mekanizma ekleyip bir şekilde kontrol mekanizması yaptığınızda servo elde edersiniz.
• Servo, sistemin hareketini sağlayan birimdir.
• Servo sistemlerde motor tipi, uygulamanın yapısına göre hidrolik, pnomatik ve elektrik motoru olarak değişir.
• Ancak günümüzde uygulamanın zorunluluğu dışında en çok elektrik motorları kullanılmaktadır. Sistemlerde çeşitli yapıdaki farklı elektrik motorları kullanılabilmektedir.
Kullanılacak DC Motor
• DC Motor Özellikleri:
– Voltage: 24 VDC
– Continuous torque (Tc) = 1,8.10
‐2Nm – Peak torque (Tpk) = 1,2.10
‐1Nm – No load speed 10,158 rpm
– Torque Constant (Kt) = 2,18.10
‐2Nm / amp – Voltage Constant (Ke) = 2,18.10
‐2V / (rad/sn) – Viscouse Damping (Bm) = 1,4.10
‐6Nms – Resistance (R) = 4.33 ohms
– Inductance (I) = 2.34 mh – Length (motor only) = 3.04«
• Dişli Kutusu
– 181:1 oranlı dişli kutusu
• Encoder
– 100 ppr, 3 channel (A,B,I) optical encoder
Pittman 24V DC Motor
SK-2011 17
Motor Geri Bildirim Elemanı
• Motorlarda geribildirim amacıyla temelde 2 tip sensör kullanımı vardır.
Bunlar enkoder ve resolver’dir.
• Enkoder pozisyon kontrolü işlemlerinde tercih edilirken, resolver hız kontrol işlemlerinde kullanılmaktadır.
• Enkoderlerin çalışmasının altında opto‐kuplör mantığı bulunmaktadır.
• Opto‐kuplör optik alıcı ile led elemanlarının bir kılıf altında toplanmasıyla oluşur.
• Led’e enerji verildiğinde ledin ışığından etkilenen alıcı eleman karşı tarafta durum değiştirmektedir.
SK-2011 18
Enkoder ile Geri Bildirim
• Enkoder içerisinde, opto‐kuplör kolları arasına üzeri delikli bir disk yerleştirildiğinde ışığın karşıya geçmesi ve kesilmesine bağlı olarak pozisyon bilgisi elde edilir.
• Diskin dönmesiyle transistör tarafında palsler oluşacaktır.
• Bu palslerin sayılması ile pozisyon bilgisi elde edilir.
• A‐B kanallarından bilginin alınmasına bağlı olarak motorun saat yönü veya tersi yönde döndüğü tespit edilir.
SK-2011 19
Mikrodenetleyici Seçimi
• Sistemde geri bildirim elemanı enkoderden verileri okuyabilmek için mutlaka QEI(Quadrature Encoder Interface) modülü bulunan mikrodenetleyici seçimi yapılmalıdır.
• Bu tarz motor çalışmalarında kullanılmak üzere Microchip Firmasına ait
‘Motion Feedback Module’ birimi bulunan entegreler mevcuttur.
• Enkoder okuma özelliği bulunan diğer PIC mikrodenetleyicileri,
– dsPIC30F4011 (40pin 1 enc), dsPIC30F4012 (28pin 1 enc),
– dsPIC33FJ128MC804 (44pin 2 enc), dsPIC33FJ128MC802 (28pin 2 enc),
SK-2011 20
PIC18F4431 Mikrodenetleyicisi
• 16K program hafıza, 768 Byte Ram hafıza, 256 Byte EEPROM hafıza
• 36 adet I/O pini
• 9 kanal 10 bit ADC modülü
• 40Mhz’e kadar esnek osilatör yapısı (10MIPS)
• 2 adet CCP modülü
• 1 adet EUSART modülü
• SSP modülü (SPI ve I2C iletişim)
• 1 adet 8 bit, 3 adet 16 bit zamanlayıcı
– Timer0, Timer1, Timer2, Timer5
• 14 bit power PWM modülü
• Motion feedback modülü
– 3 adet bağımsız giriş yakalama kanalı (Input Capture)
– Enkoder geri bildirim arayüzü (Quadrature Encoder Interface ‐ QEI)
SK-2011 21
PIC18F4431 Mikrodenetleyicisi
SK-2011 22
Quadrature Encoder Interface QEI PID Kontrol Algoritması
• Kontrolör Çıkışı
• Hata değerinin türevi ve integrali
– Sürekli artan hata Türevi İntegrali
– Sabit değerli hata Türevi İntegrali
PID Kontrol Algoritması
• Türev Fonksiyonu
• Türev almak, fonksiyona ait eğimin bulunmasıdır.
•
• d(error) = error – last_error
– error : hata değeri – last_error : son hata değeri
• İntegral Fonksiyonu
• İntegral almak, fonksiyonun altında kalan alanın bulunmasıdır.
• İntegral(error) = error + sumERROR
SK-2011 25
PID Kontrol Algoritması
• PID kontrol işleminin algoritmasının uygulanabilmesi için sistemin çıkışından bir geri bildirim değeri alınmalıdır.
• Geri bildirim alma işlemi dijital sistemlerde sürekli durumda yapılamaz.
• Ayrık zamanlı kontrol yapılmalıdır. Bunun için sensörlerden alınan bilgi ve buna bağlı kontrol çıkışı sabit zaman aralıklarında olmalıdır.
• Daha sonra alınan geri bildirim değeri ile referans değer arasındaki hata hesaplanmalıdır.
• Daha sonra sırayla oransal, integral ve türevsel terimlere ait ifadeler hesaplanır.
SK-2011 26
PID Kontrol Algoritması
• DC motor pozisyon kontrolü için pid algoritması
– cur_pos = read_pos(); //mevcut pozisyonun okunması – error = ref_pos - cur_pos ; //hatanın belirlenmesi
– der_error = error – last_error; //türev alma – sum_error = error + sum_error; //integral alma
– prop_term = Kp * error; //oransal etki
– intg_term = Ki * sum_error; //integral etkisi
– der_term = Kd * der_error; //türevsel etki
– sum_pid = prop_term + intg_term + der_term;
– //pid sonucu = oransal + integral + türevsel
– last_error = error; //sonraki adım için son hata değeri güncellemesi
SK-2011 27 SK-2011 28
Kontrol Kartı ve Motor Sürücü Kartı Baskı Devre Şeması
SK-2011 29
Power PWM modülü ile ilgili Kaydediciler
SK-2011 30
QEI Modülü ile ilgili Kaydediciler CAPxCON Kaydedicileri
QEICON Kaydedicisi
SK-2011 33
DFLTCON Kaydedicisi
SK-2011 34
• Setup_qei()
• setup_qei(qei_mode, filter_mode);
• Qei_mode
– #define QEI_DISABLED 0 – #define QEI_VELMODE_ON 0x00 – #define QEI_VELMODE_OFF 0x80 – #define QEI_MODE_X2 0x00 – #define QEI_MODE_X4 0x10 – #define QEI_RESET_WHEN_MAXCOUNT 0x08 – #define QEI_RESET_WHEN_IDX_PULSE 0x04 – #define QEI_VPREDUC_DIV_BY_1 0x00 – #define QEI_VPREDUC_DIV_BY_4 0x01 – #define QEI_VPREDUC_DIV_BY_16 0x02 – #define QEI_VPREDUC_DIV_BY_64 0x03
SK-2011 35
• Setup_qei()
• Filter mode
– #define QEI_FILTER_ENABLE 0x78 – #define QEI_FILTER_DISABLE 0x00 – #define QEI_FILTER_DIV_1 0x00 – #define QEI_FILTER_DIV_2 0x01 – #define QEI_FILTER_DIV_4 0x02 – #define QEI_FILTER_DIV_16 0x03 – #define QEI_FILTER_DIV_32 0x04 – #define QEI_FILTER_DIV_64 0x05 – #define QEI_FILTER_DIV_128 0x06
SK-2011 36
• QEI.h include file
• #BYTE INTCON=0x0FF2
• #BYTE IPR3=0x0FA5
• #BYTE PIE3=0x0FA3
• #BYTE QEICON = 0x0FB6 // quadrature configure
• #bit QEICONDIR = 0x0FB6.5
• #bit QEICONOVERROR = 0x0FB6.6
• #BYTE DFLTCON = 0x0F60 // quadrature noise filter configure
• #BYTE CAP1BUFL = 0x0F69 // velocity register
• #BYTE CAP1BUFH = 0x0F68
• #BYTE CAP2BUFL = 0x0F66 // position counter
• #BYTE CAP2BUFH = 0x0F67
• #BYTE CAP3BUFL = 0x0F64 // max count
• #BYTE CAP3BUFH = 0x0F65
• #BYTE CAP1CON = 0x0F63
• #BYTE CAP2CON = 0x0F62
• #BYTE CAP3CON = 0x0F61
• #BYTE T5CON = 0x0FB7
• #BYTE TMR5H = 0x0F88
• #BYTE TMR5L = 0x0F87
• #BYTE PR5H = 0x0F91
• #BYTE PR5L = 0x0F90
SK-2011
UY GULAMA_13_01
37• QEI.h include file
• void set_qei_max_count(int16 conf)
• {
• CAP3BUFH = make8(conf,1);
• CAP3BUFL = make8(conf,0);
• }
• void set_qei_count(signed int16 cntr)
• {
• CAP2BUFH = make8(cntr,1);
• CAP2BUFL = make8(cntr,0);
• }
• void set_qei_velocity(signed int16 cntr)
• {
• CAP1BUFH = make8(cntr,1);
• CAP1BUFL = make8(cntr,0);
• }
• signed int16 get_qei_count(void)
• {
• signed int16 cnt;
• return cnt = make16(CAP2BUFH,CAP2BUFL);
• }
SK-2011
UY GULAMA_13_01
38• QEI.h include file
• ……
• signed int16 get_qei_velocity(void)
• {
• signed int16 vel;
• return vel = make16(CAP1BUFH,CAP1BUFL);
• }
• void setup_qei(int8 mode, int8 filter, signed int maxcount)
• {
• QEICON=mode;
• DFLTCON=filter;
• CAP1CON = 0x40;
• }
• int1 get_qei_dir(void)
• {
• return QEICONDIR;
• }
• int1 get_qei_overror(void)
• {
• return QEICONOVERROR;
• }
UY GULAMA_13_01
motion_cont.c
• #include <18F4431R.h>
• #device adc=10
• #FUSES NOWDT //No Watch Dog Timer
• #FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
• #FUSES H4 //High speed osc with HW enabled 4X PLL
• #FUSES NOPROTECT //Code not protected from reading
• #FUSES IESO //Internal External Switch Over mode enabled
• #FUSES BROWNOUT //Reset when brownout detected
• #FUSES BORV27 //Brownout reset at 2.7V
• #FUSES NOPUT //No Power Up Timer
• #FUSES NOCPD //No EE protection
• #FUSES STVREN //Stack full/underflow will cause reset
• #FUSES NODEBUG //No Debug mode for ICD
• #FUSES NOLVP //Low Voltage Programming on B3 or B5
• #FUSES NOWRT //Program memory not write protected
• #FUSES NOWRTD //Data EEPROM not write protected
• #FUSES FCMEN //Fail-safe clock monitor enabled
• #FUSES NOWINEN //WDT Timer Window Disabled
• #FUSES T1LOWPOWER //Timer1 low power operation when in sleep
• #FUSES HPOL_LOW
• #FUSES NOWRTC //configuration not registers write protected
• #FUSES NOWRTB //Boot block not write protected
• #FUSES NOEBTR //Memory not protected from table reads
• #FUSES NOEBTRB //Boot block not protected from table reads
• #FUSES NOCPB //No Boot Block code protection
• #FUSES LPOL_HIGH //Low-Side Transistors Polarity is Active-High (PWM 0,2,4 and 6)
• #FUSES PWMPIN //PWM outputs disabled upon Reset
• #FUSES MCLR //Master Clear pin enabled
• #FUSES FLTAC1 //FLTA input is multiplexed with RC1
UY GULAMA_13_01
motion_cont.c
• ……
• #use delay(clock=40M, oscillator=10M)
• #use rs232(baud=115200,parity=N,uart1, bits=8)
• #include <LCD.h>
• #include <QEI.h>
• #define LEDL PIN_C1
• #define LEDR PIN_C0
• #define CH_A PIN_A3
• #define CH_B PIN_A4
• #define CH_I PIN_A5
• #define PWM_OUT PIN_B0
• #define BRAKE_OUT PIN_B3
• #define DIR_OUT PIN_B2
• #define LEFT PIN_E0
• #define RIGHT PIN_E2
• #define MIDDLE PIN_E1
• ……
SK-2011
UY GULAMA_13_01
41motion_cont.c
• ……
• signed int16 pos=0, posdeg=0;
• signed int16 pwm_rat=0;
• signed int16 maxpos=36200;
• signed int16 middeg=18100;
• unsigned int16 qei_value = 0;
• signed int16 const_term=0;
• signed int16 Kp=400, Ki=2, Kd=40, Ks=1, Kidiv=1;
• signed int16 limitdeg=90, stepdeg=5;
• signed int16 reqpos=0, refpos=0;
• signed int16 reqdeg=0, refdeg=0;
• signed int32 refdeg32=0, posdeg32=0;
• signed int32 errordeg=0, sumERRdeg = 0, last_errordeg=0, derv_error=0;
• signed int32 prop_term=0, intg_term=0, deriv_term=0;
• signed int32 sum_pid=0; //function return value
• unsigned int16 vel=0;
• int8 sampling=0, sampling_ratio=20, bufind=0;
• int8 bi=0;
• signed int16 readed=0;
• signed int16 pidbuf=0;
• signed int16 pwmbuf[101];
• signed int16 posbuf[101];
• signed int16 velbuf[101];
• unsigned int16 quadhigh=0;
• int16 pidcont_pwmgen(signed int16);
• void test (void);
SK-2011
UY GULAMA_13_01
42motion_cont.c
• ……
• #int_IC2QEI
• void QuadRollover(void)
• {
• QEICONDIR?quadhigh++:quadhigh--;
• //output_toggle(LEDR);
• }
• #int_TIMER2 //for discreete time control
• void timer2_isr(void)
• {
• output_toggle(PIN_C0);
• vel = get_qei_velocity();
• pwm_rat = pidcont_pwmgen(refdeg);
• set_power_pwm0_duty(pwm_rat);
• if(sampling<sampling_ratio)
• {
• sampling++;
• }
• else
• {
• sampling=0;
• if(bufind<100)
• {
• pwmbuf[bufind] = pidbuf;
• posbuf[bufind] = posdeg;
• velbuf[bufind] = vel;
• bufind++;
• }
• }
• }
SK-2011
UY GULAMA_13_01
43motion_cont.c
• ……
• #int_IC1
• void IC1_isr(void)
• {
• vel = get_qei_velocity();
• output_toggle(LEDR);
• set_timer5(0);
• }
• #int_RDA
• void serial_isr(void)
• {
• unsigned char readed0=0,readed1=0,readed2=0;
• readed0=getc();
• readed1=getc();
• readed2=getc();
• output_toggle(PIN_C1);
• if(readed0<30)
• {
• readed = make16(readed1,readed2);
• switch(readed0)
• {
• case 11:{
• Kp = readed;
• lcd_gotoxy(11,4); printf(lcd_putc,"%li-%li-%li ",Kp,Ki,Kd);
• }break;
• case 12:{
• Ki = readed;
• lcd_gotoxy(11,4); printf(lcd_putc,"%li-%li-%li ",Kp,Ki,Kd);
• }break;
• ……
SK-2011
UY GULAMA_13_01
44motion_cont.c
• ……
• case 13:{
• Kd = readed;
• lcd_gotoxy(11,4); printf(lcd_putc,"%li-%li-%li ",Kp,Ki,Kd);
• }break;
• case 10:{
• putc(make8(Kp,0));
• putc(make8(Kp,1));
• putc(make8(Ki,0));
• putc(make8(Ki,1));
• putc(make8(Kd,0));
• putc(make8(Kd,1));
• }break;
• case 18:{
• for(bi=0;bi<bufind;bi++)
• {
• putc(make8(velbuf[bi],0));
• putc(make8(velbuf[bi],1));
• }
• }break;
• case 19:{
• for(bi=0;bi<bufind;bi++)
• {
• putc(make8(pwmbuf[bi],0));
• putc(make8(pwmbuf[bi],1));
• }
• }break;
• ……
SK-2011
UY GULAMA_13_01
45motion_cont.c
• ……
• case 20:{
• for(bi=0;bi<bufind;bi++)
• {
• putc(make8(posbuf[bi],0));
• putc(make8(posbuf[bi],1));
• }
• }break;
• case 21:{
• reqpos = readed;
• refpos=reqpos;
• lcd_gotoxy(11,3); printf(lcd_putc,"%li-%li ",refpos,reqpos);
• bufind = 0;
• }break;
• case 22:{
• reqdeg = readed;
• refdeg=reqdeg;
• lcd_gotoxy(11,3); printf(lcd_putc,"%li-%li ",refdeg,reqdeg);
• bufind = 0;
• }break;
• case 23:{
• putc(make8(posdeg,0));
• putc(make8(posdeg,1));
• }break;
• case 31:{ output_bit(BRAKE_OUT,1);
• putc(bufind);
• output_bit(BRAKE_OUT,1);
• }break;
• }
• }
• //output_toggle(PIN_B4);
• }
SK-2011
UY GULAMA_13_01
46motion_cont.c
• ……
• int16 pidcont_pwmgen(signed int16 rfps)
• {
• signed int16 pid=0;
• pos = get_qei_count() - middeg;
• posdeg32 = (signed int32)pos;
• //posdeg32 = make32(quadhigh,get_qei_count());
• refdeg32 = (signed int32)rfps;
• posdeg32 = posdeg32*9/905;
• posdeg = (signed int16)posdeg32;
• //lcd_gotoxy(11,2); printf(lcd_putc,"%li-%li ",pos,posdeg);
• errordeg = refdeg32 - posdeg32; //error
• derv_error = errordeg - last_errordeg; //derivative of error
•
• if(sumERRdeg>-80000 && sumERRdeg<80000) //error integrator
• sumERRdeg += errordeg;
•
• prop_term = errordeg * Kp; //proportional
• intg_term = sumERRdeg * Ki / Kidiv; //integral
• deriv_term = derv_error * Kd; //derivative
•
• sum_pid = prop_term + intg_term + deriv_term + const_term; //sum of p,i,d
• sum_pid = sum_pid / Ks; //Ks is gain divider
• last_errordeg = errordeg; //update last_error
• if(sum_pid>15999) //pid max saturation
• { sum_pid = 15999; }
• else if(sum_pid<-15999) //pid min saturation
• { sum_pid = -15999; }
UY GULAMA_13_01
motion_cont.c
• ……
• pidbuf = (signed int16)sum_pid; //pidbuf for the pwm_array
• pid = pidbuf; //'pid' is the returned value of this function
• if(pid>0)
• { output_bit(DIR_OUT,1); }
• else
• { pid = -1*pid;
• output_bit(DIR_OUT,0); }
• return pid;
• }
• void PIC_Setup(void)
• {
• setup_adc_ports(NO_ANALOGS|VSS_VDD);
• setup_adc(ADC_OFF|ADC_TAD_MUL_0|ADC_WHEN_INT0|ADC_INT_EVERY_OTHER);
• setup_spi(FALSE);
• setup_wdt(WDT_OFF);
• setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
• setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
• setup_timer_2(T2_DIV_BY_4,249,5); //every 500us a interrupt ==> a operation
• setup_timer_5(T5_INTERNAL|T5_DIV_BY_1);
• set_power_pwm0_duty(0);
• setup_power_pwm_pins(PWM_BOTH_ON,PWM_OFF, PWM_OFF, PWM_OFF);
• setup_power_pwm(PWM_CLOCK_DIV_4|PWM_FREE_RUN|PWM_UPDATE_DISABLE,1,0,3999,0,1,0);
• set_power_pwm0_duty(0);
• setup_qei(QEI_MODE_X2|QEI_VELMODE_ON|QEI_RESET_WHEN_MAXCOUNT|QEI_VPREDUC_DIV_BY_1,QEI_FILTE R_ENABLE|QEI_FILTER_DIV_1);
• output_a(0xFF);set_tris_a(0xFF);
• output_e(0xFF);set_tris_e(0xFF);
• set_tris_b(0x00);output_b(0x00);
UY GULAMA_13_01
motion_cont.c
• ……
• void main()
• {
• PIC_Setup();
• lcd_init();
• lcd_GOTOxy(1, 1);lcd_putc(yazi1);
• lcd_GOTOxy(1, 2);lcd_putc(yazi2);
• lcd_GOTOxy(1, 3);lcd_putc(yazi3);
• lcd_GOTOxy(1, 4);lcd_putc(yazi4);
• delay_ms(2000);
• lcd_putc('\f');
• lcd_gotoxy(1,1); printf(lcd_putc,"PWM Puls: ");
• lcd_gotoxy(1,2); printf(lcd_putc,"EncoderP: ");
• lcd_gotoxy(1,3); printf(lcd_putc,"PositReq: ");
• lcd_gotoxy(1,4); printf(lcd_putc,"Kp-Ki-Kd: ");
•
• lcd_gotoxy(11,1); printf(lcd_putc,"%li ",pwm_rat);
• lcd_gotoxy(11,2); printf(lcd_putc,"%li ",posdeg);
• lcd_gotoxy(11,3); printf(lcd_putc,"%li-%li ",refdeg,reqdeg);
• lcd_gotoxy(11,4); printf(lcd_putc,"%li-%li-%li ",Kp,Ki,Kd);
•
• set_qei_max_count(maxpos);
• set_qei_count(0);
• set_qei_velocity(0);
• set_power_pwm0_duty(0);
• output_bit(BRAKE_OUT,0);
• output_bit(DIR_OUT,1);
• ……
SK-2011
UY GULAMA_13_01
49motion_cont.c
• ……
• pwm_rat=0;
• pos=0;
• posdeg=0;
• posdeg32=0;
• set_qei_count(middeg); //load middeg value
• set_power_pwm0_duty(0);
• delay_ms(10);
•
• enable_interrupts(INT_IC2QEI); // interrupt on maxcount or underflow
• enable_interrupts(INT_RDA);
• enable_interrupts(INT_IC1);
• enable_interrupts(INT_TIMER2);
• set_timer5(0);
• enable_interrupts(GLOBAL);
• while (1)
• {
• output_bit(LEDL,get_qei_dir());
• output_bit(LEDR,get_qei_overror());
• if(input(RIGHT)==0)
• {
• delay_ms(200);
• if(reqdeg<limitdeg)
• reqdeg+=stepdeg;
• lcd_gotoxy(11,3); printf(lcd_putc,"%li-%li ",refdeg,reqdeg);
• }
• ……
SK-2011
UY GULAMA_13_01
50motion_cont.c
• ……
• if(input(LEFT)==0)
• {
• delay_ms(200);
• if(reqdeg>-limitdeg)
• reqdeg-=stepdeg;
• lcd_gotoxy(11,3); printf(lcd_putc,"%li-%li ",refdeg,reqdeg);
• }
• if(input(LEFT)==0 && input(RIGHT)==0)
• {
• delay_ms(200);
• while(input(LEFT)==0 || input(RIGHT)==0);
• reqdeg=0;
• lcd_gotoxy(11,3); printf(lcd_putc,"%li-%li ",refdeg,reqdeg);
•
• output_toggle(DIR_OUT);
• }
• if(input(MIDDLE)==0)
• {
• delay_ms(200);
• while(input(MIDDLE)==0);
• refdeg=reqdeg;
• bufind = 0;
• lcd_gotoxy(11,3); printf(lcd_putc,"%li-%li ",refdeg,reqdeg);
• }
• lcd_gotoxy(11,1); printf(lcd_putc,"%li ",pwm_rat);
• lcd_gotoxy(11,2); printf(lcd_putc,"%li ",posdeg);
• }
• }
SK-2011
UY GULAMA_13_01
51MATLAB ile PID Kontrol Arayüzü
SK-2011 52