Gcode dairesel çizim hatası

@kerem89
Tam anlayalım.
Phyton kodun arduino ya gcode gönderiyor.
Arduinoda da gcode yorumlamak için kendi yazdığın kod çalışıyor.

Böyle ise öncelikle Gcode'un arduino'ya tam eksiksiz gittiğini kontrol etmeli. Arada bazı gcode satırları işlenmez-atlanırsa gönderdiğin resime benzer bir görüntü olur.

Burada sorun yoksa arduino üzerindeki koda odaklanmak gerek.

Lineer, dairesel enterpolasyonlar için nasıl bir algoritma kullanıyorsun. Rampalama vs.? Doğru kodlandı mı?

Benim de PCB kazıma amaçlı yazdığım bir Gcode yorumlayıcısı var. 32f4disco üzerinde çalışıyor. Sadece g0-1-2-3 destekli.
Arduino da sadece firmata yüklü ve bütün iş python kodunda ve kod direkt olarak satırlardaki x ve y değerini alıp motorların kaç adımda o mesafeyi gideğini hesaplayıp o kadar kez motorları tetikliyor. Yazdığınız kodu görmek isterim.
 
Yani arduino ya gcode gitmiyor.
Gcode pc de yorumlanıp arduinoya 0-1 gibi birşeyler gönderiyorsun. Arduino da puls-dır çalışan motor sürücülerine sinyaller yolluyor.
Bakarım dediğine göre Bresenham falan da kullanmıyorsun.
Öncelikle phyton koduna bi bakalım.
Ama kodla birlikte gcode yorumlamak için kurguladığın yapıyı anlamak önemli.


Benim kod uVision ile yazıldı. Register seviyesinde. Kesmelerle çalışan asenkron bir yapı.
Bir süre sonra bakınca neyi niye yapmışım mı anlamak benim de biraz zamanımı alıyor.

Lineer enterpolasyon hesabı için kullandığım Bresenham kısmı. Timer içinden çağrılıyor.
C:
void Bresenham_linear_2D_Update()
{
    volatile int errorX2, errorY2, errorZ2 ;
    pulsPort = 0x0000EFFF;

    X.PulsEnable = 0;
    Y.PulsEnable = 0;
    Z.PulsEnable = 0;

//    GPIOD->ODR |= 0x0000E000;
//     if (X.posDirection != 0)    {X.PulsEnable = 1; X.startPos++; portD &= 0x0000DFFF;}
//     if (Y.posDirection != 0)    {Y.PulsEnable = 1; Y.startPos++; portD &= 0x0000BFFF;}
//     if (Z.posDirection != 0)    {Z.PulsEnable = 1; Z.startPos++; portD &= 0x00007FFF;}
    
    errorX2 = 2 * Bresenham_ErrX;
    errorY2 = 2 * Bresenham_ErrY;
    errorZ2 = 2 * Bresenham_ErrZ;
    
    if (startPos != endPos)
    {
        Bresenham_ErrX -= X.deltaPos;
        Bresenham_ErrY -= Y.deltaPos;
        Bresenham_ErrZ -= Z.deltaPos;
        startPos++;
    }
    
    if(X.startPos == X.endPos)
        {X.PulsEnable = 0;}
    else if(errorX2 <  deltaPos)
        {Bresenham_ErrX += deltaPos;    X.PulsEnable = 1; X.startPos++; X.pulsActive = MAX_ACTIVE;}     

    if(Y.startPos == Y.endPos)
        {Y.PulsEnable = 0;}
    else if(errorY2 <  deltaPos)
        {Bresenham_ErrY += deltaPos;    Y.PulsEnable = 1; Y.startPos++; Y.pulsActive = MAX_ACTIVE;}     

    if(Z.startPos == Z.endPos)
        {Z.PulsEnable = 0;}
    else if(errorZ2 <  deltaPos || Z.G0 == 1)
        {
            Bresenham_ErrZ += deltaPos;   
            Z.PulsEnable = 1;
            Z.startPos++;
            Z.pulsActive = MAX_ACTIVE;
        }     
}

