Hi-Tech ile encoder okuma, kod mantığı.

Düzenekte encoder takılı ise mecburen onu kullanacaksınız. Absolute encoder hem pahalıdır ve hem de haberleşme zaman alır. Incremental encoder kullanırsanız çok yavaş hareketlerde puls alamayabilir ve dolayısıyle pozisyon bilgisini sağlıklı kontrol edemeyebilirsiniz. O nedenle encoder çıkışlarını ya yüksek kazançlı bir yükselteç ile (max 5 vol çıkışı olsun) ver veya 877 analog comparatör modunda giriş bacaklarına ver ve dahili karşılaştırma voltajını küçük seç.

Yukarıda örneğini verdiğiniz
degisken=PORTA & %00000011
işleminde %00000011 sayısı, port A nın diğer bacaklarından gelen bilgiyi maskelemek içindir. Sonuçta a0 ve a1 den gelen bilgi (0, 1, 2 veya 3) ne ise ona göre hareket yönünü ve pozisyonu saymak için kullanacaksınız. AB encoder diye araştırırsan görürsün. Bir bacağı alçıda birisinin merdiven basamaklarını çıkması veya inmesi gibidir. Encoderin bacaklarını dijital porta bağlarsan adım sırasından yön bilgisini bulursun.

Hassas pot kullansan daha iyi olabilir. Pot kullanacaksan analog kanalı (A0) ı kullan.

PID yerine PI kontrol algoritması daha iyi olabilir. Kol yatayda hareket ediyor olsa PID kullanmak zoundasın derdim.

Timer1 i hassas zamanlama için kullan (CCP1 compare modunda 50 yada 100 ms. için ayarlayabilirsin). Bu senin delta t zamanını belirler. Floating point aritmetiğine hiç girme. Her türlü hesaplamayı integer aritmetiği ile hem güvenilir ve hem de hızlı bir şekilde yapabilirsin.

CCS derleyicisini kullan. İçerisinde her konuda örnek beraberinde gelir. PWM örneği de mevcut.

Yazdığın programları Proteus ISIS üzerinde test edebilirisin.

Projenin %60'ını bu bilgilerle tamamlamış oldun.

Kolay gelsin.

Hocam size de çok teşekkür ediyorum.

degisken=PORTA & %00000011 ifadesi 0. ve 1. bitin değerini değişkene atıp diğerlerini maskeliyor demek.

Gerçi picbasic kullanmayacağım ama bu bilgide bulunsun kenarda.

Absolute encoder'i maliyet yüzünden kullanmak istemiyorum, dediğiniz gibi pahalı.

Incremental encoder kulllanımı için söylediklerinizi de aklımda tutacağım hesaplama için integer tavsiyesini de.

Vallahi teşekkür ediyorum hepinize, bu aşamada bu kadar yardımcı oldunuz ilk kod vucuda bir gelse yapacağınız katkılarla bu işi halledeceğiz demektir.

Teşekkürler.
 
pic_loader, evet encoder'ın çıkışından 1(+5v) ve 0(gnd) şeklinde lojik çıkış geliyor ya ben ssiteme tam iyi bakmamaışım kusura bakma ben encoder motor üstünde zannediyordum encoder ze_tr hocamın dediği gibi A ve B diye iki çıkışı var bir puls diğeri yön bilgisini veriyor ve senin burda her iki çıkışıda kullanman gerek çünkü kol aşağı veya yukarı çıktığınıda bilmen gerek yani yön bilgisini bu nedenle iki ucuda kullanırsın ve bu encoder çıkışlarını daha düzgün sinyaller almak için lm339 komparatöründen geçirebilirsin ya ben şimdi sana örnek birde program vereyim bu program encoder dan alınan bilgilerle devir ve yön bilgilerini veriyor ccs c ile
**********************************
#INCLUDE <16F877A.H>
#USE DELAY (CLOCK=20000000)
#use fast_io (b)
#use fast_io (c)
#define use_portb_lcd true
#INCLUDE <LCD420.c>
int16 tur=0;
float tur_metre=0.15;//cm
//
#int_timer1
void timer1_kesmesi ()
{
set_timer1(65500);
if(input(pin_c7))
tur--;
else
tur++;
printf(lcd_putc,"\ftur sayisi:%ldtur\n",tur);
printf(lcd_putc,"metre:%0.2fm",tur*tur_metre);
}
void main()
{
set_tris_c(0x81);
output_c(0x00);
lcd_init();
setup_timer_1(t1_div_by_1|t1_external);
enable_interrupts(int_timer1);
enable_interrupts(global);
printf(lcd_putc,"\ftur sayisi:%ldtur\n",tur);
printf(lcd_putc,"metre:%0.2fm",tur*tur_metre);
set_timer1(65500);
while(1);
}
*********************************
bu program fikir vermek için eksik yönleri olabilir

