Added support for LED ring

Changed larger PCB radius option from 30mm to 35mm
Added 60 LEDs in a ring
Added KiCad PCB template for a 12 coil 8 layer 70mm OD 20mm ID PCB with 60 LEDs
Added option to set net of each track, via and pad
Added option to set width of each track
This commit is contained in:
robdobsn 2023-02-03 22:11:44 +00:00
parent 7bde6ea9f3
commit 5fac72557d
5 changed files with 4477 additions and 196 deletions

File diff suppressed because one or more lines are too long

View file

@ -66,7 +66,10 @@
"PAD_PITCH = 2.5\n",
"\n",
"STATOR_HOLE_RADIUS = 5.5\n",
"HOLE_SPACING = 0.25"
"HOLE_SPACING = 0.25\n",
"\n",
"# Coils net name\n",
"COIL_NET_NAME = \"coils\""
]
},
{
@ -320,9 +323,9 @@
"\n",
" tracks_f.append(coil_A_f)\n",
" tracks_b.append(coil_A_b)\n",
" vias.append(create_via(get_arc_point(angle, COIL_VIA_RADIUS)))\n",
" vias.append(create_via(get_arc_point(angle, COIL_VIA_RADIUS)), COIL_NET_NAME)\n",
" silk.append(\n",
" create_silk(get_arc_point(angle, COIL_CENTER_RADIUS), coil_labels[i % 3])\n",
" create_silk(get_arc_point(angle, COIL_CENTER_RADIUS), coil_labels[i % 3], COIL_NET_NAME)\n",
" )\n",
"\n",
"# raidus for connecting the bottoms of the coils together\n",
@ -348,10 +351,10 @@
"coils_b[6].append(coil_A3_A4_inner[0])\n",
"coils_b[9].append(coil_A3_A4_inner[-1])\n",
"# add the vias to stitch them together\n",
"vias.append(create_via(coil_A1_A2_inner[0]))\n",
"vias.append(create_via(coil_A1_A2_inner[-1]))\n",
"vias.append(create_via(coil_A3_A4_inner[0]))\n",
"vias.append(create_via(coil_A3_A4_inner[-1]))\n",
"vias.append(create_via(coil_A1_A2_inner[0], COIL_NET_NAME))\n",
"vias.append(create_via(coil_A1_A2_inner[-1], COIL_NET_NAME))\n",
"vias.append(create_via(coil_A3_A4_inner[0], COIL_NET_NAME))\n",
"vias.append(create_via(coil_A3_A4_inner[-1], COIL_NET_NAME))\n",
"\n",
"# create tracks to link the B coils around the center - this can all be done on the bottom layer\n",
"coil_B1_B2_inner = draw_arc(coil_angles[1], coil_angles[4], connection_radius1)\n",
@ -376,10 +379,10 @@
"coils_b[8].append(coil_C3_C4_inner[0])\n",
"coils_b[11].append(coil_C3_C4_inner[-1])\n",
"# add the vias to stitch them together\n",
"vias.append(create_via(coil_C1_C2_inner[0]))\n",
"vias.append(create_via(coil_C1_C2_inner[-1]))\n",
"vias.append(create_via(coil_C3_C4_inner[0]))\n",
"vias.append(create_via(coil_C3_C4_inner[-1]))\n",
"vias.append(create_via(coil_C1_C2_inner[0]), COIL_NET_NAME)\n",
"vias.append(create_via(coil_C1_C2_inner[-1]), COIL_NET_NAME)\n",
"vias.append(create_via(coil_C3_C4_inner[0]), COIL_NET_NAME)\n",
"vias.append(create_via(coil_C3_C4_inner[-1]), COIL_NET_NAME)\n",
"\n",
"# connect the last three coils together\n",
"common_connection_radius = SCREW_HOLE_RADIUS - (SCREW_HOLE_DRILL_DIAM / 2 + 0.5)\n",
@ -404,13 +407,13 @@
"coils_f[4].append(get_arc_point(coil_angles[4], outer_connection_radius_B))\n",
"coils_f[7].append(get_arc_point(coil_angles[7], outer_connection_radius_B))\n",
"vias.append(\n",
" create_via(get_arc_point(4 * 360 / 12 + COIL_ROTATION, outer_connection_radius_B))\n",
" create_via(get_arc_point(4 * 360 / 12 + COIL_ROTATION, outer_connection_radius_B), COIL_NET_NAME)\n",
")\n",
"vias.append(\n",
" create_via(get_arc_point(7 * 360 / 12 + COIL_ROTATION, outer_connection_radius_B))\n",
" create_via(get_arc_point(7 * 360 / 12 + COIL_ROTATION, outer_connection_radius_B), COIL_NET_NAME)\n",
")\n",
"\n",
"# connect the outer C coilds together\n",
"# connect the outer C coils together\n",
"outer_connection_radius_C = outer_connection_radius_B - TRACK_SPACING - VIA_DIAM / 2\n",
"tracks_b.append(\n",
" draw_arc(\n",
@ -426,10 +429,10 @@
" get_arc_point(8 * 360 / 12 + COIL_ROTATION, outer_connection_radius_C)\n",
")\n",
"vias.append(\n",
" create_via(get_arc_point(5 * 360 / 12 + COIL_ROTATION, outer_connection_radius_C))\n",
" create_via(get_arc_point(5 * 360 / 12 + COIL_ROTATION, outer_connection_radius_C), COIL_NET_NAME)\n",
")\n",
"vias.append(\n",
" create_via(get_arc_point(8 * 360 / 12 + COIL_ROTATION, outer_connection_radius_C))\n",
" create_via(get_arc_point(8 * 360 / 12 + COIL_ROTATION, outer_connection_radius_C), COIL_NET_NAME)\n",
")\n",
"\n",
"# create the pads for connecting the inputs to the coils\n",
@ -441,21 +444,21 @@
" create_silk((INPUT_PAD_RADIUS - PAD_HEIGHT - 2.5, -PAD_PITCH), \"A\", \"b\", 2.5, -900)\n",
")\n",
"\n",
"pads.append(create_pad((INPUT_PAD_RADIUS, -PAD_PITCH), PAD_WIDTH, PAD_HEIGHT, \"b\"))\n",
"pads.append(create_pad((INPUT_PAD_RADIUS, 0), PAD_WIDTH, PAD_HEIGHT, \"b\"))\n",
"pads.append(create_pad((INPUT_PAD_RADIUS, PAD_PITCH), PAD_WIDTH, PAD_HEIGHT, \"b\"))\n",
"pads.append(create_pad((INPUT_PAD_RADIUS, -PAD_PITCH), PAD_WIDTH, PAD_HEIGHT, \"b\"), COIL_NET_NAME)\n",
"pads.append(create_pad((INPUT_PAD_RADIUS, 0), PAD_WIDTH, PAD_HEIGHT, \"b\"), COIL_NET_NAME)\n",
"pads.append(create_pad((INPUT_PAD_RADIUS, PAD_PITCH), PAD_WIDTH, PAD_HEIGHT, \"b\"), COIL_NET_NAME)\n",
"\n",
"# connect coil A to the top pad\n",
"pad_connection_point_x = INPUT_PAD_RADIUS\n",
"pad_angle = np.rad2deg(np.arcsin(PAD_PITCH / pad_connection_point_x))\n",
"coils_f[0].append(get_arc_point(coil_angles[0], pad_connection_point_x))\n",
"vias.append(create_via(get_arc_point(coil_angles[0], pad_connection_point_x)))\n",
"vias.append(create_via(get_arc_point(coil_angles[0], pad_connection_point_x)), COIL_NET_NAME)\n",
"# connect coil B to the middle pad\n",
"coils_f[1].append((pad_connection_point_x + PAD_WIDTH / 2 + VIA_DIAM / 2, 0))\n",
"coils_f[1].append((pad_connection_point_x + PAD_WIDTH / 2 + VIA_DIAM / 2, 0), COIL_NET_NAME)\n",
"vias.append(create_via(((pad_connection_point_x + PAD_WIDTH / 2 + VIA_DIAM / 2, 0))))\n",
"# connect coil C to the bottom pad\n",
"coils_f[2].append(get_arc_point(coil_angles[2], pad_connection_point_x))\n",
"vias.append(create_via(get_arc_point(coil_angles[2], pad_connection_point_x)))"
"vias.append(create_via(get_arc_point(coil_angles[2], pad_connection_point_x)), COIL_NET_NAME)"
]
},
{
@ -552,7 +555,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.10.7 ('venv': venv)",
"display_name": ".venv",
"language": "python",
"name": "python3"
},
@ -566,11 +569,11 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.7 (main, Sep 27 2022, 14:37:32) [Clang 14.0.0 (clang-1400.0.29.102)]"
"version": "3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)]"
},
"vscode": {
"interpreter": {
"hash": "1ce20143987840b9786ebb5907032c9c3a8efacbb887dbb0ebc4934f2ad26cb3"
"hash": "97df458a008df4bb35f481235dd1a04940c0d868e77540a7386d9922f34deb97"
}
}
},

