Picproje Elektronik Sitesi

DERLEYİCİLER => MikroC - PIC => MikroC dsPIC/PIC24/PIC32 => Konuyu başlatan: computerboy - 12 Şubat 2013, 13:25:28

Başlık: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 12 Şubat 2013, 13:25:28
Arkadaşlar kodu internette buldum 2-3 gündür irdelemeye çalışıyorum anlayamadığım noktalar var neden böyle olmuş çözemedim. yardımcı olursanız sevinirim aşama aşama buraya soracağım tecrübeli arkadaşların yardımını bekliyorum. Saygılar.

Anlayamadığım yada anladığım :) yada anladığımı sandığım noktaları kodun içine gömdüm.


#define SL signed short long

#define MAX(a,b) (((a)>(b))?(a):(b))

#define ABS(a) (((a)<0) ? -(a) : (a))

#define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)

extern void point3d(SL x, SL y, SL z);
void line3d(int step,long end,SL  x1, SL  y1, SL  z1, signed long  x2, signed  long  y2, signed  long  z2);

SL x=0,        // SL = Signed short Long = 24bits
y=0,
z=0,
oldX=0,
oldY=0,
oldZ=0,
t=0;

signed char sx=0,
sy=0,
sz=0;  // 8bit= -127 to 128       


signed long x2,
y2,
z2;

long  enddelay,
stepcount;

int stepdelay;





void line3d(int step,long end,SL  x1, SL  y1, SL  z1, signed long  x2, signed  long  y2, signed  long  z2)
   
{

    SL  x, y, z; // signed shot long tanımlamalar
    SL  xd, yd, zd;
    SL  ax, ay, az;
    SL  dx, dy, dz;

stepdelay=step; // integer
enddelay=end; // long

    dx = x2 - x1; // x2 den x1 çıkartılıyor sonuç dx aktarılıyor.
    dy = y2 - y1;
    dz = z2 - z1;

    ax = ABS(dx) << 1; // sola 1 bit kaydırılıyor (burdaki amacı anlamadım sonuçta çarpma işlemi olmuyormu bu ?)
    ay = ABS(dy) << 1;
    az = ABS(dz) << 1;

    sx = ZSGN(dx); // gelen rakam küçükse sadece -1 değer alıyor büyükse sadece +1 değer alıyor
    sy = ZSGN(dy);
    sz = ZSGN(dz);

    x = x1;
    y = y1;
    z = z1;
stepcount=0;

    if (ax >= MAX(ay, az))            // ax ay ve az den büyükmü diye bakılıyor.
    {
        yd = ay - (ax >> 1); // burda ise 1 bit sağa kaymış(kısacası bölmüş niye ?)
        zd = az - (ax >> 1);
        for (;;)
        {
            point3d(x,y,z); // step motoru sürmek için gönderilen step bilgisi.
            if (x == x2)                              // x değeri x2 ile eşit olana kadar döngüden çıkılmayacak
            {
                return ;
            }

            if (yd >= 0)                            // yd sıfırdan büyük yada eşitse y değerine pozitif veya negatif değer ata.
            {
                y += sy;
                yd -= ax;                           // yd değerine ax değerini çıkar ve ata.
            }

            if (zd >= 0)
            {
                z += sz;
                zd -= ax;
            }

            x += sx;
            yd += ay;
            zd += az;
        }
    }                                                 
}


Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: Salih - 12 Şubat 2013, 14:19:51
Bildiğim kadarıyla CCS'de 24 Bitlik sayı tipi yok.

