1. sayfa
takipteyim benim de buna benzer bir projem var. Umarım cevap veren arkadaşlar çıkar. |
evet umarım cevap veren çıkar ![]() |
PID 'nin P si için set değerinden gerçek ( ölçtüğün ) değeri çıkar P katsayısıyla çarpıp arduino çıkışa ver sanırım hazır bir motor sürücün var arduinonun çıkışı ne olacak ? 0-10 V kontrol sinyali - bunu sürücünün hız kumanda girişine vereceksin I kısmı için gene set değerinden ölçtüğün değeri çıkar bunu long integer türünde bir değişkene her saykılda topla ( mesela her 10 milisaniyede bir ) sonra bunu I katsayısına böl ve deminki P değerine topla D kısmı için de bir önce ölçtüğün değeri en son ölçtüğün değerden çıkar bunu D katsayısıyla çarpıp gene deminki PI toplamıyla topla temeli bu , yalnız D parçası osilasyona sebep olabilir bunun katsayısını küçük tut bir de PID de oluşan ham değerlerin kendisi değil (-1) ile çarpılmışı yani tersi gerekebilir onu deneyerek bulacaksın nasıl bulacaksın ? mesela önce P ile başladın ve kontrol çevrimini kapatınca motor hızı uçtu o zaman sinyalin yönü ters olması gerekirmiş - bunun gibi |
Hocam öncelikle cevabın için çok teşekkür ediyorum. Ama PID kısmını bende zihnimde oluşturabiliyorum, dediğim gibi asıl sıkıntı kod kısmında yani giriş çıkış verme pinleri atama falan yapıyorum ama pid yi koda dökmede sıkıntı yaşıyorum o konuda yardımcı olabilir misiniz. bu arada sürücüm yok ama labdaki deney seti üzerindeki filtre ve power amplifier üzerinden motoru sürmeyi planlıyoruz. (en azından hoca öyle dedi) ![]() |
arkadaşlar şu forumda arduino programlamadan anlayan üstatlar yok mu ya şu imdat çağrıma bir cevap verin lütfen ![]() |
beyler ardunıo yu bılmıyorum ama hı-tech c ile yaptığım pid kontrollü çizgi izleyen robot var isterseniz örneğini atayım ona göre ardunio kodları ile değiştirip uygularsınız. |
valla burada paylaşabilirsen çok makbüle geçer ![]() |
Üniversite de yazmaya çalışmıştım isis de çalışmıştı ama devre üstünde bir türlü çalıştıramadım donanımsal dı sanırım hatalar. şimdi tekrardan bakayım dedım de unutmuşum proğramlamayı neredeyse :D // hı-tech pid deneme 877a #include <htc.h> #include "delay.h" char deger=0; long k=0,i,a,sens[8],maxdeg[8]={500,500,500,500,500,500,500,500},mindeg[8]={500,500,500,500,500,500,500,500}; long fon=0,fon2=0,say=0,sensor,last_sensor,duz; long last_error,error,correction=0,mak=250,pr,der,derr; char kp=0.45,kd=5.25,m=0; void duz_hareket() { T2CKPS1=1; // Prescaler 1:16 oluyor T2CKPS0=1; TOUTPS3=0; // Postscale 1:1 oluyor TOUTPS2=0; TOUTPS1=0; TOUTPS0=0; PR2=250; CCPR1L=0x3E; // Duty registere 250 yükleniyor CCP1X=1; // Duty cycle 1ms periyodunda CCP1Y=0; CCP1M0=1; // CCP1 PWM modunda CCP1M1=1; CCP1M2=1; CCP1M3=1; CCPR2L=0x3E; // Duty registere 250 yükleniyor CCP2X=1; // Duty cycle 1ms periyodunda CCP2Y=0; CCP2M0=1; // CCP2 PWM modunda CCP2M1=1; CCP2M2=1; CCP2M3=1; TMR2ON=1; // Timer 2 çalıGtırılıyor*/ PORTB=4; DelayMs(250); PORTB=0; char j=0; for(j=10;j<250;j++) { RB2=~RB2; CCPR1L=j; CCPR2L=j; DelayMs(1); } CCPR1L=250; CCPR2L=250; PORTB=0x0f; } void sifirla() // sıfırlanması gereken değerleri sıfırla... { fon=0; fon2=0; say=0; duz=0; } void sensor_oku() { RB2=~RB2; CHS2=0; // AN0 seçiliyor CHS1=0; CHS0=0; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[0]=deger; CHS2=0; // AN1 seçiliyor CHS1=0; CHS0=1; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[1]=deger; CHS2=0; // AN2 seçiliyor CHS1=1; CHS0=0; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[2]=deger; CHS2=0; // AN3 seçiliyor CHS1=1; CHS0=1; DelayUs(35); deger=(ADRESH*256+ADRESL); GO=1; // Çevrim baGlatılıyor while(GO); sens[3]=deger; CHS2=1; // AN4 seçiliyor CHS1=0; CHS0=0; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[4]=deger; CHS2=1; // AN5 seçiliyor CHS1=0; CHS0=1; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[5]=deger; CHS2=1; // AN6 seçiliyor CHS1=1; CHS0=0; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[6]=deger; CHS2=1; // AN7 seçiliyor CHS1=1; CHS0=1; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[7]=deger; for(i=0;i<8;i++) { sens=(int)((1000*(sens-mindeg))/(maxdeg-mindeg)); if(sens<250) { sens=0; } else if(sens>850) { sens=1000; } fon=fon+(sens*say); fon2=fon2+sens; say=say+1000; duz=duz+sens; if((fon/fon2)==0) { sensor=last_sensor; } else { sensor=(fon/fon2); } last_sensor=sensor; } } void ilk_ayar() { for(a=0;a<25;a++) { PORTB=0; for(i=0;i<255;i++) { CHS2=0; // AN0 seçiliyor CHS1=0; CHS0=0; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[0]=deger; CHS2=0; // AN1 seçiliyor CHS1=0; CHS0=1; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[1]=deger; CHS2=0; // AN2 seçiliyor CHS1=1; CHS0=0; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[2]=deger; CHS2=0; // AN3 seçiliyor CHS1=1; CHS0=1; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[3]=deger; CHS2=1; // AN4 seçiliyor CHS1=0; CHS0=0; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[4]=deger; CHS2=1; // AN5 seçiliyor CHS1=0; CHS0=1; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[5]=deger; CHS2=1; // AN6 seçiliyor CHS1=1; CHS0=0; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[6]=deger; CHS2=1; // AN7 seçiliyor CHS1=1; CHS0=1; DelayUs(35); GO=1; // Çevrim baGlatılıyor while(GO); deger=(ADRESH*256+ADRESL); sens[7]=deger; for(k=0;k<8;k++) { if(sens[k]>maxdeg[k]) { maxdeg[k]=sens[k]; } if(sens[k]<mindeg[k]) { mindeg[k]=sens[k]; } } } } for(m=0;m<=5;m++) { DelayMs(250);DelayMs(250); RB1=~RB1; } } void main(void) { TRISA=0xEF; // analog okumalar acıldı TRISE=0xFF; // RA0 ve RA1 giriG TRISC=0xF0; // PORTC çıkıG olarak ayarlanıyor TRISB=0xF0; // RB4..RB7 giriG, diğerleri çıkıG PORTB=0x00; // PORTB sıfırlanıyor PORTC=0; PCFG3=0; // AN0-AN7 analog girişleri açıldı PCFG2=0; PCFG1=0; PCFG0=0; ADFM=1; // Sağa dayalı yazılıyor ADON=1; // ADIF=0; // ADC bayrağı temizleniyor // ADIE=1; // ADC kesmesi izni veriliyor TMR2IF=0; TMR2IE=1; PEIE=1; // Genel ve yardımcı kesme izinleri veriliyor GIE=1; ilk_ayar(); for(;;) { duz_hareket(); PORTB=255; PORTD=0; while(1) { sensor_oku(); error=sensor-750; if(error>-70 && error<70) { CCPR1L=200; CCPR2L=200; } else { CCPR1L=250; CCPR2L=250; } pr=(error*kp); // oransal deger = hata *kp der=(error-last_error); derr=der*kd; last_error=error; correction=pr+derr; if(correction>mak) { correction=mak; } if(correction<-mak) { correction=-mak; } if(correction>0) { CCPR1L=(mak-correction); CCPR2L=250; } else { CCPR2L=(mak+correction); CCPR1L=250; } sifirla(); } } } void interrupt an_dig(void) { // if(ADIF) // Çevrim bitiş kesmesi bekleniyor // { // deger=ADRESH*256+ADRESL; // ADIF=0; // Kesme bayrağı sıfırlanıyor // } if(TMR2IF) { TMR2IF=0; } } |
Hocam benimde aslinda pek bilgim yok ama bir onerim olcak. Arduinoturkiye foruma bakarsaniz kesinlikle yardimci olurlar. |
Yaptığım çizgi izleyene ait PID kısmından bir örnek. analogWrite komutu ile sinyali PWM kanalına aktarmış oluyoruz.
|
Burada cevabı arayanlar için arduino sitesinde çok güzel bir kütüphane oluşturulmuş, rahatça yapabilirsiniz. http://playground.arduino.cc/Code/PIDLibrary |
http://playground.arduino.cc/Code/PIDLibrary kullanarak yaptığım bir çalışmayı aşağıdaki videodan izleyebilirsiniz. https://www.youtube.com/watch?v=6iFlfeCihDY ana döngüde tek yaptığım aşağıdaki yazılım. PID kontrolün en önemli özelliği linear time invariant sistemler için kullanılabiliyor olması. Eğer sisteminizin tepkileri zamanla değişiyorsa sistemi modelleyip adaptive tuning yapmanız gerekir. myPID.Compute(); ServoOutput=servocenter+Output; myServo.writeMicroseconds(ServoOutput); Kolay gelsin |
1. sayfa
Bitirme projesi olarak arduino ile pid motor kontrolü yapmamızı istedi hoca. Bir arkadaşımla birlikte yapıyorum ama ne ben ne de o programlama konusunda iyi sayılmayız.
Arduino uno aldık biraz üstünde çalıştık ama pid işi biraz karıştırıyor malesef.
hocanın bizden istediği şu; arduino nun pwm çıkışını alçak geçiren filtreden geçirdikten sonra laboratuvardaki motora vereceğiz ve feedback olarak da motorun şaftına bağlı olan tachogeneratorden gelen sinyali alacağız. input değerlerini arduino üzerinden potansiyometre ile vermemizi istiyor. Donanım olarak sıkıntımız yok zaten laboratuvardaki ekipmanları kullanıyoruz ama dediğim gibi büyük sıkıntı yazılım konusunda
pid yazılımı konusunda yardım edebilecek arkadaşlar varsa lütfen yardımlarını esirgemesinler.
şimdiden herkese teşekkür ediyorum.
DH forumlarında vakit geçirmekten keyif alıyor gibisin ancak giriş yapmadığını görüyoruz.
Üye Ol Şimdi DeğilÜye olduğunda özel mesaj gönderebilir, beğendiğin konuları favorilerine ekleyip takibe alabilir ve daha önce gezdiğin konulara hızlıca erişebilirsin.