Yaptığım bir cihazın menü çözümü için rotary encoder kullanmak istiyorum. Fakat o kadar kolay değilmiş. Mekanik olduğundan bounce olayı var. Program tarafında ne yaptıysam engelleyemedim, bir tek sabit zaman aralıklarıyla polling yapmayı denemedim, onu da deneyeceğim. Bacaklara kondansatör bağlamak PIC'i sapıttırıyor. Kod tarafının da yeterince verimli olmadığı kanaatindeyim, portu iki kere okuyup, iki bitini filtreleyip XOR uyguluyorum. Teoride çalışmalı ama pratikte nadiren birer, çoğunlukla ikişer bazen de üçer atlıyor. Portb'nin change interruptunu kullanarak yaptığım gürültüden etkileniyor ki, adam gibi okuyamadı bile. Bir de buffer deneyeceğim tavsiye üzerine.
Anlayamadığım şey, kaydırık cihazlarda bulunan ultra dandik encoderlar sapasağlam çalışırken benimkiler niçin çalışmaz. Bu değiştirdiğim 2. encoder. İlki daha felaketti, şimdikiler push buttonlu ve ufak, aslında çalışsa çok güzel olacak.
Ne önerirsiniz?
_____________________________
Rüzgar ters esiyorsa, yelkenlerini rüzgar yönüne göre ayarlamaya bak; çünkü dünya çektiğin sıkıntılarla değil, gemiyi limana ulaştırıp ulaştıramadığınla ilgilenir.
Ben daha önce kullanmadım ama; Rotary encoderların binary ve gray kod üreten çeşitleri varmış. Acaba sizin atlama nedeniniz buradan kaynaklanıyor olabilirmi?
Ayrıca bişey sorayım,proteusta ben rotary encoder olarak bişey bulamadım,simülasyon olarak deneme şansımız var mı?
Bendeki gray code üreten, yani 00, 01, 11, 10. En azından aldığım yer öyle biliyor, ayrıca binary diye bir encoder de bilmiyorum bu arada. Quadrature(=incremental =relative) kullanıyorum, diğer tip olan absolute'da encoderin o an bulunduğu nokta kesin olarak bilinebilir. Bu tip pahalıdır ve benim için gereksizdir. Benim amacım sağa mı sola mı dönüyor, kaç "tık" dönüyor onu bilmek.
Proteus için model var ama ya model bozuk, ya da benim programlar, düzgün çalıştıramadım hiç.
_____________________________
Rüzgar ters esiyorsa, yelkenlerini rüzgar yönüne göre ayarlamaya bak; çünkü dünya çektiğin sıkıntılarla değil, gemiyi limana ulaştırıp ulaştıramadığınla ilgilenir.
01 dediğin biri açık biri kapalı devre mi yoksa gerçekten alçak ve yüksek lojik seviyede mi? Eğer ilk dediğimse çok basit birşeyi unutmuş olabilir misin acaba? İlgili portları pull-up ya da pull-down yapmayı?
Bütün bunlar tamamsa encoderin interruptu çalıştıktan sonra kendini kapatsın ve interrupta bağlı bir timer başlatsın, projene uygun bir süre belirle, timer interruptu tetikleyince encoder interruptunu açsın. Bu şekilde mutlaka çalışacaktır.
Kodlarındaki ergenekon bağlantılarını çıkar gerisini buraya koy ki yorum yapabilelim Katade nin uyarısı yerinde idi ama anlaşılamadı sanırım. Senin kullandığın gray değil . A-B çıkışları birbirinden 90 derece kayık incremental tip.Böylece sağ-sol dönüşü algılayabilirsin. Kesme kullanman şart yoksa puls kaçırırsın.Maskeleme xorlama filan bir şeyler yapıldığını gösteriyor.Programın başka yerlerinde oyalanıyor gibisin. Proteus dosyaları yardımı güçlendirir...
Liu, aletin C pini toprağa bağlı olduğundan, pullup dirençleri olmasaydı MCU girişinde hiçbirşey göremezdi. Pulluplarımız var. 47k ve 10k olarak denedim. 100nf kondansatör atmayı denedim, PIC beğenmedi bunu gerçi. Şimdi son olarak içimde kalmasın, buffer olayını deneyeceğim. Bu encoder denilen cihazı okurken port interrupt kullanırsak, tek bir "tık" için interrupt 4 kere çalışıyor. Arada timer çalıştırmak işleri ne hale sokar tahmin edemedim, tabi yarın sağlam kafayla tekrar bakarım.
musallim, Incremental yani quadrature encoder kullandığımız kesin. Aldığım yer de gray code olduğunu yazmış. Bunun bir de binary olanı varmış, birkaç gerideki mesajımda yok dedim, lakin varmış. Bunun en garantili yolu osiloskoptan geçiyor. Bende de yok, ama bu işi kafama koydum ses kartını kullanacağım. Verdiğiniz iki linkten de haberim var :) Fakat dün gece bir link daha buldum, http://www.robotroom.com/Counter4.html adresinden başlayarak birkaç sayfa gidiyor. Sanırım buradan bir fikir alabilirim. Şu an kullandığım Basic kodunu koyuyorum, kesmesiz mesmesiz, polling stili; anlaşılabilir birşey zaten.
GetEncoder:
'
OldPos = (PORTB & %11000000)>>6 ' PORTB<7:6>yı filtrele
NewPos = OldPos
' encoder hareketini kontrol et
'
WHILE NewPos=0 OR NewPos=3
NewPos = (PORTB & %11000000)>>6 ' PORTB<7:6>yı filtrele
WEND
pause 20 ' debounce süresi
' Encoder çıkış tablosu (saat yönü):
' -------------------------------------------------
' 00
' 01 yarım tık
' 11
' 10 yarım tık
'
' XOR görevi:
'
' OldPOS : 0 0 3 3
' NewPos : 1 2 1 2
' hareket : sa st st sa (sa=saat yönü, st=saat yönü tersi)
' XOR -------------------------------
' 1 2 2 1
'
' NewPos XOR OldPos = 1 => artış
' Newpos XOR OldPos = 2 => azalış demek.
'
NewPos=NewPos ^ OldPos
SELECT CASE NewPos
CASE 1
menupointer=menupointer+1
CASE 2
menupointer=menupointer-1
END SELECT
RETURN
Hazır koddan yararlanıldı.
_____________________________
Rüzgar ters esiyorsa, yelkenlerini rüzgar yönüne göre ayarlamaya bak; çünkü dünya çektiğin sıkıntılarla değil, gemiyi limana ulaştırıp ulaştıramadığınla ilgilenir.
// Rotary Encoder inkrementale Drehgeber
// Rotary-Encoder Drehimpulsgeber
#include <16F871.H>
#include <int16CXX.H>
// Speicherschutz12,13,4,5=aus,Debug11=aus,ProgrammFlash9=an,EEpromRead8=an,NiedervoltProgr7=aus
// NiederVoltReset6=an,EinschaltTimer3=an,WachDogTimer2=aus,Oszillator0,1=XC
#pragma config |= 0b.11.111101.11.00.10
#pragma bit En1 @ PORTB.7
#pragma bit En2 @ PORTB.6
#pragma origin 4
bit n1,n2;
char Enkoder;
//***************** Interrupt ****************************************
interrupt int_server( void)
{
int_save_registers // W, STATUS (and PCLATH)
if ( RBIF) // Am port B hat sich etwas geändert
{
if (En1!=n1) // Wenn es vom Eingang1 kamm dann wurde Drehimpulsgeber gedreht.
{
if (En2==n1) // Wenn, wehrend Eingang1 geändert wurde, Eingang2 alte Signal hat, dann
{
Enkoder--; // war das Drehung nach Links
if (Enkoder==14)Enkoder=15; // Untergrenze des Einstellwertes setzen
}
else // Ansonsten war das Drehung nach Rechts
{
Enkoder++;
if (Enkoder==41)Enkoder=40; // Obergrenze des Einstellwertes setzen
}
n1=En1; // Zuschtand merken
n2=En2;
}
W = PORTB; // clear mismatch
RBIF = 0; // reset flag
}
int_restore_registers // W, STATUS (and PCLATH)
}
//****************************************************************************
void main(void)
{
TRISB=0b.1100.0000; // RB6->En2, RB7->En2 Eingänge zum Drehimpulsgeber
TRISD=0b.0000.0000; //
PORTD=0;
GIE=1; // Interrupts erlauben
RBIE=1; // Interrupt von PORTB erlauben
while(1)
{
PORTD=Enkoder; // Ständige Ausgabe
}
}
Yüksek hız gerekli olduğunda kesme şart(RB4-7).Örneğin 100 (100*4=400) lük encoder ile motor devri okumaya çalışılınca... Kesme olsa da tmr0 arka planda yazılımdan bağımsız çalışır.
mehaba arkadaşlar bende sizden bu konuda yardım isteyebilirmiyim. Bende bu şekilde bir encoderi devremde kullanacağım. ama ben bilgisayardan devreyi direk kontrol ediyorum(PCI I/O kart ile). ve encoder verilerinide direk bilgisayarda karşılaştıracağım. bu encoderler bu şekilde kullanılabilir mi. birde kesme yap diyorsunuz ya onu nasıl yapacağız. yardım ederseniz sevinirim.
Bu malzeme hakkında açıklayıcı bir bilgi yazabilecek zamanı olan var mı ?
Ne olduğunu anlayamadım.
Genellikle oto teyplerinde,radyolarda ,müzik setlerinde veya osiloskoplarda sinyal genliğini,frekansını değiştirmek için kullanılan bu anahtarın özelliği;işlevi genelde potansiyometre gibi olmasına rağmen sonsuza dek dönebilmesidir.Kullanıldığı uygulamalarda rotary pulse encoder,sistem ilk çalışmaya başladığında her zaman ayar ettiği büyüklük varsayılan değerinde kabul edilir.En son bırakılan büyüklük değeri isteğe göre kayıt edilebilir. Rotary pulse encodelar ağa yada sola sonsuz tur dönebilen ve dönüş yönü 2 bitlik binary sayı çıkışıyla veren elemandır.Yapısına göre optik ve mekanik olmak üzere iki çeşittir.