void TIM2_IRQHandler(void)
{
    TIM2->SR = 0x00000000;   

    if     (circleSpeedChangeFlag)
        speed_acceleration_Circle();

    ZCalibrate();

    if(X.pulsActive > 0)         {X.pulsActive--;}
    if(Y.pulsActive > 0)         {Y.pulsActive--;}
    if(Z.pulsActive > 0)         {Z.pulsActive--;}

    if (motorEnable == 1)
    {
        if (runningCmd == 0 || runningCmd == 1)
        {
            Bresenham_linear_2D_Update();

            if (X.PulsEnable == 1)
            {
                calcStep(&X);
                speed_acceleration(&X);
            }
        
            if (Y.PulsEnable == 1)
            {
                calcStep(&Y);
                speed_acceleration(&Y);
            }

            if (Z.PulsEnable == 1)
            {
                calcStep(&Z);
                speed_acceleration(&Z);
            }
        }
        else
        {
            if ((runningCmd == 2) || (runningCmd == 3))
                G2G3_Arc_SQR_Int();
        }
    }
    

    if(X.pulsActive > MAX_ACTIVE/2)         {X_PULS_HIGH;} else {X_PULS_LOW;}
    if(Y.pulsActive > MAX_ACTIVE/2)         {Y_PULS_HIGH;} else {Y_PULS_LOW;}
    if(Z.pulsActive > MAX_ACTIVE/2)         {Z_PULS_HIGH;} else {Z_PULS_LOW;}
    
}
 
Gcode pc de yorumlanıp arduinoya 0-1 gibi birşeyler gönderiyorsun.
aslında tam olarak bu şekilde değil arduino yüklendiğinde beraberinde gelen Standartfirmata python gibi programlarla iletişimi sağlıyor ve Python kodunda arduino yu kütüphane olarak ekliyorsun şimdi kodu atıyorum anlaşılırlığı biraz zor maalesef. Bresenham için ayrı bir kod yazdım ama o dosyaya inkscape çıktısı gcode u okutuyorsun ve o bresenham ın yapacağı işi yapıyor ve yeni bir gcode oluşturuyor.

Python:
from pyfirmata import Arduino, util, SERVO
import time

switchTetikSayisi = 0
xDegeriYazdirmaDeger = 0
yDegeriYazdirmaDeger = 0
zAcisiYazdir = 0