(http://dl.dropbox.com/u/20087162/CCS_Tipler.JPG)
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 12 Şubat 2013, 14:25:50
Arkadaşlar çok özür konu başlığını yanlışlıkla CCS' ye açmışım PIC C kısmına taşınabilir.

Programı C18 ile çalışıyorum.
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 13 Şubat 2013, 17:33:06
Arkadaşlar kodları azda olsa izah edecek biri yokmu.
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: iyildirim - 14 Şubat 2013, 16:13:58
Aslında açıklamaların dışında sorduğun tek soru neden iki ile çarpılıp bölündüğü..
Nedeni ise mcu üzerinde 0.5 gibi float ve üzerinde işlem yapması yorucu bir sayı ile uğraşmak yerine 2 ile çarparak integer sayılarla çalışması. Daha sonra ikiye bölünmesi de önceden 2 ile çarpıldığı için.. 
Yani float yerine integer sayı kullanmak için scale işlemi yapılmış..

Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 14 Şubat 2013, 16:35:28
Ordaki yazdığım açıklamalar doğrumu üstad. ordaki algoritma mantığını çözmeye çalışıyorum amacı tam anlamıyla kavrayamadım. mesela x_step 500 y_step 1400 z_step 600 bu döngüyü kurarken en büyük rakamı buluyor ve diğer değerleri 1400 rakamı içinde eşit bölüp step sayısını geçen zamana göre uygun değerdemi gönderiyor tam anlamıyla sormak istediğimide ifadede edemedim. kodun mantığını çözsem yeter. sonra timer2 yada timer3 ile uygun frekans uygulaması yapacağım.
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: iyildirim - 14 Şubat 2013, 18:03:57
24 bit ve -127 +128 (-128 + 127 olmalı) dışında hatalı birşey gözüme çarpmadı.
Algoritmanın float ve integer kullanımı için dökümana bir bak.
http://www.cs.toronto.edu/~smalik/418/tutorial2_bresenham.pdf (http://www.cs.toronto.edu/~smalik/418/tutorial2_bresenham.pdf)
Bulduğun-bulacağın hazır kod parçaları büyük ihtimalle birbirleri veya yapmak isteğin şeyle, kafanda kurduğun algoritma ile uyumlu olmayacak. Öncelikle algoritmayı anlamaya ve uygulamana nasıl implemente edeceğine odaklanmalısın.

CNCiçin kullanacaksan zamanlamalar önemli.. Hem dökümanda hemde verdiğin kodda zamanlama ile ilgili bir şey yok.. point3d nin altında bekleme varsa bilemem..
Örnekler daha çok LCD veya grafik bellekte çizgi çizmekle ilgili. putpixel, point3d fonksiyonlarının ne zaman çağrıldıkları cnc için önemli. Ne zaman çağırıldıkları da hız ve hızlanmaya bağlı..

Fikir vermesi açısından; Algoritmaya göre daha uzun yol kateden eksende fonksiyon her çağrıldığında hareket olur diye düşünürsek yapabileceğin;
ya önceden hesaplayıp her adımı bufferlamak ve uzun yol kateden eksene göre zamanını ayarladığın bir timer kesme ile bufferı pinlere aktarmak,
yada  hareket anında hesaplamak ve gerekli gecikmeleri de hesaplayıp beklemek..
Bresenham kullanacaksan bileşke hızdan eksen hızına dönmen ve timerı buna göre kurman gerekir.


Bresenham kullanmak istemezsen şöyle bir şeyde yapabilirsin doğrusal enterpolasyon için..
İstediğimiz aslında;
Her eksenin aynı anda harekete başlayıp, gidecekleri yol farklı bile olsa yolu aynı zaman aralığında katetmeleri.
Önce bileşke hızı hesaplayıp, istenen hız, hızlanma değerine göre yolun ne kadar zamanda gidileceğini hesaplarsın. 
Her bir eksen yolu x saniyede gidecekse ve gidecekleri yolda belli ise geriye kalan tek şey, her bir eksen için hızı hesaplayıp timer kurmak olur.. Eğer hız aralıkların uygunsa (ki uygun prescaler değerleri kullanarak uydurabilirsin) timer kesmelerinde darbeleri üretebilirsin. Hatta sadece uzun yol kateden eksene ait timer kesmelerini saymak diğerlerini mcu da uygunsa PWM modunda bırakmak da olabilir. Tabii sadece enterpolasyon modunda iken ve sabit hız için.   Hızlanma aşamasında diğer eksenlerin hızları (timer değerleri) en hızlı eksene (master eksen) göre başta hesapladığımız orana göre tekrar hesaplanmalı

G-code'u-komutu alınca biraz hesap dan sonra bir daha başında beklemek gerekmediği için bu yöntem bana daha uygun görünüyor. Timer değerleri bir kaç komut veya makul bir süre için hesaplanırsa cnc hiç duraklamadan çalışabilir. 
Dairesel enterpolasyon için bu yöntemi küçük adımlar için çalıştırabilir veya Bresenham kullanabilirsin..
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 15 Şubat 2013, 16:59:03
Teşekkürler hocam anladım algoritmayı kurdum şimdide timer üzerinde çalışıyorum yalnız timeri aktif edince usb çalışması duruyor nette araştırdım ama nasıl yapacağımı çözemedim şu şekilde bir hata ile karşılaşıyorum.

Error - section 'high_vector' can not fit the absolute section. Section 'high_vector' start=0x00000008, length=0x00000732

verdiğim vektör adreside bu

#pragma code high_vector=0x08

18f4550.lkr dosyasından vectors  adresi yazan yerde nasıl bir düzenleme yapılması lazım bilgisi olan varmı ?

18f4550.lkr

// $Id: 18f4550.lkr,v 1.3 2004/08/23 18:08:22 curtiss Exp $
// File: 18f4550.lkr
// Sample linker script for the PIC18F4550 processor

LIBPATH .

FILES c018i.o
FILES clib.lib
FILES p18f4550.lib

CODEPAGE   NAME=vectors    START=0x0            END=0x29           PROTECTED
CODEPAGE   NAME=page       START=0x2A           END=0x7FFF
CODEPAGE   NAME=idlocs     START=0x200000       END=0x200007       PROTECTED
CODEPAGE   NAME=config     START=0x300000       END=0x30000D       PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE       END=0x3FFFFF       PROTECTED
CODEPAGE   NAME=eedata     START=0xF00000       END=0xF000FF       PROTECTED

ACCESSBANK NAME=accessram  START=0x0            END=0x5F
DATABANK   NAME=gpr0       START=0x60           END=0xFF
DATABANK   NAME=gpr1       START=0x100          END=0x1FF
DATABANK   NAME=gpr2       START=0x200          END=0x2FF
DATABANK   NAME=gpr3       START=0x300          END=0x3FF
DATABANK   NAME=usb4       START=0x400          END=0x4FF          PROTECTED
DATABANK   NAME=usb5       START=0x500          END=0x5FF          PROTECTED
DATABANK   NAME=usb6       START=0x600          END=0x6FF          PROTECTED
DATABANK   NAME=usb7       START=0x700          END=0x7FF          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED

SECTION    NAME=CONFIG     ROM=config

STACK SIZE=0x100 RAM=gpr3
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: Goo - 15 Şubat 2013, 23:27:17
Kesme bölümünü ben aşağıdaki şekilde kullanıyorum ve şimdiye kadar bir problemle karışlaşmadım. Tabii kullanılan kesmenin fonksiyon prototipini(void tmr0_kesmesi(void)) yukarıda tanımlamayı unutmamak lazım.


#pragma code high_vector_section=0x08
void high_vector(void)
{
  if(INTCONbits.TMR0IF==1)
  {
   _asm GOTO tmr0_kesmesi _endasm
  }
}
#pragma code
#pragma interrupt tmr0_kesmesi
void tmr0_kesmesi(void)
{
  INTCONbits.TMR0IF=0;
}

Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 16 Şubat 2013, 09:02:43
usb yi devre disi birakinca timer calisiyor kesme vektorunu usbde kullaniyor tahminimce yada baska bir nedeni var arastirdim lkr dosyasindaki page ayarini uygun hale getirilmesi lazimmis ama nasil yapacagimi cozemedim
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 16 Şubat 2013, 13:47:30
timer kullanmaktan şimdilik vazgeçtim. hocam şu şekilde bir algoritma kurdum putmotor kısmında step sayısı fazla olunca step sayısı az olan motorda hafif titreme oluyor onu nasıl bir algortima mantığı ile çözerim. mesela x_step 5000 y_step 6000 olunca x_step motorunda titreme oluyor.  aradaki step farkı 1000 her motor için step farkına göre  gecikme yaratsam sorun çözülürmü acaba.


/***** Bresenham Algoritma ******************************************************/

#include "plazmaport.h"
#include "bresenham.h"
#include "delays.h"


SL x=0,           // Signed Long Tanımlama
y=0,
z=0,
oldX=0,
oldY=0,
oldZ=0,
x2,
y2,
z2;

signed char sx=0, // Signed Char Tanımlama
sy=0,
sz=0;   

long  stepcount=1;

int x_h;
int y_h;
int z_h;

int x_h_s=30;
int y_h_s=30;
int z_h_s=30;


void putMotor(SL x, SL y, SL z )
{

if(x-oldX==1) DIR_X = 1;else DIR_X = 0;
if(y-oldY==1) DIR_Y = 1;else DIR_Y = 0;
if(z-oldZ==1) DIR_Z = 1;else DIR_Z = 0; 

if(x_h>x_h_s) x_h=x_h--;
if(y_h>y_h_s) y_h=y_h--;
if(z_h>z_h_s) z_h=z_h--;


if(x-oldX==1 || x-oldX==-1) STP_X = 0;
Delay100TCYx(x_h);
if(y-oldY==1 || y-oldY==-1) STP_Y = 0;
Delay100TCYx(y_h);
if(z-oldZ==1 || z-oldZ==-1) STP_Z = 0;
Delay100TCYx(z_h);

STP_X =1;
Delay100TCYx(x_h);
STP_Y =1;
Delay100TCYx(y_h);
STP_Z =1; 
Delay100TCYx(z_h);
         
stepcount=stepcount+1;

oldY = y;
oldX = x;
oldZ = z;

}

//**********************************************************
void line3d(int s_d, int e_d, SL  x1, SL  y1, SL  z1, SL  x2, SL  y2, SL z2)
{

SL  x, y, z; //Signed Long Tanımlamalar
    SL  xd, yd, zd;
    SL  ax, ay, az;
    SL  dx, dy, dz;

    dx = x2 - x1; //x2 değerinden x1 değerini çıkar ve dx değerine ata.
    dy = y2 - y1;
    dz = z2 - z1;

    ax = ABS(dx) << 1; // sola 1 bit kaydırılıyor (bir nevi çarpma işlemi)
    ay = ABS(dy) << 1;
    az = ABS(dz) << 1;

    sx = SGN(dx); // gelen rakam küçükse -1 değer, büyükse +1 değer alıyor.
    sy = SGN(dy);
    sz = SGN(dz);

    x = x1; // atamalar yapılıyor.
    y = y1;
    z = z1;

stepcount=0; // step count sıfırlanıyor.

x_h = x_h_s*2; // Yavaşlama hızlanma
y_h = y_h_s*2;
z_h = z_h_s*2;


    UsbVeriGonder((rom char*)"2D Kesim İşlemi");
    if (ax >= MAX(ay, az))            /* x axis hesaplaması */
    {
        yd = ay - (ax >> 1); // (ax 1 bit sağa kaydır. (bölme işlemi sayılır) ay değerinden çıkar ve yd değerine ekle.
        zd = az - (ax >> 1);
        for (;;) // döngü kuruluyor
        {
            putMotor(x, y, z);
            if (x == x2)
            {
                return ;
            }

            if (yd >= 0)
            {
                y += sy;
                yd -= ax;
            }

            if (zd >= 0)
            {
                z += sz;
                zd -= ax;
            }

            x += sx;
            yd += ay;
            zd += az;
        }
    }
    else if (ay >= MAX(ax, az))            /* y dominant */
    {
        xd = ax - (ay >> 1);
        zd = az - (ay >> 1);
        for (;;)
        {
            putMotor(x, y, z);
            if (y == y2)
            {
                return ;
            }

            if (xd >= 0)
            {
                x += sx;
                xd -= ay;
            }

            if (zd >= 0)
            {
                z += sz;
                zd -= ay;
            }

            y += sy;
            xd += ax;
            zd += az;
        }
    }
    else if (az >= MAX(ax, ay))            /* z dominant */
    {
        xd = ax - (az >> 1);
        yd = ay - (az >> 1);
        for (;;)
        {
            putMotor(x, y, z);
            if (z == z2)
            {
                return ;
            }

            if (xd >= 0)
            {
                x += sx;
                xd -= az;
            }

            if (yd >= 0)
            {
               y += sy;
                yd -= az;
            }

            z += sz;
            xd += ax;
            yd += ay;
        }
    }
}






Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: Goo - 16 Şubat 2013, 19:37:30
Eğer aynı vektörü kullanıyorlarsa; usb kesme bağrağını(eğer varsa bilmiyorum) aynı yöntemle test edip ilgili fonksiyonuna dallandırabilirsiniz.
#pragma code high_vector_section=0x08
void high_vector(void)
{
  if(INTCONbits.TMR0IF==1)
  {
   _asm GOTO tmr0_kesmesi _endasm
  }
  if(usb_kesme_bayragi==1)
{
  _asm GOTO usb_kesmesi _endasm
}
}
#pragma code
#pragma interrupt tmr0_kesmesi
void tmr0_kesmesi(void)
{
  INTCONbits.TMR0IF=0;
}
void usb_kesmesi(void)
{
  usb_kesme_bayragi=0;
}
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 16 Şubat 2013, 22:01:57
evet hocam dediğiniz gibi usbde aynı vektörleri kullanıyor. şimdilik timer işini rafa kaldırdım algoritma üzerine çalışıyorum hızlanma ve yavaşlama olayını çözsem nasıl bir algoritma ile çözerim acaba
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: iyildirim - 17 Şubat 2013, 02:55:08
Alıntı yapılan: computerboy - 16 Şubat 2013, 22:01:57
evet hocam dediğiniz gibi usbde aynı vektörleri kullanıyor. şimdilik timer işini rafa kaldırdım algoritma üzerine çalışıyorum hızlanma ve yavaşlama olayını çözsem nasıl bir algoritma ile çözerim acaba

C18'i de 18F serisini de detaylı bilmiyorum. O konuda yorum yapamam..

Timer işini rafa kaldırman doğru değil.  Delay gibi fonksiyonlarla yapacağın bekleme araya girecek kesme kodları vs. nedeniyle her zaman aynı süreyi vermeyecek. Üstelik usb de kullanıyorsan her 1 ms de kesme çalıştırıyorsun..
Timer kullanmak için illa da kesme kullanmak zorunda değilsin. bekleme fonksiyonunda TMR registerinin istediğin değere gelmesini beklemen yeterli. Üstelik bu şekilde kullanmak yazdığın koda daha uygun. 

Alıntı yapılan: iyildirim - 14 Şubat 2013, 18:03:57
Fikir vermesi açısından; Algoritmaya göre daha uzun yol kateden eksende fonksiyon her çağrıldığında hareket olur diye düşünürsek yapabileceğin;
ya önceden hesaplayıp her adımı bufferlamak ve uzun yol kateden eksene göre zamanını ayarladığın bir timer kesme ile bufferı pinlere aktarmak,
yada  hareket anında hesaplamak ve gerekli gecikmeleri de hesaplayıp beklemek..
Demiştim.
Uzun yol kateden eksende putMotor her çağrıldığında hareket olacaksa, putMotor içinde en başta TMR registerinin istediğin değere gelmesini bekleyip sonra ne yapmak istiyorsan  yapabilirsin. Tabii birde TMR registerini sıfırlayacaksın.



void putMotor(SL x, SL y, SL z )
{

    while(TMR1 < delayTime);
    TMR1 = 0;
/* minPeriod , hız parametresine göre en başta hesapladığın master eksenin hızı..periodu 1 / STEP_sn den hesaplanacak */
    if (delayTime > minPeriod)             
        delayTime -= hızlama_miktarı       
   

.......

gibi. Burada minPeriod max hıza göre timer periodu, delayTime ise o anki hızına göre period. delayTime başta büyük bir değere set edilip azaltılırsa basit bir hızlanma işlevi de yapmış olursun.   Diğer bekleme fonksiyonlarını  iptal edip bu şekilde bir dene derim.

DIR değişkenlerini komutu aldığında set edersen putMotor içinde her seferinde hesaplamak zorunda kalmazsın. Bu şekilde hareket etmeyen motorda bir yönde DIR pininde STEP ile uyumlu sürekli bir darbe olacak.

Titreme demişsin. Bu ileri geri bir titrememi, ilerle dur gibi titrememi anlamak, pozisyon hatası oluyormu ona bakmak lazım. Sürücü olarak ne kullanıyorsun.?

-------------------------------------------
edit: while(TMR1 >= delayTime);
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 17 Şubat 2013, 21:24:46
titreme usb kesmesinden kaynaklanıyormuş hocam usb devre dışı kalınca sorun kalmıyor. birde sizin dediğiniz şekilde kodları düzenlemeye çalıştım ama tam anlayamadım bi inceleseniz çok öğreneceğim var sizden ayrıca DIR ayarlarınıda bresenham koda gömdüm.



void putMotor(SL x, SL y, SL z )
{


if(x-oldX==1 || x-oldX==-1) STP_X = 0;
while(TMR1 < x_h); TMR1 = 0;
if(x_h>x_h_s) x_h-=x_h;

if(y-oldY==1 || y-oldY==-1) STP_Y = 0;
while(TMR1 < y_h); TMR1 = 0;                 // TMR1  usb kesmesini sayıyor.
if(y_h>y_h_s) y_h-=y_h;

if(z-oldZ==1 || z-oldZ==-1) STP_Z = 0;
while(TMR1 < z_h); TMR1 = 0;
if(z_h>z_h_s) z_h-=z_h;

STP_X =1;
while(TMR1 < x_h); TMR1 = 0;
if(x_h>x_h_s) x_h-=x_h;

STP_Y =1;
while(TMR1 < y_h); TMR1 = 0;
if(y_h>y_h_s) y_h-=y_h;

STP_Z =1; 
while(TMR1 < z_h); TMR1 = 0;
if(z_h>z_h_s) z_h-=z_h;
         
stepcount=stepcount+1;

    oldY = y;
    oldX = x;
    oldZ = z;

}
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: iyildirim - 18 Şubat 2013, 02:02:08
Herhalde titreme son eklediğin kod ile ortadan kalkmamıştır. Bu kod ile doğru çalışması da mümkün görünmüyor ve öylesine hazırlanmış gibi.

Bahsettiğimiz şeyde anahtar nokta uzun yol kateden eksende (buna master eksen diyelim) putMotor her çağrıldığında hareket olması.
Bresenham ile tam olarak bir kareli defter sayfasında imiş gibi hareket ediyoruz. Bu ekranda-bellekte grafik çizerken işimizi kolaylaştırıyor. Ekran çözünürlüğüne göre bilgiyi digitize ediyoruz. Cnc de de aynı şekilde.
Cnc ile Kareli defter sayfasını üzerinde ilerlediğini düşün. İki çizgi arası mesafe de senin step boyun.  putMotor her çağrıldığında eksenlerin pozisyonu ancak çizgilerin kesişme noktaları olabilir.
Master eksende daima ilerleme olacak diğerinde bazen. Bu yüzden sadece master eksene tek bir timer kurmak yeterli.

Verdiğin kodda aynı timer 3 kere kullanılmış. Diğer eksende hareket olduğunda Master eksen hızın anlık olarak düşecek.

PutMotor için bu koda bir bak.

void putMotor(SL x, SL y, SL z )
{
    while(TMR1 < delayTime); /* veya aşağıdaki açıklamaya göre while(TMR1 < delayTime>>1);*/
    /* minPeriod ve delayTime 'ın hareket başındaki startup değeri dışarıda set edilmiş olmalı. */
    TMR1 = 0;
/* minPeriod , hız parametresine göre en başta hesapladığın master eksenin hızı..periodu 1 / STEP_sn den hesaplanacak */
    if (delayTime > minPeriod)             
        delayTime -= hızlama_miktarı       


/* sürücün yükselen kenarda step alıyorsa    if(x-oldX |= 0) STP_X = 1; gibi olmalı.. düşen kenar için aşağıdaki gibi..
burada ne zaman step puls göndereceğimizi hallediyoruz. Ama step darbesi bir süre sonra pasif konumuna gelmeli.
Burada ya belli bir süre yada tam %50 duty istersek delayTime kadar beklenecek. delayTime üzerinden gidilecekse, süreyi hesaplarken
iki kere delayTime beklendiğini gözönüne almak gerekir. Birde daha detayda buradaki kodun işlenme süresi var.
Diğer seçenek ise işlemci uygunsa OC modülü kullanıp one shot puls üretmek olabilir. İşlemcin uygun değilse de uygun olanını kullanmanı öneririm..
OC için kullanılan timer aynı zamanda delayTime için kullandığın timer olacak. Bu şekilde burada beklemek yerine bresenham'a daha fazla zaman ayırabilir ve daha yüksek hızlara çıkabilirsin.
*/
if(x-oldX |= 0) STP_X = 0;
if(y-oldY |= 0) STP_Y = 0;
if(z-oldZ |= 0) STP_Z = 0;

while(TMR1 < delayTime); /* veya yukarıdaki açıklamaya göre while(TMR1 < delayTime>>1);*/

STP_X =1;// veya STP_X = 0
STP_Y =1;
STP_Z =1; 
                       
stepcount=stepcount+1;

    oldY = y;
    oldX = x;
    oldZ = z;

}

Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 18 Şubat 2013, 13:52:42
Hocam bu şekilde diyorsunuz sanırım. beynim durdu anlayamıyorum.  delay time derken mesela delaytime 200 olsun minperiod 60 hizmiktari 3. şimdi maxsimum hıza yani 60 ulaşması için 3 er 3er çıkarma işlemimi yapıyoruz burda ?

birde while(TMR1 < delayTime>1); ve while(TMR1 < delayTime); burda büyüktür işareti koymuşsunuz görevi ne acaba programlamada eksikliklerim var kusura bakmayın sizinde başınızı ağrıtıyorum.

SL delayTime=200; // delayTime ise o anki hızına göre period.
SL minPeriod=60; // minPeriod en yüksek hıza göre master eksenin hızı.
SL hizMiktari=3; // hızlanma miktarı

void putMotor(SL x, SL y, SL z)
{

if(x-oldX==1 || x-oldX==-1) STP_X = 0; // sürücü düşen kenardan step alıyor.
if(y-oldY==1 || y-oldY==-1) STP_Y = 0; 
if(z-oldZ==1 || z-oldZ==-1) STP_Z = 0;

while(TMR1 < delayTime>1);TMR1 = 0; // burda delaytime 1000 olsun diyelim tmr1 değeri 1000' e ulaşıncaya kadar döngü kuracak ve 1000'e ulaşınca alt satırlardaki kodları işlemeye alacak değilmi ?
    if (delayTime > minPeriod)             
        delayTime -= hizMiktari;

STP_X =1;
STP_Y =1;
STP_Z =1;           
               
while(TMR1 < 20);TMR1 = 0;    // Fazla aktif etmedim 20 usb kesmesi yaptım.

oldY = y;
oldX = x;
oldZ = z;

}
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: JKramer - 18 Şubat 2013, 15:11:52
Büyüktür işareti değil, sağa kaydırma (>>1, ikiye bölme).
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 18 Şubat 2013, 15:47:31
hocam iki adet olunca kaydırma işlemii olmuyormuydu yanlışmı biliyorum. orda sadece bir tane var.
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: JKramer - 18 Şubat 2013, 15:52:54
iyildirim'ın bu mesajına (https://www.picproje.org/index.php/topic,45164.msg334612.html#msg334612) bakıyoruz değil mi?
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 18 Şubat 2013, 16:07:28
evet hocam mesaj değişmiş :) dün akşam bakmıştım en son :)
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: iyildirim - 18 Şubat 2013, 17:37:38
Alıntı yapılan: computerboy - 18 Şubat 2013, 13:52:42
birde while(TMR1 < delayTime>1); ve while(TMR1 < delayTime); burda büyüktür işareti koymuşsunuz görevi ne acaba
>>  olacak.. Yanlış yazmışım. Düzelttim sonra. Periodu 2 ye bölmek için. while(TMR1 < delayTime>>1); olmalı.  Tam %50 duty li kare dalga için.

