Pic ile encoder sinyallerini saydırmak

Arkadaşlar size tavsiyem.Rotary encoder den gelen pulsleri okumak istiyorsanız.RB.0 harici kesmesini kullanın.Çünkü TIMER0 kesmesinde çoğu zaman PIC pulsleri kaçırıyor ve sağlıklı bir ölçüm yapamıyorsunuz.
 
EGEHAYDAR ' Alıntı:
Arkadaşlar size tavsiyem.Rotary encoder den gelen pulsleri okumak istiyorsanız.RB.0 harici kesmesini kullanın.Çünkü TIMER0 kesmesinde çoğu zaman PIC pulsleri kaçırıyor ve sağlıklı bir ölçüm yapamıyorsunuz.

evet güzel öneri, peki RA4/T0CKI girişine ne oldu?? bu yöntem en etkini ve daha cazip olanı değil mi?
 
Yön bilgisi gerekli ise , ya işareti donanımla izlersiniz-HCTL2016-2020 ve pahalıdır- ya da hem A hem B ile kesmeye gidersiniz.Kesmede sadece yön belirlenir ve sayılıp hemen çıkılır.Kullandığınız frekansa ve komut satırlarına göre gerekli satırların işlem süresi ne kadarsa ondan az uzun(min)puls hızını yakalayabilirsiniz.
Aynı pic e başka işlem yaptıracaksanız ve kesmeden öncelikli bir şeyler varsa hata olur.PBP da pause kesmeye aldırış etmez bekler.LCD kullanımında , lcd dosyalarında pauseler var.Ya kullanmamaya çalışırsınız ya da uzun pauselerden kaçarsınız , illa gerekli ise çevrimlerle ara verebilirsiniz.
Özet : A-B gerekli ise RB4-7 kesmesi gerekir.
 
Hocam Rb4-Rb7 port değişim kesmesi ile yapmaya çalıştım başaramadım. Bana PBP kodlarını yazarmısın?
 
3 kanallı encoder işini kolaylaştırır. A kanılı, B kanalı, ve Z kanalı. Z kanalı encoder'in her turda 1 pals verir. TMR0 veya TMR1'e bu palsleri sayar, programda A ve B kanallarını okutarak hangi yöne döndüğünü anlayabilirsin. bizim kulandığımız enkoderler bir turda 512 veya 1024 pals üretir. Z kanalı ise her turda bir pals üretir. A kanalı 1 iken B kanalı 0'dır. Örnek ence A kanalından bir gelirse motor sağ yönde B kanalından bir gelirse motor ters dönüyor anlamına gelir.
 
@ETE hocamın notlarında ders6 da kesmeler örnekleriyle anlatılıyor.
Kesme içerisine girilince yukarıdaki gereken kod satırlarını kullanabilirsiniz.
 
encoder sinyalleri (A ve B) 90 decere faz farkı ile gelir. Sadeleştirmek gerekir ise A palsi geldiğinde (1); B "1" ise bir yöne, A palsi geldiğinde (1); B "0" ise diğer yöne dönüyor demektir.

Bu şekilde değerlendirilerek yazılım yapılabilinir.
 
Bir arkadasim icin protonda yazmistim. 400 Hz lik encoderde kacirmadan calisiyormus. Ben kodu denemedim.


Kod:
Device 16F877A
Config  HS_OSC,WDT_OFF , PWRTE_OFF  
XTAL 20
CMCON=7
Declare LCD_TYPE 0  
Declare LCD_DTPIN PORTD.4 
Declare LCD_ENPIN PORTD.3 
Declare LCD_RSPIN PORTD.2 
Declare LCD_INTERFACE 4  
Declare LCD_LINES  4

