İki motoru aynı anda encoder okuyarak sürmek

Başlatan dyonizos, 10 Eylül 2011, 19:08:29

dyonizos

merhaba arkadaşlar,
yapmak istediğim projede iki tane optik encoderli dc motorum var. bunlardan birisi x birisi z ekseninde çalışıyor.
benim istediğim her iki motor için mesela
x motoru : 1548
y motoru : 257
encoderden okudugum bu degerler kadar donmelerı ve durmalarını saglamak.
Ancak encoderden hızlı dondugu ıcın olsa gerek yada benım bılgısızlıgımden bır turlu dogru degerı okuyamıyorum. dogal olarakta motora don yada dur dıyemıyorum.
encoderlerden gelen 1 ve 0 degerlerı var sadece. yon onemlı degıl. bu degerlerı saydırma konusunda bır turlu basarılı olamadım.
nasıl bır kod kullanmalıyımkı mesela A1 portundakı encoder degerını duzgun saydırabılıyım. bu arada A2 portundakı motorun encoderınıde saydırabılmem gerekıyor ( bu kısmı cok onemlı degıl, sıraylada saysalar olur. ama onemlı olan encoderden gelen degerı kacırmadan sayabılmem)
encoderden gelen degerlerı dogru okuyabılırsem aslında motorun donusunu encoderden okuyarak ayarlayabılırım.


tesekkurler sımdıden.

camby

Merhaba,
kullandıgınız encoderlarda anladıgım kadarıyla tek faz var , standart olarak a-b-z gıbı encoder cıkısları yok . Bu sıstemde puls kacırmamak ıcın encoder gırıslerını kesme kullanarak işlemek gerekır. Burada bırbırınden bagımsız 2 farklı kaynak olduguna gore 2sine de ayrı kesme ayırmamız gerekır .

Sız nasıl bır sıstem oluşturdunuz ?

dyonizos

TMR0 kesme ile saydırdığımızda max 255 e kadar saydırabılıyoruz. Ancak elımdekı encoder dırek motorun shaftına baglı oldugu ıcın dakıkada 3000 devıre yakın donuyor ve 24 bolmesı olan encoder 10 tur doner donmez kesme degerı 0 oluyor. kesme degerını artırmanın bır yolu varmı acaba?

serdararikan

16 bit counter e sahip bir işlemci kullan sende.

camby

@dyonizos

tmr0 ile neyi sayıyorsun ?

Puls'ların kesme girişlerini bağlı olacak , her kesme oluştuğunda da program içerisinde pozisyon sayacını arttıracaksın. Kesme olarak birini RB0 kesmesini kullanabilirsin.

Basit bir servo motor yapmaya çalışıyorsun , o yüzden 2 motora 1 sürücü olmasın , her motora ayrı bir sürücü yap.

dyonizos

aşağıdaki şekilde kullanımım doğrumu acaba?
Şu anda sayıyor gibi palsleri ama kaçırıp kaçırmadığından çokta emin olamıyorum.


On Interrupt GoTo KESME
OPTION_REG.6=1
INTCON=%10010000     

LCDOUT $FE, 1

BASLA:
LCDOUT $FE,$80 
LCDOUT "ENC=", DEC2 encoder ," "
GoTo BASLA
Disable
KESME:
encoder=encoder+1
INTCON.1=0
Resume
Enable
End 


dyonizos

dk da yaklasık olarak 1260 pals saydım. bır tur 24 pals urettıgıne gore dakıkada bu motorun 1260/24 gıbı bır degerde dondugu sonucu cıkıyor. Ancak motor 3000devir/dk gıbı bır degerde donuyor. Bu durumda yukarıdaki kodda da sankı encoder ı okuyamıyorum gıbı bır sonuc cıkıyor sanırım.

mokan

tam pals değerini hesaplarken(tmr0 için) tmr0'ın frekans bölme oranını da göz önüne alman lazım.örneğin; 1/2 oranında sayım yapıyorsan," 255*2*kesme sayısı" formülasyonunu kullanmalısın.Diğer encoder kesmesi için bence başka donanım sayıcısı kullan.tmr1 olabilir.Çünkü rb0 kesmesinde tmr0 a göre, daha sık kesme olacak.Eğer program içinde pause gibi zaman gecikme komutlarını kullanıyorsan, bu kesmeleri kaçırmana sebep olur.(basic de pause komutunun işlenmesi bitene kadar kesmeye gitmez).Ama tmr1 yada tmr0 da bu süreleri daha uzun tutarak daha az kesme sıklığı yapabilirsin.burada dikkat etmen tek nokta, eğer çok hassas bir sayım yapıyorsan(25 pals/dev encoder kullandığına göre çok hassas bir işde kullanmıyorsun galiba) frekans bölme oranlarını min yap.

dyonizos

