bluepowerwzh 发表于 2011-9-25 22:54:23

雕刻PCB,你是怎样做的?如何解决想在焊盘周围多雕几道以方便焊接的问题

我是雕刻机初学,主要用来做PCB,今日做了20多块电路板之后有一些问题,总结一下,并请教老鸟,看是如何解决的:

我用proteus做电路设计,生成bmp图片,在artcam中生成刀路,由于电路比较简单,就没想着把多余的覆铜清除掉,这样可以省下不少时间:)

我电路中设置的点、线最小距离都是20th,用0.3的刀雕两遍即可,但是我觉得焊盘周围还是有点紧张,为了节约加工时间,最好是把焊盘周围

的覆铜再走两刀,用artcam试验了半天,导入的bitmap中焊盘和覆铜、走线颜色均不一样,故在焊盘及覆铜的颜色上创建矢量,想用矢量相交,

没有成功。随后发现CopperCam可以在焊盘周围多走两刀,但是试验后发现coppercam虽然可以在焊盘周围多走,但是每在焊盘周围多走一道,

布线周围也会随之多走一刀,虽然走的是原来布线周围的路径,但是雕刻机总的走到时间多了不少,不知道有人试过没有,倒是可以用删除一段

刀路的方法将重复刀路去掉,但是手工去除全部电路上的重复刀路不太现实。现在我的办法是用photoshop处理电路图片,通过在焊盘和覆铜、走线

周围依次描边,在焊盘周围画上其他的颜色,导入artcam,在此颜色上上再生成刀路,但是这个方法比较麻烦,而且刀路边角处不太好(今天我的网速

比较慢,没法上传图片说明),请教各位老鸟,有没有好办法(不增加太多重复刀路,节约加工时间)在焊盘周围多走几刀?

bluepowerwzh 发表于 2011-9-26 22:31:34

回复【楼主位】bluepowerwzh
-----------------------------------------------------------------------

今天,写了个c#的程序处理电路图Bitmap图片,在焊盘的周围加上一圈描边,比photoshop的效果好,但是我处理

15x20cm的板子的图的时候发现程序效率比较低,处理一张图要一分多钟,主要是程序中使用的是Bitmap的GetPixel

和SetPixel方法,效率太低,而且不能直接处理proteus导出的4位(16色)图,要转换为24位图。看来还是要把处理方法改为

直接处理Bitmap文件的像素数据。明天再调试下。 本论坛上真的没有人有处理焊盘刀路的经验?还是没有人肯说??

bluepowerwzh 发表于 2011-9-27 12:56:56

第六贴

bluepowerwzh 发表于 2011-9-27 13:09:09

现在传上C#程序部分源码及程序,可执行程序,.Net3.5ourdev_680098G40RT0.rar(文件大小:4K) (原文件名:main.rar)


using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Diagnostics;

class Progarm
{
        //处理指定点
        static void ProcessDot(Bitmap bmp,Bitmap desBmp,Color clBack,Color clEdge,int x,int y)
        {
                if( (x>=0)&&(x<bmp.Width) )
                {
                        if( (y>=0)&&(y<bmp.Height) )
                        {
                                if(bmp.GetPixel(x,y)==clBack)
                                {
                                        desBmp.SetPixel(x,y,clEdge);
                                }
                        }
                }

        }

        /*
        static void ProcessDotMatrix(byte *srcP ,byte * desP,int width,int height,Color clBack,Color clEdge,int x,int y)
        {
                        if( (x>=0)&&(x<width) )
                        {
                                if( (y>=0)&&(y<height) )
                                {
                                        Color tc=*(Color *)(srcP+x*height+y);
                                        if(tc==clBack)
                                        {
                                                *(Color *)(desP+x*height+y)=clEdge;
                                        }
                                }
                        }
        }
        */

