Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => Atmel => Konuyu başlatan: berkay_91 - 08 Ağustos 2014, 14:29:15

Başlık: Rotary Encoder okuma problemi
Gönderen: berkay_91 - 08 Ağustos 2014, 14:29:15
merhaba, atmega 8 için bulduğum bu kodlarda, rotary encoderı hangi yöne döndürürsem döndüriyim LCD de sayıların arttığını görüyorum. normalde sayıların encoder bir yönde döndüğünde artıp diğer yönde döndüğünde azalması gerekiyor. Yardımcı olursanız sevinirim...


[color=black]
#define F_CPU 1000000UL
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "lcd.h"


int enc = 10;

// Subroutine declarations
void initInterrupts(void);

// The Interrupt Service Routine for external INT1
ISR(INT1_vect)
{
// When an interrupt occurs, we only have to check the level of
// of pin PD5 to determine the direction
if (bit_is_set(PIND,5)){

enc++;
_delay_ms(200);
}

else if(bit_is_set(PIND,3)){

enc--;
_delay_ms(200);
}
}

// Routine to setup INT1
void initInterrupts(void)
{
// Assure that pin PD3 (INT1) and PD5 are inputs
DDRD &= ~(1<<PD5);
DDRD &= ~(1<<PD3);

// Enable the pull-up resistors
PORTD |= (1<<PD5)|(1<<PD3);

// Falling edge in INT1 (PD3 / pin17) to cause interrupt
MCUCR |= (1<<ISC11);

// Enable and INT1
GICR |= (1<<INT1);
}

FILE lcd_str = FDEV_SETUP_STREAM(lcd_putc, NULL, _FDEV_SETUP_WRITE);

int main(void)
{
DDRB=0xff;
initInterrupts();

sei();

lcd_init(LCD_DISP_ON);

stdout = stdin = &lcd_str;

lcd_clrscr();

lcd_gotoxy(0,0);
lcd_puts("Encoder test");

while (1)
{

lcd_gotoxy(0,1);
printf("%d ",enc);

_delay_ms(10);
}
}
[/color]
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Kabil ATICI - 08 Ağustos 2014, 20:08:28
söylediğin şekilde olması gayet normal. Çünkü kesme bacağın inen kenarda kesmeyi tetikleyecek şekilde ayarlamışsın. Bu nedenle diğer şartın oluşması imkansız. Kesme içinde
if(bit_is_set(PIND,3)) oluşması imkansız.

Bacağın biri için INT0 diğeri için INT1'i kullanıp ona göre karşılaştırma yapmak gerekir.
Atamaları kendin yapman gerekecek;

ISR(INT1_vect)
{
    // When an interrupt occurs, we only have to check the level of
    // of pin PD2 to determine the direction
    if (bit_is_set(PIND,2))
{   
    enc++;
    _delay_ms(200);
    }
}

ISR(INT0_vect)
{
    // When an interrupt occurs, we only have to check the level of
    // of pin PD3 to determine the direction
    if (bit_is_set(PIND,3))
{   
    enc--;
    _delay_ms(200);
    }
}
üç aşağı beş yukarı buna benzer bir şey.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: berkay_91 - 08 Ağustos 2014, 21:34:50
teşekkür ederim dediğini denicem
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: mozkan87 - 08 Ağustos 2014, 23:58:11
Aslında iki interrupt pinini bu iş için kullanmaya gerek yok interrupt source anychance olarak ayarlayınca pinlerin durumuna göre okuma yapılabilir.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: berkay_91 - 09 Ağustos 2014, 02:33:35
kodları aşağıdaki gibi değiştirdim şimdi nispeten daha iyi ama yinede sayı artarken arada azalıyo sonra tekrar artıyor azalırkende aynı şekilde arada bir artıyo sonra azalmaya devam ediyor




/*
* rotary_encoder.c
*
* Created: 09.06.2014 20:47:46
*  Author: BERKAY
*/

#define F_CPU 1000000UL
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "lcd.h"

int enc = 10;

void initInterrupts(void);

ISR(INT1_vect){

    enc--;

_delay_ms(100);


}

ISR(INT0_vect){

enc++;

_delay_ms(100);

}

void initInterrupts(void){

// Falling edge in INT0 and INT1
MCUCR|=(1<<ISC01)|(1<<ISC00)|(ISC10)|(1<<ISC11);

GICR|=(1<<INT0)|(1<<INT1);

sei();
}

FILE lcd_str = FDEV_SETUP_STREAM(lcd_putc, NULL, _FDEV_SETUP_WRITE);

