{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "\n", "import matplotlib.pyplot as plt\n", "from skspatial.objects import LineSegment, Line, Vector\n", "\n", "from enum import Enum\n", "Layer = Enum(\"Layer\", \"FRONT BACK\")\n", "\n", "from helpers import *\n", "from pcb_json import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Parameters \n", "edit those:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Track width and spacing\n", "TRACK_WIDTH = 0.127\n", "TRACK_SPACING = 0.127\n", "\n", "# via defaults\n", "VIA_DIAM = 0.8\n", "VIA_DRILL = 0.4\n", "\n", "# this is for a 1.27mm pitch pin\n", "PIN_DIAM = 1.0\n", "PIN_DRILL = 0.65\n", "\n", "SCREW_HOLE_DRILL_DIAM = 2.3 # 2.3mm drill for a 2mm screw\n", "\n", "# this is for the PCB connector - see https://www.farnell.com/datasheets/2003059.pdf\n", "PAD_WIDTH = 3\n", "PAD_HEIGHT = 2\n", "PAD_PITCH = 2.5\n", "\n", "# how to connect coils\n", "PAD_ENABLE = False\n", "CONNECT_WITH_VIAS = True\n", "\n", "# NET Naming\n", "COIL_NET_NAME = \"coil\" \n", "USE_INDIVIDUAL_NET_NAMES_PER_COIL = False # appends numbering to COIL_NET_NAME\n", "USE_ABC_NET_NAMES_FOR_COILS = True # appends A,B,C to COIL_NET_NAME\n", "\n", "# draw on edge cuts:\n", "PCB_EDGE_CUTS = False\n", "\n", "LAYERS = 4\n", "\n", "# Geometry RADIUS_\n", "# -------------------------------------------------\n", "RADIUS_STATOR_HOLE = 20 # 14\n", "RADIUS_CONNECTIONS_INSIDE = RADIUS_STATOR_HOLE + 3 * TRACK_SPACING # for connecting the bottoms of the coils\n", "\n", "RADIUS_COIL_START = 33\n", "RADIUS_COIL_CENTER = 38\n", "RADIUS_COIL_CENTER_VIA = RADIUS_COIL_CENTER + 0.5\n", "RADIUS_COIL_END = 40\n", "\n", "RADIUS_CONNECTIONS_OUTSIDE = 53\n", "RADIUS_CONNECTOR = 53\n", "\n", "RADIUS_TOTAL_STATOR = 55\n", "\n", "SCREW_HOLE_RADIUS = RADIUS_TOTAL_STATOR # where to put the mounting pins\n", "\n", "# many coils (are placed ccw)\n", "NUM_SEGMENTS = 12\n", "NUM_COILS = 12\n", "\n", "ROTATION = 0\n", "\n", "space = RADIUS_COIL_START * np.sin(np.deg2rad(360 / NUM_COILS / 2)) \n", "TURNS = int(space / (TRACK_SPACING+TRACK_WIDTH))\n", "\n", "FILE_NAME = f\"coil_motor_{RADIUS_TOTAL_STATOR}mm.json\"\n", "\n", "# meta helper\n", "coil_windings_width = TURNS * (TRACK_WIDTH+TRACK_SPACING)\n", "radius_coil_start_effective = round(RADIUS_COIL_START - coil_windings_width, 2)\n", "radius_coil_end_effective = round(RADIUS_COIL_END + coil_windings_width,2)\n", "\n", "print(TURNS)\n", "print(f\"Effective radius range: {radius_coil_start_effective} - {radius_coil_end_effective}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Arbitrary Coil Generation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# templates must be convex, simetric around the X axis and must include the center points on both size (e.g. (X1, 0).... (X2, 0) )\n", "template = [\n", " (-3.5, 0),\n", " (-3.5, -0.01),\n", " (1.9, -1.45),\n", " (1.9, 0.0),\n", " (1.9, 1.45),\n", " (-3.5, 0.01),\n", "]\n", "\n", "def plot_points(template):\n", " df = pd.DataFrame(template, columns=[\"x\", \"y\"])\n", " ax = df.plot.line(x=\"x\", y=\"y\", color=\"blue\")\n", "\n", " scatter_df = pd.DataFrame(template, columns=[\"x\", \"y\"])\n", " scatter_df.plot.scatter(x=\"x\", y=\"y\", color=\"red\", ax=ax)\n", "\n", " ax.axis(\"equal\")\n", " plt.grid(True)\n", " \n", " ax.text(0.05, 0.95, f\"len= {len(template)}\", transform=ax.transAxes, ha=\"left\")\n", "\n", "plot_points(template)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def calculate_point(point, p_here, p_next, spacing, turn):\n", " vector = Vector(p_here) - Vector(p_next)\n", " normal = vector / np.linalg.norm(vector)\n", " normal = np.array([-normal[1], normal[0]]) # rotate 90 degrees\n", "\n", " reference_vector = Vector([-100, 0])\n", " angle = np.rad2deg(Vector(point).angle_between(reference_vector))\n", " if point[1] > 0:\n", " angle = 360 - angle\n", "\n", " # move the point along the normal vector by the spacing\n", " offset = spacing * (turn * 360 + angle) / 360\n", " coil_point = point + normal * offset\n", " return (coil_point[0], coil_point[1])\n", "\n", "\n", "def get_coil(template, turns, spacing):\n", " coil_points = []\n", " reference_vector = Vector([-100, 0])\n", "\n", " for turn in range(turns):\n", " for index in range(len(template)):\n", " p_here = template[index]\n", " turn_here = turn\n", "\n", " p_next = template[(index + 1) % len(template)]\n", "\n", " turn_here = turn\n", " turn_next = (turn * len(template) + index + 1) // len(template)\n", "\n", " coil_p_here = calculate_point(p_here, p_here, p_next, spacing, turn_here)\n", " coil_p_next = calculate_point(p_next, p_here, p_next, spacing, turn_next)\n", "\n", " if len(coil_points) >= 2:\n", " \n", " line1 = Line(\n", " coil_points[-2],\n", " np.array(coil_points[-1]) - np.array(coil_points[-2]),\n", " )\n", " # create a line from the two new points\n", " line2 = Line(\n", " np.array(coil_p_here),\n", " np.array(np.array(coil_p_here) - np.array(coil_p_next)),\n", " )\n", "\n", " # find the intersection of the two lines\n", " try: # replace the previous point with the intersection\n", " intersection = line1.intersect_line(line2)\n", " coil_points[-1] = intersection\n", " except: # the lines did not intersect so just add the points\n", " coil_points.append(coil_p_here)\n", "\n", " coil_points.append(coil_p_next)\n", " else:\n", " coil_points.append(coil_p_here)\n", " coil_points.append(coil_p_next)\n", "\n", " return coil_points\n", "\n", "def coil(template): \n", " return get_coil(template, TURNS, TRACK_SPACING + TRACK_WIDTH)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Generate a single coil" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x_from = -3.5\n", "x_to = 1.9\n", "y_amp = 1.45\n", "\n", "radius_len = RADIUS_COIL_END - RADIUS_COIL_START\n", "\n", "angle = round(360/2/NUM_COILS,2)\n", "y_amp = round(np.sin(np.deg2rad(angle)) * radius_len, 2)\n", "x_len = round(np.cos(np.deg2rad(angle)) * radius_len, 2)\n", "\n", "x_to = RADIUS_COIL_END - RADIUS_COIL_CENTER\n", "x_from = x_to - x_len\n", "\n", "micro = 0.01 #1e-6\n", "template = [\n", " (x_from, 0),\n", " (x_from, -micro),\n", " (x_to, -y_amp),\n", " (x_to, 0.0),\n", " (x_to, y_amp),\n", " (x_from, +micro)\n", "]\n", "shape = [\n", " (x_from+x_len/2, -y_amp/2),\n", " (x_to, -y_amp*0.8),\n", " (x_to, 0),\n", " (x_from+x_len/2, +y_amp/2),\n", " (x_to, +y_amp*0.8),\n", "]\n", "shape = [\n", " (x_to, -y_amp),\n", " (x_to, 0.0),\n", " (x_to, y_amp),\n", "]\n", "# template = shape\n", "# template.insert(0, (x_from, 0))\n", "# template.insert(1, (x_from, -micro))\n", "# # # for i in range(len(shape)):\n", "# # # j = len(shape)-i-1\n", "# # # template.append([shape[j][0], -shape[j][1]])\n", "# template.append((x_from, +micro))\n", "if 1:\n", " print(template)\n", "\n", " plot_points(template)\n", " plot_points(optimize_points(coil(template)))\n", " plot_points(chaikin_(coil(template), 5))\n", "\n", " ###############\n", " template_f = []\n", " for i in range(len(template)):\n", " template_f.append(template[len(template) - i - len(template) // 2])\n", " # print(f\"i = {i}, map = {len(template) - i - len(template) // 2}, template_f = {template_f[i]}\")\n", "\n", " template_f = flip_x(template_f)\n", "\n", " points_top = chaikin_(flip_x(coil(template_f)), 5)\n", " points_bot = chaikin_(coil(template), 5)\n", "\n", " # add point to middle for via\n", " points_top = [(RADIUS_COIL_CENTER_VIA - RADIUS_COIL_CENTER, 0)] + points_top\n", " points_bot = [(RADIUS_COIL_CENTER_VIA - RADIUS_COIL_CENTER, 0)] + points_bot\n", "\n", " def plot_tracks_vias(track_points_top, track_points_bot, via_points=0):\n", "\n", " df = pd.DataFrame(track_points_top, columns=[\"x\", \"y\"])\n", " ax = df.plot.line(x=\"x\", y=\"y\", color=\"red\")\n", " df = pd.DataFrame(track_points_bot, columns=[\"x\", \"y\"])\n", " ax = df.plot.line(x=\"x\", y=\"y\", color=\"blue\", ax=ax)\n", "\n", " if via_points:\n", " scatter_df = pd.DataFrame(via_points, columns=[\"x\", \"y\"])\n", " scatter_df.plot.scatter(x=\"x\", y=\"y\", color=\"green\", ax=ax)\n", "\n", " ax.axis(\"equal\")\n", " plt.grid(True)\n", " ax.text(0.05, 0.95, f\"len= {len(template)}\", transform=ax.transAxes, ha=\"left\")\n", "\n", "\n", " plot_tracks_vias(points_top, points_bot, 0)\n", "\n", "\n", "# Compute Track Length, estimate resistance and print\n", "def compute_track_length(points):\n", " track_length = 0\n", " for i in range(len(points) - 1):\n", " track_length += np.linalg.norm(np.array(points[i + 1]) - np.array(points[i]))\n", " return round(track_length,2)\n", "\n", "def compute_pcb_track_resistance(length_mm, track_width_mm, copper_thickness_mm=0.035, resistivity=1.68e-8):\n", " cross_sectional_area_m2 = (track_width_mm / 1000.0) * (copper_thickness_mm / 1000.0)\n", " resistance_ohms = resistivity * (length_mm / 1000.0) / cross_sectional_area_m2\n", " return round(resistance_ohms,2)\n", "\n", "length = compute_track_length(points_top+points_bot)\n", "resistance = compute_pcb_track_resistance(length, TRACK_WIDTH)\n", "\n", "#print(f\"Result with 2coils in series: {round(length)} mm, resistance: {resistance} \\u03A9\")\n", "resistance /= 2 #another pair of coils in parrallel\n", "print(f\"with 2x2coils (2 in series: {round(length)} mm) and of those 2 in parallel resistance: {resistance} \\u03A9\")\n", "\n", "used_voltage = 5 # V\n", "print(f\"With a voltage of {used_voltage} V, the maximum current is {round(used_voltage / resistance,2)} A\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Reproduce coils" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vias = []\n", "tracks_top = []\n", "tracks_bot = []\n", "pads = []\n", "pins = []\n", "mounting_holes = []\n", "silk = []\n", "components = []\n", "\n", "arc_seg = 360 / NUM_COILS\n", "\n", "USE_LABELS = False #todo\n", "\n", "def angleAt(coil_index):\n", " return coil_index * arc_seg + ROTATION\n", "\n", "def place_coil(coil_points, angle, radius):\n", " return translate(rotate(coil_points, angle), radius, angle)\n", "\n", "# def appendTo(tracks_obj, name, pts):\n", "# tracks_obj.append({\"net\": name, \"pts\": pts})\n", " \n", "# the main coils\n", "coil_labels = [\"A\", \"B\", \"C\"]\n", "coils_top = []\n", "coils_bot = []\n", "for i in range(NUM_SEGMENTS):\n", " angle = angleAt(i)\n", " radius = RADIUS_COIL_CENTER\n", " if (i // 3) % 2 == 0:\n", " coil_top = place_coil(points_top, angle, radius)\n", " coil_bot = place_coil(points_bot, angle, radius)\n", " else:\n", " # slightly nudge the coils so that they don't overlap when flipped\n", " coil_top = place_coil(flip_y(points_top), angle, radius)\n", " coil_bot = place_coil(flip_y(points_bot), angle, radius)\n", " \n", " coils_top.append(coil_top)\n", " coils_bot.append(coil_bot)\n", "\n", " name = COIL_NET_NAME + \"_\"\n", " if USE_INDIVIDUAL_NET_NAMES_PER_COIL:\n", " name += str(i).zfill(2)\n", " if USE_ABC_NET_NAMES_FOR_COILS:\n", " name += coil_labels[i % 3]\n", "\n", " tracks_top.append({\"net\": name, \"pts\": coil_top})\n", " tracks_bot.append({\"net\": name, \"pts\": coil_bot})\n", " \n", " vias.append(create_via(pol2cat(angle, RADIUS_COIL_CENTER_VIA), name))\n", " silk.append(create_silk(pol2cat(angle, RADIUS_COIL_CENTER), coil_labels[i % 3]))\n", " # silk.append(create_silk(pol2cat(angle, RADIUS_TOTAL_STATOR), coil_labels[i % 3]))\n", " silk.append(create_silk(pol2cat(angle+1.5, radius_coil_end_effective+2), coil_labels[i % 3]))\n", "\n", "if 1:\n", " via_points = []\n", " for via in vias:\n", " via_points.append([via[\"x\"], via[\"y\"]])\n", "\n", " track_points_top = []\n", " for t in tracks_top:\n", " for p in t[\"pts\"]:\n", " track_points_top.append(p)\n", "\n", " track_points_bot = []\n", " for t in tracks_bot:\n", " for p in t[\"pts\"]:\n", " track_points_bot.append([p[0], p[1]])\n", " \n", " plot_tracks_vias(track_points_top, track_points_bot, via_points)\n", " \n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Create coil inner connections" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# all ___At functions are little helpers that take coil_index + sometimes radius\n", "def pointAt(coil_index, radius):\n", " return pol2cat(angleAt(coil_index), radius)\n", "\n", "def nameAt(coil_index):\n", " name = COIL_NET_NAME\n", " if USE_ABC_NET_NAMES_FOR_COILS:\n", " name += coil_labels[coil_index % 3]\n", " return name\n", "\n", "def appendAt(coils_ref, coil_index, radius):\n", " coils_ref[coil_index].append(pointAt(coil_index, radius))\n", "\n", "def appendVia(coil_index, radius):\n", " vias.append(create_via(pointAt(coil_index, radius), nameAt(coil_index)))\n", "\n", "radius_coni_common = RADIUS_CONNECTIONS_INSIDE\n", "\n", "# connects coils with arc and uses last points of coils to connect to the arc\n", "def connect_coils_auto_arc(c1, c2 , tracks_ref, radius):\n", " tracks_ref.append({\n", " \"net\": nameAt(c1),\n", " \"pts\": (\n", " [coils_bot[c1][-1]]\n", " + draw_arc(angleAt(c1), angleAt(c2), radius)\n", " + [coils_bot[c2][-1]] )}) \n", " \n", "def connect_coils_with_arc(c1, c2 , tracks_ref, radius, radius_points):\n", " pts = draw_arc(angleAt(c1), angleAt(c2), radius)\n", "\n", " if radius_points != 0:\n", " pts = [pointAt(c1, radius_points)] + pts + [pointAt(c2, radius_points)]\n", "\n", " tracks_ref.append({\n", " \"net\": nameAt(c1),\n", " \"pts\": pts}) \n", " \n", " appendAt(coils_top, c1, radius)\n", " appendAt(coils_top, c2, radius)\n", "\n", " # append vias everywhere to connect middle layers properly in parallel.\n", " appendVia(c1, radius)\n", " appendVia(c2, radius)\n", "\n", "if 1: # create coil ic = inner connections\n", "\n", " space = 5 * TRACK_SPACING \n", "\n", " radius_coni_A = radius_coni_common + 3 * space + VIA_DIAM / 2\n", " for c in range(0, 12, 3):\n", " point = pointAt(c, radius_coni_A)\n", " coils_bot[c].append(point)\n", " vias.append(create_via(point, nameAt(c)))\n", " for con in range(2):\n", " connect_coils_auto_arc(con*6+0, con*6+3, tracks_top, radius_coni_A)\n", " \n", " radius_coni_B = radius_coni_common\n", " for c in range(1, 12, 3):\n", " point = pointAt(c, radius_coni_B)\n", " coils_bot[c].append(point)\n", " vias.append(create_via(point, nameAt(c)))\n", " for con in range(2):\n", " connect_coils_auto_arc(con*6+1, con*6+4, tracks_bot, radius_coni_B)\n", " \n", " radius_coni_C = radius_coni_common + 2 * space - VIA_DIAM / 2\n", " for c in range(2, 12, 3):\n", " point = pointAt(c, radius_coni_C)\n", " coils_bot[c].append(point)\n", " vias.append(create_via(point, nameAt(c)))\n", " for con in range(2):\n", " connect_coils_auto_arc(con*6+2, con*6+5, tracks_top, radius_coni_C)\n", "\n", "### OUTSIDE CONNECTIONS\n", "# ------------------------------------------------------------------------------------\n", "if 1:\n", " # connects the middle/star point\n", " r = RADIUS_CONNECTIONS_OUTSIDE\n", " r_inc = - 5 * TRACK_SPACING \n", "\n", " connect_coils_with_arc(9, 11, tracks_top, r, 0)\n", " appendAt(coils_top, 10, r)\n", " appendVia(10, r)\n", "\n", " r += r_inc\n", " connect_coils_with_arc(3, 6, tracks_top, r, 0)\n", "\n", " r += r_inc\n", " connect_coils_with_arc(4, 7, tracks_bot, r, 0)\n", "\n", " r += r_inc\n", " connect_coils_with_arc(5, 8, tracks_bot, r, 0,)\n", "\n", "# create the pads for connecting the inputs to the coils\n", "if PAD_ENABLE:\n", "\n", " def appendSilk(y, text, size=1, angle=0):\n", " silk.append(create_silk((RADIUS_CONNECTOR - PAD_HEIGHT - 2.5, y), text, \"f\", 2.5, -900))\n", "\n", " appendSilk(+PAD_PITCH, \"C\")\n", " appendSilk( 0, \"B\")\n", " appendSilk(-PAD_PITCH, \"A\")\n", " \n", " def appendPad(y, name):\n", " pads.append(create_pad([RADIUS_CONNECTOR, y], PAD_WIDTH, PAD_HEIGHT, \"a\", name))\n", " \n", " appendPad(+PAD_PITCH, nameAt(0))\n", " appendPad(0, nameAt(1))\n", " appendPad(-PAD_PITCH, nameAt(2))\n", "\n", " # connect coil A to the top pad\n", " pad_connection_point_x = RADIUS_CONNECTOR\n", " pad_angle = np.rad2deg(np.arcsin(PAD_PITCH / pad_connection_point_x))\n", " coils_top[0].append(pointAt(0, pad_connection_point_x))\n", " appendVia(0, pad_connection_point_x)\n", "\n", " # connect coil B to the middle pad\n", " coils_top[1].append((pad_connection_point_x + PAD_WIDTH / 2 + VIA_DIAM / 2, 0))\n", " vias.append(create_via(\n", " ((pad_connection_point_x + PAD_WIDTH / 2 + VIA_DIAM / 2, 0)), nameAt(1)))\n", " \n", " # connect coil C to the bottom pad\n", " coils_top[2].append(pointAt(2, pad_connection_point_x))\n", " appendVia(2, pad_connection_point_x)\n", "\n", "elif CONNECT_WITH_VIAS:\n", " for i in range(3):\n", " appendAt(coils_top, i, RADIUS_CONNECTOR)\n", " appendVia(i, RADIUS_CONNECTOR)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Multi-Layer" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# if we are doing multiple layers then duplicate the front and back layers\n", "tracks_in = []\n", "if LAYERS >= 4:\n", " tracks_in.append(tracks_bot.copy())\n", " tracks_in.append(tracks_top.copy())\n", "if LAYERS >= 6:\n", " tracks_in.append(tracks_bot.copy())\n", " tracks_in.append(tracks_top.copy())\n", "if LAYERS == 8:\n", " tracks_in.append(tracks_bot.copy())\n", " tracks_in.append(tracks_top.copy())" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Generate JSON" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Generate the JSON output file\n", "if PAD_ENABLE:\n", " # these final bits of wiring up to the input pads don't need to be duplicated\n", " tracks_bot.append({\n", " \"net\": COIL_NET_NAME,\n", " \"pts\": [\n", " (pad_connection_point_x + PAD_WIDTH / 2, 0),\n", " (pad_connection_point_x, 0),\n", " ],\n", " })\n", " tracks_bot.append({\n", " \"net\": COIL_NET_NAME,\n", " \"pts\": draw_arc(angleAt(0), -pad_angle, pad_connection_point_x, 1),\n", " })\n", " tracks_bot.append({\n", " \"net\": COIL_NET_NAME,\n", " \"pts\": draw_arc(angleAt(2), pad_angle, pad_connection_point_x, 1),\n", " })\n", "\n", "nibble_angle_size = 360 * SCREW_HOLE_DRILL_DIAM / (2 * np.pi * RADIUS_TOTAL_STATOR)\n", "\n", "if PCB_EDGE_CUTS:\n", " outer_cuts = (\n", " draw_arc(\n", " -45 + nibble_angle_size / 2, 45 - nibble_angle_size / 2, RADIUS_TOTAL_STATOR, 5\n", " )\n", " + translate(\n", " rotate(draw_arc(5, 175, SCREW_HOLE_DRILL_DIAM / 2, 5)[::-1], 135),\n", " RADIUS_TOTAL_STATOR,\n", " 45,\n", " )\n", " + draw_arc(\n", " 45 + nibble_angle_size / 2, 135 - nibble_angle_size / 2, RADIUS_TOTAL_STATOR, 5\n", " )\n", " + translate(\n", " rotate(draw_arc(5, 175, SCREW_HOLE_DRILL_DIAM / 2, 5), 225)[::-1],\n", " RADIUS_TOTAL_STATOR,\n", " 135,\n", " )\n", " + draw_arc(\n", " 135 + nibble_angle_size / 2, 225 - nibble_angle_size / 2, RADIUS_TOTAL_STATOR, 5\n", " )\n", " + translate(\n", " rotate(draw_arc(5, 175, SCREW_HOLE_DRILL_DIAM / 2, 5), 315)[::-1],\n", " RADIUS_TOTAL_STATOR,\n", " 225,\n", " )\n", " + draw_arc(\n", " 225 + nibble_angle_size / 2, 315 - nibble_angle_size / 2, RADIUS_TOTAL_STATOR, 5\n", " )\n", " + translate(\n", " rotate(draw_arc(5, 175, SCREW_HOLE_DRILL_DIAM / 2, 5), 45)[::-1],\n", " RADIUS_TOTAL_STATOR,\n", " 315,\n", " )\n", " )\n", "\n", " edge_cuts = [\n", " outer_cuts,\n", " draw_arc(0, 360, RADIUS_STATOR_HOLE, 1),\n", " ]\n", "else:\n", " edge_cuts = []\n", "\n", "# dump out the json version\n", "json_result = dump_json(\n", " filename=FILE_NAME,\n", " track_width=TRACK_WIDTH,\n", " pin_diam=PIN_DIAM,\n", " pin_drill=PIN_DRILL,\n", " via_diam=VIA_DIAM,\n", " via_drill=VIA_DRILL,\n", " vias=vias,\n", " pins=pins,\n", " pads=pads,\n", " silk=silk,\n", " tracks_f=tracks_top,\n", " tracks_in=tracks_in,\n", " tracks_b=tracks_bot,\n", " mounting_holes=mounting_holes,\n", " edge_cuts=edge_cuts,\n", " components=components,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot_json(json_result, 70)\n", "print(json_result['parameters'])\n", "\n", "print(TURNS)\n", "print(f\"Effective radius range: {radius_coil_start_effective} - {radius_coil_end_effective}\")" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.6" }, "vscode": { "interpreter": { "hash": "97df458a008df4bb35f481235dd1a04940c0d868e77540a7386d9922f34deb97" } } }, "nbformat": 4, "nbformat_minor": 2 }