if __name__ == '__main__':
    Arduino = Arduino('COM5')
    Arduino.digital[5].mode = SERVO
    print("program calismaya basladi")

    iterator = util.Iterator(Arduino)
    iterator.start()

    yp = Arduino.get_pin('d:9:eek:')
    yd = Arduino.get_pin('d:8:eek:')
    xp = Arduino.get_pin('d:11:eek:')
    xd = Arduino.get_pin('d:10:eek:')
    ys = Arduino.get_pin('d:7:i')
    xs = Arduino.get_pin('d:6:i')

    xPozisyon = 0
    yPozisyon = 0
    satirNumarasi = 0
    motorBirTurdakiAdimSayisi = 1600

    sayac = 0
    oku = open("YHTest.gcode","r")
    dizi = oku.readlines()

    motorgecikmeleri = 0.001

    def XArti ():

        xd.write(1)
        xp.write(1)
        #Arduino.pass_time(motorgecikmeleri)
        xp.write(0)
        #Arduino.pass_time(motorgecikmeleri)
    def YArti ():

        yd.write(1)
        yp.write(1)
        #Arduino.pass_time(motorgecikmeleri)
        yp.write(0)
        #Arduino.pass_time(motorgecikmeleri)
    def XEksi():

        xd.write(0)
        xp.write(1)
        #Arduino.pass_time(motorgecikmeleri)
        xp.write(0)
        #Arduino.pass_time(motorgecikmeleri)
    def YEksi():

        yd.write(0)
        yp.write(1)
        #Arduino.pass_time(motorgecikmeleri)
        yp.write(0)
        #Arduino.pass_time(motorgecikmeleri)

    while switchTetikSayisi == 1:
        print("baslangic noktasi ayarlaniyor...")
        while (xs.read() == False) and (ys.read() == False):
            Arduino.digital[5].write(180)
            YEksi()
            XEksi()
            print("eksenler sifirlaniyor...")

        while (xs.read() == True) and (ys.read() == False):
            Arduino.digital[5].write(180)
            YEksi()
            print("x ekseni sifirlaniyor...")

        while (ys.read() == True) and (xs.read() == False):
            Arduino.digital[5].write(180)
            XEksi()
            print("y ekseni sifirlaniyor...")

        if (ys.read() == True) and (xs.read() == True):
            print("baslangic noktasi ayarlandi")
            switchTetikSayisi = switchTetikSayisi + 1
            break

    while True:
        ilkHarf = str(dizi[satirNumarasi])[0:1]

        Arduino.digital[5].write(150)

        if ilkHarf == "M":
            harfDegeri = str(dizi[satirNumarasi])[1:str(dizi[satirNumarasi]).find(" ")]
            if harfDegeri == "300":
                kalemAciDegeri = str(dizi[satirNumarasi])[6:3+ str(dizi[satirNumarasi]).find("S")]
                int(kalemAciDegeri)
                #kalemAciDegeri servo motorun donecegi acidir
                kalemAciDegeri2 = 160
                if kalemAciDegeri == "50":
                    kalemAciDegeri2 = 180
                if kalemAciDegeri == "30":
                    kalemAciDegeri2 = 150
                if zAcisiYazdir == 1:
                    print(kalemAciDegeri2)
                def servo(kalemAciDegeri2):
                    Arduino.digital[5].write(kalemAciDegeri2)
                servo(kalemAciDegeri2)
                Arduino.pass_time(0.5)

        if ilkHarf == "G":
            harfDegeri = str(dizi[satirNumarasi])[1:str(dizi[satirNumarasi]).find(" ")]
            if harfDegeri == "4":
                beklemeSuresi = str(dizi[satirNumarasi])[4:4+ str(dizi[satirNumarasi]).find("P")]
                Arduino.pass_time(int(beklemeSuresi)/1000)
            if harfDegeri == "1":
                g1dogrulama = str(dizi[satirNumarasi])[str(dizi[satirNumarasi]).find(" ")+1:str(dizi[satirNumarasi]).find(" ")+2]
                if g1dogrulama == "X":
                    # f = open("Cnc_3_ayarlar_part.py" , "r")
                    # x = f.read().rfind("xDegeriYazdirmaDeger:")
                    # satir = f.seek(int(x) + 2) / 24
                    # f.close()
                    # f = open("Cnc_3_ayarlar_part.py" , "r")
                    # a = f.readlines()
                    # xDegeriYazdirmaDeger = str(a[int(satir)])[str(a[int(satir)]).find(":") +2:3+str(a[int(satir)]).find(":")]
                    # f.close()
                    # f = open("Cnc_3_ayarlar_part.py" , "r")
                    # x = f.read().rfind("xDegeriYazdirmaDeger:")
                    # satir = f.seek(int(x) + 2) / 24
                    # f.close()
                    # f = open("Cnc_3_ayarlar_part.py" , "r")
                    # a = f.readlines()
                    # yDegeriYazdirmaDeger = str(a[int(satir)])[str(a[int(satir)]).find(":")+2:3+str(a[int(satir)]).find(":")]
                    # f.close()


                    xDeger = str(dizi[satirNumarasi])[1+str(dizi[satirNumarasi]).find("X"): str(dizi[satirNumarasi]).find(".")]
                    xDegerVS = str(dizi[satirNumarasi])[1+str(dizi[satirNumarasi]).find("."): str(dizi[satirNumarasi]).find("Y")-1]
                    xDegeri = int(xDeger) + int(xDegerVS) / 100

                    yDeger = str(dizi[satirNumarasi])[1+str(dizi[satirNumarasi]).find("Y"): str(dizi[satirNumarasi]).rfind("F")-4]
                    yDegerVS = str(dizi[satirNumarasi])[str(dizi[satirNumarasi]).rfind("F")-2:str(dizi[satirNumarasi]).rfind("F")-1]
                    yDegeri = int(yDeger) + int(yDegerVS) / 100
                    print("satir numarasi: " + str(satirNumarasi+1) + " Degerler : X" + str(xDegeri) + " Y" + str(yDegeri))
                    print(xDegeriYazdirmaDeger)
                    if int(xDegeriYazdirmaDeger) == 0:
                        print("x degeri: "+ str(xDegeri))
                    if int(yDegeriYazdirmaDeger) == 0:
                        print("y degeri: "+ str(yDegeri))

                    while True:
                        if xPozisyon < (int(xDegeri)*5*(-1)*(motorBirTurdakiAdimSayisi / 200)):
                            XEksi ()
                            xPozisyon = xPozisyon + 1
                            #print("x degeri artiyor")
                        if xPozisyon > (int(xDegeri)*5*(-1)*(motorBirTurdakiAdimSayisi / 200)):
                            XArti ()
                            xPozisyon = xPozisyon - 1
                            #print("x degeri azaliyor")
                        if yPozisyon < (int(yDegeri)*5*(-1)*(motorBirTurdakiAdimSayisi / 200)):
                            YEksi ()
                            yPozisyon = yPozisyon + 1
                            #print("y degeri artiyor")
                        if yPozisyon > (int(yDegeri)*5*(-1)*(motorBirTurdakiAdimSayisi / 200)):
                            YArti ()
                            yPozisyon = yPozisyon - 1
                            #print("y degeri azaliyor")
                        if (yPozisyon == (int(yDegeri)*5*(-1)*(motorBirTurdakiAdimSayisi / 200))) and (xPozisyon == (int(xDegeri)*5*(-1)*(motorBirTurdakiAdimSayisi / 200))):
                            break
        satirNumarasi = satirNumarasi + 1


