rotary encoder

Başlatan raltundal, 12 Mayıs 2006, 12:11:18

raltundal

merhaba arkadaşlar bir sorunum var elimde 100khz lik encoder var ama bir türlü kararlı bir şekilde pic den okutamadım.877,628 denedim olmadı sorun şu hızlı bir tur attığında atıyorum 100 sayıyorsa yavaş çevirip bir tur attığında 200 sayıyor. bunu kararlı hale nasıl getire bilirim.program olarak pıcbasıc kullanarak kesme kullandım olmadı, aç kapa anahtarlama olarak kullandım olmadı 2 side aynı şekilde sonuç verdiler. frekans bölücümü kullanmam gerekli acaba yada dac mi kullansam. bu konuda bilgisi olanvarmı. devreyi soracak olursanız normal tek girişli encoder bacağındaki çıkış sinyalini okuyan bir devre tabi lcd de bağlı. pic i 10 ve 20 mhz kristallerde denedim.

not:yaptığım devre proteusta istenilen frekanslarda çalışıyor.

Erol YILMAZ

Öncelikle hoşgeldin,

Büyük ihtimalle elektriksel bir gürültüden etkileniyorsun, Encoder çıkışını filtre etmen gerekiyor.
Bu arada gerçekte bir tur attırdığında kaç pals okuman gerekiyor ?
Sen kaç okuyorsun ?
Hatanın kaynağı nerede ?

Bunu incelemen gerekiyor.

Kolay Gelsin.

raltundal

Alıntı yapılan: "Erol"Öncelikle hoşgeldin,

Büyük ihtimalle elektriksel bir gürültüden etkileniyorsun, Encoder çıkışını filtre etmen gerekiyor.
Bu arada gerçekte bir tur attırdığında kaç pals okuman gerekiyor ?
Sen kaç okuyorsun ?
Hatanın kaynağı nerede ?

Bunu incelemen gerekiyor.

Kolay Gelsin.

filtrelemeyi denemedim onu denerim.bir turda verdiği pulse sayısı 256 benim okuduğum bir turda 85.
gördüğüm kadarıyla pic pulse sinyalini okumaya yetişemiyor muş gibi durum sergiliyor.

ete

Programın Encoderi okuma kısmını da burada verirsen daha iyi fikir yürütebiliriz.
Bu arada benim bildiğim rotary encoderlar (tabiiki bir rotary encoder dan bahsediyor isek) tur başına verdikleri pals ile tanımlanırlar örneğin 250 puls/tur gibi. Sizin, 100 KHz lik Encoder  ifadenizi anlayamadım. Ne anlama geliyor. Şayet gerçekten tur başına 100KHz gibi bir değer veriyor iseki hiç sanmıyorum ozaman okumada sorunlu olabilir. Bu kısmı iyice açıklamak gerek.

Ben bayağı uğraştım encoderlar ve pic'e okutma konusu ile.  Senin bahsini ettiğin gibi önce direk okuma yaptım. Sonra şüphelendim ve RB0 kesme sine bağladım işi sonuç pek değişmedi. Ancak hız arttıkça Kesme ile yapılan daha emniyetli oldu. En iyisi TMR0 kullanarak harici puls girişinden encoderi okutmak. Böylece programdan bağımsız ve gerekirse pic'in kendi bölücüsünüde kullanarak okutmak mümkün olabiliyor. Hız ise hiçde yabana atılacak cinsten değil.  Saniyede 100KHz ve üzeri palsleri rahatlıkla okutabilirsin.

Sonuç olarak yön seçme önemli ise pic'in iki adet pininden giriş yapmak gerekiyor. Bunlardan birini RA4 seçersen ve kesmeyi açıp harici clok palsi okumaya ayarlarsan işin çözülmüş olur bence.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

raltundal

Alıntı yapılan: "ete"Programın Encoderi okuma kısmını da burada verirsen daha iyi fikir yürütebiliriz.
Bu arada benim bildiğim rotary encoderlar (tabiiki bir rotary encoder dan bahsediyor isek) tur başına verdikleri pals ile tanımlanırlar örneğin 250 puls/tur gibi. Sizin, 100 KHz lik Encoder  ifadenizi anlayamadım. Ne anlama geliyor. Şayet gerçekten tur başına 100KHz gibi bir değer veriyor iseki hiç sanmıyorum ozaman okumada sorunlu olabilir. Bu kısmı iyice açıklamak gerek.