Alıntı yapılan: computerboy - 18 Şubat 2013, 13:52:42
Hocam bu şekilde diyorsunuz sanırım. beynim durdu anlayamıyorum.  delay time derken mesela delaytime 200 olsun minperiod 60 hız miktarı 3. şimdi maxsimum hıza yani 60 ulaşması için 3 er 3er çıkarma işlemimi yapıyoruz burda ?
Evet..

Diyelim ki G1 X500 Y300 F100 gibi bir komut işleyeceksin. F100 mm/sn cinsinden olsun. Max hızın saniyede 100mm ve 5mm hatveli vidali mil kullanıyorsun. Step motorun 200adım/tur ve sürücünde 8mikrostep destekliyor.
100 mm/sn hız, 5mm hatveye göre  100/5 = 20 tur/sn demek.

Üretmen gereken palslerin max frekansı = 20tur * 200(adım/tur) *8(mikrostep) = 32000Hz bulunur.
Diyelimki işlemcin 16MIPS ve Timer 16 bitlik ve Timer prescaler değeri olarakda 1 kullanıyorsun. 

Bu durumda 16e6/1 (prescaler) = 16e6 max üretebileceğin frekans değeri.  Minimum Frekans yani puls sayısı ise 16e6/65535 = 244 hz olur.
Buda 244 /8(mikrostep)/200 (adım/tur) * 60 =  9 RPM eder.