Arduino.pass_time(1)
 
Son düzenleme:
aslında tam olarak bu şekilde değil arduino yüklendiğinde beraberinde gelen Standartfirmata python gibi programlarla iletişimi sağlıyor ve Python kodunda arduino yu kütüphane olarak ekliyorsun şimdi kodu atıyorum anlaşılırlığı biraz zor maalesef.
firmata kütüphanesi Arduino'dan pin durumu okuma, pin set etme, analog okuma yapma gibi bir altyapı sağlıyor.
Yani dediğim gibi gcode phyton ile yorumlanıp arduino ya motorlara puls yollaması için pin durumlarını set ediyor.
Görebildiğim kadarı ile de eksen hesapları için ayrı bir kütüphane var.

Gcode parse ederken herşeyin standart sırada geleceğini varsayıyorsun.
Hatan büyük ihtimalle burada.
Mesela her satırda F değerinin geleceğini varsayıyorsun. Senin koduna göre F değeri gelmezse Y değerini hatalı okursun.
Oysa F yani eksen hızı gcode'da modal bir parametredir. Bir kere set edildikten sonra her satırda tekrarlanması gerekmez.

Ayrıca kod da biraz spagetti olmuş.
Koduna olabildiğince açıklamalar eklersen, paragraflara dikkat edersen sonrasında sende daha rahat okursun.

evt arduino kullanıyorum ama daha sonra programı özelleştirmeyi planladığım için grbl ye hiç bulaşmadım. Yani sıradan bir cnc olarak kalmasını istemiyorum ve grbl ye şuanki cnc yi uydurmak için biraz alışveriş yapmam gerecek sanırım teşekkürler.
Demişsin ama bu yapı özellikli bir cnc için daha iyi değil. En başta performans sorunu olur.
Görebildiğim kadarı ile USB HID veya com port kullanıyor. Her bir puls için bu ortamdan komut göndermek tam bir darboğaz.
Ne kadar hızlı da olsa bir işletim sistemi çalıştıran bir PC 'de puls zamanlamaları vs. bir mikrodan daha kaliteli olmuyor. Özellikle de puls lar seri şekilde gönderildiğinde.
Mesela Mach3 paralel port kullanır. Buna rağmen mach3 çalıştıran makinada başka programların çalışması tavsiye edilmez. Puls zamanlama kalitesi bozulmasın diye. Mach3 USB vs çalışanlarda gcode'u mikro üzerinde işlerler veya sağlam bir buffer üzerinden pulsler iletilir.

GRBL, firmata denen bu yapıdan çok daha iyi ve oturmuş durumda.
Ayrıca motorların vs. çalışıyorsa grbl için niye alışveriş ihtiyacın olsun ki. grbl içinde pin ayarları, eksenlerin bir devrinde ne kadar hareket ettiği gibi ayarları yapman yetmiyormu?

İlk gcode yorumlayıcı kodu yazalı 10 yıldan fazla oldu. O dönemde grbl gibi oturmuş hazır bir ortam olsaydı, Ne code yorumlamakla nede gerber'den gcode üretmekle uğraşmazdım sanırım. Ya grbl, linux-cnc gibi açık kaynak bir projeyi yi alır direkt kullanır, yada ihtiyacıma göre modifiye etmeyi tercih ederdim.
Önerimdir.
 