Ben bayağı uğraştım encoderlar ve pic'e okutma konusu ile.  Senin bahsini ettiğin gibi önce direk okuma yaptım. Sonra şüphelendim ve RB0 kesme sine bağladım işi sonuç pek değişmedi. Ancak hız arttıkça Kesme ile yapılan daha emniyetli oldu. En iyisi TMR0 kullanarak harici puls girişinden encoderi okutmak. Böylece programdan bağımsız ve gerekirse pic'in kendi bölücüsünüde kullanarak okutmak mümkün olabiliyor. Hız ise hiçde yabana atılacak cinsten değil.  Saniyede 100KHz ve üzeri palsleri rahatlıkla okutabilirsin.

Sonuç olarak yön seçme önemli ise pic'in iki adet pininden giriş yapmak gerekiyor. Bunlardan birini RA4 seçersen ve kesmeyi açıp harici clok palsi okumaya ayarlarsan işin çözülmüş olur bence.

Ete


kodlar bu bilgisayarda yok.enkısa zamanda nasıl yazdığıma dahir bilgi vericem. 100khz den kastım her pals hızı 100khz hızında demek.bencede en mantıklısı tmr0 kesmesi.bendeki encoder tekel marka.ama eskibir model.

10 mhz lik bir kristalle bu encoderi okuması lazım.dediğim gibi her palsi 100khz hızında.

Erol YILMAZ

Şimdi şunu kesin olarak anlamakta fayda var. encoderden 1000 adet pals gelse bu sinyal 10 mS surede mi gelecek ?

Oyle ise 1 palsin periyodu 10uS oluyor.
Çok kısa bir süre...

Klein

10uS çok kısa sayılmaz.  ama yinede birçok işlemciyi kasar. bence de en iyi çözüm  encoderi timer in triggeri olarak kullanmak.  Ama eğer mesele sadece tur ve pulse saymak değilse , yani aynı hızda bir process de varsa yapacak pek birşey yok. mecburen ext. interrupt kullanılacak.

Macera

Bu problem benide uğraştırmıştı.
C altında yazdığım vede test etmiş olduğum bir programı ekliyim fikir verebilir.Kablo bende ekranlıydı.

/*  
    3 Agustos 2005
    enkoder denemesi test edildi onaylandı.
    port b.0 dan enkoder girişi
    port b.1 dan enkoder yönü
    olacak şekilde ayarlanacak
    enkoderin iki girişi xorlanıp port b.0 a girecek
    enkoderin bir girişide b.1 e girecek
*/
#pragma chip PIC16F877A
#pragma bit dir    @ PORTB.1
#pragma bit pulse   @ PORTB.0
#include "int16CXX.H"


#pragma origin 4
static int16 counter;
uns8 dir1;
interrupt int_server( void)
{
    int_save_registers    // W, STATUS (and PCLATH)
 //   swPCLATH = PCLATH;
    if ( INTF)  
    {
        INTEDG=!INTEDG;
        dir1=counter.low8 & 0x02;
        if ((PORTB & 0x02)==dir1) counter++;
            else counter--;   
        INTF = 0;  /* reset flag */
     }
    int_restore_registers // W, STATUS (and PCLATH)
  //  PCLATH = swPCLATH;
}
#include "Stdio.c"
void main( void)
{
    int16 oldcount;
    GIE = 1;    /* interrupts allowed */
    INTE= 1;
    PORTB = 0b00000000;
    TRISB = 0b00000011;
    counter =0;
    if (pulse)  INTEDG  =1;
    else 
        {
            INTEDG = 0;
            ++counter;
        }
    if (dir) {
            ++counter;
            --counter;
            }
    PORTC   = 0b.0000.0000;
    TRISC   = 0b.1000.0000;//Input RC7 - Incoming Data RX
    SPBRG   = 129; //20MHz for 9600 baud rate
    TXSTA   = 0b.0010.0100; //8-bit asych mode, high speed uart enabled
    RCSTA   = 0b.1001.0000; //Serial port enable, 8-bit asych continous receive mode
    oldcount=0;
    while(1)
    {  
        if (counter != oldcount)
        {
        printf(" %h ",counter.high8);
        printf(" %h \n",counter.low8);
        oldcount=counter;
        }
    }
        
}
"Art without engineering is dreaming; engineering without art is calculating." -- Steven K. Roberts