Bu aralıklar diyelim ki işimizi görüyor. Görmüyorsa prescaler değerleri ile oynayıp uydurman gerekecek.
max Hız için timer değeri 500 çıkıyor. min hız için timer değeri 65535.. 65535/500 = 131 gibi bir şey çıkacak. Yani dairesel enterpolasyonda eksen hızları arasındaki max oran bu  olacak. Yeterlimi sen karar ver. 
Yani öncelikle çalışma aralığını limitlerini vs. işlemcinin yetenekleri çerçevesinde tasarlamalısın.

Şimdi 20 Tur/sn için 32000 puls üretecektik. 16e6/ 32000 = 500 timer değerimiz.  Bu hesabı mcu da yapabilir veya PC de hesaplayıp mcu ya direkt timer değerini yollayabilirsin.
Hızlanmada olacak ve bir başlangıç hızımız olacak. Diyelimki 0.5 Tur/sn  yani 0.5*200*8 = 800 Hz başlangıç hızımız, puls frekansımız.  Bu durumda başlangıç timer period değeri 16e6/800= 20000 olacak..
20000 olan Timer periodunu 500 değerine kadar birer, üçer ,beşer eksiltirsek belli bir hızlanma sağlayacağız. Ama, eğer hızlanmanın tam lineer olmasını istiyorsan üçer beşer arttırmak işini görmez..  Hızlanma için ayrı bir timer kullanabilirsin.
Öte yandan birde hızlandığımız gibi yavaşlamakta lazım. Ve her zaman eksen yolları max hıza çıkabilmeni sağlayacak kadar uzun olmaz. Bu durumda daha tanımlı hıza ulaşamadan yavaşlamaya başlaman ve ne zaman yavaşlamaya başlayacağını da bilmen gerekir. 