Alıntı yapılan: mokan - 11 Eylül 2011, 10:20:51
tam pals değerini hesaplarken(tmr0 için) tmr0'ın frekans bölme oranını da göz önüne alman lazım.örneğin; 1/2 oranında sayım yapıyorsan," 255*2*kesme sayısı" formülasyonunu kullanmalısın.Diğer encoder kesmesi için bence başka donanım sayıcısı kullan.tmr1 olabilir.Çünkü rb0 kesmesinde tmr0 a göre, daha sık kesme olacak.Eğer program içinde pause gibi zaman gecikme komutlarını kullanıyorsan, bu kesmeleri kaçırmana sebep olur.(basic de pause komutunun işlenmesi bitene kadar kesmeye gitmez).Ama tmr1 yada tmr0 da bu süreleri daha uzun tutarak daha az kesme sıklığı yapabilirsin.burada dikkat etmen tek nokta, eğer çok hassas bir sayım yapıyorsan(25 pals/dev encoder kullandığına göre çok hassas bir işde kullanmıyorsun galiba) frekans bölme oranlarını min yap.

Hocam bu yazdığın kesmeler için örnek verebilirmisin. yada örnek olarak yararlanabileceğim bir döküman varmı? Sanırım yukarıda yazdığım kod örneğinden farklı bir yol öneriyorsun.


teknikelektronikci

Alıntı yapılan: mokan - 11 Eylül 2011, 10:20:51
tam pals değerini hesaplarken(tmr0 için) tmr0'ın frekans bölme oranını da göz önüne alman lazım.örneğin; 1/2 oranında sayım yapıyorsan," 255*2*kesme sayısı" formülasyonunu kullanmalısın.Diğer encoder kesmesi için bence başka donanım sayıcısı kullan.tmr1 olabilir.Çünkü rb0 kesmesinde tmr0 a göre, daha sık kesme olacak.Eğer program içinde pause gibi zaman gecikme komutlarını kullanıyorsan, bu kesmeleri kaçırmana sebep olur.(basic de pause komutunun işlenmesi bitene kadar kesmeye gitmez).Ama tmr1 yada tmr0 da bu süreleri daha uzun tutarak daha az kesme sıklığı yapabilirsin.burada dikkat etmen tek nokta, eğer çok hassas bir sayım yapıyorsan(25 pals/dev encoder kullandığına göre çok hassas bir işde kullanmıyorsun galiba) frekans bölme oranlarını min yap.


hocam zaten arkadas timer kesmesini kullanmyiorki interrupt kesmeyi kullanyior donanimsal yanlismi biliyorum ugrasmayali epey oldu


dynozisos arkadasim sana tavsiyem vhdl + cpld(fpga) :D
Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

mokan

#10
Alıntı yapılan: teknikelektronikci - 11 Eylül 2011, 12:02:57
hocam zaten arkadas timer kesmesini kullanmyiorki interrupt kesmeyi kullanyior donanimsal yanlismi biliyorum ugrasmayali epey oldu

yukarıda tmr0 denemiş ondan dolayı bahsettim.basic de daha sağlıklı olur diye.



Alıntı yapılan: dyonizos - 11 Eylül 2011, 11:05:40
Hocam bu yazdığın kesmeler için örnek verebilirmisin. yada örnek olarak yararlanabileceğim bir döküman varmı? Sanırım yukarıda yazdığım kod örneğinden farklı bir yol öneriyorsun.

Dediğim şu; kesmeleri rb0 ile sayacağına,  kullandığın denetleyicideki donanım sayıcı(ları)nın external girişini encoder çıkışına bağlayarak oku palsleri.Bu sayede, hem pic senin yerine 255/65535 'e kadar sayar hemde ana program içinde bulunan zaman gecikmelerinden dolayı kesmeleri kaçırma ihtimalin azalır.Her tmr0/tmr1 kesmesi sonrasında tıpkı yukarıdaki kod örneğinde olduğu gibi bir değişkenin içeriğini artır.Pals değerini de hesaplarken bu değişken ile kullandığın donanım sayıcısının saydığı max değeri ve frekans bölme oranının paydası ile çarparsan pals değerini elde edersin.yani;

carpan: tmr0/tmr1 taşma kesmesi olduğunda içeriği artacak değişken.
pals: hesaplanan pals değerini tutan değişken.
t: tmr0/tmr1'in anlık değerinin okunup yazıldığı değişken.

pals=carpan*(255 veya 65535)*(frekans bölme oranının paydası)+ t*(255 veya 65535)

son toplama işlemi ile, o anki tmr0/tmr1 değerini okuyup gerçek pals sayısını hesaplamış olursun.Bende bu şekilde kullanıyorum şu an uğraştığım projede çok güzel şekilde çalışıyor.

camby

Alıntı yapılan: teknikelektronikci - 11 Eylül 2011, 12:02:57

hocam zaten arkadas timer kesmesini kullanmyiorki interrupt kesmeyi kullanyior donanimsal yanlismi biliyorum ugrasmayali epey oldu


dynozisos arkadasim sana tavsiyem vhdl + cpld(fpga) :D

Örnek bir şeyler araklasana bize vhdl ile motion kontrol adına : ) )

teknikelektronikci

Alıntı yapılan: camby - 11 Eylül 2011, 12:51:25
Örnek bir şeyler araklasana bize vhdl ile motion kontrol adına : ) )


oldu hocam :D
Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!