ze_tr, hocam şu aşağıdaki mesaja kısaca neden böyle olduğuna dair bize bilgi veririmisiniz.
teşekkür ederim
"PID yerine PI kontrol algoritması daha iyi olabilir. Kol yatayda hareket ediyor olsa PID kullanmak zoundasın derdim"
 
pic_loader, evet encoder'ın çıkışından 1(+5v) ve 0(gnd) şeklinde lojik çıkış geliyor ya ben ssiteme tam iyi bakmamaışım kusura bakma ben encoder motor üstünde zannediyordum encoder ze_tr hocamın dediği gibi A ve B diye iki çıkışı var bir puls diğeri yön bilgisini veriyor ve senin burda her iki çıkışıda kullanman gerek çünkü kol aşağı veya yukarı çıktığınıda bilmen gerek yani yön bilgisini bu nedenle iki ucuda kullanırsın ve bu encoder çıkışlarını daha düzgün sinyaller almak için lm339 komparatöründen geçirebilirsin ya ben şimdi sana örnek birde program vereyim bu program encoder dan alınan bilgilerle devir ve yön bilgilerini veriyor ccs c ile

Hocam estf, hata benim derdimi anlatamıyorum acemiyiz sonuç olarak :)

Verdiğiniz kod örneği içinde teşekkür ederim, gerçi bende derleyicisi yok ama mantığından istifade ederiz inşallah.

Şu pic'deki ADC, TIMER ve PWM kısımlarını biraz daha derinlemesine öğreneyim yazacağım ilk kodu burada sizlerle paylaşacağım ve eleştirilerinizi rica edeceğim.

Hepinize teşekkür ederim.
 
Arkadaşlar hepinize merhaba.

Ufak ufak işe koyulalım dedim, okuduğum dökümandan anladığım kadarıyla RB4 RB7 kesmesini kullanarak encoder'in üreteceği pulse değerini saymayı amaçlayan bir kod yazdım.

Burada Encoder'in A bacağı RB4 pinine, B bacağıda RB5 pinine bağlı.

Tabi teknik hiçbir bilgim yok, bu bacaklar buralara bağlanırmı diye :) Artık hata varsa söylersiniz.

Mantıkda basit, tam bir acemi işi.

Pulse üretildikçe kesme olacağından interrupt içinde pulse değerini tutan değişken sinyalin geldiği bacağa göre artıyor yada eksiltiliyor.

Kod:
#include <htc.h>

void main(void) {
	TRISB=0xF0; // RB4..RB7 giris, diğerleri çıkıs
	RBIF=0; // RB4..RB7 kesme bayrağı temizleniyor
	RBIE=1; // RB4..RB7 kesme izni veriliyor
	GIE=1; // Genel kesme izni veriliyor
	
	for(;;); // Islemci sonsuz döngüde bekletiliyor
}

static void interrupt rb4_rb7(void) {
	
	char pulse_deger; // Kesme içinde bir dğeisken tanımlanıyor
	if(RBIF) { // RB4..RB7 kesme olusmus mu bakılıyor
		GIE=0; // Kesme varsa, baska kesme gelmemesi için genel kesme sıfırlanıyor
		if(RB4) // Encoder'in A bacagindan sinyal geldi ise pulse_deger'i arttir
			pulse_deger++;
		else if(RB5) // Encoder'in B bacagindan sinyal geldi ise pulse_deger'i azalt
			pulse_deger--;
		
		RBIF=0; // Tekrar dıs kesme alınabilmesi için kesme bayrağı temizleniyor
		GIE=1; // Tekrar kesme alınabilmesi için genel kesme bayrağı set ediliyor
	}
	
}