firmata kütüphanesi Arduino'dan pin durumu okuma, pin set etme, analog okuma yapma gibi bir altyapı sağlıyor.
Yani dediğim gibi gcode phyton ile yorumlanıp arduino ya motorlara puls yollaması için pin durumlarını set ediyor.
Görebildiğim kadarı ile de eksen hesapları için ayrı bir kütüphane var.

Gcode parse ederken herşeyin standart sırada geleceğini varsayıyorsun.
Hatan büyük ihtimalle burada.
Mesela her satırda F değerinin geleceğini varsayıyorsun. Senin koduna göre F değeri gelmezse Y değerini hatalı okursun.
Oysa F yani eksen hızı gcode'da modal bir parametredir. Bir kere set edildikten sonra her satırda tekrarlanması gerekmez.

Ayrıca kod da biraz spagetti olmuş.
Koduna olabildiğince açıklamalar eklersen, paragraflara dikkat edersen sonrasında sende daha rahat okursun.


Demişsin ama bu yapı özellikli bir cnc için daha iyi değil. En başta performans sorunu olur.
Görebildiğim kadarı ile USB HID veya com port kullanıyor. Her bir puls için bu ortamdan komut göndermek tam bir darboğaz.
Ne kadar hızlı da olsa bir işletim sistemi çalıştıran bir PC 'de puls zamanlamaları vs. bir mikrodan daha kaliteli olmuyor. Özellikle de puls lar seri şekilde gönderildiğinde.
Mesela Mach3 paralel port kullanır. Buna rağmen mach3 çalıştıran makinada başka programların çalışması tavsiye edilmez. Puls zamanlama kalitesi bozulmasın diye. Mach3 USB vs çalışanlarda gcode'u mikro üzerinde işlerler veya sağlam bir buffer üzerinden pulsler iletilir.

GRBL, firmata denen bu yapıdan çok daha iyi ve oturmuş durumda.
Ayrıca motorların vs. çalışıyorsa grbl için niye alışveriş ihtiyacın olsun ki. grbl içinde pin ayarları, eksenlerin bir devrinde ne kadar hareket ettiği gibi ayarları yapman yetmiyormu?

İlk gcode yorumlayıcı kodu yazalı 10 yıldan fazla oldu. O dönemde grbl gibi oturmuş hazır bir ortam olsaydı, Ne code yorumlamakla nede gerber'den gcode üretmekle uğraşmazdım sanırım. Ya grbl, linux-cnc gibi açık kaynak bir projeyi yi alır direkt kullanır, yada ihtiyacıma göre modifiye etmeyi tercih ederdim.
Önerimdir.
Bu kadar emek verdiğiniz için teşekkür ederim. O zaman ilk olarak grbl için gerekli ayarlamaları yapmaya çalışacağım. Peki istediğim performansı grbl den aldıktan sonra onu modifiye etmek için kodu kendim yazmak istesem. Ne önerirsiniz? Python kullanmalı mıyım ilk olarak? sonrasında dediğiniz darboğazdan kurtulmak için ne yapmalıyım?
 
Bende bu işlere girmek istiyorum ama donanım olarak neyi nasıl kullanırım bilemediğim için şu an askıda proje. Donanım derken bendeki sistem çok hızlı çalışmalı. Galvo tarayıcı için. 10mt/sn hızlar normal tarayıcılarda. Birde düz çizgi diye bir olay yok. Optik bozulmalardan dolayı düz çizgi eğri şeklinde sonuç verir. Dolayısı ile düz çizgi önce eğriye dönüşecek (kalibrasyon) sonra işlenecek. Velhasıl çözünürlük içerisindeki tüm noktaları tek tek işlemek lazım. Üstelik bu işi çok hızlı yapmak lazım. Gözüm yemiyor...
 
Bu kadar emek verdiğiniz için teşekkür ederim. O zaman ilk olarak grbl için gerekli ayarlamaları yapmaya çalışacağım. Peki istediğim performansı grbl den aldıktan sonra onu modifiye etmek için kodu kendim yazmak istesem. Ne önerirsiniz? Python kullanmalı mıyım ilk olarak? sonrasında dediğiniz darboğazdan kurtulmak için ne yapmalıyım?

