Rotary encoder çif atlama

Başlatan smyomekatronik, 22 Temmuz 2019, 22:25:33

smyomekatronik

mikroc ile rotary encoder ileri ve geri çift atlayıp sayıyor. encoderi ölçtüğümde bir tık 1-1 bir tık daha 00 oluyor, 0-1,1-1,1-0 gibi olması lazım değilmi. Kodlar tam gecekondu işi oldu, ordan burdan kopyala yapıştır.
// DAC module connections
sbit Chip_Select at RC0_bit;
sbit Chip_Select_Direction at TRISC0_bit;
// End DAC module connections

char GLCD_DataPort at PORTD;

sbit GLCD_CS1 at RB6_bit;
sbit GLCD_CS2 at RB7_bit;
sbit GLCD_RS  at RB2_bit;
sbit GLCD_RW  at RB3_bit;
sbit GLCD_EN  at RB4_bit;
sbit GLCD_RST at RB5_bit;


sbit GLCD_CS1_Direction at TRISB7_bit;
sbit GLCD_CS2_Direction at TRISB6_bit;
sbit GLCD_RS_Direction  at TRISB2_bit;
sbit GLCD_RW_Direction  at TRISB3_bit;
sbit GLCD_EN_Direction  at TRISB4_bit;
sbit GLCD_RST_Direction at TRISB5_bit;

unsigned int value, tmp;
char txt[5];
char new_encoder;
char last_encoder;


void InitMain() {
  ADCON1 |= 0x07;     // Khong su dung ADC


  Chip_Select = 1;                       // Deselect DAC
  Chip_Select_Direction = 0;             // Set CS# pin as Output
  SPI1_Init();  
  Glcd_Init();                                   // GLCD hazırla
  Glcd_Fill(0x00);                          // Initialize SPI module
}

// DAC increments (0..4095) --> output voltage (0..Vref)
void DAC_Output(unsigned int valueDAC) {
  char temp;

  Chip_Select = 0;                       // Select DAC chip

  // Send High Byte
  temp = (valueDAC >> 8) & 0x0F;         // Store valueDAC[11..8] to temp[3..0]
  temp |= 0x30;                          // Define DAC setting, see MCP4921 datasheet
  SPI1_Write(temp);                      // Send high byte via SPI

  // Send Low Byte
  temp = valueDAC;                       // Store valueDAC[7..0] to temp[7..0]
  SPI1_Write(temp);                      // Send low byte via SPI

  Chip_Select = 1;                       // Deselect DAC chip
}

void main() {

  InitMain();                            // Perform main initialization

  value = 2048;                          // When program starts, DAC gives
                                         //   the output in the mid-range

 while (1) {                             // Endless loop
     new_encoder = (PORTb & 0x03);      // keep only 2 bits
   if(new_encoder != last_encoder)      // if encoder has changed
   {
      if(new_encoder.F1 == last_encoder.F0) value++;
      else value--;

      last_encoder = new_encoder;   // save for next time
   }

    DAC_Output(value);                   // Send value to DAC chip
    Delay_ms(1);                         // Slow down key repeat pace
     Glcd_Write_Text("Sayac", 30, 1, 1);
     
     tmp=value;
      wordtostr(tmp,txt);
      Glcd_Write_Text(txt, 30, 2, 1);
  }
}

erkantr67

#1
Koduna bakmadım.

Rotary encoder sağa ve sola çevirdiğinde her iki çıkıştanda 90 derece faz farklı pulse verir. Örneğin sağa döndürdüğünde 1. Çıkış ilk önce lojik 1 olur, 90 derece sonra ikinci çıkış lojik 1 olur, aynı derece farkıylada sırayla lojik 0 olur.

Yani sağa veya sola bir tık döndürmede her iki çıkıştanda sinyal alırsın. Dikkat etmen gereken nokta faz farkı. Fazı ileride olanı okuduktan sonra geride olanı yazılımsal olarak ya da donanımsal olarak sönümlemen gerekir.


Ek:
Tabi ark önlemide alınmalı.

Ek 2:
Her bir tıkta çift pulse verdiğini hatırlamıyorum ama eğer öyleyse bu durumuda pulse sayısını bir değişkene atarak ya da ilk pulse'i aldıktan sonra bir bit hafızayı set edip, ikinci pulsede clear yaparak bir bit hafızaya görede işlem yapabilirsin. Daha bir çok çözüm yolu bulunabilir.


gokhangokcen

Bu tarz enkoderlar ile bir çalışmam oldu. Benzer bir yapıyı şu uygulamada kullanmıştım ilgili kod kısmını alıp kendine göre uyarlayabilirsin.

Rotary Enkoder
Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.

smyomekatronik

@erkantr67 yardımınız için teşekkür ederim, ark önlemi için resimdeki devreyi kullandım değişen bir şey olmadı demekki sorun yazılımsal. @gokhangokcen kodları mikroc ye göre düzenleyebilirisem test aderim yoksa ccs ye geçeriz  :D .
Aslında aurdiona tam bana göre gibi, bakımcılığı üç seneden beri bıraktım, elektroniğide hobby düzeyine indirdim. Arada böyle ufak tefek devreler yapıyorum kendim kullanmak için.

ete

Pek çok kişi bu tür encoderler de her tıkta bir konum verdiğini düşünür. Bende öyle düşünüyordum ama benzer sorunlar yaşadığım için dikkatlice inceleyince baktım ki bu tür rotary encoderler iki tık arasında 4 konum veriyor. Yani %00-%10-%01-%11 şeklinde.Üstelik encoderi bıraktığınız anda da rastgele bir konumda kalıyor. Yani her zaman %11 veya %00 gibi sabit bir konumda kalmıyor. Arada bir yerde kalıyor. Bu nedenle bir tık da işlemci ve program hızına bağlı olarak çift atlama olabiliyor.
Çözüm bu 4 konumun yalnızca birinde sayı artımı yaptırılması şeklinde uygulanabilir.
Hem encoderin döndüünü algılayacak hemde belirli bir konumu mesela %00 yakalayınca sayacınızı bir artıracaksınız.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com