Burada yaptığım bir hata var mı?

İlk aklıma gelen kesme içinde değişkenin yerelliği, global bir değişken hi-tech'te nasıl tanımlanıyor henüz bilmiyorum.

Yoksa pwm üzerine çalışmaya başlayaım :)
 
Arkadaşım bence bu rb4-rb7 kesmesini kullanma burda gitmez çünkü encoder çıkışlarından yön bilgisinin lojik seviyesi puls sinyalinin tam ortasında değişiyor
encoder'ın çıkış sinyallerine baksan ne demek istediğimi anlarsın
şimdi fikrimce senin ilerde yapacağın uygulama için sana yön bilgiside lazım olacak gibi (kolun aşağı ve yukarı hareketi için)
bence şöyle olabilir timer0 veya timer1'i sayıcı moduna ayarla encoder puls çıkışıylada timer0 veya timer1 sayacını artır ve kesme işlemini yükselen kenarda yap (bu önemli değil düşen kenarda olabilir) ve bir tanede giriş portu tanımla bunada getir encoder'ın yön bilgisi sinyalini bağla kesme oluştuğunda yön bilgisini kontrol et "0" ise puls sayısını 1 azalt "1" ise puls sayısını bir artır
(gönderdiğim uygulamalar arasında bu işi yapan bir tane program var)
(encoder'ın puls sinyali ile yön bilgisi sinyali arasında 90 derece faz farkı var)
*******************
"yon" burda giriş olarak tanımlanmış bir pin
**************
timer1_kes()
{
if(yon==0)
puls--; //kol aşağı iniyor
else
puls++; //kol yukarı çıkıyor
}
****************
çok basit oldu ama fikir vermesi açısından bence sen bu timer'ların sayıcı olarak
kullanılması olayına bak ve birde sana göndermiş olduğum encoder uygulamasını
isisde bir çalıştır ve motoru ileri ve geri çalıştırarak bu encoder sinyalleri nasıl değişiyor diye bak
kolay gelsin
 
SALIH-46 hocam cevap için teşekkürler.

En sondan başlayayım proteusu sistemime kuramadım, garip bir çakışma var çalışmıyor, o yüzden kodları böyle bir araçla test edemiyorum.

Bu yüzden gönderdiğiniz CCS C örneklerini test edemiyorum.

Kod için yaptığınız eleştiriyi dikkate alarak yeni bir şey yazmayı deneyeceğim.

Yanlız anlamadığım tek nokta "encoder puls çıkışı" tabiri.

Henüz hiç bir malzemeyi almadığım için belki bilmiyorum, sadece teknik bir iki döküman okudum.

Ben incremental encoder ile çalışacağım, bunda bu dediğiniz var mı?

Yoksa bana absolute encoder mi öneriyorsunuz?
 
açıkcası arkadaşım bu iki encoder tipi hakkında bilgim yok ama bence her ikisindede aynı çıkışlar vardır ama farklılık başka yerlerdedir heralde ama z_tr hocam incremental encoder için ucuz demiş o nedenle incremental al deyim ve
birde bence encoder'ın çözünürlüğü fazla olmalı yani bir devirde ürettiği puls sayısı eğer bu çok küçük olursa zaten senin mesafede az doğrusallık iyi olmaz
ve bu encoder çıkışlarını lm339 komparatöründen geçirerek daha düzgün sinyaller alırsın bence o sorun olmazda ama dediğim gibi bir devirde üretiği puls sayısı bence 500 lerde filan olursa iyi olur ya şimdi encoder puls çıkışı dediğim encoder'ın mili hareket ettikçe ürettiği kare dalga +5v ile 0v arasında mil hangi yöne hareket ederse etsin bu ucdan devamlı kare dalga görürsün ya buna takılmada isisi kurmaya bak isisi kurarken eğer antivirüs kullanıyorsan antivirüsü devre dışı bırak öyle kurmayı dene
 
Benim sana tercihim PIC 30F4012 kullanman. Üzerinde hem donanımsal olarak Enkoder modülü hemde PWM modülü mevcut ve en önemlisi 30 mips çalışabilmesi.
videoya da göz atmayı unutma...

YouTube - Quadrature Encoder Interface - dsPIC33F

Etkileyici.

Şimdi 16f877'le ilgili biraz mesafe aldık tekrar sil baştan yapamayız, fazla vaktim de kalmadı.

Ama bu iş hoşuma gitti, ilgilenmeye devam ederim diye düşünüyorum.

Sonrasında bu pice de el atarız nasipse :)