View file

@ -23,7 +23,7 @@ def create_tracks(board, group, net, layer, thickness, coords):
if net is not None:
track.SetNetCode(net.GetNetCode())
board.Add(track)
# group.AddItem(track)
group.AddItem(track)
last_x = x
last_y = y
@ -54,38 +54,39 @@ class CoilPlugin(pcbnew.ActionPlugin):
# put everything in a group to make it easier to manage
pcb_group = pcbnew.PCB_GROUP(board)
# board.Add(pcb_group)
# find the matching net for the track
net = board.FindNet("coils")
if net is None:
net = pcbnew.NETINFO_ITEM(board, "coils")
board.Add(net)
# raise "Net not found: {}".format(track["net"])
board.Add(pcb_group)
# create tracks
for track in coil_data["tracks"]["f"]:
net = self.findNet(board, track)
create_tracks(
board, pcb_group, net, pcbnew.F_Cu, track_width, track
board, pcb_group, net, pcbnew.F_Cu, track["width"], track["pts"]
)
for track in coil_data["tracks"]["b"]:
net = self.findNet(board, track)
create_tracks(
board, pcb_group, net, pcbnew.B_Cu, track_width, track
)
for track in coil_data["tracks"]["in1"]:
create_tracks(
board, pcb_group, net, pcbnew.In1_Cu, track_width, track
)
for track in coil_data["tracks"]["in2"]:
create_tracks(
board, pcb_group, net, pcbnew.In2_Cu, track_width, track
board, pcb_group, net, pcbnew.B_Cu, track["width"], track["pts"]
)
pcb_layers = [
pcbnew.In1_Cu,
pcbnew.In2_Cu,
pcbnew.In3_Cu,
pcbnew.In4_Cu,
pcbnew.In5_Cu,
pcbnew.In6_Cu,
]
for i, track_list in enumerate(coil_data["tracks"]["in"]):
for track in track_list:
net = self.findNet(board, track)
create_tracks(
board, pcb_group, net, pcb_layers[i], track["width"], track["pts"]
)
# create the vias
for via in coil_data["vias"]:
net = self.findNet(board, via)
pcb_via = pcbnew.PCB_VIA(board)
pcb_via.SetPosition(
pcbnew.wxPointMM(via["x"] + CENTER_X, via["y"] + CENTER_Y)
@ -94,7 +95,7 @@ class CoilPlugin(pcbnew.ActionPlugin):
pcb_via.SetDrill(int(via_drill_diameter * 1e6))
pcb_via.SetNetCode(net.GetNetCode())
board.Add(pcb_via)
# pcb_group.AddItem(pcb_via)
pcb_group.AddItem(pcb_via)
# create the pins
# for pin in coil_data["pins"]:
@ -117,6 +118,7 @@ class CoilPlugin(pcbnew.ActionPlugin):
lset = pcbnew.LSET()
lset.AddLayer(pcbnew.B_Cu)
for pin in coil_data["pads"]:
net = self.findNet(board, pin)
x = pin["x"] + CENTER_X
y = pin["y"] + CENTER_Y
module = pcbnew.FOOTPRINT(board)
@ -152,7 +154,7 @@ class CoilPlugin(pcbnew.ActionPlugin):
if text["layer"] == "b":
pcb_txt.Flip(pcbnew.wxPointMM(x, y), True)
board.Add(pcb_txt)
# pcb_group.AddItem(pcb_txt)
pcb_group.AddItem(pcb_txt)
# create the mounting holes
# for hole in coil_data["mountingHoles"]:
@ -217,5 +219,16 @@ class CoilPlugin(pcbnew.ActionPlugin):
ec.SetPolyPoints(v)
board.Add(ec)
def findNet(self, board, element):
# find the matching net for the track
net_name = "coils"
if "net" in element:
net_name = element["net"]
net = board.FindNet(net_name)
if net is None:
net = pcbnew.NETINFO_ITEM(board, net_name)
board.Add(net)
# raise "Net not found: {}".format(net_name)
return net
CoilPlugin().register() # Instantiate and register to Pcbnew])

File diff suppressed because it is too large Load diff

View file

@ -6,15 +6,16 @@ import matplotlib.pyplot as plt
from helpers import rotate
def create_pin(radius, angle, name):
def create_pin(radius, angle, name, net_name):
return {
"x": radius * np.cos(np.deg2rad(angle)),
"y": radius * np.sin(np.deg2rad(angle)),
"name": name,
"net": net_name,
}
def create_pad(point, width, height, layer, angle=0):
def create_pad(point, width, height, layer, net_name, angle=0):
return {
"x": point[0],
"y": point[1],
@ -22,6 +23,7 @@ def create_pad(point, width, height, layer, angle=0):
"height": height,
"layer": layer,
"angle": angle,
"net": net_name,
}
@ -36,12 +38,12 @@ def create_silk(point, text, layer="f", size=5, angle=0):
}
def create_via(point):
return {"x": point[0], "y": point[1]}
def create_via(point, net_name):
return {"x": point[0], "y": point[1], "net": net_name}
def create_track(points):
return [{"x": x, "y": y} for x, y in points]
# def create_track(points, net_name):
# return [{"x": x, "y": y, "net": net_name} for x, y in points]
def create_mounting_hole(point, diameter):
@ -68,12 +70,37 @@ def dump_json(
pads,
silk,
tracks_f,
tracks_in1,
tracks_in2,
tracks_in,
tracks_b,
mounting_holes,
edge_cuts
):
tracks_inner = [[
{
"net":track_info["net"],
"width": track_info["width"] if "width" in track_info else track_width,
"pts":create_track_json(track_info["pts"]),
}
for track_info in track_vals]
for i, track_vals in enumerate(tracks_in)]
tracks = {
"f": [
{
"net":track_info["net"],
"width": track_info["width"] if "width" in track_info else track_width,
"pts":create_track_json(track_info["pts"]),
}
for track_info in tracks_f],
"b": [
{
"net":track_info["net"],
"width": track_info["width"] if "width" in track_info else track_width,
"pts":create_track_json(track_info["pts"]),
}
for track_info in tracks_b],
"in": tracks_inner
}
# dump out the results to json
json_result = {
"parameters": {
@ -87,12 +114,7 @@ def dump_json(
"pins": pins,
"pads": pads,
"silk": silk,
"tracks": {
"f": [create_track_json(points) for points in tracks_f],
"in1": [create_track_json(points) for points in tracks_in1],
"in2": [create_track_json(points) for points in tracks_in2],
"b": [create_track_json(points) for points in tracks_b],
},
"tracks": tracks,
"mountingHoles": mounting_holes,
"edgeCuts": [create_track_json(points) for points in edge_cuts],
}
@ -109,13 +131,13 @@ def plot_json(json_result):
# plot the back tracks
ax = None
for track in json_result["tracks"]["b"]:
df = pd.DataFrame(track, columns=["x", "y"])
df = pd.DataFrame(track["pts"], columns=["x", "y"])
ax = df.plot.line(x="x", y="y", color="blue", ax=ax)
ax.axis("equal")
# plot the front tracks
for track in json_result["tracks"]["f"]:
df = pd.DataFrame(track, columns=["x", "y"])
df = pd.DataFrame(track["pts"], columns=["x", "y"])
ax = df.plot.line(x="x", y="y", color="red", ax=ax)
ax.axis("equal")