ALL_DIGITAL = TRUE		'LCD 2 satýrdan oluþuyor
Symbol RBIF = INTCON.0 ' RB Port Interrupt Flag
Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol T0IF = INTCON.2 ' TMR0 Overflow Interrupt Flag
Symbol RBIE = INTCON.3 ' RB Port Change Interrupt Enable
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol T0IE = INTCON.5 ' TMR0 Overflow Interrupt Enable
Symbol PEIE = INTCON.6 ' Peripheral Interrupt Enable
Symbol GIE = INTCON.7  ' Global Interrupt Enable
'**************************TMR1******************
Symbol TMR1ON = T1CON.0     ' Timer1 ON
Symbol TMR1CS = T1CON.1     ' Timer1 Clock Source Select
Symbol NOT_T1SYNC = T1CON.2 ' Timer1 External Clock Input Synchronization Control
Symbol T1OSCEN = T1CON.3    ' Timer1 Oscillator Enable Control
Symbol T1CKPS0 = T1CON.4    ' Timer1 Input Clock Prescale Select bits
Symbol T1CKPS1 = T1CON.5    ' Timer1 Input Clock Prescale Select bits



PORTB_PULLUPS = 1		
OPTION_REG     =%11000101			
TRISB= %11000000
PORTB=0
TRISA=0
PORTA=0
Dim YON As Byte
Dim x As Byte 
Dim count As Word 
Dim Timer_1         As TMR1L.Word
On_Interrupt GoTo ENCODE_OKU
INTCON=0
GIE=1
RBIE=1		     
Print At 1,2,"DENEME"
GoTo MAIN
ENCODE_OKU:
If x= 1 Then 
    If PORTB.7 =1 Then 
        YON=2
        x=0
    Else
        YON=1
        x=0
    EndIf
EndIf
If PORTB=0 Then x=1 
RBIF=0
T0IF=0 
Context Restore

MAIN:
    
   If YON=1 Then Print At 2,1,"ileri"
   If YON=2 Then Print At 2,1,"geri "

DelayMS 1000
GoTo MAIN
 
pic te herhangi bir inputta yükselen veya düşen kenarı nasıl okuyoruz.
a ve b inputlarından a ya 1 geldiğinde pozitif kenarda set bye 1 geldiğinde reset olacak bunu nasıl yaparız?
 
Merhabalar!

16F84 le çok baş başa kalamadan, at89c51 e geçiş yapmış biri olarak, rotary encoder ı ortak nokta kabul ederek sizlerle fikir alışverişi yapalım.

---
Ben autonics marka 500 pulce lik 3 çıkışlı ve 3 de aynı çıkışların değillenmiş halleri olan (x1,x2 ve y ( y bir turda bir clock veriyor) ) TTL-5V luk rotary encoderla proje geliştiriyorum. Bi yürüyen bandın ana sisteme bağlı olmadan kaç mm fazla yada az çekildiğini bulmak (KABA HASSASİYET) ve kalan milimetreyide optik sensörle cross denilen özel bir kontrol baskısını arattıran ( İNCE HASSASİYET) tamamiyle bağımsız çalışan bir proje yapıyorum. Projede bandın kaç cm çekileceğini girmek için 4*4 tuş takımı, seri eeprom, metin lcd, optik sensör, endüktif sensör ( ayar yapan kolların sınırları için 2 tane) falan filan var. Biraz fazla açıkladım ama projeyi anlarsanız beni daha iyi anlayabileceğinizi düşündüğümden! :)
-----------

Yapmak istediğim şu: rotary encoderın hangi yöne döndüğü ve kaç tur attığı?Bu bilgiyi aldıktan sonra zaten bandın durup durmadığını iki okuma arası karşlılaştırma ile anlarız ->> ilk != son ise bant hareketli :)

----

Ben yön bilgisini yönlü bir 16bit integer (tamsayı) kullanarak almayı düşündüm

RX1 diye rotary nin ilk ucu olan X1 i tanımladım
RX2 diye rotary nin ikinci ucu X2 yi tanımladım

C dili ile:

