Yürüyen bant..Aslıdna yürüyen ban değil yürüyen stand oluyor herhalde.
Üretim bandı.bant üzerinde pliask kutu ileri gidecek.İşlem yapılacka sonra geri gelecek filan.Ama DC motor ile kurduğumdan Encoder ihtiyaçı doğdu.
Sistemde çift motor var.İnce kauçucuk türü bir malzeme motorlara bağlı rulolara sarılma ve bırkılma işlemleri ile üzerinde ürün taşınacak..
Fakat 2 encoderımdan gelen datayı tek bir PIC16f877 ile okumam gerekiyor.Bunu 20 mhz osilator kullanarak yapacam..Fakat okumada bir hatam var herhalde...Aşağıya kodu veriyorum.YArdımcı olursanız sevinirim...
'****************************************************************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2006 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 23.06.2006 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
DEFINE OSC 20
EPSDEGERI VAR BYTE
EPSDEGERI = 360
encoder1toplam VAR BYTE
encoder2toplam VAR BYTE
PROGRAM:
LCDOUT $fe,1, " Bant "
LCDOUT $fe, $C0, " yürüsün "
HIGH portd.0 ' bantı çekecek motor çalıştırıldı
HIGH portd.1 ' bantı salacak motor çalıştırıldı
GOTO ENCODER1SAY:
LCDOUT $fe,1, " Bant "
LCDOUT $fe, $C0, " taşındı "
goto BITIR
'****Encoder say alt programı***************************************************
ENCODER1SAY:
if encoder1=0 then ENCODER1BAK: ' 1 NOLU ENCODERDAN DATA GELİYORSA GİT
if encoder2=0 then ENCODER2BAK: ' 2 NOLU ENCODERDAN DATA GELİYORSA GİT
IF encoder1toplam=EPSDEGERI AND encoder2toplam=EPSDEGERI THEN ENCODERBITIR:
goto ENCODER1SAY:
ENCODER1BAK:
IF encoder1=1 THEN encoder1toplam=encoder1toplam+1
goto ENCODER1BAK:
IF encoder1toplam=EPSDEGERI THEN
LOW portd.0
LOW portd.1
ENDIF
goto ENCODER1SAY:
ENCODER2BAK:
IF encoder1=1 THEN encoder1toplam=encoder1toplam+1
goto ENCODER2BAK:
IF encoder2toplam=EPSDEGERI THEN
LOW portd.2
LOW portd.3
ENDIF
goto ENCODER1SAY:
ENCODERBITIR::
encoder1toplam=0
encoder2toplam=0
reTURN
BITIR:
end
ENCODER1SAY:
if encoder1=0 then ENCODER1BAK: ' 1 NOLU ENCODERDAN DATA GELİYORSA GİT
if encoder2=0 then ENCODER2BAK: ' 2 NOLU ENCODERDAN DATA GELİYORSA GİT
IF encoder1toplam=EPSDEGERI AND encoder2toplam=EPSDEGERI THEN ENCODERBITIR:
goto ENCODER1SAY:
ENCODER1BAK:
IF encoder1=1 THEN encoder1toplam=encoder1toplam+1
Burada anlayamadığım şey encoder1=0 iken ENCODER1BAK'a dallanıyorsun ama ENCODER1BAK döngüsünde sayımı encoder1'in '1' durumundan alıyorsun?
Bana göre iki ayrı sayma döngüsü yapıp hangisi istenen sayma koşulunu sağlıyorsa ona göre işlem yapman..
Yani
ENCODER1SAY:
IF ENCODER1 = 0 THEN
ENCODER1TOPLAM = ENCODER1TOPLAM+1
ENDIF
ENCODER2SAY:
IF ENCODER2 = 0 THEN
ENCODER2TOPLAM = ENCODER2TOPLAM+1
ENDIF
ENCODERKONTROL:
IF ENCODER1TOPLAM = EPSDEGERI AND ENCODER2TOPLAM = EPSDEGERI THEN
ENCODER1TOPLAM=0
ENCODER2TOPLAM=0
ENDIF
GOTO ENCODER1SAY
Evet, ilk başta bende oyle yaptım.Ama şu var.
Encoderdan data;
01010101010101010....
gibi geliyor.Ben sedece 0 ları sayarsam.1 leri atlarsam.Encoderın donuş hızı da yavaş olup bir dakai okuduğumda tekrar 1 e denk gelebilir.
O zamanda 0 ı okumamış olurum...
Once 0 gelir sonra hemen ardından 1 gelir.Eğer boyle ise encoderdan data almış sayılırım.
Ama yinede yanılıyor olabilirim.
YArdımcı olursanız sevinirim..
Anladım... gün içerisinde benimde aklıma geldi :D ...Eğer senin için bir pals tolerans sorun olmayacaksa bence herzaman '0' ları yada '1' leri say ama yok benim için önemli diyorsan onun içinde bir kaç satır kod yazman lazım..
Eğer motora start verildiğinde veya verilmeden önce pals girişi ne ise onun ters değerlerisini saydırma koşulu olarak yapmalısın..
Şimdilik bu kadar yazabildim..
hasssiyeyet gerçekten onemli.Çünkü 1 PUls likl sapma çemberin merkezinde 1 derecelik sapma yapacak.Buda Yarı çapa bağlı olarak 5 cm lik bir sapma olacak.Bu çok fazla.Zaten normalde bu sapmayı engellemek için bu encoderları kullanmak istiyorum..
Bu bahsettin kodlar konusunda birşetler karalayabilirmisin.Benimkisi tutmuyor valla..
PİC basic veya asm hiç farketmez..
basla:
....
....
if encoder1=1 and ilkencoder1<>encoder1 then
encoder1toplam=encoder1toplam+1
endif
ilkencoder1=encoder1
....
....
goto basla
Bu kısa kodla hem encoder1'deki değişim hem de encoder1'in 1 olduğu an yakalanır ve toplam 1 artırılır. Encoder1'den gelen 0'ları saymak için sadece
if enceoder1=1 and ilkencoder1<>encoder1 then
yerine
if enceoder1=0 and ilkencoder1<>encoder1 then
yazmak yetelidir.
Senin yazdığın kodda darbeler kaçabilir çünkü değişim sadece sıçrama anında oluyorsa yakalanır.
Kolay gelsin.
kodu anlayamadım.Amacım 2 encodeerıda okumak.Biraz kodu toparlayabilirseniz benim için sevinirim..
Öncelikle sorayım neden iki encoder var sistemde?. Belirli bir gerekçesi ve yerleştirme mantığı var ise bilmek lazım. Zira, 1. encoderin sıfır olduğu anda 2. encoder de sıfıra denk gelmiş ise birinden birini saymadan atlayacaksın demektir. Çünki programın birini kontrol edebiliyor. Birde sistemin ileri gidip geri geldiğinden bahsediyorsun. Programda geri gelme hareketi kontrol edilmiyor. Acaba önemsizmidir?. Bana göre ileri palsler sayılıyor ise gerilerde ayrıca sayılmalı gibi geliyor. Tabiiki tamamen kullanım mantığına bağlı bir husus. Sİstem hakkında biraz daha açıklama verirsen daha akıllıca bir kod okuma yazılabilir. Aklıma gelen ilk akıl olarak her iki encoderi birer diyot ile PortB.0'a ayrıca bağlasan ve PrtB.0 kesmesinide açsan böylece iki encoderden herhangi biri veya ikiside sıfır olduğunda kesme oluşsa ve sen encoderların esas girişlerini burada kontrol etsen hangisi sıfır ise onu bir artırsan veya her ikiside sıfır ise her ikisinide bir artırsan iki sayımıda kaçırmamış olursun. Bu şekilde sistem teorik olarak doğru çalışır. Ben uygulamasını yapmış idim.
Ete
(http://www.lastpoint.biz/fatih/rr.jpg)
Sistem şekildeki gibi.Gri Bant rulolar üzerine sarılarak hareket sağlanmaya çalışılıyor.Yani 1 nolu silindir Bantı salarken, 2 nolu silindir bantı sarıyor.
Bu hareket tam terside olabiliyor.2 Nolu salarken 1 nolu silindir sarabiliyor.Programın yapsına göre değişiyor.Neye programlanmışsa ona göre hareket edecek.Ancak sorun şu;
1 nolu silindirdeki motor 5 tur dönüp bantı saldığında, 2 nulu silindirde tam 5 tur donüp salınan malzemeyi yani bantı sarması gerekiyor.
Bu işlemin gerçek zamanlı olarak olarak yapılması gerekiyor.Yani önce bir salsın, salma bittikten sonra diğer motor çalışsın ve bantı sarsın şeklinde olmuyor.
Amaç salınan malzemeyi hemen sararak işlemi devam ettirmek.
Normalde motorlar DC Motor
İlk denemede zamanlamalı olarak yapmıştım:)
yani; 1. motor 3 sn çalışsın, 2. motor 3 sn çalışsın aynı mesafeyi alırlar diye tahmin etmiştim.Fakat olmadı..Çünkü Dc motordu.:D
Bu nedenle Encoder kullanma ihtiyacı hissettim..
Çarkları birleştir diyenler de oldu ama böyle bir imkanım yok mekanik olarak.Zaten çarklar birleşirse malzeme yani bant ruloya sarıldığında çap artacağından illaki yine bir bolllaşma olacaktır..
Halbuki encoder kullanırsa PIC yazılımında bu Çapın kalınlaşmasını hesaba katarak motorları gerektiği kadar oynatılmasını sağlayabilirm.
Amaç;;;
1. ve 2. Motor çalışır.
1. ve 2. Encoder çalışır.Ve motoların Kaç tur attığını saymaya başlar
Sonuçta 2 motorda aynı turu atacaktır.Dolayısı ie 1. ve 2 encoderdan gelen pulsler eşit ve istenilen değere geldiğinde motorlar durduralacaktır.
Aynı şekilde motorlar bu işlemlemden sondara programın yapısına göre ters olarak 10 turda dönebilir.Yine encoderlar saymaya başlar.Tur sayıları istenilen değere geldim motorlar durdururlur.
RB0 Kesmesi kullanmamak isteme nedenim;
Program belirli işlemleri olmuyan bir program.Admin böülümden PIC bazı emirler veriyor..
yani kendi programı kendin oluşturabiliyorsun;
Bekle
3 Tur geri git
5 tur ileri git
bekle
2 tur iler
yarınm tur geri
...
İşte bu şekilde admin bölümünden bu programı değiştirebiliyorsun.
dolayisı ile Encoder işlemler Alt Program olarak yapılması gerekiyor.
Bir diğer handikap Mekanik sistemde dili çark koruması yok.Yani sistemde dışarıdan banta hafif bir etki yapıldığında Hemen alt program gider ve encoder saymaya başlar.ve programın dışına çıkıp sapıtmış olur..
Tüm bu saydığım nedenlerden dolayı 2 ENCODERI, RB0 kesmesi olmadan PIC16f877 ile 20 mhz osilator kullanarak kurmak istedim..
Hatalarım olabilir.Belkide yanlış bir seçim yapmışımdır.Yardımcı olursanız sevinirim.
Değişkenlerinin arasına iki adet bit tipinde değişken oluşturur isek;
ENC1STAT VAR BIT
ENC2STAT VAR BIT
Ve Programın ilk satırlarına
if encoder1 = 1 then
enc1stat = 0
else
enc1stat = 1
endif
if encoder2 = 1 then
enc2stat = 0
else
enc2stat = 1
endif
bu kodları eklersek sistem ilk açıldığında yani daha motorlar çalışmadan encoderlerin o andaki durumu algılanıp varolan durumun tersini sayma palsi olarak algılatabilirsin
Sayma işleminide şu şekilde yapabilirsin;
ENCODER1SAY:
IF ENCODER1 = ENC1STAT THEN
ENCODER1TOPLAM = ENCODER1TOPLAM+1
ENDIF
ENCODER2SAY:
IF ENCODER2 = ENC2STAT THEN
ENCODER2TOPLAM = ENCODER2TOPLAM+1
ENDIF
Şimdi burda dikkat edilmesi gereken nokta ;
motorlara ilk hareketi verdin ve sonra motorları bahsettiğin gibi geri döndürmek istiyorsun bana göre motorlar geri dönmeden yine encoder durumlarının algılamalısın. Çünkü motoru sen nekadar hemen durdurabiliyorum desende sistemdeki ataletten veya başka sebeplerden dolayı encoder durumu değişebilir.
Şimdilik bu kadar.. :D
Umarım bir faydası dokunur
Bir proteus devresi kurdum.Bu devrede PULS gonderebiliyorum.YAni bir nevi encoderları simule etmek istedim.Ki PULS sayıcı devremde PULS kaçırıp kaçırmadığımı anlayayım.
Aynı şekilde PULS alma içinde basit bir devre yapacğım hemen.Verdiğiniz kodları düzenleyip deneyeceğim.Burayada göndereceğim.
Son yazıyı doğru anlamışmıyım ?
Motorlar çalıştı 3 tur donduler.Encoder sayısı istenilen değere ulaştı ve sistem durdu.Tekrar motorlara iki tur at dediğimde Encoderların 0 damı yoksa 1 demi olduğunu anlamamımı söylüyorsunuz.
Ama zaten Encoder ı PULUP balğlamıyacakmıyım...
Karıştı biraz ama devre eklersem daha açık olacak.
Biraz sonra devreyi çizeceğim.Göndereceğim.
Saygılar..
Encoder simulasyonu için aşağıdaki devreyi kullanabilirsiniz. Hatta geri dönüş simulasyonu bile yapabilirsiniz. Çift encoder için bundan iki adet yapmanız gerekir.
(http://img.photobucket.com/albums/v208/ete/encoder.jpg)
Tabiiki pals hızı clock frekansı ile ayarlanacaktır. Yön değiştirme swiç ile yapılmaktadır. Devrede iki adet çıkış görmektesiniz bunun bir A diğeride B çıkışıdır. Standart C çıkışı çok gerekli olmadığından kullanılmamıştır. Yön bulak için A ile B arasındaki faz farkından yararlanılır. Bir osiloskop bağlayıp baktığınızda faz farkını görebilirsiniz.
Normal olarak encoder girişlerinde pull-up kullanılmaz. Kendi devresi bunu zaten yapar. Kullanacağınız pull up veya pull down yanlış okumalara sebep olabilir.
Kolay Gelsin
Ete
abim amma hızlı yetiştin bende tam devreyi ekliyordum..Ama dur yinede ekleyeyim hata gözükmüş olsun...
Bahsettiğim encoder okuma ve gonderme devresini buradan çıkarabildiğim kodlarla yazarak deneme çalıştım.Ama olmadı gibi..
Devreyi Buradan (http://www.lastpoint.biz/fatih/encoderdeneme.zip) indirebilirsiniz..
PİC BAsic Kodlarını yaninda..
yardımlarınız bekliyorum..
@ete abim o devredeki elemanlar nelerdir.Bulamadım.yada indirebileceğim bir yer varmı..
Sevgili ete nin eklediği eleman proteus active library isi içinde bulunan DTFF yani D tipi filip flop..
Herneyse sen verdiğim kodlar üzerinden yola çıkarak bir şeyler karalayıp denedinmi devreni?
Senin verdiğin cevaba göre bir çözüm üretebiliriz..
evet gonderdiğim dosya senin kodların gibi.Ama bir türlü olmadı galiba..
Bir yerlerde hata yapıyorum..
Alıntı yapılan: elektroombankevet gonderdiğim dosya senin kodların gibi.Ama bir türlü olmadı galiba..
Cümlendeki galiba kısmını biraz açarmısın..devrede gerçekleşmeyen olay nedir?? Devreni ilk başta tek encoder sayacak şekilde çalıştırıp daha sonra ikinci encoderi eklemeyi denedinmi?
birde biraz önce bir sitede Encoderlı DC Motor Library si buldum galiba..
Bir bakarmınız benim simulasyonda bunu kullanabilirmiyim..
Library buradan indirebilirsiniz (http://www.lastpoint.biz/fatih/DCMotorTTL2.zip)
okumayı atlıyor.Tek bir PULS alınca tüm PULS alınmış gibi işlem yapıyor..
Devredeki elemanlar;
1 adet Clock üreteci.
1 adet 4013 (D tipi Filip Flop)
2 adet switch çift sıra
1 adet logic probe (çıkışın low yoksa high mı olduğunu görmek için.
Hepsi bu kadar.
Ete
Elamanlar tama bu şekildede denedim.Fakat olmadı..Bir yerlerde hatam var..
Denediğim devreyi buradan (http://www.lastpoint.biz/fatih/teklideneme.zip) indirebilirsiniz...
Encoder çizimin çalışıyor. Dİğer kısmı çıkartıp sırf encoderi çalıştırdım. Baktım çalışıyor. Yalnızca clock frekansı çok düşük. Normalde bu kadar düşük olmaz sanırım. Bu frekansı enz 20-30 HZ dolayında ayarla.
Çalışmaması senin diğer sisteminde veya programında bir sorun olmalı.
O kısma henüz bakmadım.
Ete
İşte dediğim gibi PİC basic kismında bir yerlerde sorunum var.
Ama çözemiyorum.Dediğiniz gib yaptım.Ama beceremedim..
Okuma sadece tekli olarak deniyorum. ENcStat ile encoderın durumun algılıyorum.ve dediğiniz gibi sayma kodları ile denedim.Devre ve kodlar 2 mesaj üstte.Aynen ordaki gibi yaptım.ama yine okumuyor..
encoder yerine omronun aşağıda çizdiğim bir ürünü war NPN ve PNP olarak çıkış veriyor sistemin kafalarına birer küçük dişli takarak moturun devirin ölçüp istediğin adım da durdurabilirsin dişli ne kadar küçük olursa o kadar hasas iş olur(http://img476.imageshack.us/img476/1118/graphic13jj.jpg)
@Elektroombank,
Yazmış olduğun program parçasından bu işte çok eksik olduğunu anlıyorum.
Programda gerçekten çok fazla hata var. Tabiiki ana mantığı çok iyi çözümleyemedim ama programı istediğin hale getirdim.
aşağıda veriyorum. Etiket ve değişken isimlerini çok uzun kullanma. İnsan yazarken bıkıyor.
ADCON1 = 7 ' tüm portlar dijital yapılıyor
'-------------------------------------------------------------------------------
TrisD=%00100000
SYMBOL ENCODERA=PORTD.5 ' Encoder 1 buraya bağlı
TOPLAMPULS VAR BYTE
TOPLAMPULS = 30
ENC1STAT VAR BIT
ENC2STAT VAR BIT
ENC1TOPLAM VAR BYTE
BASLA:
'-------------------------------------
PAUSE 500
ENC1TOPLAM=0
LCDOUT $fe,1, " SISTEM "
LCDOUT $fe, $C0, " BASLASIN "
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
LCDOUT $fe,1, " 1. tur "
LCDOUT $fe, $C0, " tamamlandi "
'---------------------------------------
pause 500
ENC1TOPLAM=0
LCDOUT $fe,1, " 2. tur "
LCDOUT $fe, $C0, " BASLASIN "
PAUSE 5000
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
Gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
pause 500
LCDOUT $fe,1, " 2. tur "
LCDOUT $fe, $C0, " tamamlandi "
'---------------------------------------
pause 500
ENC1TOPLAM=0
LCDOUT $fe,1, " 3. tur "
LCDOUT $fe, $C0, " BASLASIN "
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
Gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
pause 500
LCDOUT $fe,1, " 3. tur "
LCDOUT $fe, $C0, " tamamlandi "
pause 500
LCDOUT $fe,1, " BASA "
LCDOUT $fe, $C0, " DONULUYO "
goto basla:
'****Encoder sayma Alt Programı Başlangıçı Burası******************************
ENCSAY:
while ENCODERA = 1
wend
ENC1TOPLAM = ENC1TOPLAM + 1
while encodera=0
wend
lcdout $fe,$c0,"encoder1=",# ENC1TOPLAM ," "
IF ENC1TOPLAM = TOPLAMPULS THEN RETURN
' Puls sayısı istene değerde ise ana programma don
GOTO ENCSAY
end
BU başlıkta yazdıklarına şöyle bir baktım yeniden.
Önceki kodalrda yapılan hata şu encoder belirli bir noktada kalır ise örneğin sıfır konumunda kaldı ve çıkış sürekli sıfır veriyor. Bu durumda encoder sürekli sayar. Halbuki encoder çıkışını bir pals çıkışı gibi düşünüp hem low konumunu hemde high konumunu aşmanız ve bunlardan birirnde de sayma yapmanız gerekir. Böylece encoder bir konumda durmuş olsa bile sayma yapmayacaktır. Yukarıdaki program bu işlemi yapıyor. Biraz geliştirirsen işini görebilir.
İllaki iki encoder kullanman gerekiyor ise mutlaka ikisinide aynı anda kontrol etmen gerekir. Yoksa birinden mutlaka pals kaçırırsın.
Yine tekrarlıyorum. Bu işin en doğru yolu kesme kullanmaktır. Hatta RB0 kesmesi yerine PortB (RB4-RB7) kesmesi kullanırsan işin biraz daha kolay olur. O dediğin adminden programlama işini kesinlikle kesme aksatmaz.
Birde şu hususa dikket etmeni öneririm. Ortada sarılan ve bırakılan bir bant var ise bu bantın kalınlığına bağlı olarak her iki silindirin dolayısıyla motorların tur adetleri aynı olmayabilir. Sarma konumundaki silindir çapı büyüyeceği için boşaltma silindirine oranla daha az tur atacaktır. Ancak bu husus ihmal edilir seviyede ise önemli değil. Birde bandın sarkma ve gerilme durumunu kontrol ederek yapmayı denesen. Alta ve üste iki fotosel veya proximity swich koysan bunlarla işi kontrol edebilirsin. Bant sarkmış ise sarma motorunu hızlandır, gerilmiş ise sarma motorunu yavaşlat gibi emirler vererek işi kotarabilirsin sanırım. Verdiğim bir akıl sadece işe yararsa kullanabilirisin.
Ete.
---
Önceki kodalrda yapılan hata şu encoder belirli bir noktada kalır ise örneğin sıfır konumunda kaldı ve çıkış sürekli sıfır veriyor. Bu durumda encoder sürekli sayar. Halbuki encoder çıkışını bir pals çıkışı gibi düşünüp hem low konumunu hemde high konumunu aşmanız ve bunlardan birirnde de sayma yapmanız gerekir
----
Evet.Haklısın zaten bu durum beni çok karıştırıyordu.İlk örneklerimde o şekilde denemiştim ama yinede hatam varmış.Olsun öğrenmiş olduk hatalar ile beraber.Kodları aldım.Optik Senssor filan gerçekten çok zor.
Yani dış ortamda filan bulunacağından.Birde bu bat malzeme değişeceğinden böyle bir durum pekte olanaklı değil.
Verdiğin örneği ÇİFt encoder halien getirmeyi deneyip Önce RB0= ile deneyeceğim.Dediğin gibi programı etkileme hikaesi olmazza kesme kullanırım.
Bu kesme kuıllanmadaki mantığım ne olmalı?
Yeni devreyi Buradan (http://www.illustrasyoncu.com/fatih/whiledeneme.zip) indirebilirsiniz..
yeni verdiğiniz gibi kodları denedim.İki Encoder oluşturdum.1 tur saymasını yapıyor.ancak 2 tur saymasında Encoder A =1 deyip kalma yapıyor.
Halbki alt program donüşünde Tüm Encoder Topla değikenlerini sıfırlıyorum.
Birde bu while döngüsünde Bekleme yapıyormu.Yani bir encoderı 50 Khz yaptım.diğerini 10 Khz.fakat okumada bariz bir fark olması gerekirken olmadı.
Buda bende While da bekleme yaptığı düşüncesi uyandırdı.?
Bekleme olsa bile 2 turda neden takıldı? Toplam değerler 0 olduğu halde..
Yapmak istediğini çok iyi anlayamıyorum. İki adet encoder kullanıyorsun ancak birisi bana kalırsa hiç işe yaramıyor. Zira yazdığın programda birinci encoder pals değiştirmeden diğerine zaten bakılamıyor. Burada mantık değiştirmek lazım. Mademki sisteme iki adet encoder bağlı aynı anda her ikisinde olan değişiklikler izlenmeli ve hangisi pals değiştirmiş ise onun sayıcısı bir artırılmalı. Birde Programda TRIS registerlerini iyi kullanamıyorsun. Portlar hem giriş hemde çıkış olabiliyor biliyorsun. Port pinlerinden birisini çıkış yapmak için o porta ait TRIS registerinde çıkışa denk gelen bit sıfır yapılır. Aynı pin giriş yapılmak isteniyor ise yine Tris registerinde o pine denk gelen bit 1 yapılır. Ben tek encoderli sistemde TRISD=%00100000 yazmış idim. Sen iki girişe çıkarmana rağmen TRISD registerini değiştirmemişsin. TRIS adı verilen yön registerlerine dikkat etmelisin.
Diyelimki her şeyi doğru ayarladık. senin temel amacın yada programın temel amacı hangi encodere ait pals sayıcısı toplam pals değerine ulaşır ise ona bağlı motor dursun ve her iki motorda durmuş ise işlem bir kademe atlasın veya başa dönsün istiyorsun sanırım. Bu durumda tavsiye olarak söylüyorum. Bir defa encoder girişlerini yan yana iki port pinine gir. Mesela Port D.4 ve D.5 pinlerini kullan. Sonrada aşağıdaki programı dene bakalım. Bu program her iki encoder girişini aynı anda değerlendirip hangisinde değişiklik var ise onu artırmaktadır. Ben isis de denedim güzel çalışıyor.
Kolay Gelsin
Ete
define osc 20
ADCON1 = 7 ' tüm portlar dijital yapılıyor
'-------------------------------------------------------------------------------
TrisD=%00110000
SYMBOL ENCODERA=PORTD.5 ' Encoder 1 buraya bağlı
SYMBOL ENCODERB=PORTD.2 ' Encoder 2 buraya bağlı
TEMP VAR BYTE
ESKI VAR BYTE
YENI VAR BYTE
TOPLAMPULS VAR BYTE
TOPLAMPULS = 5
ENC1STAT VAR BIT
ENC2STAT VAR BIT
ENCODERATOPLAM VAR BYTE
ENCODERBTOPLAM VAR BYTE
BASLA:
'-------------------------------------
PAUSE 500
ENCODERATOPLAM=0
ENCODERBTOPLAM=0
LCDOUT $fe,1, " SISTEM "
LCDOUT $fe, $C0, " BASLASIN "
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
LCDOUT $fe,1, " 1. tur "
LCDOUT $fe, $C0, " tamamlandi "
'---------------------------------------
pause 500
ENCODERATOPLAM=0
ENCODERBTOPLAM=0
LCDOUT $fe,1, " 2. tur "
LCDOUT $fe, $C0, " BASLASIN "
PAUSE 1400
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
Gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
pause 500
LCDOUT $fe,1, " 2. tur "
LCDOUT $fe, $C0, " tamamlandi "
'---------------------------------------
pause 500
ENCODERATOPLAM=0
ENCODERBTOPLAM=0
LCDOUT $fe,1, " 3. tur "
LCDOUT $fe, $C0, " BASLASIN "
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
Gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
pause 500
LCDOUT $fe,1, " 3. tur "
LCDOUT $fe, $C0, " tamamlandi "
pause 500
LCDOUT $fe,1, " BASA "
LCDOUT $fe, $C0, " DONULUYO "
goto basla:
'****Encoder sayma Alt Programı Başlangıçı Burası******************************
ENCSAY:
ESKI=(PORTD & %00110000)>>4
TEKRAR: YENI=(PORTD & %00110000)>>4
' lcdout $fe,2,"ESKI=",dec2 eski," YENI=",dec2 yeni
if eski=yeni then TEKRAR
TEMP=ESKI XOR YENI
IF TEMP & %01=%01 then ENCoderATOPLAM = ENCODERATOPLAM + 1
IF TEMP & %10=%10 then ENCoderBTOPLAM = ENCODERBTOPLAM + 1
IF ENCODERATOPLAM = TOPLAMPULS THEN Low PORTD.0
IF ENCODERBTOPLAM = TOPLAMPULS THEN Low PORTD.1
lcdout $fe,$c0," A=",dec2 ENCODERATOPLAM," B=",dec2 ENCODERBTOPLAM
' IF ENCODERATOPLAM = TOPLAMPULS AND ENCODERBTOPLAM = TOPLAMPULS THEN
IF portD.0=0 AND PortD.1=0 then
ENCODERATOPLAM=0
ENCODERbTOPLAM=0
RETURN
else
GOTO ENCSAY:
ENDIF
end
@ete abim dediğin gibi TRIS registerleri.
PIC Assembly ile yazarken yapıyorum.Ama PIC Basic Pro da yapmak gerektiğini bilmiyorum.Direk giriş çıkış yaptığından olur zannediyordum..
""senin temel amacın yada programın temel amacı hangi encodere ait pals sayıcısı toplam pals değerine ulaşır ise ona bağlı motor dursun ve her iki motorda durmuş ise işlem bir kademe atlasın veya başa dönsün istiyorsun sanırım.""
Evet tam bu şekilde idi bahsetmet istediğim.Kodları aldım.Dediğin gibi Portd 4 ve 5 inci olarak bağladım, denedim.
Ellerine sağlık gayet güzel çalışıyor.
Ama birşey hala aklıma takıldı.Bu PULS üreticilerin Hz hızlarını değiştiriyorum (Çünkü dc motorlar tam olarak aynı hızda dönmüyorlar)
Ve Simulasyonu başaltıyorum.Ama Lcd ekrandaki sonuca göre Sıralı olarak okuyor.Halbuki bir Encoderın daha geç işlemi bitirmesi lazım değilmi?
Simulasyonun Hatası olabilir mi? Eğer ondan ise devreyi kuracağım artık.
Sevgiler
Şayet clock frekanslarını farklı yaparsan göreceksin. Biri diğerine göre daha geç bitiriyor. Ancak, yinede sorun olabilir. Biraz daha incelemek gerekiyor.
Ete
Hz leri farklı olarak denediğim devreyi buradan (http://www.lastpoint.biz/fatih/4ve5ten.zip) indirebilirsiniz...
100hz ve 10 hz olark denedim.Ama yinede aynı anda eşitleniyorlar..
Birde aşağıdaki programı dene bakalım.
define osc 20
ADCON1 = 7 ' tüm portlar dijital yapılıyor
'-------------------------------------------------------------------------------
TrisD=%00110000
SYMBOL ENCODERA=PORTD.4 ' Encoder 1 buraya bağlı
SYMBOL ENCODERB=PORTD.5 ' Encoder 2 buraya bağlı
TEMP VAR BYTE
ESKIA VAR BYTE
YENIA VAR BYTE
ESKIB VAR BYTE
YENIB VAR BYTE
TOPLAMPULS VAR BYTE
TOPLAMPULS = 10
ENCODERATOPLAM VAR BYTE
ENCODERBTOPLAM VAR BYTE
BASLA:
'-------------------------------------
PAUSE 500
ENCODERATOPLAM=0
ENCODERBTOPLAM=0
LCDOUT $fe,1, " SISTEM "
LCDOUT $fe, $C0, " BASLASIN "
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
LCDOUT $fe,1, " 1. tur "
LCDOUT $fe, $C0, " tamamlandi "
'---------------------------------------
pause 500
ENCODERATOPLAM=0
ENCODERBTOPLAM=0
LCDOUT $fe,1, " 2. tur "
LCDOUT $fe, $C0, " BASLASIN "
PAUSE 1400
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
Gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
pause 500
LCDOUT $fe,1, " 2. tur "
LCDOUT $fe, $C0, " tamamlandi "
'---------------------------------------
pause 500
ENCODERATOPLAM=0
ENCODERBTOPLAM=0
LCDOUT $fe,1, " 3. tur "
LCDOUT $fe, $C0, " BASLASIN "
HIGH PORTD.0 ' MOtor 1 çalışsın
HIGH PORTD.1 ' Motor 2 çalışsın
Gosub ENCSAY: 'hemen encoder saymaya gidilsin
Low PORTD.0 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
low PORTD.1 'Motorlar puls değeri kadar döndü.Motorlar artık durabilir
pause 500
LCDOUT $fe,1, " 3. tur "
LCDOUT $fe, $C0, " tamamlandi "
pause 500
LCDOUT $fe,1, " BASA "
LCDOUT $fe, $C0, " DONULUYO "
goto basla:
'****Encoder sayma Alt Programı Başlangıçı Burası******************************
ENCSAY: ' BA
ESKIA=PORTD.4
ESKIB=PORTD.5
IF ESKIA=0 AND ESKIB=0 THEN ENCSAY
TEKRAR: YENIA=PORTD.4
YENIB=PORTD.5
IF ESKIA=YENIA AND ESKIB=YENIB THEN TEKRAR
if ESKIA=1 AND YENIA=0 THEN
IF ENCoderATOPLAM <TOPLAMPULS THEN ENCODERATOPLAM= ENCODERATOPLAM + 1
ENDIF
IF ESKIB=1 AND YENIB=0 THEN
IF ENCODERBTOPLAM<TOPLAMPULS THEN ENCoderBTOPLAM = ENCODERBTOPLAM + 1
ENDIF
IF ENCODERATOPLAM = TOPLAMPULS THEN Low PORTD.0
IF ENCODERBTOPLAM = TOPLAMPULS THEN Low PORTD.1
lcdout $fe,$c0," A=",dec2 ENCODERATOPLAM," B=",dec2 ENCODERBTOPLAM
IF portD.0=0 AND PortD.1=0 then
ENCODERATOPLAM=0
ENCODERbTOPLAM=0
RETURN
else
GOTO encsay
ENDIF
end
Yarın bir seyehate çıkıyorum. Foruma çok sık bakamıyacağım. Ama sanırım budefa oldu ve gerisini sen halledersin artık.
Kolay Gelsin
Ete
Evet abim tam dediğim gibi işte herzler farklı iken farklı.
Artık sıra geldi encoder seçmeye.İlk sayfada sistemin görünümünü atmıştım.O sisteme ugun bir encoder arıyorum.Birde Motor hızları hakkında bilgi vereyim.
Motorlar 1 sn 'de 2 tur atıyor.Yani 120 rpm.
Bu durumda sistemde 2 Derecelik hassasiyet olacağına göre motorlar bir dönüşte 180 PULS verecek.Motorlar tam bir turunu 0.5 sn'de yaptığına göre;
Bir encoder 1 saniyede toplam 360 Puls gönderecek.
Aynı anda diğer encoder'da puls göndereceğinden PIC 1 sn'de Toplam
720 PULS ile boğuşacak.
Osilator olarak 20 MHz XT osilator kullanmayı düşünüyorum.Yani PIC'e girince bir komut 5 MHz hızında çalışacak.Yani bir komut 0.2µs de çalışacak.
Saniyede 720 PULS 720 KHz olur diye biliyorum.Doğrumudur?
Eğer bu şekilde ise programın PULS kaçırması gibi bir durumda söz konusu olmuyor.
O zaman benim şimdi Encoder almam gerekiyor. Hemde 0.5 sn'de 360 Derece dönerken 180 PULS gönderebilen cinsten...
Birde tür olarak ne seçmeliyim.Optik mi, Rotary mi, yoksa başka bilmediklerimdemi var?
Saniyede 720 puls 720 HZ dir. 720.000 Hz=720 KHz dir.
Ete
ozaman çok daha iyi oluyor.hız baya iyi oluyor.
0.5 sn'de 360 Derece dönerken 180 PULS gönderebilen cinsten bir encoder önerebilirmisiniz.İstanbulda Karaköyde filan alabileceğim yerler
nelerdir.
Ben Ankara da oturuyorum. Bu nedenle yardımcı olamıyacağım.
Ancak omron dan veya Bankalar Cad. elektrikçi ve elektronikçilerden araştırabilirsin. Muhtemelen 180 puls bulamıyacaksın. 200 muhtemelen bulurusun.
Ete
Bankalar caddesi menevşe handa bir ara orada bulabilirsin..
Marka veya Tür verebilirmisiniz?
Sorduğumda nasıl bir encoder diyolar...
Arkadaşlar bugün gittim encoder almaya ama karar veremedim.Esnafa sordum farkları ne diye.Biri Optik biri Rotary dedi.Yani farkı bilmiyordu.
Bende bilmiyordum.
Birisi benim için bu farkı söyleyebilir mi?
Ticari anlamda farklılıklarını bilmiyorum. Önceden bir kaç tane encoder sökmüş idim. Onlardan bildiğim kadarı ile içinde bir disk ve diskin üzerinde tur başına pals sayısı kadar delikler mevcut. Bir encoder de ham A hem B ve birde C denilen üç adet çıkış bulunmaktadır. A ile B birbirinden yarım faz farklı şekilde çıkış verecek şekilde delikler yerleştirilmiştir. C ise daha uzun palsler verecek şekilde dizayn edilmiş. A ile B aynı anda kontrol edilerek encoderin dönüş yönü bulunabilmektedir. Pals üretme sistemi hemen hepsinde optik olarak yani bir ifrared led ve bir foto diyot veya transistör yardımı ile olmaktadır. Bu tip encoderler Rotary encoder olarak adlandırılmaktadır.
Senin Optik olarak nitelendirdiğin encoderlar ise yine rotary yani döner şekilde çalışmaktadırlar ve sanırım bizim optik maus'lardaki sistemin bir benzeri mantık ile çalışmaktadırlar. Ben ilk defa optik maus gördüğümde hemen aklıma gelmiş idi aynı mantık ile bir encoder yapılamaz mı diye. Ancak A ile B nin faz farkı nasıl yaratılır düşünememiş idim.
Şimdi çok emin değilim ama yine optik encoder de yine rotary çalışan ancak pals üretme sistemid elikli disk ile değilde optik maus sistemi ile çalışan bir alet galiba.
Senin işini rotary normal encoder görür. Hangisi ucuz ise onu al derim.
Ete
Ok abi dediğin gibi yapıcam.fakat şimdi dikkatimi çeken birşey oldu.
Yani A B ve C uçları.Bana yön tyini gerekmiyor.Yönü zaten hep aklımda tutuyorum program olarak.yani sadece A ucunu bağlayıp aynı pulsı İleri veya geri konumda ikende alabilirmiyim.
evet alabilirsin
ete
benim bildiğim encoder dönüşleri palsler şeklinde oluyo palsleri sayarak nekadar hareket ettiği ölçülüyo konu ile ilgili tüm cevapları okumadım ama programda enkoderden bilgi almak için ''COUNT pin,var'' şeklinde yazılması gereken yerler var if kullanmışsın onun yerine
Alikeskinkilic,
Count komutu puls sayar bu doğru ama encoder için uygun bir komut değildir. Encoder de A ve B çıkışları vardır ve yön tayini için her iki girişin birlikte değerlendirilmesi gerekir. Count komutu ile aynı anda iki pinden bir den puls sayamazsın. Tek pulsda belki kullanılabilir.
Ete