        static void ProcessPcbColor(Bitmap bmp,Bitmap desBmp,Color clPad,Color clBack,Color clEdge)
        {
                //循环处理每一个点
                for(int x=0;x<bmp.Width;x++)
                {
                        for(int y=0;y<bmp.Height;y++)
                        {
                                //只处理焊盘色
                                int offset=1;
                                Color t=bmp.GetPixel(x,y);
                                if(t!=clPad)
                                {
                                        desBmp.SetPixel(x,y,t);
                                        continue;
                                }
                                /*
                                if(Math.Abs(t.G-clPad.G)>offset)
                                {
                                        desBmp.SetPixel(x,y,t);
                                        continue;
                                }
                                else if(Math.Abs(t.B-clPad.B)>offset)
                                {
                                        desBmp.SetPixel(x,y,t);
                                        continue;
                                }
                                else if(Math.Abs(t.R-clPad.R)>offset)
                                {
                                        desBmp.SetPixel(x,y,t);
                                        continue;
                                }
                                */
                               
                                ProcessDot(bmp,desBmp,clBack,clEdge,x-1,y-1);
                                ProcessDot(bmp,desBmp,clBack,clEdge,x,y-1);
                                ProcessDot(bmp,desBmp,clBack,clEdge,x+1,y-1);
                                ProcessDot(bmp,desBmp,clBack,clEdge,x-1,y);
                                ProcessDot(bmp,desBmp,clBack,clEdge,x+1,y);
                                ProcessDot(bmp,desBmp,clBack,clEdge,x-1,y+1);
                                ProcessDot(bmp,desBmp,clBack,clEdge,x+1,y);
                                ProcessDot(bmp,desBmp,clBack,clEdge,x+1,y+1);
                        }
                }//end of for(int x=0;

        }