Kod:
integer FonkRotaryOku()  {

int hafiza;
byte okuma;
byte yon;

hafiza = 0;

timerAyarla(10); // 10ms lik timer ayarlandı ve TMFULL=1 olursa süre dolar!

while(!TMFULL) {
okuma=0;

if(RX1) {
while(RX1 && !TMFULL) {
if(RX2) { if(!RX2) { yon = 0; okuma=1; } } else { if(RX2) { yon = 1; okuma=1; } }
}
}	  
else {
while(!RX1 && !TMFULL && z==0) {
if(RX2) { if(!RX2) { yon = 1; okuma=1; } } else { if(RX2) { yon = 0; okuma=1; } }
}  
}	
if(okuma==1) {if(yon==1) {hafiza ++;} else {hafiza --;} }
}		  

}
return hafiza ;
}

Evetttt!... Yukarıdaki kod arkadaşların dediği gibi

x1 = 1 iken x2 = 1 ise a yöne, 0 ise b yöne dönüyor demektir!

Peki ya okuma esnasında x1=0 ise ne yapacak! Ozaman tersi olacak x2=1 ise b yöne, 0 ise a yöne dönüyor demektir!!! Bu sayede hassasiyet artmış olur!

Kod ilk başta zamanlayıcıyı ayarlıyor. 10ms ye ye bu atmelde farklı kayıtçıların yüklenmesi ile oluyor o sebeple örnek bir ifade ile anlattım ve taşma dediğimiz zamanlayıcının işini bitirmesi sonucu etkilenen bayrağıda TMFULL ile gösterdim.

10 ms içinde X1 in konumu ne ise ( 1 yada 0 ) while döngüsü içinde diğer while e giriyor. Sonra x1=1 kabul edersek, o whilein içinde x2 nin o anki değerine göre ilgili if koşuluna bakıyor. O koşulun içindede x2 nin değili var yani bir clock darbesi olup olmama olayı!. Eğer x1=1 iken ve 10msn dolmamışken, x2=1 den X2=0 a geçiyor ise YON = 0 kabul edilir ve bir işlem yapıldığı için okuma = 1 kabul edilerek while den çıkılır ve okuma yapıldığı için en alttaki koşulun içine girilir ve yön=0 olduğundan hafıza değerinden düşme yapılır! Sonra asıl while in ( sayacın taşmasına bağlı olan) ilk satırına gidilir. Burada da okuma=0 yapılarak ilgili işlemler sayaç taşana kadar tekrarlanır!

Hiç bir dönme yoksa, zamanlayıcının taşması ile fonksiyon zaten bitirilecektir.

İyi hoş! Buraya kadar iş gören bir kodumuz var! Acak, benim rotary 500 pulce lik ken ben lcd den genelde 200 falan okuyorum! Bu durumu lcd ye gönderilecek rakamların basamaklanması ve lcd ye yazılması ile uğraşılıyor olması yüzünden yaşanan geçikmeden dolayı rotarynin okunamaması denilebilir.

Ben bunu hiç bir ilem yapmadan şu şekilde denedim:

toplam_miktar=0;
for(x=0;x<100;x++) {
toplam_miktar += FonkRotaryOku();
}

biçiminde yaptım. Yani fonksiyon 1 saniye boyunca rotarinin okunmasından başka bir iş yapmıyor!

Sonuç gine aynı oldu!

Bu arada atmel 60MHz lik ve 1 işlem 12pulce de oluyor. Yani saniyede 5 milyon işlem ve 1 işlemin süresi 200nsn ediyor.
5MHz lik sinyalleri algılayabilir bir sistem yapılamaz ama 1Mhz ye yaklaşılır bence! Giriş değerinin okunması, karşılaştırılması ve dallanmalar falan 1MHz de çok oldu :)

Neyse arkadaşlar, x1 in 1 ve 0 kenki durumlarınıda hesaba katıp bir işlem yapayım dedim ama 500 lük rotary den anca 200 ile 250 arası pulce okudum. Böyle bir uygulama bırakın kaba hassasiyet yapmayı sistemi komple hurdaya götürür. Takmasak sorunlu bir otomasyon daha iyi çalışacaktır :D:D:D:D
 

Forum istatistikleri

Konular
128,157
Mesajlar
915,504
Kullanıcılar
449,900
Son üye
adidas2131

Yeni konular

Geri
Üst