Öncelikle grbl nin setup vs. kısmını çalışın.
Grbl 'nin yetmediği nokta olursa kodu inceleyip, dökümanlarını okuyup mantığını anlamak gerek.
Phyton PC üzerinde kullanıcı arabirimi oluşturmak için yüksek seviyeli güzel bir ortam.
Gcode'ları mikro üzerinde yorumladığınızda o darboğazı zaten aşmış olacaksınız.
Bunun dışında 8bitlik mikrolar yerine yine arduino ile 32 bitlik stm32 gibi mikrolar kullanabilirsiniz. Ciddi hız farkı yaratır. Yetmezse arduino yerine platformun native derleyicileri kullanılabilir.
 
Bende bu işlere girmek istiyorum ama donanım olarak neyi nasıl kullanırım bilemediğim için şu an askıda proje. Donanım derken bendeki sistem çok hızlı çalışmalı. Galvo tarayıcı için. 10mt/sn hızlar normal tarayıcılarda. Birde düz çizgi diye bir olay yok. Optik bozulmalardan dolayı düz çizgi eğri şeklinde sonuç verir. Dolayısı ile düz çizgi önce eğriye dönüşecek (kalibrasyon) sonra işlenecek. Velhasıl çözünürlük içerisindeki tüm noktaları tek tek işlemek lazım. Üstelik bu işi çok hızlı yapmak lazım. Gözüm yemiyor...
10mt/sn ışının tarama hızı sanırım.
Bir yerlerde ışın çapın 30um yazmıştın diye hatırlıyorum.
Her bir piksel de ışını kesip yeniden on yapsak 300-350Khz lik bir anahtarlama frekansı gerekir. Ki yanyana iki aktif piksel de kapatıp açmaya da gerek yok. Yani bir dolu bir boş piksel olsa max anahtarlama frekansı 150-200Khz olur.

Kenar bozulmaları olmasa taranacak bir satırı bufferlayıp, mesela stm32 üzerinde PWM çıkışlı bir timer'ı DMA'e bağlayıp, DMA'e buffer adresini göstermek yeterli olurdu. DMA de şart değil bu arada.

Ama kenar bozulmalarından dolayı ya galvo kafaları değişken hızda hareket etmeli. Yada sabit galvo kafa hızı varsayıp, lazeri on-off ettiğimiz zaman ile oynamak lazım.
Bu durumda kenar bozulmalarının image üzerindeki gridden kaymasını kompanze etmek için yukarıdaki şartlara ek olarak yüksek çözünürlüklü bir PWM gerekecek.

Mesela dsPIC'lerin smps serileri yaklaşık 1GHz den pwm frekansı bölüyor. Ki son çıkan mikroları 1-2 yıldır takip etmiyorum. Ve istediğiniz şekilde pwm puls'ının başlama gecikmesi, erken sonlanması, merkezlenmiş darbe üretimi, modül aktifken çalışma modu, frekans vs. değiştirebilme özellikleri var. Her bir puls başlangıcında kesme vs de üretebiliyor.
Zamanında motor sürücüleri ile bütünleşik gcode yorumlayıcı ile uğraşmıştım. 50mips tek bir mikroda yaklaşık 40Khz den çift sargı, 3 eksende yaklaşık 240K PID işletmek mümkün oluyordu.

Stm32F3 serilerinde 3Ghz'den pwm üreten daha hızlı mikrolarda var.
Donanım olarak gayet yeterli bir ortam var.

Asıl iş kenar bozulmalarını kompanze etme.
Ya mikro üzerinde her satırdan önce bufferlama sırasında, veya önceden PC de işlenip, sonra mikroya gönderilecek. Hesabı da çok karışık olmasa gerek. Basit trigonometri yeterli. Sabit hızlı galvonun belirli bir mesafeden düz bir yüzey üzerindeki hız değişimi hesaplanıp, kompanze edilecek.

Son olarak; galvo kafaları HDD kafası gibi mi çalışıyor, yoksa sabit hızda tek yöne süreklimi dönüyor diye sorayım.
 
Hdd kafası gibi çalışıyor. Sabit hızda dönenlerde var ama çok çok nadir ve onlar daha hızlı.

Kenar bozulmaları kesinlikle pc de düzeltilip gönderiliyor. Bahsettiğim eğrilikten biraz fazlası var. Matematiğine kafa yormak lazım.

Böyle bir proje için önce cad programı yazıp sonra ilerlemek lazım diye düşünüyorum.
 