int main(void)
{
DDRB=0xff;
DDRD&=~(1<<2)|(1<<3);

PORTD|=(1<<2)|(1<<3);

initInterrupts();
   
    lcd_init(LCD_DISP_ON);

stdout = stdin = &lcd_str;

lcd_clrscr();

lcd_gotoxy(2,0);
lcd_puts("Encoder Test");

while (1)
{

lcd_gotoxy(0,1);
printf("%d ",enc);

_delay_ms(10);
}
}






Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: arm-beginner - 09 Ağustos 2014, 17:51:31
Encoder için interrupt kullanılmaz. Veya şöyle söyleyim: interrupt kullanmamak daha doğru olur.
Gönderdiğim link'de 100'lerce kişi tarafından denenmiş çalışan kodlar. Maalesef Almanca.

http://www.mikrocontroller.net/articles/Drehgeber (http://www.mikrocontroller.net/articles/Drehgeber)
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Mucit23 - 09 Ağustos 2014, 19:46:05
Benim yaptığım çalışma aslında sizin işinizi görüyor.
http://arectron.com/microchip/pic16f628_ile_aci_olcer.html (http://arectron.com/microchip/pic16f628_ile_aci_olcer.html)
İşin mantığını anlatmışım. Yüksek çözünürlüklü encoderlerde interrupt değişim hızına yetişemiyebiliyor. Bu yüzden encoder den puls saymak için interrupt kullanılmıyor timer kullanılıyor.

