Commit b2e61ac9 authored by Jake Read's avatar Jake Read
Browse files

add doc for machine week

parent f161ee39
......@@ -11,42 +11,145 @@ TESC, April 2016 - August 2016
so did those motors.
Once around is never enough*
Eulagies aside, I am still motivated to do this. Brushless motors are the go-to motive force for electromechanical systems. By that I mean that just about any time you see a robot-like thing, or machine, moving about, there's a big likelihood that the thing doing-the-moving has a brushless motor in it's guts - or some variant thereof (stepper motors count as BLDCs in my books).
Eulagies aside, I am still motivated to do this. Brushless motors are the go-to motive force for electromechanical systems. By that I mean that just about any time you see a robot-like thing, or machine, moving about, there's a big likelihood that the thing doing-the-moving has a brushless motor in it's guts - or some variant thereof (stepper motors count as BLDCs in my books). See [this characterization of actuators](https://jakeread.pages.cba.mit.edu/actuators/) to get a sense for why.
## Others
# An Overview of BLDC Drive
I'm not intending to put myself in league with these people - these links are here because they are motivated by (similar) things.
### Electric Motors actuate with a rotating a magnetic field.
In relation to [Ashby's fundamental actuator types](/papers/ashby-actuators.pdf), brushless or brushed electric motors are effectively continuously-rotating solenoids.
We have something with magnets, and something else with electromagnets, we use the electromagnets to rotate the field, we pull the magnets along. Rotating the field is called *Commutating* the motor, and can be done mechanically or electrically. With mechanical commutation, we have Brushed DC Motors, with electrical, Brushless DC Motors.
![dc](/images/dcmop.gif)
### Brushed Motors rotate the magnetic field using 'brushes'
Brushes are mechanical switches that use the motor's own rotation to change the magnetic field. Super neat. [Here's a link to Sparkfun's explanation.](https://learn.sparkfun.com/tutorials/motors-and-selecting-the-right-one/dc-brush-motors---the-classic)
And a GIF. While the rotor rotates, different switches are connected to current, and the coils - to - pads relationship is set up such that the current will cause the motor to rotate. Pardon my abbreviated explanation.
![brushed-dc](brushed-dc.gif)
Brushes make motors very simple. You just pump voltage (in time, current) through the rotor, and things happen. However, there are resistive losses at the brushes, as well as friction losses.
#### Brushless Motors rotate the magnetic field with switches.
Power transistor technology means that we can do this electronically - use a computer (or simple timer) to switch the phases.
So we can make the coils stationary, and 'artificially' switch the direction and timing of current flowing through them.
Here's an example of '6-step' commutation. This is incredibly common for speed control, and simpler devices, as it requires very little processor work. It can also be done in an open-loop fashion, where we blindly switch currents at a set rate to control for speed.
![bldc](/images/bldc-motor-gif.gif)
Here's a nice GIF of sinusoidal commutation (where phase currents follow a nice, smooth wave). This is more ideal than 6-step commutation for a number of reasons, some of which are discussed in the next section. Mostly, we get to use more of each coil (we have all three on simultaneously) and we have finer control over the magnetic vector.
![bldc-animation](/images/bldc-motor-vectors.gif)
We can see the three current vectors (that translate into a combined magnetic field vector). The permanent magnetic field of the rotor follows this electromagnetic field around.
Digikey has a nice article on sinusoid control [here.](https://www.digikey.com/en/articles/techzone/2017/jan/why-and-how-to-sinusoidally-control-three-phase-brushless-dc-motors)
### Control
Control of Brushed DC motors is straightforward, we use one Full H-Bridge to drive current in both directions across the coils.
![dc-schematic](/images/dc-motor-schematic.png)
However, a brushless motor requires a bit more thinking. We use three Half H-Bridges to source and sink current between the three coils, each having a common connnection to one another.
![simple-bldc](/images/simple-bldc-schematic.jpg)
### Gate Driving
Driving those Half-Bridges also requires a bit of doing, and gets us into some intricacies of MOSFET selection and, well, gate driving. Namely, MOSFETS have 'gate charge' - a set charge we have to drive into the gate pin before the fet turns on. If you look at the [mosfet datasheet](/datasheet/Infineon-IRF6648-DS-v01_02-EN.pdf) from the FET I'm using in this circuit, you'll find the fets have a gate charge of 36nC. We have to drive this charge into the gate every time we turn it on, and we're doing so at 20kHZ or more. This adds up. While we can get away with driving a low-side MOSFET right out of a microcontroller pin, we might be limited at how fast we can do so due to that current. And we can't even begin to switch the high-side MOSFET with a microcontroller pin, as the V_gs (voltage between the gate and source) is above our source voltage, since in the case of a high-side fet, the source is our motor voltage.
We can also use a P-doped fet on the high side, simplifying gate drive. See [this](http://files.mikrokopter.de/BL_Ctrl_V2_0_Doku.pdf) schematic for an example of that scheme.
#### Commutation Schemes
While it's possible to blindly drive the switches at a set frequency (determining rotor speed) it's really advantageous to drive the coils with some form of feedback on the rotor's relative electric position. There are a few ways to do so.
**Hall Effect Sensors & Six Step**
Hall effect sensors measure the position of the rotor's magnets:
![hall](/images/sensboard5.jpg)
This is a straightforward and very popular method for commutation, and is always useful information, but only completely effective for motor control schemes using 6-step commutation.
**Back EMF & Six Step**
Hall sensors add complexity, so Back EMF has become popular, although it doesn't work at lower velocities.
With Back EMF, we take advantage of the fact that at any given time one of the coils is not being driven. This means that we can measure it's voltage (it's acting like a generator) and use the zero-crossing point (when that voltage is 1/2 of the voltage driving the other two phases) to inform our commutation (which should happen shortly thereafter.
![bemf](/images/bemf.jpg)
Because we're driving the other two ends of the coil whose voltage we're measuring with a PWM signal, there's some complexity here. I won't get into it, now, but for jumping off try [this](https://www.digikey.com/en/articles/techzone/2013/jun/controlling-sensorless-bldc-motors-via-back-emf) or [this](http://www.ti.com/lit/an/sprabq7a/sprabq7a.pdf).
**Field Oriented Control**
aka FOC
This is 'modern' motor control, and represents the state of the art. FOC uses a good deal of embedded computing, and has a control schematic that looks like this:
![foc](/images/foc-schematic.jpg)
We use rotor position to drive a sinusoid of phase currents, and do control over those currents to overcome inductive lag.
Normally, position information comes from an encoder, but Sensorless FOC exists where a state estimator is used to guess at the rotor position.
In order to jump off here, try [this](http://www.copleycontrols.com/Motion/pdf/Field-Oriented-Control.pdf), a brief overview, and [this](http://www.ti.com/lit/an/sprabq3/sprabq3.pdf), a monster, from TI, on sensorless FOC.
#### Circuits
A number of brushless motor controllers are available in the open-source world:
[ODrive](https://odriverobotics.com/shop)
[VESC](http://vedder.se/2015/01/vesc-open-source-esc/)
[Ben Katz](http://build-its-inprogress.blogspot.com/search/label/Motor%20Control)
[MKBLDCDriver](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver)
#### A few things to understand:
Here's the schematic that I'm most familiar with:
**(1) Electric Motors move by rotating a magnetic field** - we have something with magnets, and something else with electromagnets, we use the electromagnets to rotate the field, we pull the magnets along. Rotating the field is called *Commutating* or *Commutation*.
![schematic](/images/brushless-motor-schematic.png)
**(2) Brushed Motors rotate the magnetic field using 'brushes'** - these are mechanical switches that use the motor's own rotation to change the magnetic field. Super neat. [Here's a link to Sparkfun's explanation](https://learn.sparkfun.com/tutorials/motors-and-selecting-the-right-one/dc-brush-motors---the-classic)
And the board,
And a GIF. While the rotor rotates, different switches are connected to current, and the coils - to - pads relationship is set up such that the current will cause the motor to rotate. Pardon my abbreviated explanation.
![mkbldc](/images/mkbldc.jpg)
In each of these boards, we find a microcontroller, a gate driver, three half-bridges (6 MOSFETS), and current and voltage sensing circuitry. And a few BFCs never hurt.
#### Typically Available:
For motors, I am deeply in love with [Hobbyking](https://hobbyking.com/en_us/power-systems-1/electric-motors/size.html).
'Outrunner' Motors (rotor wraps stator) are popularized by drone enthusiasts and have fairly high torque densities due to an increased gap radius.
![outrunners](/images/outrunners.jpg)
![pancake](/images/pancake.jpg)
[here](http://store-en.tmotor.com/goods.php?id=475)
![brushed-dc](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/brushed-dc.gif)
Inrunners (rotor inside stator) are great for speed.
![Typical Inrunner](/images/inrunner.jpg)
Brushes are awesome - and make motors very simple. You just pump voltage (so current) through the rotor, and things happen. However, there are resistive losses at the brushes, as well as friction losses.
To control these, look [here](https://hobbyking.com/en_us/power-systems-1/speed-controllers-esc.html) to start, but preferrably pick up one of the open-source ESC's mentioned above - or try building your own. With off the shelf ESCs, open loop speed control is the only thing you can do.
With the advent of transistor technology (for switching logic AND for switching big power) we can do this electronically - use a computer (or simple timer) to switch the phases.
### The State of the Art
**(3) Brushless Motors rotate the magnetic field with switches** - so we can make the coils stationary, and 'artificially' switch the direction and timing of current flowing through them. Here's a nice GIF of sinusoidal commutation (where phase currents follow a nice, smooth wave).
The design of BLDCs is not changing radically - it's a good idea, and it works.
![bldc-animation](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/bldc-motor-vectors.gif)
**There is one exception to this** - [Thingap Motors](http://www.thingap.com/) use an ironless winding [(patent here)](https://www.google.com/patents/US20130300241) and have relatively high torque densities. The [performance is impressive](http://www.thingap.com/standard-products/) but they cost ~1k at the low end.
We can see the three current vectors (that translate into a combined magnetic field vector). We also have a simpler type of switching, where we only turn two of the three phases on at a time. You can see an example of that [here](https://www.youtube.com/watch?v=oFI7VW6WGR4) - including a nice diagram of the switch setup.
What is interesting is where BLDCs are being used, controlled, and how they are being designed (shape, new densities). Take a look at [The Biomimetics Lab at MIT's](http://biomimetics.mit.edu/research/optimal-actuator-design) discussion on optimizing gap radius, etc.
#### Where it gets complicated:
![mit-cheetah](/images/mitcheetah-actuator.jpg)
- Circuit design to switch big voltages / currents
- Closed loop control on current in motor
- Sensing: rotor position, electrical phase, offsets, shunt amplifiers oh my!
The MIT Cheetah team had their motors custom made to optimize for torque density (at a cost of total power density). Their discussion is really interesting, you can read [This Paper](/papers/mit-cheetah-actuator.pdf), a great intro to the state of the art in robotic control, of which Brushless Motors and their cousins play a large role.
#### Towards accessible robotics
As well, [Ben Katz'](/papers/katz-thesis.pdf) thesis contains an excellent review, and more intelligent discussion, on FOC, motor selection, etc.
Mostly the motivation for me to go through this is (1) to train myself in the field, and (2) to help others along a similar journey, not just cobbling bits together, but understanding how and why they work. This is ongoing work!
\ No newline at end of file
And [Simon Galouche's](/papers/kalouche-thesis.pdf) thesis contains a similar review on actuator selection for robotics.
\ No newline at end of file
# Machine Kit BLDC Driver: Circuit Development
Warning! Train-of-though documentation!
#### FET Selection
Using 2x20 pin header on ATSAMS70 Switch -
I want to use these fancy DirectFets because I know they can handle really big currents in astoundingly small packages - aiming at a 2kW spindle here. The PN<sup>1</sup> I found is IRF6648TRPBF, switches 60v at 86a - this is rated by the silicon<sup>2</sup>, so won't really get that close, but it's a big number nonetheless - and even at ~ 40% of that I'm running near 2KW (also, power is switched with 6 - so load is a bit split up, though the picture is not so simple - i.e. during moments of the phase only one is 'full on' on the top - or bottom - side of the phases.)
I also found an eagle library for this package, nice.
These are apparently a pain to solder - you need reflow. I'm OK with that, as I think reflow ovens are not hard to build... I know it makes it a little bit un-fabbable, but it makes me stoked about this project. So here we are.
Now - an aside, to introduce you to [Ben Katz](http://build-its-inprogress.blogspot.com/search/label/Motor%20Control) a researcher at MIT's Biomimetic Robotics Lab, who is an expert in motor control, and keeps this great blog about it. Also, this is [Benjamin Vedder](http://vedder.se/2015/01/vesc-open-source-esc/)<sup>3</sup> - who's project is hugely popular in the Electric Longboard community. Niche. Great software, great board design.
#### Layout
I start by laying out the Three Half-Bridges that drive the Motor. The FET I am using actually has multiple pins per connection - so I pulled those out on the symbol to make it clearer what I needed to connect. Here's my schematic for the gates:
![gates schematic](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/schematic-gates.jpg)
A few notes - I'm using Labels instead of directly 'routing' on the schematic. This helps keep things diagrammatic... And not messy. You'll notice my Shunt symbols have separate legs for sensing - you'll get that when you see the layout. I also pull out a pin from the low-side of the gates that the gate-driver uses to sense the voltage there (actually not ~ exactly ground). I also have a few voltage dividers setup on phases, which is useful when doing closed-loop sensorless BLDC or FOC control. Not something I imagine I'll have time to implement in code, but good to have.
Now I try a first-shot at the gate layout on the board, to get a sense for generally where things will end up.
![gates single layout](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/board-single-halfbridge.jpg)
This is really just to figure out what the topology is - what wraps around what. When I really route the big juice, I'll be drawing big polygons that I can do copper pours in. I like this particular layout because I have a 'side' for each big current pull - my shunt is happy with a big tail to some groundplane I'll lay down over there, the phase (in between the FETS) gets a nice edge to face-out to where I'll put motor lines (and that pesky voltage divider), and I have another happy, big edge to dump VCC on. I can even sneak the gate-drives in without any vias, nice.
Next I'm going to draw the DRV8302 Schematic and Footprint. Oy.
![drv device](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/drv-device.jpg)
TI Provides an excellent example layout - I'm using this as a reference as I draw the circuit.
![drv reference](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/drv-reference.jpg)
I got the DRV8302 all schematic'd out, and put a rough plan in place on the board. This looks a bit complicated .... That's because this DRV8302 packs a lot of circuit into one die. I'm actually not sure if it is only one die... You can see this all here:
![drv blocks](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/drv-blocks.jpg)
Here's my schematic block for just the DRV
![drv schematic](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/schematic-drv.jpg)
There's gate drivers - that's the real business that we're after - this comes with a swath of external capacitors. Critically, BST_x and CP1, CP2 connected capacitors are Charge Pump caps - these are what the DRV uses to crank voltage into the high-side gates - very important that these find a good home really close to the DRV.
GVDD and DVDD are still a bit of a mystery to me - internal voltages in the DRV that want external bypass capacitors.
There's also the current sense amplifiers - the bottom chunk of the chip. These amps *TODO: explain current sensing* and they get a tiny filter on the inputs, a reference voltage.
On the 'top' of the chip is a buck voltage regulator, a world into itself. The buck gets a whole whack of support - a BST_BK capacitor, a whole bunch of R_Sense circuitry, etc.
And then there are a few fault outputs (that I connect to LEDS for super-simple debugging, but should properly trigger interrupts on a microcontroller), some settings-related pins, etc. It's a lot, and with more time I would write my process for this up in detail. Wrestling with this chip taught me a lot about EE.
OK. Next, I'm going to try to reconcile the pin-inputs I need for this driver with the pin-outputs I've developed for Machine Kit. Briefly, I know I'm going to need 6 PWM Pins (3 phases x hi/lo) and 5 ADC pins - two for current sensing *TODO: explain kirchoff's summing*, and 3 for phase voltage measurement. Actually 6, because I want to measure the input voltage as well. So I already know I need (want) another ADC pin on the MK Header. This is a lot of analog (er, PWM-ish) circuitry! I'm glad I have this test case in developing the MK Switch. Turns out I am maxed on the analog pins available on the ATSAMS70. So I have to jettison measuring source voltage, which is OK when we are not running on batteries - but kind of a bummer to have that hardware limitation. Could open one phase to high and measure then, I think, but wouldn't be able to do it continuously during operation. That's fine.
I'm also going to add a header / plug for 'other things' - I'll use the SPI pins, that I think I can set as GPIO as well - I want to be able to talk to SPI devices (sensors, etc) and / or ABI input encoders. Wow. I am biting off a lot.
Also - I want to push 48v into this chip (I am planning on most machines running at 48V, the power supplies are readily available, and 48v is the right amount for a KW spindle - says reasons?). This means I have to push a bunch of big capacitors onto the chip - 10uF at 100v (next step up) is a 2220 package - big !
OK - I finally got my schematic dialed down where I wanted it, and footprints worked out. I'm going to start routing.
#### Routing
![routing begins](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-begins.jpg)
I have one ground plane (bottom trace) and three voltage planes on the top - a VCC (motor voltage, will be nominally 48v), a +5V (the output from the buck regulator, also - turns out I need this on some SPI / encoder devices, nice bonus) and a +3V3 - that's my logic level - the DRV uses 5v logic, but, all good.
I got started routing the inputs to the DRV, working over to the drive side. Once there, I focused on making the FETS and Caps etc... power side... work well. I'm also keeping an eye on my ground plane - a big problem with two-sided routing is that you can 'pinch' the plane out in some cases. This was a big issue when I routed that 100-pin switch, here it seems a bit easier - there's less going on overall - the scale is a bit different.
![routing halfway](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-halfway.jpg)
I got this routed, and I'm feeling good about the board. I turned on only the layers that will actually show up in fab - so the solder mask, traces, holes, etc - really I want to take some time now to make a decent silkscreen - this can make component placing much easier!
![routing presilk](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-presilk.jpg)
For adding silk, I tried to go about doing it by adding silk to the components - not just drawing them on the board.
OK, actually I want to keep the silk really clean. Things should be beautiful.
I sent these out, and sent an order to digikey for parts. Now some waiting. Here's a list of notes, as they occur, for next time.
## Fab: the board
OK, I got these boards in from the fab. Noice. I also splurged for the solder paste stencil (spending the CBA's money, thanks CBA!) - actually it's only $15 to get a stencil, and it saves me 2hr/board that I assemble, so if time = money... well.
![fab stencil and board](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-stencil-and-board.jpg)
I'm well into reflowing boards (it's amazing, and has a surprisingly low overhead - highly recommended) and this is kind of the next step. The stencil lets me apply all of my solder paste at once, a huge time-saver, and prevents me from accidentally applying too much and shorting pins together. [Here is a great tutorial](https://www.sparkfun.com/tutorials/58) from Sparkfun on how to do this.
After I lay the paste down, it takes about ~35 minutes to lay the components down. If I did this in parallel, I would guess I could do 10 boards in ~1.5 hours, probably less if I got really into the zone and had a nice workstation.
In any case, here's the back of one of those DirectFets and it's associated footprint to the left. Here you can see the heckin' silicone die RIGHT THERE underneath the tin. I'm not super sure that I nailed this footprint, so we'll see what happens when I try to boot it up.
![fab directfet](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-directfet.jpg)
A group of components pre-reflow:
![fab prereflow](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-prereflow.jpg)
And afterwards - I am excited that these 56-HTSSOP pins on the DRV8302 are not welding together. Go solder paste, go.
![fab postreflow](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-postreflow.jpg)
And completed - looks nice!
![fab smd complete](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-smd-complete.jpg)
## Testing
Here's my setup:
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-stand.jpg)
And I'm using a 24V Supply - I designed & rated this to 83V (capacitors are largely 100v, 83v rating comes from the DRV8302 and the FETS). But I want to stay safe and steer clear of burnouts for now.
I carefully checked all of my pinouts and double-checked that I was sending a PWM signal that I liked, then I turned it on! I had some success, and then a stall. I *thought* I saw some smoke, so not sure what's up.
I also noticed the power lines to the ATSAM chip started to flash - so I am having a power supply issue to my brain-board. This whole situation is more complicated than it needs to be. The DRV has a 5V Buck regulator, and uses that 5V Signal on a few pins... so I can't just throw it out. The ATSAM board has a 5V line, that it passes through a regulator to get the 3v3 it needs.
I imagine the 5V Buck Regulator on the DRV8302 is unhappy - it's actually a fairly complex thing, using some feedback loops to control a PWM cycle, that then is filtered with an LC on the output to generate a smooth 5V. I imagine this is going unstable.
What I did to diagnose the whole thing was connect my logic analyzer to the 5V line, 3V3 line, and to my three phases. Note - not *directly* to my three phases, as they will be being driven to 24v, and I'm quite sure I would fry my logic analyzer. I already have voltage dividers setup for the microcontroller to read the phase voltages, so here I'm just reading off of those. Nice.
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-buck-unbuck.jpg)
The first three are my gate voltages - they're being driven very nicely, thanks very much. The bottom two lines are my 5V (Channel 3) and 3V3 lines (Channel 4). So, this is dropping, the pwms are becoming very sad, and this oscillation starts.
It looks like I can remedy this by just supplying also 3V3 with my UART Cable - although I know I'll be introducing basically conflicting 3V3 lines, which is bad. We'll give it a go.
OK, great success! First thing's first, my motor turns:
![test first turns](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-first-turns.gif)
This is good news. Better news, I can read all of my phase voltages, and it looks like I'm getting satisfactory reading on my current sensing circuitry as well.
The traces here are: (0) Phase U Voltage, (1) Phase V Voltage, (2) Phase W Voltage, (3) 5V Line, (4) 3V3 Line, (5) Phase V Current, and (6) Phase W Current.
Here we see happy PWM cycles above, and what looks like a chopped sinusiod (of current) below.
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-all-sensing-one.jpg)
Zoom in:
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-all-sensing-two.jpg)
I sped this up some and it looks more like a chopped sinusoid - this means I should either dial down the sense amplification (I think the two options are gains of 10 and 40), or put smaller shunts on - right now I have 0.005 Ohm shunts (I wanted a more sensitive measurement for smaller currents).
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-all-sensing-three.jpg)
That's it for now.
While I previously went through this with the [ATSAMS70](atsams70.md), I'm at it again with a new micro - the ATSAMD51, so I'm re working most of it.
# Version 0.2
......@@ -168,7 +18,6 @@ I *think* I read the datasheet correctly on how hi/lo channels are multiplexed h
I also added microcontroller input to a few lines: the gain selection on the drv8302 (controls current sense amp gain) and the fault line, and the pwm mode line (so that in worst case I can just send hi-side signals, the drv will do lo/hi deadtime insertion and complimenting for me).
## New Routing
But *holy shit* did I ever open up the ratsnest :|
......@@ -191,7 +40,11 @@ The last thing, routing all of the voltage sense lines, was a bit of a pain. I h
In any case, here it is
![the-ratsnest](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-bothsides.png)
![routed](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-bothsides.png)
![routed](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-groundplane.png)
![routed](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-top.png)
And the full schematic
......
# Circuit Documentation for v0.1
Using the ATSAMS70
Warning! Train-of-though documentation!
#### FET Selection
Using 2x20 pin header on ATSAMS70 Switch -
I want to use these fancy DirectFets because I know they can handle really big currents in astoundingly small packages - aiming at a 2kW spindle here. The PN<sup>1</sup> I found is IRF6648TRPBF, switches 60v at 86a - this is rated by the silicon<sup>2</sup>, so won't really get that close, but it's a big number nonetheless - and even at ~ 40% of that I'm running near 2KW (also, power is switched with 6 - so load is a bit split up, though the picture is not so simple - i.e. during moments of the phase only one is 'full on' on the top - or bottom - side of the phases.)
I also found an eagle library for this package, nice.
These are apparently a pain to solder - you need reflow. I'm OK with that, as I think reflow ovens are not hard to build... I know it makes it a little bit un-fabbable, but it makes me stoked about this project. So here we are.
Now - an aside, to introduce you to [Ben Katz](http://build-its-inprogress.blogspot.com/search/label/Motor%20Control) a researcher at MIT's Biomimetic Robotics Lab, who is an expert in motor control, and keeps this great blog about it. Also, this is [Benjamin Vedder](http://vedder.se/2015/01/vesc-open-source-esc/)<sup>3</sup> - who's project is hugely popular in the Electric Longboard community. Niche. Great software, great board design.
#### Layout
I start by laying out the Three Half-Bridges that drive the Motor. The FET I am using actually has multiple pins per connection - so I pulled those out on the symbol to make it clearer what I needed to connect. Here's my schematic for the gates:
![gates schematic](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/schematic-gates.jpg)
A few notes - I'm using Labels instead of directly 'routing' on the schematic. This helps keep things diagrammatic... And not messy. You'll notice my Shunt symbols have separate legs for sensing - you'll get that when you see the layout. I also pull out a pin from the low-side of the gates that the gate-driver uses to sense the voltage there (actually not ~ exactly ground). I also have a few voltage dividers setup on phases, which is useful when doing closed-loop sensorless BLDC or FOC control. Not something I imagine I'll have time to implement in code, but good to have.
Now I try a first-shot at the gate layout on the board, to get a sense for generally where things will end up.
![gates single layout](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/board-single-halfbridge.jpg)
This is really just to figure out what the topology is - what wraps around what. When I really route the big juice, I'll be drawing big polygons that I can do copper pours in. I like this particular layout because I have a 'side' for each big current pull - my shunt is happy with a big tail to some groundplane I'll lay down over there, the phase (in between the FETS) gets a nice edge to face-out to where I'll put motor lines (and that pesky voltage divider), and I have another happy, big edge to dump VCC on. I can even sneak the gate-drives in without any vias, nice.
Next I'm going to draw the DRV8302 Schematic and Footprint. Oy.
![drv device](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/drv-device.jpg)
TI Provides an excellent example layout - I'm using this as a reference as I draw the circuit.
![drv reference](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/drv-reference.jpg)
I got the DRV8302 all schematic'd out, and put a rough plan in place on the board. This looks a bit complicated .... That's because this DRV8302 packs a lot of circuit into one die. I'm actually not sure if it is only one die... You can see this all here:
![drv blocks](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/drv-blocks.jpg)
Here's my schematic block for just the DRV
![drv schematic](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/schematic-drv.jpg)
There's gate drivers - that's the real business that we're after - this comes with a swath of external capacitors. Critically, BST_x and CP1, CP2 connected capacitors are Charge Pump caps - these are what the DRV uses to crank voltage into the high-side gates - very important that these find a good home really close to the DRV.
GVDD and DVDD are still a bit of a mystery to me - internal voltages in the DRV that want external bypass capacitors.
There's also the current sense amplifiers - the bottom chunk of the chip. These amps *TODO: explain current sensing* and they get a tiny filter on the inputs, a reference voltage.
On the 'top' of the chip is a buck voltage regulator, a world into itself. The buck gets a whole whack of support - a BST_BK capacitor, a whole bunch of R_Sense circuitry, etc.
And then there are a few fault outputs (that I connect to LEDS for super-simple debugging, but should properly trigger interrupts on a microcontroller), some settings-related pins, etc. It's a lot, and with more time I would write my process for this up in detail. Wrestling with this chip taught me a lot about EE.
OK. Next, I'm going to try to reconcile the pin-inputs I need for this driver with the pin-outputs I've developed for Machine Kit. Briefly, I know I'm going to need 6 PWM Pins (3 phases x hi/lo) and 5 ADC pins - two for current sensing *TODO: explain kirchoff's summing*, and 3 for phase voltage measurement. Actually 6, because I want to measure the input voltage as well. So I already know I need (want) another ADC pin on the MK Header. This is a lot of analog (er, PWM-ish) circuitry! I'm glad I have this test case in developing the MK Switch. Turns out I am maxed on the analog pins available on the ATSAMS70. So I have to jettison measuring source voltage, which is OK when we are not running on batteries - but kind of a bummer to have that hardware limitation. Could open one phase to high and measure then, I think, but wouldn't be able to do it continuously during operation. That's fine.
I'm also going to add a header / plug for 'other things' - I'll use the SPI pins, that I think I can set as GPIO as well - I want to be able to talk to SPI devices (sensors, etc) and / or ABI input encoders. Wow. I am biting off a lot.
Also - I want to push 48v into this chip (I am planning on most machines running at 48V, the power supplies are readily available, and 48v is the right amount for a KW spindle - says reasons?). This means I have to push a bunch of big capacitors onto the chip - 10uF at 100v (next step up) is a 2220 package - big !
OK - I finally got my schematic dialed down where I wanted it, and footprints worked out. I'm going to start routing.
#### Routing
![routing begins](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-begins.jpg)
I have one ground plane (bottom trace) and three voltage planes on the top - a VCC (motor voltage, will be nominally 48v), a +5V (the output from the buck regulator, also - turns out I need this on some SPI / encoder devices, nice bonus) and a +3V3 - that's my logic level - the DRV uses 5v logic, but, all good.
I got started routing the inputs to the DRV, working over to the drive side. Once there, I focused on making the FETS and Caps etc... power side... work well. I'm also keeping an eye on my ground plane - a big problem with two-sided routing is that you can 'pinch' the plane out in some cases. This was a big issue when I routed that 100-pin switch, here it seems a bit easier - there's less going on overall - the scale is a bit different.
![routing halfway](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-halfway.jpg)
I got this routed, and I'm feeling good about the board. I turned on only the layers that will actually show up in fab - so the solder mask, traces, holes, etc - really I want to take some time now to make a decent silkscreen - this can make component placing much easier!
![routing presilk](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/routing-presilk.jpg)
For adding silk, I tried to go about doing it by adding silk to the components - not just drawing them on the board.
OK, actually I want to keep the silk really clean. Things should be beautiful.
I sent these out, and sent an order to digikey for parts. Now some waiting. Here's a list of notes, as they occur, for next time.
## Fab: the board
OK, I got these boards in from the fab. Noice. I also splurged for the solder paste stencil (spending the CBA's money, thanks CBA!) - actually it's only $15 to get a stencil, and it saves me 2hr/board that I assemble, so if time = money... well.
![fab stencil and board](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-stencil-and-board.jpg)
I'm well into reflowing boards (it's amazing, and has a surprisingly low overhead - highly recommended) and this is kind of the next step. The stencil lets me apply all of my solder paste at once, a huge time-saver, and prevents me from accidentally applying too much and shorting pins together. [Here is a great tutorial](https://www.sparkfun.com/tutorials/58) from Sparkfun on how to do this.
After I lay the paste down, it takes about ~35 minutes to lay the components down. If I did this in parallel, I would guess I could do 10 boards in ~1.5 hours, probably less if I got really into the zone and had a nice workstation.
In any case, here's the back of one of those DirectFets and it's associated footprint to the left. Here you can see the heckin' silicone die RIGHT THERE underneath the tin. I'm not super sure that I nailed this footprint, so we'll see what happens when I try to boot it up.
![fab directfet](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-directfet.jpg)
A group of components pre-reflow:
![fab prereflow](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-prereflow.jpg)
And afterwards - I am excited that these 56-HTSSOP pins on the DRV8302 are not welding together. Go solder paste, go.
![fab postreflow](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-postreflow.jpg)
And completed - looks nice!
![fab smd complete](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/fab-smd-complete.jpg)
## Testing
Here's my setup:
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-stand.jpg)
And I'm using a 24V Supply - I designed & rated this to 83V (capacitors are largely 100v, 83v rating comes from the DRV8302 and the FETS). But I want to stay safe and steer clear of burnouts for now.
I carefully checked all of my pinouts and double-checked that I was sending a PWM signal that I liked, then I turned it on! I had some success, and then a stall. I *thought* I saw some smoke, so not sure what's up.
I also noticed the power lines to the ATSAM chip started to flash - so I am having a power supply issue to my brain-board. This whole situation is more complicated than it needs to be. The DRV has a 5V Buck regulator, and uses that 5V Signal on a few pins... so I can't just throw it out. The ATSAM board has a 5V line, that it passes through a regulator to get the 3v3 it needs.
I imagine the 5V Buck Regulator on the DRV8302 is unhappy - it's actually a fairly complex thing, using some feedback loops to control a PWM cycle, that then is filtered with an LC on the output to generate a smooth 5V. I imagine this is going unstable.
What I did to diagnose the whole thing was connect my logic analyzer to the 5V line, 3V3 line, and to my three phases. Note - not *directly* to my three phases, as they will be being driven to 24v, and I'm quite sure I would fry my logic analyzer. I already have voltage dividers setup for the microcontroller to read the phase voltages, so here I'm just reading off of those. Nice.
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-buck-unbuck.jpg)
The first three are my gate voltages - they're being driven very nicely, thanks very much. The bottom two lines are my 5V (Channel 3) and 3V3 lines (Channel 4). So, this is dropping, the pwms are becoming very sad, and this oscillation starts.
It looks like I can remedy this by just supplying also 3V3 with my UART Cable - although I know I'll be introducing basically conflicting 3V3 lines, which is bad. We'll give it a go.
OK, great success! First thing's first, my motor turns:
![test first turns](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-first-turns.gif)
This is good news. Better news, I can read all of my phase voltages, and it looks like I'm getting satisfactory reading on my current sensing circuitry as well.
The traces here are: (0) Phase U Voltage, (1) Phase V Voltage, (2) Phase W Voltage, (3) 5V Line, (4) 3V3 Line, (5) Phase V Current, and (6) Phase W Current.
Here we see happy PWM cycles above, and what looks like a chopped sinusiod (of current) below.
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-all-sensing-one.jpg)
Zoom in:
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-all-sensing-two.jpg)
I sped this up some and it looks more like a chopped sinusoid - this means I should either dial down the sense amplification (I think the two options are gains of 10 and 40), or put smaller shunts on - right now I have 0.005 Ohm shunts (I wanted a more sensitive measurement for smaller currents).
![test getdown](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/test-all-sensing-three.jpg)
That's it for now.
\ No newline at end of file
......@@ -36,11 +36,11 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFu
[Win_1]
Type="Schematic Editor"
Loc="-1928 -8 -9 1008"
Loc="0 0 1919 1016"
State=1
Number=2
File="mkbldcdriver.sch"
View="-191.238 -0.355913 101.124 110.209"
View="-216.353 -128.597 511.138 146.524"
WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6"
......@@ -79,7 +79,7 @@ ArcDirection=0
AddLevel=2
PadsSameType=0
Layer=91
Views=" 1: -191.238 -0.355913 101.124 110.209"
Views=" 1: -216.353 -128.597 511.138 146.524"
Sheet="1"
[Win_2]
......@@ -88,7 +88,7 @@ Loc="0 0 1919 1016"
State=1
Number=1
File="mkbldcdriver.brd"
View="21.1469 45.1135 67.1527 46.5425"
View="-12.6588 37.2079 124.714 41.4748"
WireWidths=" 0.0762 0.1016 0.127 0.15 0.508 0.6096 0.8128 2.54 1.016 1.27 0.3048 0.254 0.2 0.4064 0.2032 0.1524"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.3"
......@@ -135,7 +135,7 @@ State=1
Number=0
[Desktop]
Screen="3840 1080"
Screen="6000 2160"
Window="Win_1"
Window="Win_2"
Window="Win_3"
......@@ -20,7 +20,7 @@
<layer number="24" name="bOrigins" color="15" fill="1" visible="yes" active="yes"/>
<layer number="25" name="tNames" color="7" fill="1" visible="no" active="yes"/>
<layer number="26" name="bNames" color="7" fill="1" visible="no" active="yes"/>
<layer number="27" name="tValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="27" name="tValues" color="7" fill="1" visible="no" active="yes"/>
<layer number="28" name="bValues" color="7" fill="1" visible="no" active="yes"/>
<layer number="29" name="tStop" color="7" fill="3" visible="no" active="yes"/>
<layer number="30" name="bStop" color="7" fill="6" visible="no" active="yes"/>
......@@ -38,13 +38,13 @@
<layer number="42" name="bRestrict" color="1" fill="10" visible="no" active="yes"/>
<layer number="43" name="vRestrict" color="2" fill="10" visible="no" active="yes"/>
<layer number="44" name="Drills" color="7" fill="1" visible="no" active="yes"/>
<layer number="45" name="Holes" color="7" fill="1" visible="yes" active="yes"/>
<layer number="45" name="Holes" color="7" fill="1" visible="no" active="yes"/>
<layer number="46" name="Milling" color="3" fill="1" visible="no" active="yes"/>
<layer number="47" name="Measures" color="7" fill="1" visible="no" active="yes"/>
<layer number="47" name="Measures" color="7" fill="1" visible="yes" active="yes"/>
<layer number="48" name="Document" color="7" fill="1" visible="yes" active="yes"/>
<layer number="49" name="Reference" color="7" fill="1" visible="no" active="yes"/>
<layer number="50" name="dxf" color="7" fill="1" visible="no" active="no"/>
<layer number="51" name="tDocu" color="7" fill="1" visible="yes" active="yes"/>
<layer number="51" name="tDocu" color="7" fill="1" visible="no" active="yes"/>
<layer number="52" name="bDocu" color="7" fill="1" visible="no" active="yes"/>
<layer number="53" name="tGND_GNDA" color="7" fill="9" visible="no" active="no"/>
<layer number="54" name="bGND_GNDA" color="1" fill="9" visible="no" active="no"/>
......@@ -157,15 +157,12 @@
<text x="75.057" y="35.941" size="1.778" layer="21" font="vector" rot="R90">V</text>
<text x="74.803" y="48.514" size="1.778" layer="21" font="vector" rot="R90">U</text>
<wire x1="95.758" y1="12.192" x2="12.192" y2="12.192" width="0.1524" layer="20"/>
<wire x1="8.89" y1="37.084" x2="99.06" y2="37.084" width="0.1524" layer="48"/>
<dimension x1="99.568" y1="37.084" x2="99.568" y2="61.976" x3="103.378" y3="49.53" textsize="1.778" layer="48"/>
<dimension x1="99.568" y1="37.084" x2="99.568" y2="12.192" x3="104.14" y3="24.638" textsize="1.778" layer="48"/>
<dimension x1="8.382" y1="37.084" x2="8.382" y2="58.928" x3="3.302" y3="48.006" textsize="1.778" layer="48"/>
<dimension x1="8.382" y1="37.084" x2="8.382" y2="15.24" x3="3.302" y3="26.162" textsize="1.778" layer="48"/>
<wire x1="53.848" y1="40.259" x2="53.848" y2="32.385" width="0.1524" layer="48"/>
<wire x1="53.086" y1="45.212" x2="53.086" y2="23.876" width="0.1524" layer="48"/>
<dimension x1="12.192" y1="58.928" x2="70.358" y2="58.928" x3="41.275" y3="64.77" textsize="1.778" layer="48"/>
<dimension x1="8.89" y1="62.484" x2="99.06" y2="62.484" x3="53.975" y3="72.644" textsize="1.778" layer="48"/>
<dimension x1="8.89" y1="62.484" x2="99.06" y2="62.484" x3="53.975" y3="69.342" textsize="1.778" layer="48"/>
<text x="24.511" y="57.912" size="0.6096" layer="21" font="vector">SPI</text>
<text x="24.638" y="18.415" size="0.6096" layer="21" font="vector">NP1</text>
<text x="22.479" y="18.669" size="0.6096" layer="21" font="vector">NP2</text>
......
# Programming the BLDC Driver
## Background
Here I'm using the chip I set up for my Networking project, it's an ATSAMS70 with four 'ports' for message passing, and a bells-and-whistles header that I'm thinking will be useful for doing-other-stuff (i.e. this motor controller is one of such things).
The board is documented [here](https://github.com/jakeread/tinynets/tree/master/circuit) and code for the switch (as well as useful bits for some peripheral setup is [here](https://github.com/jakeread/tinynets/tree/master/embedded)).
## The plan
- do PWM Setup
- do motor turning around at low level, on some set frequency / duty
- do UART interface for Frequency / Duty
- do MODS UART
## PWM Setup
OK, I'm going to start by turning on the PWM peripherals I'll use to control my switches. A few initial spec's:
Channels
- 3 channels, 6 outputs: one hi / one low - per phase
Base Frequency
- In selecting a base frequency for the PWM, a real engineer would look at the time constant of their motor. The coils of a motor are basically big inductors, so when voltage is switched 'hi' to them, it takes some time for the current in the coils to rise. The 'time constant' of a system is a pretty broad way to say on what-timescale-does-stuff-happen. So, in a small motor with relativley low inductance, we'll have a small time constant (say, of a few us[microseconds]). I'm not exactly sure what the units are like here, but I think this is like the time it takes for current to rise to 66% of what a full-out 'on' current level would be. This has something to do with impulse response.
- For the motors I'm using (smallish), I know (purely imperical) that a base frequency on the order of 10kHz is what I'm aiming at - a period of 100us. In microcontroller time, this is fairly slow! Additionally, this frequency generates an audible buzz (we hear the coils 'banging' on the mechanical system of the motor at this frequency) so being able to push this frequency outside of the audible range is awesome.
Deatime Insertion
- Because the circuit is setup with a high and low side mosfet, and the fets don't switch instantaneously, if we were to switch the high off and low on instantaneously, there would be a brief moment when the high and low switches were both on, allowing current to 'shoot through' from VCC to GND, and this is bad. To get around this we do something called 'deadtime insertion' - just putting a few us of off-time on both channels, between switching. There is a register for this, and additionally the DRV8302 does this automatically - so I maybe don't need to worry about it off the bat, but if it's straightforward I'll do that.
ADC and PWM Synchronization
- I'm reading current off of 'current shunts' that are 'below' my low-side mosfet.
- Current only flows through these shunts when the low-side mosfets are on! Otherwise, they are open to nothing, nothing flows, no measurement etc.