Kod içerisinde anlatmaya çalıştığım şey ise putMotor içinde boş yere beklemek yerine hesap kitaba nasıl daha fazla vakit ayırırsın konusu.
Puls ları üretirken bir kare dalga üretiyorsun.  Sürücünün aktif high çalıştığını varsayalım.  Puls pinini high yaptıktan sonra tekrar low yapmak zorundasın.
Bu durumda ya putmotor içinde pin high olduktan sonra belli bir  süre bekleyip pini tekrar low yapacaksın ve bekleme ile vakit kaybetmiş olacağız. Yada OC modülü ile tek seferlik puls üretip putMotor içinde bekleme yapmak gerekmeyecek ve hesap kitaba daha fazla vakit ayırabileceksin.

if(x-oldX==1 || x-oldX==-1)
master eksende her zaman hareket var ve teker teker ilerliyor. Yani ya sıfır yada değil.. Yani
if(x-oldX |=0) şeklinde yazabilirsin..

mcu nedir?..
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 19 Şubat 2013, 16:19:24
Teşekkürler hocam.

PIC18F4550 kullanıyorum 16 mips çalışıyormuş. timer2 16 bit, müsait olduğum zaman sizin örneklediğiniz şekilde deneme yapacağım

Step Motor 200 Adım
Step Sürücü 8 Mikrostep
Vidalı Mil Hatvesi 5