Videoda açı hesaplıyorum  8)
Encoder Test (http://www.youtube.com/watch?v=Bfqe2k-uq38#ws)
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: berkay_91 - 09 Ağustos 2014, 22:31:48
sağolun beyler
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Tagli - 09 Ağustos 2014, 23:18:21
Donanım desteği yoksa quadrature encoder'ın timer ile okunabileceğini sanmıyorum. Tek yönde dönüyorsa hız belirlenebilir ama yön tayini yapılamaz.

Düşük hızlarda ve düşük çözünürlüklerde port değişim kesmesi bu iş için yeterli. Ancak tabi durum tersi olduğunda sinyal kaçmaya başlıyor.

Mucit23, flip-flop ile yön tayinini daha önce de görmüştüm, hoş bir yöntem ama PIC16F628A'da timer'ı geri saydırmanın bir yolu yok. Sorunu nasıl çözdüğünü anlayamadım.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: z - 09 Ağustos 2014, 23:49:15
A-B çıkışlarına küçük bir donanım ekleyip İki timer kullanırsın. İkisi de ileri sayar. Farklarına bakarsın.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Mucit23 - 10 Ağustos 2014, 00:19:10
Alıntı yapılan: Tagli - 09 Ağustos 2014, 23:18:21
Donanım desteği yoksa quadrature encoder'ın timer ile okunabileceğini sanmıyorum. Tek yönde dönüyorsa hız belirlenebilir ama yön tayini yapılamaz.

Düşük hızlarda ve düşük çözünürlüklerde port değişim kesmesi bu iş için yeterli. Ancak tabi durum tersi olduğunda sinyal kaçmaya başlıyor.

Mucit23, flip-flop ile yön tayinini daha önce de görmüştüm, hoş bir yöntem ama PIC16F628A'da timer'ı geri saydırmanın bir yolu yok. Sorunu nasıl çözdüğünü anlayamadım.

Hocam oradaki timer ana sayacım değil benim. Ben her seferinde timerde nekadarlık bir artış olduğunu hesaplıyorum. dönüş yönüne göre ana sayacıma artış miktarı kadar ekliyorum veya çıkarıyorum. Kabaca yaptığım işlem budur.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Tagli - 10 Ağustos 2014, 16:58:20
Bu arada, dikkatimi çeken başka bir sorun daha var: Flip-flop ile kurulan bu donanım A veya B'den sadece birinin yükselen kenarına duyarlı. Bu durumda yön değişimi geç algılanabilir. Çünkü sistem her 4 adımdan birine bakıyor.

4 adet flip-flop ve belki birkaç tane de mantık kapısı kullanılarak sistemin tüm adımlara duyarlı olması sağlanabilir. Ama çözüm devre üzerinde fazla yer kaplar. Şu sıralar uğraştığım bir projede benim de bu sorunu çözmem lazım. Alanım da kısıtlı.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Kabil ATICI - 10 Ağustos 2014, 17:44:23
http://hades.mech.northwestern.edu/images/6/6e/LS7183.pdf (http://hades.mech.northwestern.edu/images/6/6e/LS7183.pdf)
bir bakılabilir.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Tagli - 10 Ağustos 2014, 18:05:47
Aslında tam aradığım şey ama Türkiye'de bulabilir miyim acaba bunları?
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Kabil ATICI - 10 Ağustos 2014, 20:42:13
Belki,
istenirse
https://www.picproje.org/index.php?topic=21555.0 (https://www.picproje.org/index.php?topic=21555.0)
türünden entegrelere bakılabilir. (HCTL-2022)
Hatta projeniz uygunsa
http://ww1.microchip.com/downloads/en/DeviceDoc/70208A.pdf (http://ww1.microchip.com/downloads/en/DeviceDoc/70208A.pdf)
http://ww1.microchip.com/downloads/en/DeviceDoc/70063D.pdf (http://ww1.microchip.com/downloads/en/DeviceDoc/70063D.pdf)
içinde bu modülü barındıran entegreler kullanılabilir.

Yinede Türkiye'de bulunabilirliğini tam olarak bilemiyorum.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Tagli - 10 Ağustos 2014, 20:59:49
QEI modülünü başka bir projede kullanıyorum, çok faydalı ve kullanışlı. Ancak bu projede fazla işlem gücüne ihtiyaç yok, o yüzden QEI'i olan dsPIC30F biraz abartılı olacak. Ayrıca QEI içeren modeller en az 28 bacaklı olduğu için fazla yer kaplıyorlar ve genelde dsPIC veya PIC24 içinde oluyorlar ki onların fiyatları pahalı sayılabilir. O yüzden 18 bacaklı bir modeli (muhtemelen PIC16) tercih ediyorum. Gerçi 18 bacaklı PIC + 8 bacaklı özel entegre daha fazla yer kaplayacak o da ayrı mesele.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: arm-beginner - 10 Ağustos 2014, 21:06:49
Bu tür entegreler dakikada birkaç 1.000 tur ile dönen motorlara bağlı olan encoder'lar için.
Bizim iki parmak arasında sağa ve sola çevirdiğimiz encoder'lar için en zayıf MCU bile fazla gelir.
Her 1ms ile bir timer-interrup tetikleyiniz ve A-B girişlerinde ne var ne yok kontrol ediniz.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Tagli - 10 Ağustos 2014, 21:20:35
Tam hızını bilmemekle birlikte benim encoder sinyalinin yüksek frekanslı olacağını tahmin ediyorum. 100 kHz veya daha yüksek frekanslı olabilecekmiş gibi sistemi ayarlamaya çalışıyorum. 8 bacaklı bir PIC12'yi sadece bu iş için ayarlayıp kodu ASM'de yazarsam belki 10 us'de döngüyü tamamlayabilirim. İlk aklıma gelen PIC12F675/629 oldu. Ama 4 MHz (1 MIPS) ile bu iş mümkün değil. Ya harici 20 MHz kristal kullanılmalı ya da PIC12F1822 gibi bir işlemci seçilmeli. İkincil işlemci 1 bitlik yön bilgisini hesaplayıp verse yeter. Ama yine de genel olarak ikincil işlemci biraz saçma bir fikirmiş gibi geliyor.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: mozkan87 - 10 Ağustos 2014, 22:51:34
Alıntı yapılan: arm-beginner - 10 Ağustos 2014, 21:06:49
Bu tür entegreler dakikada birkaç 1.000 tur ile dönen motorlara bağlı olan encoder'lar için.
Bizim iki parmak arasında sağa ve sola çevirdiğimiz encoder'lar için en zayıf MCU bile fazla gelir.
Her 1ms ile bir timer-interrup tetikleyiniz ve A-B girişlerinde ne var ne yok kontrol ediniz.


Hocam ben bu yöntemle sorun yaşadım. Rotary encoderın döndürülme hızına göre arada değer kaçırdığını gördüm, mesala yavaş çevirirken sıkıntı yoktu ama biraz hızlı çevirirken arada bazı pulsleri kaçırdığımızı gördüm. Daha sonra çözümü encoder'ın A ucunu interrupt(any change) pinine bağladım ve kesme oluştuğunda A ve B nin durumlarını karşılaştırdım, en iyi sonucu böyle elde ettim.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Mucit23 - 10 Ağustos 2014, 23:08:44
Donanımsal encoder okuma modülü olmayan mcularda Timer ile saymak en mantıklı yöntem. Şu Pot tipi encoderlerden kullanılmayacaksa kesmeye güven olmaz.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Erol YILMAZ - 10 Ağustos 2014, 23:49:13
Rotary encoder için donanım yok ise !
Timer in ileri geri ilerlemek için girişleri yok ise,

Interrupt ile okumak halen mantıklı.
Neden?

Değerleri max seviyede düşünelim...
1000 pals encoder 5 mm vidalı sistemde dk'da 15 metre hareket etmiş olsa,
biz bu encoderi 4x modunda okumuş olsak, 200.000 / sn adet INT oluşur.

48 Mhz Cortex M0 Mcu'da en zor ihtimalle, 240 komutta bir INT,
64 Mhz PIC18 Mcu'da en sor durumda, 320 komutta bir INT demek.

Olmaz değil, Biraz incelenirse, gayet güzel çalışır.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: arm-beginner - 11 Ağustos 2014, 09:06:59
Alıntı yapılan: mozkan87(...) Daha sonra çözümü encoder'ın A ucunu interrupt(any change) pinine bağladım ve kesme oluştuğunda A ve B nin durumlarını karşılaştırdım, en iyi sonucu böyle elde ettim.

Bu yöntem diğer interrupt metodlardan (A ve B sinyalerin rising veya falling edge'ler ile interrupt tetikleyenlerden) çok daha iyi. Ama encoder'lar bir süre sonra yıpranıyorlar ve sonra sinyalerde sıçramalar oluyor. Ve MCU her sıçramada konu ile ilgilenmek zorunda.
Not: burda insanların kullanımı için üretilmiş encoder'lardan bahsediyorum. Yüksek tur ile çalışan encoder'lar hakkında bilgim yok.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Tagli - 11 Ağustos 2014, 13:06:15
Alıntı yapılan: arm-beginner - 11 Ağustos 2014, 09:06:59
Bu yöntem diğer interrupt metodlardan (A ve B sinyalerin rising veya falling edge'ler ile interrupt tetikleyenlerden) çok daha iyi.
Ne açıdan daha iyi? Çözünürlük açısından daha iyi olmadığını söyleyebilirim çünkü çözünürlük yarıya düşüyor. Buna 2x modu deniyor. Hem A hem B'nin hem yükselen hem düşen kenarlarına bakıldığında 4x modu oluyor ve en yüksek çözünürlüğe bu şekilde ulaşılabilir.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: skara1214 - 11 Ağustos 2014, 15:25:00
18f2431 kullanın kasmayın uğraşmayın
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: arm-beginner - 11 Ağustos 2014, 19:37:58
Tagli, sen Encoder'larin datasheet'indeki güzel karelere bakma. Onlar belki en başta öyle bir sinyal yaratabilirler; ama bir süre sonra şuna benziyeceklerdir:

Kaynak: http://en.wikipedia.org/wiki/Switch#Contact_bounce (http://en.wikipedia.org/wiki/Switch#Contact_bounce)

Opala, resim nerde? Neyse, link'i veriyorum:
http://en.wikipedia.org/wiki/File:Bouncy_Switch.png (http://en.wikipedia.org/wiki/File:Bouncy_Switch.png)
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: Tagli - 11 Ağustos 2014, 22:28:09
Doğrudur. dsPIC30F QEI modülünün içinde opsiyonel dijital alçak geçiren filtre var. Demek ihtiyaç oluyor ki koymuşlar. BLDC hall sensörlerinde benzeri bir durum yaşamıştım. Girişlerin Schmitt trigger olması şart. R-C ile alçak geçiren filtre de ayrıca eklenebilir.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: arm-beginner - 12 Ağustos 2014, 19:26:37
Gelen A/B sinyaleri interrupt ile değerlendirmekden vazgeçmeyenler için optical encoder önerebilrim. Fiyatarı 25 EUR ile başlıyor, ama orda en azından sinyalerde sıçrama olmiyor.
Örneğin Bourns EM14-Serisi veya "para sorun değil" diyenler için EN-Serisi.
http://www.bourns.com/data/global/pdfs/EM14.pdf (http://www.bourns.com/data/global/pdfs/EM14.pdf)
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: mozkan87 - 12 Ağustos 2014, 20:14:59
Benim kullandığım devrede RC filtre mevcut bu nedenle bouncing sorunu yaşamıyorum.
Başlık: Ynt: Rotary Encoder okuma problemi
Gönderen: arm-beginner - 12 Ağustos 2014, 20:18:04
RC-Filtre tabii ki bir çözüm; ama böylece encoder'ın max. dönme hızını sınırlıyorsun. Ayrıca yazılım ile yapabileceğin birşeyi niçin donanm ile çözüyorsun?

mesaj birleştirme:: 12 Ağustos 2014, 22:20:13

Belki birisinin ilgisini çeker:
http://www.mikrocontroller.net/topic/341165 (http://www.mikrocontroller.net/topic/341165)
Kişi burda bir stepper-motorunu encoder olarak kullanıyor. İnternet'de bu tür çözümler bol miktarda var; ama burdaki özellik sinyaler ADC ile okunuyor ve basamakların geçiş-direncini 2 aşamali düzenliyor.
Atmega88 kullanılmış ve program C ile yazılmış.