Sabit hızda dönen optik olarak devir başını söyleyen bir motor sanki daha stabil çalışır gibi geliyor.
HDD kafası gibi çalışanlar, tamam çok hızlı ama sonsuz hızlı da (ivmeli) değil. Zaten ayna açısındaki değişim miktarı max 45-60 derece olsa gerek. HDD gibi çalışanlarda kafanın hız değişimini de kompanze etmek gerekmez mi?

Hesaba gelince, önce kenarlarda hedefi tutturma, sonrada hedefe aktarılan enerjinin, lazerin on süresini kompanze etmek lazım.
Sorun sabit hızlı aynadan yansıyan ışının düz bir yüzey üzerinde farklı hızda olması.
Nedeni birim zamanda düz yüzey üzerinde katedilen yol kenarlarda artıyor.
Yol artımından gelen farkı hıza, hızdan da zamanlamayı hesaplayan bir fonksiyon lazım.

Cad programı abartılı olmaz mı?
Ben basitçe VB vs. de bir görsel üzerinde hesaplarımın sonuçlarını kontrol ediyorum. Mesela G2-3 leri doğru oluşturdum mu, doğru yorumladım mı gibi.

Elinde örnek bir tasarım ve/veya hatta galvo kafalı bir mekanik var mı?
Kafaların aynalarının camsız direkt yansıtıcı yüzey olması gerek sanırım.
Önce statik de çalışabilen bir mekanik yapıp, dura kalka çalıştırıp, ölçe biçe ilerlemeli.
Elimdeki step motorlardan birine bir ayna monte edeyim.
Ayna olarak bir önerin olurmu?
 
Endistriyel kontrol kartları kendilerine özgü cad yazılımı ile geliyor. Hem cad hem kontrol yazılımı görevi görüyorlar. Endistüriyel bir sistem geliştirmek istiyorum ama Benimki şu aşamada fantazi bol vakit lazım.

Tarama kafalarında, merkezden uzaklaştıkça ışının kat ettiği yol artar. Buda odak bozulmasına yol açar. Bunu önlemek için aynalardan sonra lens kullanılır. Lens kullanılınca görüntü yamulur.

1609710320541.png


Bu yamulma doğrusalda değildir. Lens yüzeyindeki eğrilikler sonucu etkiler. Köşeler 90 olmaz paralel kenar yamul gibi şekiller ortaya çıkar. Çizgilerde düz değildir. Merkezden uzaklaştıkça bozulma başlar. Kenarda düz bir çizgi çekmek için bir eğri kordinatı gönderilir. Merkezde ise çizgi için doğru. Arada bölgeler için iterasyon. Ara bölgelerde sorun var ise ara referens... Tabi sadece matematik kısmı derken bunu kastetmiştim. Dolayısı ile kontrol kartına kartezyen sistem gibi şurdan şuraya git diyemezsin. Tüm nokta kümesini vermek lazım.

Galvokafanın içinde galvo motor var. Adı burdan geliyor. Step motor ile hassasiyetin ve hızın yanına yaklaşamazsın.

Aynalar dediğin gibi direkt yansıtıcı. Laserin dalga boyuna göre değişik kaplamalar var. ayna için Thorlabs a bakabilirsin.

Kendin mekanik olark birşeyler yapmak istiyorsan ilda laser taryıcılara bakabilirsin. Yapı çok benzer ayna uygun değil. Hassasiyet daha kötü. Onun dışında çok benzer sistem.

Ama dediğim gibi lens olmadan sanırım olmaz bu iş.

 
  • Beğen
Reactions: nt
Işın lazer olduğuna göre katettiği yol ile odak bozulması olmasını anlamadım. Bu durumda lazer zaten kaynağında tam odaklanmamış anlamına gelmezmi ?

Step motor sadece ilk denemeler aşamasında statik konumu koruyabileceği için debug amaçlı. Kenarda şu noktada olması gereken ışının hatasını ölçebilmek vs.
Sonrasında çok kutuplu bir DC motor olur, tek yönlü çalışır diye düşünmüştüm.
Ayna kısmına bakıcam. Not ettim.
 
Endistriyel kontrol kartları kendilerine özgü cad yazılımı ile geliyor. Hem cad hem kontrol yazılımı görevi görüyorlar. Endistüriyel bir sistem geliştirmek istiyorum ama Benimki şu aşamada fantazi bol vakit lazım.
Bu cad yazılımlarının ne özelliği var. Cad mi, cam mi 2 boyutlumu ?
Input ne kabul ediyorlar. Yoksa tasarım tamamen bunların üzerinde mi oluyor.
 