Teşekkürler.
 
açıkcası arkadaşım bu iki encoder tipi hakkında bilgim yok ama bence her ikisindede aynı çıkışlar vardır ama farklılık başka yerlerdedir heralde ama z_tr hocam incremental encoder için ucuz demiş o nedenle incremental al deyim ve
birde bence encoder'ın çözünürlüğü fazla olmalı yani bir devirde ürettiği puls sayısı eğer bu çok küçük olursa zaten senin mesafede az doğrusallık iyi olmaz
ve bu encoder çıkışlarını lm339 komparatöründen geçirerek daha düzgün sinyaller alırsın bence o sorun olmazda ama dediğim gibi bir devirde üretiği puls sayısı bence 500 lerde filan olursa iyi olur ya şimdi encoder puls çıkışı dediğim encoder'ın mili hareket ettikçe ürettiği kare dalga +5v ile 0v arasında mil hangi yöne hareket ederse etsin bu ucdan devamlı kare dalga görürsün ya buna takılmada isisi kurmaya bak isisi kurarken eğer antivirüs kullanıyorsan antivirüsü devre dışı bırak öyle kurmayı dene

SALIH-46 hocam kullanacağım encoder bir tam turda 3600 pulse üretecek, benim kolun hareket açısıda 90 derece olduğundan 900 pulselik bir aralıkta işlem yapacağım.

Şimdi son tavsiye ettiğiniz timeri sayaç olarak kullanmak için kod yazmayı denedim

Kod:
#include <htc.h>

char pulse_deger; // Kesme icinde bir degisken tanimlaniyor

void main(void) {

	ADCON1=0x07; // PORTA dijital yapiliyor
	TRISA=0x03;  // RA0 ve RA1 giris, RA0 Encoder A Bacagi RA1 Encoder B Bacagi
	PORTA=0x00;  // PORTA sifirlaniyor
	PR2=250;     // PR2 degerine 250 yukleniyor
	T2CKPS1=1;   // Prescaler 1:16 oluyor
	T2CKPS0=1;   // Prescale 1:16 oluyor
	TOUTPS3=1;
	TOUTPS2=1;
	TOUTPS1=1;
	TOUTPS0=1;
	TMR2IF=0; // TMR1 kesme bayragi temizleniyor
	TMR2IE=1; // TMR1 kesmesine izin veriliyor
	TMR2ON=1; // TMR1 calistiriliyor
	PEIE=1; // Yardimci kesme izni veriliyor
	GIE=1; // Genel kesme izni veriliyor

	for(;;); // Islemci sonsuz dongude bekletiliyor
}

static void interrupt timer_kesmesi(void) {
	
	
	if(TMR2IF) { // TMR2 kesmesi olusmus mu
	
		GIE=0; // Kesme varsa, baska kesme gelmemesi icin genel kesme sifirlaniyor
		
		if(RA0)//Encoder'in A bacagindan sinyal geldi ise pulse_deger'i artir
			pulse_deger++; 
		else if (RA1) //Encoder'in B bacagindan sinyal geldi ise pulse_deger'i azalt
			pulse_deger--;
		
		TMR2IF=0; // Tekrar dis kesme alinabilmesi icin kesme bayragi temizleniyor
		GIE=1; // Tekrar kesme alinabilmesi icin genel kesme bayragi set ediliyor
	}	
}

Bu kod teoride 0.064 saniyede bir çalışıp pulse sayacak.

Encoder bacakları PortA birinci ve ikinci pinine bağlı.

Bir hatam var mı?
 

Forum istatistikleri

Konular
129,029
Mesajlar
922,660
Kullanıcılar
451,287
Son üye
BURAK DURĞUN

Yeni konular

Geri
Üst