Rotary Encoder okuma problemi

Başlatan berkay_91, 08 Ağustos 2014, 14:29:15

berkay_91

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]

Kabil ATICI

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.
ambar7


mozkan87

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.

berkay_91

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);
	}
}



arm-beginner

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

Mucit23

Benim yaptığım çalışma aslında sizin işinizi görüyor.
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


Tagli

#8
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.
Gökçe Tağlıoğlu

z

A-B çıkışlarına küçük bir donanım ekleyip İki timer kullanırsın. İkisi de ileri sayar. Farklarına bakarsın.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

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.

Tagli

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ı.
Gökçe Tağlıoğlu

Kabil ATICI

ambar7

Tagli

Aslında tam aradığım şey ama Türkiye'de bulabilir miyim acaba bunları?
Gökçe Tağlıoğlu

Kabil ATICI

Belki,
istenirse
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/70063D.pdf
içinde bu modülü barındıran entegreler kullanılabilir.

Yinede Türkiye'de bulunabilirliğini tam olarak bilemiyorum.
ambar7