Işın lazer olduğuna göre katettiği yol ile odak bozulması olmasını anlamadım. Bu durumda lazer zaten kaynağında tam odaklanmamış anlamına gelmezmi ?

Step motor sadece ilk denemeler aşamasında statik konumu koruyabileceği için debug amaçlı. Kenarda şu noktada olması gereken ışının hatasını ölçebilmek vs.
Sonrasında çok kutuplu bir DC motor olur, tek yönlü çalışır diye düşünmüştüm.
Ayna kısmına bakıcam. Not ettim.

Işın odaklanmadan taşınır. Böylece birim yüzeye etkisi azdır. Aksi takdirde ayna gibi aktarım organlarına zarar verir. İş parçası üzerinde odaklama yapılır. Birim alana etki maksimum olur.
 
Bu cad yazılımlarının ne özelliği var. Cad mi, cam mi 2 boyutlumu ?
Input ne kabul ediyorlar. Yoksa tasarım tamamen bunların üzerinde mi oluyor.
Hem cad hem cam demek daha doğru sanırım. Takım yolu olarak arka planda ne yaptından emim değilim. G code midir yoksa programcı kendine özgü birşeymi yapmıştır orası belirsiz. Cad olarak tüm vektörel formatları destekliyor program bunun üzerine sıfırdan için yeterli çizim araçları var. Genelde 2.5 boyutlu. Ancak 3 boyutlu özellikler piyasada ivme kazanıyor.
 
Işın lazer olduğuna göre katettiği yol ile odak bozulması olmasını anlamadım. Bu durumda lazer zaten kaynağında tam odaklanmamış anlamına gelmezmi ?

Step motor sadece ilk denemeler aşamasında statik konumu koruyabileceği için debug amaçlı. Kenarda şu noktada olması gereken ışının hatasını ölçebilmek vs.
Sonrasında çok kutuplu bir DC motor olur, tek yönlü çalışır diye düşünmüştüm.
Ayna kısmına bakıcam. Not ettim.
Üçgen düşün tepesi aynalar. Tepeden zemine dikme in. Dikme uzunluğu 10cm. Odaklama yaptın. Odak uzaklığı 10cm sabit oldu. Dikme indiğin için merkezdesin. Işını zeminde üçgenin kenarına getir. Kenar uzunluğu 12cm. Odak 10cm idi. Odak 2cm havada kaldı...
 
Işın odaklanmadan taşınır. Böylece birim yüzeye etkisi azdır. Aksi takdirde ayna gibi aktarım organlarına zarar verir. İş parçası üzerinde odaklama yapılır. Birim alana etki maksimum olur.
Anlaşıldı. Bunu bilmiyordum.
Sanırım bu noktada bahsettiğimiz ışın oldukça güçlü.

Galvo olmayan co2 lazerle çalışan normal raster, vektör cnc lerde ışının direkt aynalarla kafaya kadar yönlendirildiğini görmüştüm. Lazer, cnc üzerindeki aynalara odaklı geliyor diye düşünmüştüm.
 
Odak mesafesinin tarama acisina gore degisimi sorunu lazer yazicilarda da oldugu icin cok ozel bir mercek tasarlamislar. Hemen drum'in onunde boylu boyunca duruyor.

Ayni sorun duz ekranli CRT ekranlarinda da vardi. Fakat onlarda odaklama elektrikle yapildigi icin cozumu kolaydi.
 

Çevrimiçi personel

Forum istatistikleri

Konular
5,825
Mesajlar
99,388
Üyeler
2,476
Son üye
mrmandos

Son kaynaklar

Son profil mesajları

gruptaki arkadaşlara selamlar. sıteyi bu gün fark ettim. Asansör için 2x7 segment LCD gösterge üretmek istiyorum. acaba bu sayfadaki arkadaşlardan destek alabilirmiyim. LCD nin mantık açılımı ektedir.
deneyci wrote on TA3UIS's profile.
Selam.
Amatör telsiz lisansı nasıl alınıyor?
Lisansı olmayanı forumlarına almıyorlar. :)
Bilgi alamıyoruz.
cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Back
Top