From 2f1c7daa0aa65d9078b162ad1024f36e2b57d76c Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 25 Oct 2024 17:52:17 +0200 Subject: [PATCH] Export wide coil specimens --- make_wide_coils.py | 100 +++++++++++++++++++++++++++++++++++ twisted_coil_gen_twolayer.py | 5 +- 2 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 make_wide_coils.py diff --git a/make_wide_coils.py b/make_wide_coils.py new file mode 100644 index 0000000..2654ade --- /dev/null +++ b/make_wide_coils.py @@ -0,0 +1,100 @@ +#!/bin/sh + +import math +import subprocess +import tempfile + +from gerbonara import utils +from gerbonara.cad.kicad import pcb as kicad_pcb +from gerbonara.cad.kicad import graphical_primitives as kicad_gr +from gerbonara.cad.kicad import footprints as kicad_fp + +outer_dias = [40, 65, 90] + +nks = [[(1, 150), + (1, 300), + (1, 480)], + [(53, 50), + (53, 100), + (53, 160)], + [(53, 100), + (53, 200), + (53, 320)], + [(53, 150), + (53, 300), + (53, 480)], + [(53, 1), + (53, 1), + (53, 1)]] + +def make_pad(x, y, side, w, h, **kwargs): + f = kicad_fp.Footprint(name=f'conn_gen_01x{n}', _version=None, generator=None, at=kicad_fp.AtPos(x, y, 0), **kwargs) + + for i in range(n): + f.pads.append(kicad_fp.Pad( + layers=['F.Mask', 'F.Cu'] if side == 'top' else ['B.Mask', 'B.Cu'], + number=str(i+1), + type=kicad_fp.Atom.smd, + shape=kicad_fp.Atom.rect, + at=kicad_fp.AtPos(0, 0, 0), + size=kicad_fp.XYCoord(w, h), + footprint=f)) + + return f + +for case_num, nk in enumerate(nks, start=1): + board_out = kicad_pcb.Board.empty_board() + + for (i, d2), (n, k) in zip(enumerate(outer_dias), nk): + d1 = d2 - 15 + + with tempfile.NamedTemporaryFile(suffix='.kicad_pcb') as f: + args = 'python twisted_coil_gen_twolayer.py --circle-segments 331 --trace-width 0.13 --via-drill 0.3 --via-diameter 0.6 --via-offset 0.3'.split() + [ + '--pcb', f.name, + '--turns', str(n), '--twists', str(k), + '--inner-diameter', str(d1), '--outer-diameter', str(d2), + ] + + if k > 100: + args += ['--stagger-inner-vias', '--stagger-outer-vias', '--via-offset', '0.4'] + + subprocess.run(args, check=True) + + for obj in kicad_pcb.Board.open(f.name).objects(): + board_out.add(obj) + + board_out.add(kicad_gr.Text(text=f'case {case_num} n={n} k={k}\\nd={d1:.1f}-{d2:.2f}mm\\nt=0.15mm', + at=kicad_gr.AtPos(0, (d1+d2)/2/2), layer=kicad_gr.TextLayer('F.SilkS'))) + + # Slots + if i < len(outer_dias)-1: + na = 8 + r2 = d2/2 + r = r2 + 2.5 + aw = 2*math.asin(3 / 2 / r) + for j in range(na): + start = utils.rotate_point(r, 0, (j+1)*2*math.pi/na - aw/2) + end = utils.rotate_point(r, 0, j*2*math.pi/na + aw/2) + arc = kicad_gr.Arc(end=end, center=(0, 0), start=start, stroke=kicad_gr.Stroke(width=1.2), layer='Edge.Cuts') + board_out.add(arc) + + # Connecting pads + board_out.add(make_pad(d2/2+1, 0, 'top', 2, 0.7)) + board_out.add(make_pad(d2/2+1, 0, 'bottom', 2, 0.7)) + board_out.add(kicad_pcb.TrackSegment(start=kicad_pcb.XYCoord(d2/2, 0), end=kicad_pcb.XYCoord(d2/2+1, 0), width=0.15, layer='F.Cu')) + board_out.add(kicad_pcb.TrackSegment(start=kicad_pcb.XYCoord(d2/2, 0), end=kicad_pcb.XYCoord(d2/2+1, 0), width=0.15, layer='B.Cu')) + + # Circular board outline + board_out.add(kicad_gr.Circle(center=kicad_gr.XYCoord(0, 0), end=kicad_gr.XYCoord(d2/2+5, 0), layer='Edge.Cuts')) + + # Silk crosshairs + r = d2/2 * math.sin(math.pi/4) + board_out.add(kicad_gr.Line(start=kicad_gr.XYCoord(-r, -r), end=kicad_gr.XYCoord(r, r), layer='F.SilkS')) + board_out.add(kicad_gr.Line(start=kicad_gr.XYCoord(r, -r), end=kicad_gr.XYCoord(-r, r), layer='F.SilkS')) + board_out.add(kicad_gr.Line(start=kicad_gr.XYCoord(-r, -r), end=kicad_gr.XYCoord(r, r), layer='B.SilkS')) + board_out.add(kicad_gr.Line(start=kicad_gr.XYCoord(r, -r), end=kicad_gr.XYCoord(-r, r), layer='B.SilkS')) + r = d2/2 + board_out.add(kicad_gr.Line(start=kicad_gr.XYCoord(0, r), end=kicad_gr.XYCoord(0, -r), layer='B.SilkS')) + board_out.add(kicad_gr.Line(start=kicad_gr.XYCoord(r, 0), end=kicad_gr.XYCoord(-r, 0), layer='B.SilkS')) + + board_out.write(f'wide_coil_{case_num}.kicad_pcb') diff --git a/twisted_coil_gen_twolayer.py b/twisted_coil_gen_twolayer.py index 2e02e69..414f574 100644 --- a/twisted_coil_gen_twolayer.py +++ b/twisted_coil_gen_twolayer.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import warnings import subprocess import sys import math @@ -714,7 +715,7 @@ def generate(outfile, turns, outer_diameter, inner_diameter, via_diameter, via_d # Check if the vias of the inner ring are so large that they would overlap if inner_via_angle*twists > (4*pi if stagger_inner_vias else 2*pi): min_dia = 2*((via_diameter + clearance) / (2*sin(pi / twists * (2 if stagger_inner_vias else 1))) + via_offset) - raise click.ClickException(f'Error: Overlapping vias in inner via ring. Calculated minimum inner diameter is {min_dia:.2f} mm.') + warnings.warn(f'Overlapping vias in inner via ring. Calculated minimum inner diameter is {min_dia:.2f} mm.') pitch = clearance + trace_width t, _, b = layer_pair.partition(',') @@ -866,7 +867,7 @@ def generate(outfile, turns, outer_diameter, inner_diameter, via_diameter, via_d x = inverse[i]*floor(2*sweeping_angle / (2*pi)) * 2*pi (x0, y0), (xn, yn), clen = do_spiral(0, outer_radius, inner_radius, start_angle, fold_angle, (x + start_angle)/total_angle, (x + fold_angle)/total_angle, circle_segments) if two_layer: - do_spiral(1, inner_radius, outer_radius, fold_angle, end_angle, (x + fold_angle)/total_angle, (x + end_angle)/total_angle) + do_spiral(1, inner_radius, outer_radius, fold_angle, end_angle, (x + fold_angle)/total_angle, (x + end_angle)/total_angle, circle_segments) else: dr = outer_radius - inner_radius xq = xn + cos(fold_angle) * dr