CaFFeiNe

Alıntı yapılan: "raltundal"bir turda verdiği pulse sayısı 256 benim okuduğum bir turda 85.
gördüğüm kadarıyla pic pulse sinyalini okumaya yetişemiyor muş gibi durum sergiliyor.
1 saniyede kaç tur attırıyorsun yaklaşık olarak?

birde picbasicte donanım kesmesi yok onun için okuma kısmında "pause" gibi icrası uzun komutlar kullanıyorsan kesmeleri kaçırabilirsin ve dediğin durum oluşur

raltundal

Alıntı yapılan: "CaFFeiNe"
Alıntı yapılan: "raltundal"bir turda verdiği pulse sayısı 256 benim okuduğum bir turda 85.
gördüğüm kadarıyla pic pulse sinyalini okumaya yetişemiyor muş gibi durum sergiliyor.
1 saniyede kaç tur attırıyorsun yaklaşık olarak?

birde picbasicte donanım kesmesi yok onun için okuma kısmında "pause" gibi icrası uzun komutlar kullanıyorsan kesmeleri kaçırabilirsin ve dediğin durum oluşur


1 saniyede 2 dakkada bunlar önemli değil sorun kararlı bir şekilde çalışmaması.sanki pic in hızı encoder 'ı okumaya yetmiyor sanırım.picde enhızlı bir şekilde okuma yapmanın yöntemi kesme kullanmak ama buda yetmedi herhalde ek devreler kullanmak lazım frekans bölücü gibi ancak o zaman pic in hızı okumaya yeter başka türlü olmıyacak sanırım.

emrahmrcn

check_knob(void)
{				
				if(time_counter==0)
				{
					input_read();					
					KnobA=input_data >> 2 & 0x01;	//input_read içinden KnobA ait 1 veya 0 çekiliyor.
					KnobB=input_data >> 5 & 0x01;
					NEW=KnobB;
					NEW=NEW << 1;
					NEW=NEW+KnobA;
					
					if(!(NEW==OLD))
					{
						OLD=OLD & 0x01;
						NEW=NEW >> 1;
						NEW=NEW & 0x01;
						YON=OLD ^ NEW;
						if(YON)
						Count++;
						else
						Count--;
						time_counter=5;
					}
				}
				
					
						
	input_read();					
	KnobA=input_data >> 2 & 0x01;
	KnobB=input_data >> 5 & 0x01;
	OLD=KnobB;
	OLD=OLD << 1;
	OLD=OLD+KnobA;			
				

					
									
}


Pic her hızı yakalar.timer counter 10ms kontrole ayarlı sen bunu kendine göre ayarlarsın.
Benim yaradılışımda bir ayrıcalık varsa o da TÜRK olmamdır. M.K ATATÜRK

CaFFeiNe

Alıntı yapılan: "raltundal"1 saniyede 2 dakkada bunlar önemli değil sorun kararlı bir şekilde çalışmaması.sanki pic in hızı encoder 'ı okumaya yetmiyor sanırım.
nasıl yani? şimdi çok yavaş çevirsende saniyede 1 tur atacak şekilde mesela ozamandamı kararsız çalışıyor?
eğer öyleyse pic'in yetişememesi değil başka bir problem vardır, ama sen bir saniyede atıyorum 1000 tur attırırsan 3-4uS de bir pals gelir haliyle kesmeler kaçabilir onun için devir önemli sen söylemezsen biz kaç devirde döndürdüğünü nerede nasıl bir encoder kullandığını nereden bileceğiz?

en iyisi biz kodları filan bekleyelim