PCB genesis大孔加小孔(即卸力孔)实现方法
一.为什么 大孔中要加小孔(即卸力孔)
这其实跟钻刀的排屑有关了,当钻刀越大孔,排屑量也越大(当然这也得跟转速,下刀速的参数有关系),通常当钻刀越大,转速越慢,下刀速也越慢(因为要保证它的排屑通畅)。
这里科普一下钻刀的【进刀速度】,【转速】,【进刀量】之间的关系是怎样的.
进刀速度、转速之间的关系对于钻头来讲,切削量越大,产生的粉尘颗粒就会更大,部分切屑尤其是铜丝,会缠绕到钻头,从而严重影响孔壁的质量。相应的,切削量越小,在钻孔时,钻头停留在孔内的时间就会越长,产生的钻污就会越多。
进刀量、转速之间的关系如果转速太高,会导致线速度增大。从而影响钻头的平稳性和动态平衡性。合适的参数可以达到合理的切削性,保证下钻过程中受力对准度和均匀性。反之会影响孔壁的凹凸度,还会产生渗铜
为了保证大孔的排屑性能好,PCB行业作法是,在钻大孔之前,提前在大孔中间钻几个小孔,先让小孔排除一定孔屑,等再钻大孔时,孔屑变少了。不会再造成大孔排屑不畅。
二.大孔加小孔实现原理
求解方法:(具体可以看下方函数)
1.通过已知大孔6.0mm,小孔与小孔间距:0.2mm
小孔个数,求出最大内切孔尺寸=2.585mm
2.最大内切孔2.585mm,向下取整 钻刀为2.55mm
3. 求大圆中心到小圆中心距离
(6-0.1*2-2.55)*0.5=1.625mm
4.以大圆为中心,并3个小孔的以圆心角为120度依次旋转,即可得到3个小圆坐标
三.C#简易代码实现:
1.大孔加小孔代码
#region 大孔加卸力孔 ydkdrl List<gP> MaxHoleList = glayer.Plist.Where(tt => tt.width >= 3200 && tt.width <= 6300).ToList(); if (MaxHoleList.Count() > 0) { for (int i = 0; i < MaxHoleList.Count; i++) { //求内切孔函数共6参数 大孔尺寸 小孔尺寸 小孔个数 小孔与小孔间距 小孔与大孔间距 旋转角度 //当小孔尺寸不填,由函数自动计算小孔孔径,否则以填写小孔孔径为准 List<gP> smallHoleList = calc2.p_small_hole_Plist(MaxHoleList[i], 0, 3, 0.2, 0.1,30); addCOM.pad(smallHoleList); } } #endregion
2.计算函数(关键在于此函数实现)
/// <summary> /// 求点P【内切圆Plist坐标】 /// </summary> /// <param name="p">点P</param> /// <param name="small_hole_size">内切圆尺寸,填写为0时自动计算</param> /// <param name="small_hole_count">内切圆个数</param> /// <param name="small2small">内切圆与内切圆间距</param> /// <param name="small2big">内切圆与外圆间距</param> /// <param name="ang_rotate">内切圆转旋角度</param> /// <param name="units">单位:mm/inch</param> /// <returns>返回:【内切圆Plist坐标】</returns> public List<gP> p_small_hole_Plist(gP p, double small_hole_size, double small_hole_count = 3, double small2small = 0, double small2big = 0, double ang_rotate = 0) { List<gP> list_p = new List<gP>(); double ang_single, ang_sum, dia_hole; gP tempP; tempP.mirror = false; tempP.attribut = ""; tempP.angle = 0; tempP.negative = false; tempP.symbols = ""; dia_hole = p.width / 1000 - small2big * 2; //units mm p.width = p.width - small2big * 2000; //units um if (small_hole_size < 0.001) small_hole_size = Math.Floor(p_small_hole_size(p, small2small, small_hole_count) / 0.05) * 0.05; //um-->mm ang_single = 360 / small_hole_count; ang_sum = 90 - ang_rotate; for (int i = 0; i <= small_hole_count - 1; i++) { tempP.p = p_val_ang(p.p, (dia_hole - small_hole_size) * 0.5, ang_sum); tempP.width = small_hole_size * 1000; tempP.symbols = "r" + tempP.width.ToString(); ang_sum += ang_single; list_p.Add(tempP); } return list_p; } /// <summary> /// 求点P【最大内切圆尺寸】 /// </summary> /// <param name="p">点P</param> /// <param name="small_hole_space">内切圆与内切圆间距</param> /// <param name="small_hole_count">内切圆个数</param> /// <returns>返回:【内切圆尺寸】</returns> public double p_small_hole_size(gP p, double small_hole_space = 0, double small_hole_count = 3) { double sin_val = Math.Sin(180 / small_hole_count * Math.PI / 180); return (sin_val * p.width * 0.0005 - 0.5 * small_hole_space) / (1 + sin_val) * 2; } /// <summary> /// 求增量坐标 /// </summary> /// <param name="ps">起点</param> /// <param name="val">增量值</param> /// <param name="ang_direction">角度</param> /// <returns></returns> public gPoint p_val_ang(gPoint ps, double val, double ang_direction) { gPoint pe; pe.x = ps.x + val * Math.Cos(ang_direction * Math.PI / 180); pe.y = ps.y + val * Math.Sin(ang_direction * Math.PI / 180); return pe; }