yukardaki özelliklere göre düz 10 cm çizgi için X4000 şeklinde step sayısı çıkması lazım. mach3 gibi gcode üreten programlarda böyle üretiyor herhalde.

Mesela ;

X4000 Y0 Z0 F100 // burdaki f100 feedrate hızımı oluyor hocam mach3deki gibi ?

4000(step sayısı)/200(Motor Adımı) = 20(tur)*5(vidalı mil hatvesi) = 100 mm/sn

saniyede 100 mm ilerleyecek mikrostep için pulse adedi = 4000(step sayısı)*8(mikrostep sürücü) = 32.000 pulse

timer değeri için 16.000.000/32.000 = 500 bu minperiod olacak.
hızlanmayı yavaş yavaş artırmak içinse 100(step sayısı)*8(mikrostep) = 800 pulse

16.000.000(mips)/800(pulse adedi) =20.000 buda delaytime olacak

hizlanma için uygun rakamıda ben belirleyeceğim.

bunun içinde


delayTime=20000;       // düşük hızdan yüksek hıza çıkmak için çıkartma işlemi uygulanacak.
minPeriod=500;       // minPeriod en yüksek hıza göre master eksenin hızı.
hizMiktari=15;       // hızlanma miktarı - delaytimeden çıkacak.

örneği doğru anlamışmıyım hocam. timeride düzgün kurarsam benden keyiflisi olmaz :)

Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: iyildirim - 20 Şubat 2013, 02:26:23
Doğrudur.
İşlemcinin timerlarından 1 ve 3 16 bit ve kullanıma uygun görünüyor.
Sadece Timer1'i kullanırsan ya putMotor içinde puls darbesini sonlandırmak için bekleyeceksin yada timer1 ile birlikte timer3'ü de delayTime/2 'ye kurup ISR de bütün puls pinlerini, puls polaritesine göre high yada low yapacaksın.
Kolay gelsin..
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 20 Şubat 2013, 16:21:36
hocam yardımlarınız için çok teşekkürler allah razı olsun. usb çalışırken timeri kuramıyorum nasıl yaparım hala araştırma içindeyim çözemedim.
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: iyildirim - 20 Şubat 2013, 17:33:27
Yukarıda @goo nun yazdığı şekilde olmuyormu. ?