        static void ProcessPcbColorMatrix(Bitmap bmp,Bitmap desBmp,Color clPad,Color clBack,Color clEdge)
        {
                BitmapData srcBmpData=bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height),ImageLockMode.ReadOnly,bmp.PixelFormat);

                BitmapData desBmpData=desBmp.LockBits(new Rectangle(0,0,desBmp.Width,desBmp.Height),ImageLockMode.ReadOnly,desBmp.PixelFormat);

                unsafe
                {
                        int width=bmp.Width;
                        int height=bmp.Height;

                        byte * srcP=(byte *)srcBmpData.Scan0.ToPointer();
                        byte * desP=(byte *)desBmpData.Scan0.ToPointer();

                        byte green=clPad.G;
                        byte blue=clPad.B;
                        byte red=clPad.R;

                        //循环处理每一个点
                        for(int x=0;x<width;x++)
                        {
                                for(int y=0;y<height;y++)
                                {
                                        //只处理焊盘色
                                        int offset=32;
                                        if(Math.Abs(srcP-red)>offset)
                                        {
                                                continue;
                                        }
                                        if(Math.Abs(srcP-green)>offset)
                                        {
                                                continue;
                                        }
                                        if(Math.Abs(srcP-blue)>offset)
                                        {
                                                continue;
                                        }
                                       
                                        //左上点


                                        srcP+=srcBmpData.Stride-width*3;
                                        desP+=srcBmpData.Stride-width*3;
                                }
                        }

                }

                bmp.UnlockBits(srcBmpData);
                desBmp.UnlockBits(desBmpData);

                /*
                ProcessDot(bmp,desBmp,clBack,clEdge,x-1,y-1);
                ProcessDot(bmp,desBmp,clBack,clEdge,x,y-1);
                ProcessDot(bmp,desBmp,clBack,clEdge,x+1,y-1);
                ProcessDot(bmp,desBmp,clBack,clEdge,x-1,y);
                ProcessDot(bmp,desBmp,clBack,clEdge,x+1,y);
                ProcessDot(bmp,desBmp,clBack,clEdge,x-1,y+1);
                ProcessDot(bmp,desBmp,clBack,clEdge,x+1,y);
                ProcessDot(bmp,desBmp,clBack,clEdge,x+1,y+1);
                */

        }


        static void ProcessPcbBitmap(String srcFile,String desFile,Color clPad,Color clBack,Color clEdge,Color clTemp)
        {
                Bitmap bmp=new Bitmap(srcFile);

                Bitmap desBmp=new Bitmap(bmp.Width,bmp.Height);//,PixelFormat.Format32bppRgb);

                if(clPad!=clEdge)
                {
                        ProcessPcbColor(bmp,desBmp,clPad,clBack,clEdge);
                }
                else
                {
                        //首先变为零时色
                        ProcessPcbColor(bmp,desBmp,clPad,clBack,clTemp);

                        //再将临时色替换为描边色
                        for(int x=0;x<bmp.Width;x++)
                        {
                                for(int y=0;y<bmp.Height;y++)
                                {
                                        if( (x==0)&&(y==0) )
                                        {
                                                desBmp.SetPixel(x,y,clBack);
                                                continue;
                                        }
                                        else if( (x==0)&&(y==1) )
                                        {
                                                desBmp.SetPixel(x,y,clBack);
                                                continue;
                                        }
                                        else if( (x==0)&&(y==2) )
                                        {
                                                desBmp.SetPixel(x,y,clBack);
                                                continue;
                                        }

                                        if(desBmp.GetPixel(x,y)==clTemp)
                                        {
                                                desBmp.SetPixel(x,y,clEdge);
                                        }
                                }
                        }
                }

                desBmp.Save(desFile);

                desBmp.Save(".\\out.bmp");

                bmp.Dispose();
                desBmp.Dispose();
               
        }

        static void CopyFile(String srcFileName,String desFileName)
        {
                Bitmap srcBmp=new Bitmap(srcFileName);

                int width=srcBmp.Width;
                int height=srcBmp.Height;

                Bitmap desBmp=new Bitmap(width,height,srcBmp.PixelFormat);

                BitmapData srcBmpData=srcBmp.LockBits(new Rectangle(0,0,width,height),ImageLockMode.ReadWrite,srcBmp.PixelFormat);

                BitmapData desBmpData=desBmp.LockBits(new Rectangle(0,0,width,height),ImageLockMode.ReadWrite,desBmp.PixelFormat);

                int stride=srcBmpData.Stride;

                unsafe
                {

                        byte * srcP=(byte *)srcBmpData.Scan0.ToPointer();
                        byte * desP=(byte *)desBmpData.Scan0.ToPointer();

                        for(int y=0;y<height;y++)
                        {
                                for(int x=0;x<width;x++)
                                {
                                        for(int i=0;i<3;i++)
                                        {
                                                //byte temp=srcP;
                                                //*(desP+x+y*stride+i)=*(srcP+x+y*stride+i);
                                                //
                                        }

                                        //srcP+=srcBmpData.Stride-width*3;
                                        //desP+=srcBmpData.Stride-width*3;
                                       
                                }
                        }
                }

                srcBmp.UnlockBits(srcBmpData);
                desBmp.UnlockBits(desBmpData);

                desBmp.Save(desFileName);
        }

        static void ProcessBmpFile(String fileName)
        {
                Bitmap bmp=new Bitmap(fileName);

                //显示图像宽高
                /*
                String msg=String.Format("Width:{0}   Height:{1}",bmp.Width,bmp.Height);
                Console.WriteLine(msg);
                */

                Color clPad=bmp.GetPixel(0,0);//焊盘色
               
                Color clEdge=bmp.GetPixel(0,1);//描边色

                Color clTemp=bmp.GetPixel(0,2);//零时色

                Color clBack=bmp.GetPixel(0,3);//覆铜色

               
                /*
                //不处理边角颜色
                bmp.SetPixel(0,0,clBack);
                bmp.SetPixel(0,1,clBack);
                bmp.SetPixel(0,2,clBack);
                */

                String preFile=".\\t.bmp";

                bmp.Save(preFile);//保存原始文件

                String tempFileFormat=".\\t{0}.bmp";

                int ProcessNum=4;

                int count=0;

                String desFile=String.Format(tempFileFormat,count++);

                ProcessPcbBitmap(preFile,desFile,clPad,clBack,clEdge,clTemp);

                for(int n=0;n<(ProcessNum-1);n++)
                {
                        preFile=desFile;
                        desFile=String.Format(tempFileFormat,count++);

                        ProcessPcbBitmap(preFile,desFile,clEdge,clBack,clEdge,clTemp);
                }

        }

                static void Main(string [] args)
        {
                if(args.Length!=1)
                {
                        Console.WriteLine("Usage: app.exe filename.bmp");
                        Console.ReadKey();
                        return;
                }

                String fileName=args;

                Console.WriteLine("file:{0}", fileName);


                /*
                Bitmap srcBmp=new Bitmap(fileName);

                int width=srcBmp.Width;
                int height=srcBmp.Height;

                BitmapData srcBmpData=srcBmp.LockBits(new Rectangle(0,0,width,height),ImageLockMode.ReadOnly,srcBmp.PixelFormat);

                Console.Write("width:{0},height:{1},stribe:{2}",width,height,srcBmpData.Stride);
                */

                //CopyFile(fileName,".\\out.bmp");

                ProcessBmpFile(fileName);

                //Process.Start("c:\\winavr-20100110\\utils\\bin\\rm.exe t*.bmp");


        }
}

