Gönderen Konu: Arduino ile Encoder kullanımı.  (Okunma sayısı 6054 defa)

Çevrimdışı TA1CD

Arduino ile Encoder kullanımı.
« : 21 Mayıs 2018, 11:11:24 »
Merhaba.

Arduino ile kontrol edilen dds vfo yaparken encoder  sürekli mesele çıkardı. Bunun nedeni kullandığım hazır library'ler.
Bir çok library'de encoder interrupt kullanıyor. Buda başka bir dezavantaj. Encoder 'i  incelerken şunu gördüm. encoderi sağa veya sola çevirdiğimizde yani mevcut pozisyondan bir sonraki pozisyona geçtiğimizde 4 ayrı değer üretiyor. Mesela sağa dönüşte:
A - B
1    1
0    1
0    0
1    0

Sola Dönüşte:
A - B
1    1
1    0
0    0
0    1
Bu durumun mantığını oturtmadan kodlamaya girişince aynı hatalara düştüm.  Merak edip LU5DJV 'nin dds projesindeki durumu kontrol ettiğimde her iki hamlede değişim yaptığını gördüm.  Denediğim bir çok yayınlanmış dds projesinde de buna benzer sıkıntılar vardı.  Kendi uygulamalarımda kullanabileceğim basit, sıkıntı çıkarmayacak, interrupt kullanmadan bir function yazmaya karar verdim. Bana göre iyi oldu. Konuyla ilgili eleştiri, önerilerinizi beklerim.  Şimdi kodu da verelim.

#include <LiquidCrystal.h>
LiquidCrystal lcd(0,1,5,6,7,8);
#define encoder_A 9      // D9 pini encoder A   (encoder üzerinde CLK yazıyor. ben bunu A kabul ettim)
#define encoder_B 10    // D10 pini encoder B (encoder üzerinde DT yazıyor. ben bunu B kabul ettim)
byte newenc, oldenc;
long frq=0;

void setup()
{
  lcd.begin(16, 2);
  pinMode(encoder_A, INPUT);
  digitalWrite(encoder_A, HIGH);
  pinMode(encoder_A, INPUT);
  digitalWrite(encoder_A, HIGH);
}

void loop()
{
  frq=frq+enkoder();  //saga dondu ise 1 arttir.
                                //sola dondu ise 1 eksilt.
  if (frq<0) frq=0;      //frekansı eksiye düşürmeyelim.
  lcd.setCursor(0,0);
  lcd.print(frq);
}

////////////////////// Encoder Fonksiyonumuz ////////////////////////
int enkoder()
{
  byte encA, encB;
  int don=0;
  encA = digitalRead(encoder_A);
  encB = digitalRead(encoder_B);
  newenc = (encA + (2 * encB));      //1.bit encoder A, 2.bit encoder B   
                                                     // saga donus->(3,2,0,1)  (3,1,0,2)<-sola donus
  if (newenc != oldenc) {
    if((oldenc==3)& (newenc==2)) don=1;  //3 den sonra 2 okundu saga dondu, yani +1
    if((oldenc==3)& (newenc==1)) don=-1; //3 den sonra 1 okundu ise sola dondu, yani -1
    if(oldenc!=3) don=0; // bir önceki değer 3 değilse encoder donusu tamamlanmamis, yani +0
    oldenc = newenc;
    }
  return don;   //
}


Selamlar,
Recep Tezkol
 

Çevrimdışı TA1MRT

Ynt: Arduino ile Encoder kullanımı.
« Yanıtla #1 : 21 Mayıs 2018, 11:48:05 »
Merhaba,

Sadece encoder için kullanılacaksa, interrupt içinde kullanılabilir ancak başka işler de yapılıyorsa sıkıntı çıkıyor.
Yönteminiz, hazır bir çok koda göre daha kullanışlı. 

Ben de PIC'de aşağıdaki gibi kullanıyorum, yöntem aynı...

//////////////////////////////////////////////////////////////////////////
       step := 1;
       index := 0;

       enc_temp.0 := PORTA.0;
       enc_temp.1 := PORTA.1;

       //if turning right..
       if (enc_temp_last = 2) and (enc_temp = 3) then index := index - step

       //if turning left..
       else if (enc_temp_last = 0) and (enc_temp = 1) then index := index + step;
       .
       .
       .
       .
       .
       enc_temp_last := enc_temp;
//////////////////////////////////////////////////////////////////////////


73 de TA1MRT






Çevrimdışı TA2UH

Ynt: Arduino ile Encoder kullanımı.
« Yanıtla #2 : 21 Mayıs 2018, 12:54:53 »
Recep Bey, Mert Bey çok teşekkürler. 73, Çağlar


Tapatalk kullanarak iPhone aracılığıyla gönderildi