I've been messing around making PCB coils, but instead of drawing them by hand,
which would be pretty frustrating I've automated the entire process.
I'm working on a new project with one of my friends and we've taken
inspiration from Carl Bugeja's amazing work on PCB Motors.
If you haven't seen his channel then check it out it's very very cool.
Now it's not clear if what we're doing will actually work as well as his projects,
but there's only one way to find out.
As always my PCBs will be manufactured by PCBWay more about them later.
So, making coils on a PCB. You might think this
is pretty trivial and for a basic coil, it actually is very simple.
So we'll start off doing this first and then move
on to the more challenging problem of creating arbitrary coil shapes.
For our PCB coils we want to create as many turns as possible.
Our main constraint is going to be our track width
and track spacing along with the number of layers that we can use.
Looking at PCBWay we can see that prices start to go up very quickly as soon as
we go below 5 mil for the track width and spacing.
So this will be the smallest size we'll try and use. This
is equivalent to a track width and spacing of 0.127 millimeters each.
Staying on the theme of keeping it cheap, we'll also be using a
two layer board. Going up to a four layer board would increase the cost considerably.
It is possible that these constraints will make our coils too weak to do anything,
but we'll see once we have the pcbs manufactured.
So how do we make a coil?
Well all we need to do is generate a spiral.
If we were just trying to make a circular track, then we would simply use these two equations.
We would then generate points on the circle by sweeping the angle from 0
to 360 degrees and keeping the radius constant.
The X and Y coordinates of the points on the circle can be calculated using basic trigonometry.
To make a spiral we just need to make the radius increase proportionally to the current Angle.
Now we can calculate the coordinates on a spiral by sweeping our angle from 0 to
360 Degrees multiplied by the number of turns that we need.
We're going to also want to have a coil on the bottom layer of the board.
So we're going to need some space in the center for a via to connect the top and bottom layers.
We can do this by starting our radius off with a small offset. We can now
just join our top and bottom chords together using a via in the center.
If we look at the direction of the magnetic field that will be created
from the two coils we can see that they will cancel each other out.
To fix this we just need to flip the bottom coil.
The current will now flow into the top coil and out of the bottom coil in the same direction.
The top and bottom coils will now reinforce each other.
Generating this and turning it into tracks and vias results in this very nice looking
PCB layout in KiCad. It's pretty cool. We have the top layer coil and the bottom layer coil.
If we apply power to the top coil the current will flow in
this direction and it will also flow in the same direction on the bottom coil.
Now we're going to be trying to repeat some of Carl's work and make a three-phase PCB motor.
For this kind of motor we're going to need three coils spaced 120 degrees around our PCB.
The motor can be made more powerful by duplicating each
coil on the opposite side of the PCB. So we end up with six coils in total.
To make the wiring up of these coils easier I'm adding a 180 degree offset
to the angle on the bottom coil so that the end of the coil finishes on
the opposite side to the start of the coil on the top layer.
We can now easily connect the pairs of coils
together by connecting the ends of the coils on the bottom layer.
To make the current flow in the correct direction we just
need to flip the Y coordinates of the opposite coils again.
Connecting the ends of the opposite coils together
to a common Point gives us the classic star wiring pattern.
If we connect A to the positive rail and B to the negative rail leaving C unconnected
then the A coils will create north magnets and the B coils will create south magnets.
Similarly connecting C to the negative rail will make the C coils create south magnets.
If we now connect A to the negative rail and B to
the positive rail we'll get north from the B coils and south from the A coils.
And so on as we drive the coils appropriately.
So this is great, but if we look at some images of
other people's PCB stators we can see that they don't always stick to circular coils.
How about generating arbitrarily shaped coils?
Now this turned out to be a surprisingly interesting problem.
I've managed to get something that works pretty well, but I'm sure there
must be other solutions - let me know in the comments if you know a good way of doing it.
My initial attempts produce some very interesting shapes. I tried to take
the existing code for creating spirals, but calculated the radius by sweeping an angle
around and casting a ray out to find the intersection point with the template shape.
I used the distance from the origin to this
intersection point as the radius and then tried offsetting this.
Now obviously, this doesn't work very well. And if we think about
what is happening with a normal spiral we can intuitively see that we are always
offsetting points at approximately a normal to the template circle shape.
So, what we need to do is offset the intersection point at right angles to the line it belongs to.
If we do this then we get something that looks much better the only issue is though
it doesn't seem to handle corners - they are getting chopped off.
My first attempt to solve this was simply to smooth the corners of the template shape.
There's a really nice algorithm we can use to do this automatically
called Chaikin's corner cutting algorithm.
This iteratively smooths lines and gives a really nice smooth
result after just a couple of iterations.
If we do this first and then run our algorithm we get quite reasonable results.
However, we're not really ending up with the shape that we originally wanted.
An alternative way to fix the corner cutter problem is to detect when we
switch to a new line segment and create an intermediate point where the corner should be.
We do this by calculating the intersection of the
previously generated points with the next two generated points.
This algorithm works really well and we get a nice looking coil.
The only issue we face now is that we can miss small details in our template shape.
We are sweeping a ray around a circle and unless
we step with very small increments we can easily miss a line segment.
But, if we step with really small increments then it takes a very long time to process.
So, what I've ended up doing is taking each point on the template. I calculate the angle
from the point to the origin and from that I can work out how much offset would be required.
This generates pretty much the same results as our original sweeping ray algorithm,
but it's a lot faster and it doesn't miss any line segments.
This works really well and we can create pretty cool wedge-shaped coils.
Here's the version with six coils, and we can even generate 12 coils instead.
The wiring up is a bit more complicated but it can still all be done programmatically.
The 12 coil version still creates the same star-shaped circuit as the six coil version.
Everything is fully automated using a KiCad plugin.
Making a keycard plugin was an adventure in itself. In
many ways it was almost as hard as actually getting the coil algorithm.
There are a couple of issues with making KiCad plugins - they are pretty hard to develop and
test - you need to edit your code, refresh the plugins, run the plugin, see if it works.
It's a slow process.
It's also quite hard to include additional Python libraries that your plugin might rely on.
KiCad comes with its own installation of Python. In theory you can add new
python libraries using the bundled pip installer.
However, on modern Mac computers this causes all sorts of problems.
Macs have an additional security layer that prevents applications from being
modified. This does help prevent viruses and malware from infecting your computer,
but unfortunately running pip install in the KiCad directory modifies the KiCad python installation.
So the operating system thinks it's no longer valid and won't let you run it.
To avoid all these issues I've developed all the complicated code in a Python notebook.
This lets me develop the coil generation algorithms much more quickly and I can
easily preview what it will look like by plotting the output directly in the notebook.
The notebook produces very simple JSON representation of the tracks, the vias,
silk and pads. And my KiCad plugin simply reads this and creates the required objects.
It's a really nice decoupling and it means we aren't really tired to KiCad at all.
We could use any PCB layout tool that supports scripting that can read JSON data.
The KiCad python API is pretty difficult to get started with. The documentation is
auto generated from header files, so it doesn't really tell you how to use it.
there are quite a few examples, but the API is pretty unstable and seems to change fairly often.
You often have to spelunk into the C++ code to see how things actually work.
A great example of this was just trying to work out how to draw a circle.
I could not work out how to set the radius - there's no setRadius function!
Digging into the code it transpires that you
use the distance between the start and end points to set the radius.
This is one of the big issues with auto-generating documentation from header
files - there's no context to help you understand how to use the API.
Having said that, it's an open source and free project. So I'm not going to complain too much.
If I really wanted to make it better I should contribute some documentation back to the project.
I won't go into too much detail on the KiCad plugin itself. It's surprisingly easy to
create everything we need including tracks, edge cuts, vias, pads and mounting holes.
It's very very cool and definitely worth investing some time in learning how it works.
I've put my code up on GitHub, hopefully, it will help other people.
My pcbs are being manufactured by PCBWay - we've used them for a lot
of projects and they keep on delivering the goods.
There's now a really nice plug in for KiCad that will submit your order directly to them - so
there's no more messing around trying to work out how to export the Gerber files properly.
If you haven't tried them out then give them a go.
I should get the pcbs pretty soon, so we'll soon see if what I've done has any chance of working.
I'll see you in the next video!