Anladığım kadarıyla bir de usb ISR var. USB kesmesi ile ilgili kodlar direkt kesme altındamı 18f leri pek bilmem ama kodun sığmaması sanki herşeyi direkt kesme altında yazıyosun gibi bir şey düşündürdü.
Ayrıca Timer'ı başka bir şey kullanıyormu gibi şeyleri kontrol edebilirsin.
Timer1 veya timer3'ü kullanabilirsin. Biriyle olmuyorsa diğerini dene.

Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 20 Şubat 2013, 18:54:35
evet goo  hocamin  dedigi gibide denedim ama olmadi usb isr kesmesi ayri calisiyor timer 0 1 2 3 fark etmiyor 10 ms'de bir kesmeye girip usb datasini kontrol etmesi gerekiyor bu yuzden timer period v.s ayarlayinca usb duzeni bozuluyor farkli yontemler ariyorum belki cdc bulk transfer metodunu kullanirim o zaman yazilimda ve kodda buyuk capli degisim gerekecek onuda gozum kesmiyor ayrica timeri aktif etmek icin sadece led yak var timer blogunda daha timer mevzusuna hic gecmedim
Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: necati - 24 Şubat 2013, 09:17:42
http://ldc.usb.ve/~vtheok/cursos/ci4321/sd11/trabajo1/Bresenham-Alvarez.pdf (http://ldc.usb.ve/~vtheok/cursos/ci4321/sd11/trabajo1/Bresenham-Alvarez.pdf)
https://sites.google.com/site/proyectosroboticos/Home (https://sites.google.com/site/proyectosroboticos/Home)

Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 28 Şubat 2013, 21:21:23
tekrar merhaba. timer işini hallettim hocam. yalnız  anlayamadığım bir sorunla karşılaştım.

örnek; x=5000 y=6000 yapınca X ekseninde anlamsız bir titreme (pozisyon bozulması-adım atlama) oluyor , x7000  y6000 yapıncada sorun olmuyor anlayamadım belirli bazı buyuk rakamlarda oluyor.



void putMotor(SL x, SL y, SL z)
{
if(x-oldX==1 || x-oldX==-1) STP_X = 1; 
if(y-oldY==1 || y-oldY==-1) STP_Y = 1; 
if(z-oldZ==1 || z-oldZ==-1) STP_Z = 1; 

while(ReadTimer1() < delayTime); WriteTimer1(0);
    if (delayTime > minPeriod)             
        delayTime -= hizMiktari;   

STP_X =0;
STP_Y =0;
STP_Z =0;           

while(ReadTimer1() < 250); WriteTimer1(0);

oldY = y;
oldX = x;
oldZ = z;
}


//**********************************************************
void line3d(SL s_d,SL e_d,SL  x1, SL  y1, SL  z1, signed long  x2, signed long  y2, signed long  z2)
   