bluepowerwzh 发表于 2011-9-27 13:11:57

C#文件的makefile,运行环境为.Net3.5,csc.exe所在目录注_册到系统环境变量路径:

PROJECT_NAME=main

all: $(PROJECT_NAME).exe

$(PROJECT_NAME).exe: $(PROJECT_NAME).cs
        csc /unsafe /out:$@ $<

clean:
        del /f *.exe

bluepowerwzh 发表于 2011-9-27 13:17:28

今天又用C++完成了程序的功能,主要是我手头有一个原来下载的处理Bitmap文件的类hGraphic32,
利用它可以打开各种格式的Bitmap图片,最后生成32位的Bmp图保存。在代码中直接操作图片像素位,
比C#的GetPixel和SetPixel效率高的多,呵呵,主要是我在C#中用的Lockbits没有调试成功,要不然
据说效率也是可以的。

bluepowerwzh 发表于 2011-9-27 13:21:58

在我的c#代码中可以看到
CopyFile函数中我尝试使用
BitmapData srcBmpData=srcBmp.LockBits(new Rectangle(0,0,width,height),ImageLockMode.ReadWrite,srcBmp.PixelFormat);

BitmapData desBmpData=desBmp.LockBits(new Rectangle(0,0,width,height),ImageLockMode.ReadWrite,desBmp.PixelFormat);
但是不知为什么,运行程序时系统总是提示这个循环中读取了不能读的内存:
for(int y=0;y<height;y++)
{
for(int x=0;x<width;x++)
{
for(int i=0;i<3;i++)
{
//byte temp=srcP;
//*(desP+x+y*stride+i)=*(srcP+x+y*stride+i);
//
}

bluepowerwzh 发表于 2011-9-29 21:52:36

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680806BSFCH1.png
1 (原文件名:1.png)

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680807V0QTXX.png
2 (原文件名:2.png)

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680808FUEIPD.png
3 (原文件名:3.png)

xiao2xu5 发表于 2011-9-29 23:33:01

多才多艺的楼主,赞一个,楼主说电路都比较简单,为什么不用粗一点的刀具呢!在设计电路前把线路也加粗一点就行了(外门汉的想法请指正)

wajlh 发表于 2011-9-29 23:44:24

但是试验后发现coppercam虽然可以在焊盘周围多走,但是每在焊盘周围多走一道,

布线周围也会随之多走一刀
————————————————————————————-
这个还真没注意,有没有多试几个版本的软件?应该不会出现这个低级的错误吧

Argee 发表于 2011-9-30 03:09:53

布线周围也会随之多走一刀
————————————————————————————-
这个还真没注意,有没有多试几个版本的软件?应该不会出现这个低级的错误吧
=========================================================================
本网站 SkyGz 大侠贡献的 copper - cam 没这个问题
点击此处下载 ourdev_680866X6MSF0.rar(文件大小:863字节) (原文件名:CutRoute.rar)
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680867A3FWNM.jpg
(原文件名:cccc.jpg)

删除多余paste内容

Argee 发表于 2011-9-30 03:22:01

coppercam本身用矢量的,这方面不回搞错。

你的程序也不错。
不过,这方面用bitmap作总归有个效率低的问题,计算量大很多。

silk 发表于 2011-9-30 10:52:31

这么处理,AD6.9生成gerberGerber导出高DPI的BMP图片,BMP图片用acdsee转换格式成gif。artcam导入gif文件,按照颜色生成矢量图。
关键步骤来了
1.用区域清除,pcb雕刻完成
2.处理你需要的多雕几圈,shift+左键 选中要多雕刻几圈的焊盘,轮廓加工,加工轮廓外侧,雕刻尖刀填得比你实际的刀具大70%(0.3mm刀具填0.5mm)。不要担心刀路会切到有用的焊盘。
3.重复上述步骤2,雕刻尖刀的填(0.5*170%=0.85)


具体操作不懂,看我发的帖子《[教程][图解][附文件]使用artcam组合刀具雕刻aleyn 煮茶村长的SOIC8-DIP8转接板 》
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4610247

bluepowerwzh 发表于 2011-9-30 13:00:22

回复【10楼】xiao2xu5 啊云
-----------------------------------------------------------------------

是应该使用最粗的刀具,比方我在电路图中设置的焊盘、走线之间的最小间距是20th,也就是20*0.0254=0.508MM
那么两点之间或者两线之间用0.3的刀需要走两刀,0.4的刀也可以,0.5的刀就不行了(因为刀尖有角度,下刀0.1mm
之后,刻出的槽实际上要大于0.5,这个可以自己计算出,也可以在CopperCAM中查看),那么0.3和0.4的刀如果都可以,
我是偏向选0.3的刀的,这样万一要雕更细的东西,你还有刀可以用,0.4的就不行了,而如果要雕更粗的,0.3和0.4的都可以。
而且,经过实际是用雕刻机,我发现即便是铣过工作台面,要想在最终吧pcb板平整的固定,也还是会有高有低的地方,我的方法
是每次在pcb覆铜层最低处将z轴归零,这样如果下刀0.1mm,可以保证每一地方都至少有0.1mm的槽,这样,pcb覆铜层高的地方
自然会下刀深,刀槽要宽一些,为了减少这样的误差,同一种刀尖宽度我就选择全角较小的,比方我现在就用0.3x10的,我以前用
的是0.3x20的刀。

bluepowerwzh 发表于 2011-9-30 13:33:52

回复【14楼】silk
-----------------------------------------------------------------------


1.生成的BMP图片不用转换格式,直接导入ArtCAM即可,不存在效率问题,我的600dpi的15cmx20cm的板子也就是个把M大小

2.如果用区域清除,不就还是不能节约加工时间么,我的目的就是仅仅在焊盘周围多走刀路,方便焊接,走线周围走两刀足矣

3.确实可以在ArtCam中单独把焊盘部分都选中,但是一般进行的是钻孔,由于焊盘和走线一般都是连着的,实际上周围的矢量都是连续的,鼠标区域内不可能单独选中焊盘轮廓(除非焊盘是孤立的)

4.处理多道刀路,实际上你是不用估计的,我给你讲一下我的办法,第一遍轮廓之后,再次轮廓加工,参数中有个“余量”,在这里你
填上你选择的刀具的行距即可,第三遍轮廓你就填上“刀宽”+行距,以此类推,具体效果你自己实验一下就知道了

5.你的帖子中还是没有解决我的问题:“只在焊盘周围多走几刀”

bluepowerwzh 发表于 2011-9-30 13:45:23

昨天晚上上传了半天我的程序,也没有传上来,也不知是我的网速或是win7系统的问题还是论坛的问题,只好发个截图实验呀:
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680954NLO3S8.jpg
我的程序截图 (原文件名:程序截图.jpg)

bluepowerwzh 发表于 2011-9-30 14:12:10

回复【12楼】Argee
-----------------------------------------------------------------------

我用的CopperCAM有2008-09-25的、2010-01-26的、还有官网上下的2011-07-20的,都有这个问题,


下载SkyGz贴“CopperCAM 最新的并给那个啥了的汉化版 我们网站和谐的CopperCam最新版... ”中的CopperCAM,呵呵,很不幸,也有这个问题,下面我来描述一下,大家看看是不是我理解错误了:
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680957IGX1F5.JPG
首先生成刀路 (原文件名:1生成刀路.JPG)

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680958J9WQOW.JPG
走线1刀焊盘多1刀 (原文件名:2走线1刀焊盘多1刀.JPG)

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680959T6ZD8R.JPG
放大焊盘看似正确 (原文件名:3放大焊盘看似正确.JPG)

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680960BJ96MN.JPG
选择删除一段刀路的功能 (原文件名:4选择删除一段刀路的功能.JPG)

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680961WJVE1P.JPG
鼠标变为剪刀时删除图中走线旁的一条刀路 (原文件名:5鼠标变为剪刀时删除图中走线旁的一条刀路.JPG)

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680962E88O6X.JPG
可以看到删了一条还剩一条 (原文件名:6可以看到删了一条还剩一条.JPG)

bluepowerwzh 发表于 2011-9-30 14:15:22

回复【13楼】Argee
-----------------------------------------------------------------------

也许是我的操作不对?理解错了?

用C++处理bitmap图还是比较方便的,直接操作像素信息资料很多,
效率比C#的getpixel快几十倍呀,我生成30M的位图也就是十秒以内。

效率应该不是问题。

bluepowerwzh 发表于 2011-9-30 14:23:43

好像大家都没有像我一样的问题?呵呵,我把这么个问题整这么复杂也不容易,谁能完美解决我的问题?
如果你发现是我用的CopperCam版本的问题,麻烦把你的版本给我发一份:wzh823@gmail.com,
在这里多谢了,晚上回来我把我的程序发上来。

实际上我用了描边时候还是发现了不少问题,生成的刀路有的地方不好,
现在我雕板子还是用0.3x10的刀走三条刀路完事,覆铜和焊盘的距离也还可以。
但是我就想把这个问题搞搞清楚,软件这么多难道就没有好办法?

描边刀路有什么问题以后我再来说吧(又要上图,我的系统呀!我的网速呀!)

silk 发表于 2011-9-30 16:37:45

回复【16楼】bluepowerwzh
回复【14楼】silk
-----------------------------------------------------------------------
1.生成的bmp图片不用转换格式,直接导入artcam即可,不存在效率问题,我的600dpi的15cmx20cm的板子也就是个把m大小
2.如果用区域清除,不就还是不能节约加工时间么,我的目的就是仅仅在焊盘周围多走刀路,方便焊接,走线周围走两刀足矣
3.确实可以在artcam中单独把焊盘部分都选中,但是一般进行的是钻孔,由于焊盘和走线一般都是连着的,实际上周围的矢量都是连续的,鼠标区域内不可能单独选中焊盘轮廓(除非焊盘是孤立的)
4.处理多道刀路,实际上你是不用估计的,我给你讲一下我的办法,第一遍轮廓之后,再次轮廓加工,参数中有个“余量”,在这里你
填上你选择的刀具的行距即可,第三遍轮廓你就填上“刀宽”+行距,......
-----------------------------------------------------------------------

你应该不习惯使用artcam雕刻pcb,就我雕刻超过30张pcb 的经验,你的疑问只是想当然
就第一个问题,artcam无法直接导入ad6.9产生的bmp图片,会提示格式错误

bluepowerwzh 发表于 2011-9-30 22:14:12

回复【21楼】silk
-----------------------------------------------------------------------

我确实没有用过ad6.9,我用的是proteus导出的时候自己指定一下bitmap的格式,单色、16位、或是其他,Artcam导入即可。

就你雕刻30张pcb的经验,请问你是怎么用Artcam单独在焊盘周围多走刀路的(不增加隔离层刀路),或是怎么单独选中焊盘从而进行轮廓加工的?能否上图解释?

bluepowerwzh 发表于 2011-10-2 22:32:17

自己顶起来,程序最新截图:
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_681519D4VMB7.png
(原文件名:程序截图.png)

bluepowerwzh 发表于 2011-10-2 22:43:17

看来还有一个办法,就是不从ArtCam要处理的图片入手,而是从最终的G代码文件入手,

如果能够处理CopperCAM生成的G代码,从中除去那些重复的刀路不就行了么,说不定还可以优化G代码的走刀路径,从而减少加工时间呢?

我想这也是一个办法,是不是已经有了现成的优化G加工刀路的软件了?先搜索之……..

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_681528CJAWBP.png
(原文件名:1.png)



2011-10-02,今天早上突然有想到,在程序处理的时候,既然是描边,干脆在焊盘和走线周围都描边,这样导入ArtCAM中的是后可以对描边色进行统一的轮廓或者区域清除,这样就解决了原来生成的刀路有接缝的问题。程序功能改为“在焊盘周围描指定像素数的边,在连线周围描指定像素数的边”。这个指定的像素数就和你的刀头及你想走多少遍刀路有关系了,可以通过计算得到。

比如我的电路中设置的最小线距、最小点距均是20th,也就是0.508mm,用0.3x10的刀,走两遍就能清完,下刀0.1mm,走一遍的刀槽宽度是0.34mm,可以设行距为0.26mm,这样还有富余,可以保证可靠清除覆铜层。那么600dpi的电路图片,0.508mm是12个像素(0.508*600/25.4),实际上,这些数据不同太精确啦,在ArtCAM中改动设置,重生成刀路直接就能看到效果,根据效果再微调一下参数即可,我主要是为了说明原理。

bluepowerwzh 发表于 2011-10-2 22:52:55

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_681530C8NN4L.png
(原文件名:2.png)
这样生成描边图片的时候还要注意一个问题,如果电路中有不需要的孔洞最好提前处理一下,你看我的:
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_681533L9SXY6.png
(原文件名:3.png)
这样生成描边图片的时候还要注意一个问题,如果电路中有不需要的孔洞最好提前处理一下,你看我的:
图中我设了个大洞准备钻孔以后在板子上穿线用,但是也被描边了,结果和其他的描边融合到了一起,这样到ArtCAM中的时候就会多生成刀路(虽然没多少,也不影响电路效果)。我的办法就是提前从Bitmap中用背景色填充掉。

根据实际在Mach3中仿真运行计算时间,处理描边色用轮廓加工比区域清除要少用一点点加工时间也就是百分之1左右的时间吧。所以完全可以使用区域清除,这样出来的电路板看上去也清爽一点。
关于填充和描边的计算量,如果图片宽=W,高=H,填充N个像素的描边色,如果用填充方式,计算量为W*H*(2*N*2*N),而逐层描边的计算量为W*H*9*N,因此使用程序不同算法描边的时候会觉得时间相差较大。


现在来测试一下实际效果吧,我每次雕刻电路板在焊盘和走线周围走三刀,基本上可以满足焊接要求,现在我在走线周围走一刀,焊盘周围走三刀,首先正常用Artcam生成两刀刀路用Mach3仿真运行测出时间。然后再用程序生成描边,在Artcam中生成走线周围两刀、焊盘周围四刀的刀路,再测试时间。结果:

走线两刀,焊盘四刀(轮廓):393.955s

走线两刀,焊盘四刀(区域清除):403.652s

焊盘、走线均走两刀:266.866s

焊盘、走线均走三刀:359.414s

焊盘、走线均走四刀:428.583s

悲剧了!!竟然时间都差不多?难道一个电路中组要的刀路都用在了焊盘周围??

bluepowerwzh 发表于 2011-10-2 22:59:15

看结论,我的时间都浪费在做无用功上面了??有没有人能解释一下,现在我把软件也传上来,大家口来分析一下吧,
有没有别人解决我的问题?
点击此处下载 ourdev_681534HTNJU6.rar(文件大小:43K) (原文件名:main.rar)

bluepowerwzh 发表于 2011-10-2 23:04:20

我想,还有一个办法,既然用CopperCAM生成的刀路有重复的,那么就直接处理G代码吧,
把重复的刀路去掉就可以了。大家有没有人知道有软件可以优化G代码?还是真的我理解
的CopperCAM软件的操作有问题?

samkkk 发表于 2011-10-3 14:08:28

強大!mark!!

Argee 发表于 2011-10-3 19:50:59

按照LZ的方法,真的发现Copper-cam 确实处理的有问题。

记得以前煮茶村长好像写过个程序来优化copper-cam生成刀路,不过好像不是真对刀路重复,而是对刀路进行排序,减少空行。本坛搜搜吧。

看来玩雕刻,也得一丝不苟阿!!顶LZ一下,向你学习!

bluepowerwzh 发表于 2011-10-4 22:16:27

根据程序分析,增加焊盘周围的刀路,会大幅度增加加工时间,除非电路图中是走线比较多,焊盘比较少,如图焊盘周围的刀路远大于焊盘之间走线周围的刀路:
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_682235UBHC25.png
(原文件名:1.png)

那么如何减少雕刻pcb板的时间呢?我想主要是以下几点:

第一,   尽量减少刀路。要想减少刀路,那就要用最少刀路来保证线路有效地隔离。比方说走一刀也就可以有效隔离了,那么就用能使用的最大刀尖的刀走一遍。我的电路中设的是最小间距20th,也就是0.508mm,那么我用0.4x20的刀就比较接近了,下刀0.1,槽宽0.44,比最小间距也就小0.068mm(应该是可以忍受的吧?无非是线路粗一点),我原来用的是0.3x10的刀,下刀0.1mm,槽宽0.32,0.3x20的刀槽宽0.34,怎么都要走两刀。(具体数据可以在CopperCAM中配置刀具后得到)

但是这里面有个问题,走两刀的刀路可以通过二维轮廓或者区域清除得到,但是走一刀的刀路怎么弄呀,ArtCAM中有个“产生中心线”,但是我试试总是不行,生成的矢量看上去乱七八糟。如果用“产生边界”,然后”沿矢量加工”,倒是可以只走一刀,但是刀尖半径范围内的电路和焊盘都要清除掉了,哈哈,这就可以用我的程序的功能了,先描上稍小于刀尖半径宽度的边(如果正好等于刀尖半径,相邻电路的描边会闭合,不便于产生矢量,自己试试就知道了),再在外面产生矢量,然后沿矢量加工不就可以了么,这样就可以使用最大可用刀尖的刀具了。


第二,   尽量加快给进。我刚开始雕刻的时候使用的是0.3x20的刀,后来雕刻过程中发现,由于工作台即便是铣过之后,夹好pcb板也会有高有低的地方,每次我都找到最低的地方归零Z轴,这样可以保证每个地方都能可靠雕刻,但是就有一个问题,下刀深的地方刀槽会因为刀尖的角度而变宽,为了尽量减小这种因为下刀深度对刀槽宽度的影响,我又选择了全角小的刀具0.3x10的刀,这种刀下刀深一点也没太大影响,但是问题又来了,小角度刀具如果走得快了或者下得深了非常容易断刀,我因此废了7、8把刀,最后把给进值降下来了,但速度下来了就不爽了,真是个两难的问题。


第三,   我是希望一遍加工完最好不换刀的,这样省事儿,实际上要想最省时间,还是要换刀的,先用小刀尖的雕两遍,然后换大刀尖的增大隔离距离即可。


比较CopperCAM生成的G-code,可以看到,CopperCAM在是首先用最快速度的一半将刀尖降到材料表面,然后以给进值下切到进刀深度,然后再走刀,而ArtCAM是用刀具的下切速度直接降到下刀深度,然后走刀,应该是CopperCAM更适合做电路板雕刻,而ArtCAM是比较可靠的走刀方法。CopperCAM的走刀方法遇到材料表面不平(Z轴零点低于材料表面)的就有断刀的危险,否则就会效率比较高。还有就是CopperCAM中刀具在安全高度的移动速度总是F3000(50mm/s),从安全高度到材料表面总是F1500(25mm/s),雕刻速度Engraving Speed可以修改,下切速度Margin Speed是可以修改的。

hu7215 发表于 2011-10-7 21:02:49

学习

bluepowerwzh 发表于 2011-12-24 22:43:59

难道真的就没有人能解决最简刀路的问题?

Onsunsl 发表于 2012-4-6 19:22:03

不错的帖子,收藏了

cqwp1211 发表于 2012-10-6 08:29:17

楼主真强人呀,但我不懂。学习来的。顶你{:handshake:}
页: [1]
查看完整版本: 雕刻PCB,你是怎样做的?如何解决想在焊盘周围多雕几道以方便焊接的问题