{

SL  x, y, z;
    SL  xd, yd, zd;
    SL  ax, ay, az;
    SL  dx, dy, dz;

    dx = x2 - x1;
    dy = y2 - y1;
    dz = z2 - z1;

    ax = ABS(dx) << 1;
    ay = ABS(dy) << 1;
    az = ABS(dz) << 1;

    sx = SGN(dx);
    sy = SGN(dy);
    sz = SGN(dz);

    x = x1;
    y = y1;
    z = z1;

minPeriod = s_d;
hizMiktari = e_d;
delayTime=10000; 
WriteTimer1(0);

UsbVeriGonder((rom char*)  "2D Kesim İşlemi..");
    if (ax >= MAX(ay, az))           
    {
        yd = ay - (ax >> 1);
        zd = az - (ax >> 1);
        for (;;)
        {

if(x-oldX==1) DIR_X = 0;else DIR_X = 1; 
if(y-oldY==1) DIR_Y = 0;else DIR_Y = 1; 
if(z-oldZ==1) DIR_Z = 0;else DIR_Z = 1; 

            putMotor(x,y,z);

            if (x == x2)
            {
                return ;
            }

            if (yd >= 0)
            {
                y += sy;
                yd -= ax;
            }

            if (zd >= 0)
            {
                z += sz;
                zd -= ax;
            }

            x += sx;
            yd += ay;
            zd += az;
        }
    }
    else if (ay >= MAX(ax, az))         
    {
        xd = ax - (ay >> 1);
        zd = az - (ay >> 1);
        for (;;)
        {

if(x-oldX==1) DIR_X = 0;else DIR_X = 1; 
if(y-oldY==1) DIR_Y = 0;else DIR_Y = 1; 
if(z-oldZ==1) DIR_Z = 0;else DIR_Z = 1; 
            putMotor(x,y,z);

            if (y == y2)
            {
                return ;
            }

            if (xd >= 0)
            {
                x += sx;
                xd -= ay;
            }

            if (zd >= 0)
            {
                z += sz;
                zd -= ay;
            }

            y += sy;
            xd += ax;
            zd += az;
        }
    }
    else if (az >= MAX(ax, ay))           
    {
        xd = ax - (az >> 1);
        yd = ay - (az >> 1);
        for (;;)
        {


if(x-oldX==1) DIR_X = 0;else DIR_X = 1; 
if(y-oldY==1) DIR_Y = 0;else DIR_Y = 1; 
if(z-oldZ==1) DIR_Z = 0;else DIR_Z = 1; 

            putMotor(x,y,z);

            if (z == z2)
            {
                return ;
            }

            if (xd >= 0)
            {
                x += sx;
                xd -= az;
            }

            if (yd >= 0)
            {
               y += sy;
                yd -= az;
            }

            z += sz;
            xd += ax;
            yd += ay;
        }
    }
}




Başlık: Ynt: Bresenham Algoritma (takıldığım noktalar var yardımcı olurmusunuz ?)
Gönderen: computerboy - 02 Mart 2013, 12:11:58
Hocam, sizinde başınızı ağrıtıyorum lütfen kusuruma bakmayın. mips olayı kafamı karıştırdı.

Vidalı Mil Hatvesi = 5 mm.
Step Motor = 1.8 (360/1.8 = 200 Adım)
Step Motor Sürücü 0.9 (360/0.9 = 400 Pulse)

Mcu Pic18f4550 ;

PLLDIV = 5 // 20 Mhz kristal takılı
CPUDIV = OSC1_PLL2//  [96 MHz PLL Src: /2]) = 96 mhz/2 = 48.000.000 hz.
Timer1 16 bit  ve 1:8 kullanıyorum buda (65535/8 = 8191) Maximum Prescaler 8191 yapıyor.


bu özelliklere göre nasıl bir hesap yapmalıyım ayrıca yukarıdaki hesabı doğrumu yapıyorum.

visual basic 6.0 ile küçük bir hesap programı yazdım vaktiniz müsait ise bir göz atabilirmisiniz ?

http://www.4shared.com/rar/90fb-t_m/Motor_Program.html (http://www.4shared.com/rar/90fb-t_m/Motor_Program.html)

birde burada ne demek istediniz biraz daha açarmısınız.

Alıntı yapılan: iyildirim - 20 Şubat 2013, 02:26:23
Doğrudur.
İşlemcinin timerlarından 1 ve 3 16 bit ve kullanıma uygun görünüyor.
Sadece Timer1'i kullanırsan ya putMotor içinde puls darbesini sonlandırmak için bekleyeceksin yada timer1 ile birlikte timer3'ü de delayTime/2 'ye kurup ISR de bütün puls pinlerini, puls polaritesine göre high yada low yapacaksın.
Kolay gelsin..

puls darbesini sonladırmak için aşağıdaki kodda while(ReadTimer1() < 250);   WriteTimer1(0); ile bekleme yaptım bu yetersizmi acaba ?:

void putMotor(SL x, SL y, SL z)
{
    if(x-oldX==1 || x-oldX==-1) STP_X = 1; 
    if(y-oldY==1 || y-oldY==-1) STP_Y = 1; 
    if(z-oldZ==1 || z-oldZ==-1) STP_Z = 1; 

    while(ReadTimer1() < delayTime); WriteTimer1(0);
    if (delayTime > minPeriod)             
        delayTime -= hizMiktari;   

STP_X =0;
    STP_Y =0;
    STP_Z =0;           
   
    while(ReadTimer1() < 250); WriteTimer1(0);

    oldY = y;
    oldX = x;
    oldZ = z;
}