Sunday, December 13, 2009

3ph Duo: Codefest, Part II

If nothing in my last post made any sense, this is what I was trying to say:

I used my good camera w/ directional microphone, and set up the scooter frame so that it would resonate. The difference is pretty clear here. Everything you hear translates to what you would feel while riding it, so the ride will be much smoother as well.

I finally worked out all the sign (+/-) kinks. The remaining task is to make it fault-tolerant and load test. The Hall effect sensors are not perfect, and they can occasionally throw in a false signal or miss a real signal. This becomes even more important when they are being relied upon for a speed estimate that drives the sine waves. The motor and MOSFETs should be able to tolerate a glitch like this, but at high speeds it can cause a draw-down on the main capacitor, which can sometimes cause the microcontroller to spontaneously jump out of the program loop. So it would be better if this didn't happen...

More to come.

Thursday, December 10, 2009

3ph Duo: Codefest

These days, most people are surprised when I tell them that my background is in mechanical engineering, not electrical, since more often then not I am troubleshooting some circuit or winding a giant inductor or something. But probably the thing that nobody knows is that my real background is in software. Okay, not in the educational sense, but I've been programming things since I was like...ten. I won't make any claims about my actual skill, but I will say that on more than one occasion I have been saved by a bit of software fidgeting that I probably couldn't have done if I hadn't been writing all those games (e.g. Pokemon Hunter and Pokemon Hunter II) when I was too little to use power tools.

In one of the saddest tragedies of my life, the original source code for Pokemon Hunter (written in QBASIC!) has been lost forever, but I assure you the graphics looked roughly like this.

Oh yeah, this is a post about my brushless motor controller. Or, the latest of them, anyway. If you've lost track, here is a side-by-side comparison of the three real iterations it has gone through:

Left-to-Right: Newest, Middle, Oldest

First was the double-stack IRFB3077-based controller (right), my very first shot at three-phase brushless motor control. While it has the distinction of MOSFETs so powerful they caused the aluminum bus bars to desolder themselves (Yes, you can solder aluminum.), it was impractically large for the scooter because each one only controlled one motor. Next was the greatly compacted 3ph Duo, so named because it controlled two motors from a single board using two IXYS GWM 100-01X1 six-pack MOSFET bridges as the inverter stages. And it works. But as I described in the last post, that won't stop me from making yet another one.

The most obvious visible change is the lack of LEM current sensors. These were large and expensive and have been replaced by the ACS714 surface-mount sensors, two each per motor. Two each so that I can effectively measure three-phase currents, instead of assuming that only two phases conduct current at a given time. If you want to know more about why I am concerned with this, this post sort-of sums it up. The goal is to implement full sine wave commutation with the possibility of phase adjustment, something that would separate this controller from other similarly sized and priced small vehicle brushless motor controllers on the market. Turns out from a hardware standpoint, this is very easy. The microcontroller I use, the TI MSP430F2274 already has six independent PWM output channels (three per motor). So the circuit board is essentially the same, with a few signals re-routed to make room for the six PWM pins.

The real challenge is the software. This is not a 32-bit processor with native floating-point. It is a regular old 16-bit mixed-signal processor that runs at a relatively poky 16Mhz and doesn't even have hardware multiply. Your cell phone probably has 10x more processing power. To roughly lay out the challenge: the PWMs are refreshed at a rate of 15kHz, setting the upper limit on the resolution of the sine waves generated. (You get 15,000 points per second with which to draw the sine function.) But to use all 15,000 points per second, six PWM values must be generated and scaled appropriately at every refresh. The clock speed is 16MHz, so all this has to happen in less than 1,000 clock cycles. To give you an idea of how hard this is, just multiplying two integer numbers together takes about 70 clock cycles on this chip. Forget about fractions and definitely forget about trigonometric functions. The only way to generate a sine wave is to use a look-up table, in this case 256 bytes in memory that store the value of the sine function for various angles. To set a baseline, this is how I originally implemented a sine-wave look-up on six channels:
aidx_int += aspeed;
aidx = aidx_int >> 8;
atemp = SIN8LUT[aidx];
btemp = SIN8LUT[(unsigned char)(aidx - TWOTHIRDSPI)];
ctemp = SIN8LUT[(unsigned char)(aidx + TWOTHIRDSPI)];
atemp = 65023 - ((atemp * amag) >> 6) + ((127 * amag) >> 6);
btemp = 65023 - ((btemp * amag) >> 6) + ((127 * amag) >> 6);
ctemp = 65023 - ((ctemp * amag) >> 6) + ((127 * amag) >> 6);

uidx_int += uspeed;
uidx = uidx_int >> 8;
utemp = SIN8LUT[uidx];
vtemp = SIN8LUT[(unsigned char)(uidx - TWOTHIRDSPI)];
wtemp = SIN8LUT[(unsigned char)(uidx + TWOTHIRDSPI)];
utemp = 65023 - ((utemp * umag) >> 6) + ((127 * umag) >> 6);
vtemp = 65023 - ((vtemp * umag) >> 6) + ((127 * umag) >> 6);
wtemp = 65023 - ((wtemp * umag) >> 6) + ((127 * umag) >> 6);
One motor is ABC, the other is UVW. This steps through the sine table at some speed, looking up values with an independent index for each motor. Then, it scales those values by some magnitude and shifts them such that their PWM-average outputs are sine wave voltages centered at half the DC voltage:

The PWM outputs, normalized to the DC (battery) voltage, for full-command (top) and half-command (bottom). In both cases, they are centered at half the battery voltage.

Well, this almost worked. It worked with 1, 2, 3, and 4 channels. But with 5 or 6 channels, the interrupts starting running into each other because it took longer than 1,000 clock cycles to get through that block of code. Luckily, it's not a very efficient way of doing things, so the next few paragraphs will describe how it was trimmed down. First, the zero-sequence hack. I don't know of anyone who refers to it as such, but this is my favorite motor code hack of all time. A lot of the code above is being used simply to offset the PWM values so that they are always centered at 50% duty cycle. This is...stupid. (Maybe not, but I declare it to be so.) So I ditched that drive method in favor of one that always puts the peak of the sine waves at +Vbat, like this:

The modified drive signals at full-command (top) and half-command (bottom).

The difference is that, except at full command, the three sine waves are shifted up to higher voltages with respect to the battery. But what really matters, as far as the motor is concerned, is the relative voltage across the three phases, which is the same in either case. The same amount of current will come out of or go into each wire, and the bulk shift does not change the motor operation. It does, however, greatly simplify the code:

aidx_int += aspeed;
aidx = aidx_int >> 8;
atemp = SIN8LUT[aidx];
btemp = SIN8LUT[(unsigned char)(aidx - TWOTHIRDSPI)];
ctemp = SIN8LUT[(unsigned char)(aidx + TWOTHIRDSPI)];
atemp = -((atemp * amag) >> 6);
btemp = -((btemp * amag) >> 6);
ctemp = -((ctemp * amag) >> 6);

uidx_int += uspeed;
uidx = uidx_int >> 8;
utemp = SIN8LUT[uidx];
vtemp = SIN8LUT[(unsigned char)(uidx - TWOTHIRDSPI)];
wtemp = SIN8LUT[(unsigned char)(uidx + TWOTHIRDSPI)];
utemp = -((utemp * umag) >> 6);
vtemp = -((vtemp * umag) >> 6);
wtemp = -((wtemp * umag) >> 6);
The extra multiplication of the magnitude to get the sine waves in the right place is gone. So is the bulk offset. All that's left is a negative of the magnitude times the sine value. (Don't ask why it's don't want to know.) This manipulation gets the interrupt routine down to a size where it can actually run at 15kHz...barely. The processor utilization is up near 60%:

This signal is high when the processor is in a PWM interrupt executing the above block of code.

Of that, roughly half of the time is spent just doing the six multiplications. There are tricks for fast software multiplication, but only if one of the operands is known a priori (not the case here). The sine table look-ups, as fast as they are, also take up some time. The adds and shifts are relatively small contributions. Amazingly, though, this actually works. Try getting your computer to do anything when its processor is being utilized by background processes 60% of the time. (Okay, dual core...I know...) But this can still execute a slow loop with control and data acquisition functions and read in more interrupts from the hall-effect sensors. It's still a little quirky, but it didn't collapse in a mess of horrible interrupt stack Jenga blocks like I thought it might. can actually be even more efficient. The key observation is in the nature of the outputs, a balanced three-phase set of voltages. This type of output only really has two degrees of freedome...magnitude and phase. So you should really only have to look up two numbers, right? (Can you see it coming?) If you add the sine of any three angles separated by 120º each, you get zero. Try it. Or have Wolfram Alpha try it. Here's my proposal: Look up and scale two sine values per motor. The third is the sum of the first two, negated. C = -(A+B). W = -(U+V). It's a bit more complicated because of magnitude offsets, but if this offset is calculated based on the magnitude in the slow loop, it can be simply added to the third value:
uidx_int += uspeed;
uidx = uidx_int >> 8;
utemp = SIN8LUT[uidx];
vtemp = SIN8LUT[(unsigned char)(uidx - TWOTHIRDSPI)];
utemp = -((utemp * umag) >> 6);
vtemp = -((vtemp * umag) >> 6);
wtemp = utemp + vtemp - woffset;

aidx_int += aspeed;
aidx = aidx_int >> 8;
atemp = SIN8LUT[aidx];
btemp = SIN8LUT[(unsigned char)(aidx - TWOTHIRDSPI)];
atemp = -((atemp * amag) >> 6);
btemp = -((btemp * amag) >> 6);
ctemp = atemp + btemp - coffset;
That's two fewer table look-ups and two fewer multiplies. The resulting interrupt should run 30% faster, giving back valuable clock time. Again, don't ask why everything is negated...

That's a far stretch in the name of efficient computation, but I assure you it makes a difference. Although everything seemed to be more-or-less working even with the bulkier interrupt. It's always good to write simple code, for many reasons. Which reminds me of another good one:

Yep, finally ran out of program memory. And I sure as hell am not going to buy the $N,000 full version of IAR Embedded Workbench. For the record, no compiler is worth that much money. It's not like Solidworks or some specialized simulation program that costs a lot of money to develop. It's a f*cking compiler. It takes C code and makes assembly code based on a set of well-understood standards. Even if I were using it for a commercially, it would be more worth my time to get a free GCC compiler and learn how to use Eclipse. Screw you, IAR. But I love your free version. :) So I will just have to keep my code size down.

Now might be a good time to step back and ask what the heck I am doing. Optimizing this one timy bit of code is a long way from making a new sine-commutated motor controller, and I have a long way to go before I can say I've finished the latter. But with the sine wave generator running at 15kHz in the background, all that's really left is to integrate the Hall effect sensors and some sort of master control loop.

The Hall effect sensors are really easy...dare I say easier than they are with the normal six-step commutation scheme where they drive a state machine. When a sensor hit comes in, you abandon whatever position you were at before and jump to the "correct" place in the sine table. "Correct" is tricky, and this is where a phase offset can be added in. But for now, I will rely on the scooter's moveable Hall sensors to make this work. The other piece of the puzzle is to set the speed of advance through the sine table, aspeed and uspeed in the code above. This is done by (carefully) estimating the time of one electrical cycle, which is six Hall effect transitions or in this case 1/7th of a revolution. I say carefully because this breaks down at low speed and also can be "glitchy". So there is more software work to be done here.

Lastly, the master control loop. This is where the high-level implementation happens. Eventually, this will hopefully measure and control both the quadrature- and the direct-axis current. The quadrature-axis current is the current that actually pulls on the magnets, creating torque. The direct-axis current can be used to change the torque-speed curve by countering the magnets, but I doubt this will make much difference for the scooter motors. Anyway, there is still some work to be done before this method of control is fully functional. For now, it is easy enough to create something that works by just controlling some semi-arbitrary current measurement, or even just running it open loop. This is where I am now...testing the subsystems to make sure they are working reliably before I integrate everything in the master loop.

But that didn't stop me from trying to ride it. The most noticeable difference (besides the fear that it might jump out of the program loop and short the motor at any moment) is the reduced torque ripple. You can actually hear the difference between DC (six-step) operation and AC (sine wave) operaiton. Okay, maybe you can't really hear the difference...but that's mostly because my microphone is terrible and the sensors were still not quite in the right place in either case. But there is definitely less high-frequency noise. If you don't believe me, believe MATLAB:

I promise I will do a better job capturing the results in a future update. That is, assuming I don't go crazy from debugging software. It's usually not my favorite thing to do. There's some fun in squeezing every last drop of computational power out of this thing, but I would still rather be making something tangible. Although in the end that's what this is for, so that's one plus. And if things go downhill, the old controller worked perfectly fine. Which...hrm...why am I doing this again?

I also promise a massive technical write-up for anyone who is interested in how this thing actually works. Ha...funny...nobody cares about controller. But there will be a write-up nonetheless.

Sunday, December 6, 2009


In case you were wondering what this was all about, this might make more sense:

Introducing Failbot.

Recently, many of the projects I've been working on have been for credit, or for a class, or continuations of my never-ending quest to build a better motor controller. Speaking of which, the newest implementation is showing promising results. Except for the fact that I ordered some incorrect components, it went together perfectly and, without giving away the big reveal, is quietly proving that sine wave control of standard hall effect sensor brushless motors is ... easy.

Right, Failbot. I've been thinking that my projects have become a bit too large in scope and slow in execution. I say that being a grad student has basically slowed my pace down by a factor of two, since for every hour I spend actually doing something, I now have to spend another hour wondering if it's the right way to do it, what the potential problems are, and how to do it more efficiently in the future. So I am taking on this mini-project as an admission of my declining ability to just do something without thinking it through from beginning to end. In fact, every time I stop to think about Failbot, I realize how likely it is to not work at all. Solution: stop thinking about it!

Anyway, the idea is simple: linear tread motors. It's something I've had in mind since about the time when I realized you could actually build a motor. The operating principle and basic construction is the same as the 12-slot, 14-pole "LRK" scooter motors. Except, it is unwrapped into a linear motor that pulls magnets attached to a tank tread. I have no doubt in my mind that, conceptually, this works. The difference here is that I don't have the time or money to invest in a properly-designed linear bearing system. So bad idea #1: The Teflon Gap. It's like an air gap, except with Teflon. This is the part where I go back to high-school physics:

That is a Teflon-coated wooden stick, a nickel-plated NdFeB magnet, and a 1kg block of steel. This isn't the magnet size being used on the treads. But for the experiment, I just wanted a nice big surface. The objective here is to find the coefficient of friction between nickel-plated magnet and Teflon. So, an inclined plane is in order:

This dirt-simple experiment shows the static friction coefficient to be about 0.11 and the kinetic coefficient to be about 0.08. Which is good, because there will be approximately 75lbs of normal force holding the magnets to the Teflon! The good news is that, unlike my 2.007 robot, the treads will stay on. The bad news is that they may not move at all. This means that the linear motor needs to develop at least 10lbs of force to do anything, let alone move smoothly. The rear scooter motor puts out about 30lbf at the air gap...but it's 1" wide. These are only 3/8" wide. In order to work, it will need similar or higher amp-turns, which is no easy task given the small slots. And I guess the coefficient of friction might change a little when the Teflon gets scratched up and little iron filings stick to the tread magnets... Oh, did I mention that there is no commercially-available reversing brushless motor controller that runs off an RC signal? Well, except maybe this one. However, ordering it on eBay might be a problem:

So assuming I don't get arrested or have my account suspended, I get a $60 controller that might be capable of reversible speed control. If you wonder why I make controllers from scratch, this is why. But in this case I would rather try my luck with the RC stuff. If it works, it will save me a lot of time and will be 2.007 hardware-compatible. Like my last little robot...minus the high-speed acrylic-shattering collisions. Maybe some MechEs will look at it and be use wheels instead.

Thursday, December 3, 2009

HSV: Arrows and Fruit

In case you've never seen what an arrow going through fruit looks like in 333x slow motion.

These videos were shot with a Phantom high speed video camera in the Edgerton Center Strobe Lab during a freshman seminar. The lighting came out very well, even at 10,000 frames per second. Everyone's favorite seems to be the one where the arrow misses, taking out the cups but leaving the fruits hanging in mid-air. Newton's first and second law in action.

An interesting side note: the Phantom capture software saved the video in raw 8-bit format at a resolution of 512x256 (exactly 512x256 bytes per frame, no compression). But it added a .mov header. Although Quicktime could play it, my custom video converter tried to extract the frames as raw data. It put the header in as dummy pixels on the first frame, then all subsequent frames were shifted by that amount (so that they looked off-center). The fix was some very simple math:

  1. Divide the file size in bytes by (512x256). Take the remainder.
  2. Subtract that number of bytes from the file using a hex editor. This is the header.
  3. Confirmation that the header ends after this number of bytes:

A wonderful little tag "mdat" (movie data?) at the exact address of the remainder. I love raw video! Compression is for losers.

Wednesday, November 25, 2009

Everything You Ever Wanted to Know About Brushless Motors

I've been doing a lot of reading lately about brushless motors and their control. Every once in a while I find a good application note or paper or website that makes something clearer to me. (Other times, the information I find contradicts other things I've read or just makes things more confusing.) But just last week I stumbled across the single most consistent and thorough explanation of motors I have ever seen, a Master's thesis by James Mevey from Kansas State.

Make no mistake, this is not a quick read (355 pages), and it requires a basic background in electromagnetism, circuit theory, and electric machine theory. But I promise you that if you have at any point been frustrated by the inconsistent or incomplete treatment of electic motors found on the interwebs, or by the abstracted and overly complex theory in research papers and electric machine textbooks, this report is what you've been missing.

It's clear that the author put a tremendous amount of effort into this thesis, more than I can even comprehend.The explanations are clear, but not simplified. The notations are internally consistent and many (most?) variations found in other literature are explained and compared in tables, charts, and figures. Oh, the figures! They are all HAND DRAWN. And not like my hand drawn pictures.

Is that a jellyfish stuck inside an axial flux motor?

No, nothing like that. These have all the nice scale and readability of computer-generated graphics, but with the friendly this-isn't-as-complicated-as-it-sounds style of whiteboard sketches. Almost like a comic strip. About electric mtors. Look for yourself!

Anyway, I'm not telling you to read the whole thing (yes I am) but I did. In case you're busy watching football or eating Thanksgiving dinner (I will be, but I already read it), I can do a book review-style highlight of the most important concepts that I got out of it, without going into detail or ruining the ending.

1. Back EMF and torque are two sides of the same coin.
I sort-of knew this already. In a brushed motor, the back EMF constant (relating voltage produced at the open motor terminals to the speed of the motor) and the torque constant (relating torque produced to the current passing through the motor) are the same number. The simple explanation for this is that after all the electrico-magneto-mechanical interactions that happen inside the motor, the only thing that really matters is power conservation. Pushing current into a voltage (such as the back EMF) is positive power. This results in a positive torque (torque attempting to increase the speed of the motor).

The conversion is lossless.
All the losses are taken into account by adding resistors to the electrical model and/or damping to the mechanical model. So if you put 500 electrical Watts into the back EMF, you will get 500 mechanial Watts out. If you divide by the speed of the motor, this gives you the torque. This is always true. At zero speed, you can take the limit of this to find that torque is still proportional to current. For negative power (generating), you have to be pulling negative current out of a positive back EMF (or pushing positive current into a negative back EMF).

The simple DC motor model.

The thing made clear to me by James Mevey's thesis was that this model works just as well for a brushless DC motor. The power conservation through back EMF works the same way. You can prove this using a few different E&M and/or field theory tricks. (He does all of them, for good measure.) But intuitively it also makes sense that there needs to be something to push against, namely the back EMF, for power to be converted. In the limit as the back EMF and speed go to zero, torque is still proportional to current.

But, unlike a brushed DC motor, the shape of the back EMF of each phase of a brushless motor is a function of rotor position and is periodic. It repeats every two poles, so for a 14-pole motor like on the scooter, it repeats seven times per revoltion. This base shape then gets scaled by the speed. It's as if the back EMF "constant" for a given phase is actually a periodic function of the rotor position. That's sort-of obvious, but the less obvious conclusion is that, taking the limit of the power conversion through the back EMF as speed approaches zero, the torque "constant" is the same period function of rotor position. So another way to look at it is that the torque produced by each phase is simply the base shape of this same rotor position-dependent function multiplied by the current going into the phase. This is also always true.

2. None of the above changes for trapezoidal (BLDC) vs. sinusoidal (BLAC/PMSM) motors.
Just by applying the very simple power-conserving back EMF idea, you can analyze any motor with any drive. I was wondering about the functional differences between BLDC and BLAC/PMSM. James Mevey says:
"It is the author’s opinion that the difference between trap and sine BPMs is surrounded by more misunderstanding and confusion than any other subject in the field of brushless motor control..."
I am inclined to agree. But this thesis makes it very clear that the only functional difference is the shape of the waveforms (both the back EMF and the drive waveform). BLDC refers to motors with more-or-less trapezoidal back EMF, common in small motors. Like this:

From the scooter motors, line-to-line and assumed line-to-neutral.

Why is it trapezoidal? This is entirely due to the geometry of the motor. It has nothing to do with the controller, which should be obvious (although for some reason it's not) since this measurement can be made with nothing attached to the motor at all. It has to do with the layout of magnets and coils and steel. The more you can see sharp transitions in magnets, coils, or steel, the more trapezoidal it becomes. This is common in small motors because it's easier to make a motor with concentrated windings and discrete, non-skewed magnets.

As a counter-example, larger motors often called "brushless AC" or "permanent magnet AC" tend to have skewed magnets and overlapped windings in a large number of slots, so their back EMF looks more sinusoidal. These motors can (should) be driven with a pure AC signal. If, for example, the back EMF and current are both sine waves that are in phase, and there are three balanced phases separated by 120º electrical, the power (torque) produced will be constant. Try adding together three sin^2 waves (current times backEMF) shifted by 1/3 period each. Or have Wolfram Alpha do it for you. There is clearly an advantage to having constant torque in things like large machines, electric vehicles, etc.

But what about BLDC motors with trapezoidal back EMFs? Well, this is where things get more interesting. You can drive them with a signal that looks like a square wave, except with gaps where the trapezoid has non-zero slope. Like this:

Ignore the blips.

To the extent which you back EMF is truly a trapezoid with a 120º-wide top, you can split the drive into six equal-length segments, two positive, two negative, and two off. By doing so, you get zero current during the sloped part of the trapezoid and full current during the flat part. Multiplying back EMF by current still gives power (torque). Accounting for all three phases, offset by 1/3 period each, also gives constant power (torque). This is the basis of brushless DC motor control. It's very simple to implement in software or even just pure logic chips. Since it relies only on 60º position estimates, it can be easily accomplished with three hall-effect sensors or with many sensorless estimation methods.

If they are simpler to make and to control, but yet still give constant ripple-free power, why not make all brushless motors this way? Well, for one, the purely trapezoidal back EMF is not realistic. It may not be as flat, for as long, as the 120º approximation. Things tend to smooth out into sinusoids if you let them. Which brings up the next point: what happens when you account for inductance?

That's the same square-wave drive, but now with a reasonable inductance factored in. Permanent magnet motors tend to have low inductance in general, but even so it still distorts the shape of the drive current at even modest speeds. It's not even a clean low-pass filter. That's because the drive inverter has flyback diodes start to conduct current during the "off" period. And on top of all that, the whole thing is phase-shifted so that current and back EMF no longer line up perfectly. The net result is a power (torque) fluctuation. The good news is that the fluctuation is at six times the commutation frequency, and so at high speed the system inertia easily damps it out. The bad news is it's still significantly lower than the torque produced at zero speed, since the low pass filter takes power out of the harmonics and moves the whole thing out of phase with the back EMF. The other bad news is that the diode conduction in the controller can start to cause more heating in otherwise highly-efficient MOSFET drives.

There is an obvious benefit to using sinusoidal drive, then. Everything, after passing through a low-pass filter, gets closer to looking like a sine wave anyway. You can also eliminate the diode conduction periods which throw the whole analysis off. And if your motor is designed to have sinusoidal back EMF, everything works nicely and all that's left are magnitude and phase shifts. To the extent which a trapezoidal motor can be thought of as having a fundamental sinusoidal component, some of the analysis used in sinusoidal drive can also be applied to trapezoidal motors, understanding that there will be harmonic distortion. But everthing still works within the back EMF power conservation analysis method for figuring out torque.

3. Field-oriented control is all about keeping current and back EMF in phase.
There are a lot of complicated ways to explain it, but the one that makes the most sense to me is that the goal of field-oriented control is to make up for the phase lag that comes in at high speed when the inductance start to become significant. Obviously for induction motors, there is more to it. But for permanent magnet motors, it's as simple as keeping the two sine waves (or whatever waves) of the back EMF and the current in phase as much as possible. This produces maximum torque, for reasons that should be obvious from the power conservation approach I keep mentioning.

The back EMF in a permanent magnet motor is fixed to the rotor position, always. This was another point of confusion for me, namely when it comes to field weakening. But field weakening is a lot simpler than I thought. It does not change the back EMF. The back EMF comes from the rotor magnets alone. What field weakening does is produce another field that fights the magnets in the air gap, reducing the flux to some degree. But this is all accounted for already! It's the inductor in the circuit! It's really that simple. But it only really makes sense if you look at things from the rotor reference frame, often called the d-q frame. (d = direct = in line with the magnet flux, q = quadrature = leading the magnet flux by 90º electrical). In this frame, there are only a few simple rules:
  • Back EMF leads magnet flux by 90º. That is, it is always on the q-axis.
  • Voltage leads current by some amount determined by the motor inductance and resistance.
  • Torque is proportional to the amount of current in phase with back EMF, i.e. the dot product.
What this looks like for a few different cases:

The first case is what things look like when the motor is spun up with no load. The voltage on the terminals (whether you apply it or not) is equal in magnitude to and in phase with the back EMF, which leads the magnets by 90 electrical degrees. (Keep in mind this whole picture is in electrical degrees, so you have to divide by the number of pole pairs to get the mechanical equivalent.) The second case is what happens when a load is applied to the motor without changing the relative position of the voltage. This would be like a simple hall-sensor or encoder based commutation that always fires the phases at the same position.,i.e. open-loop control. The problem is that at high speeds, current goes out of phase with back EMF, since some voltage is developed across the low pass filter. The sum of back EMF, voltage on the inductor, and voltage on the resistor is still equal to the voltage applied at the terminals, but this is a vector sum so things get tricky.

Now here are two cases where the relative phase of voltage can be controlled (advanced). For demonstration purposes, this could be done by physically rotating the position sensor on the motor. Obviously for control, it would instead be done by adding some phase offset in software. The left-most case is field-oriented torque control. The voltage is advanced to make up for the current lagging behind it. The net result is current in phase with back EMF, the theme of this story, and ideal torque. The right-most case is what happens when you advance the voltage even more. Now, current goes out of phase the other way, so some torque is lost. But, the other components of voltage rotate out of the way a little, allowing the back EMF (speed) to grow without increasing the voltage applied. This is field weakening. You trade off torque for a bit more speed. The back EMF could even be higher than the voltage applied, extending the speed range of the motor without increasing the DC supply voltage. How much of this you can get away with depends on the inductance of the motor. Generally, surface-mounted magnet motors have low inductance and limited field-weakening capability. But "limited' might still mean you can get 50% or 100% more speed!

To some extent, I knew this already. But the great thing about seeing it consistently presented is that I now understand why it works. And even more cool, I see that it's all part of the same, simple model. Everything is accounted for without even diving into the magnetic domain. You just measure back EMF, draw some triangles, and come up with the performance of the motor. It's all become simpler to comprehend because it fits into a minimalist model.

Now I have some more solid footing to stand on for the full-AC version of my controller. I can start thinking about field-oriented control, how it will interact with different motors (trapezoidal, sinusoidal) at different speeds, etc. I guess at heart I am more interested in motor control than in motors themselves, but as I can see now you can't understand one without the other!

READ IT! Here's the link again.

Monday, November 23, 2009

Sunday, November 15, 2009

3ph Duo: Afterburner

So here's the deal: My 3ph Duo motor controller is 100% working. It's been in service on the scooter for some time now, happily controlling two 500W brushless DC motors. In a previous post, I explained how it is already comparable to commercially-available BLDC controllers of similar power. I am completely satisfied with the current version as a finished design that could actually compete with what's out there now. So now it's time to kick on the afterburners and make it something that doesn't even exist in this price range.

Nitpick #1: It's still a good deal larger than some of the nice RC plane controllers out there. Okay, but it's a full vehicle controller! And I already made it much much smaller than v1.0 so it would fit inside the scooter deck! Okay fine:

I swear this as short as it can get.

Now it's 1.047" from heat sink surface to tallest component. (Previously 1.205".) That makes it shorter than, for random example, a 26650-sized battery. How did I do that?

The LEM current sensors are gone, which brings me to...

Nitpick #2: The current sensing was not great. I had this clever idea that you could sense current in a BLDC system using only a single sensor, since one phase is always off. Well...not really. It works great at stall and at low speeds, but at high speeds the inductance of the motor starts to make it so that even when a phase is "off" it still conducts for some time. Conversely, the phase you think is on may take some time to start conducting. So at any given time, all three phases might actually be carrying current.

"Real" controllers use two sensors on two phases. The third is easy to find, since Ia+Ib+Ic=0. So I ditched the LEM sensor for two of this wonderful find: the Allegro Microsystems ACS714. It's a 30A bi-directional current sensor with 0-5V output. And it's surface mount, so it takes up much less space. I'm out of analog ports, so there will have to be a 2x1 multiplexer to read in two currents per motor. But since the ADC is multiplexed inside the microcontroller anyway, this shouldn't affect processing time.

Nitpick #3: It's somewhat expensive. But it runs two motors! And trasmits data wirelessly! Recession? What are you talking about? Okay, fine. How about this deal: Four of the ACS714 at $4 each and two $0.50 multiplexers gives $17. Versus two LEM current sensors, totalling $38. That's a savings of $21 per board. But wait, there's more. The most expensive set of components on the board are actually the six DCP021515 isolated high-side supplies, which used to cost $12.25 a piece. Magically, they are now $11.75 on Digi-Key. Well, as it turns out, there is actually a lower-power version of this, named the DCP011515. The 02 vs. 01 means 2W versus 1W. The gate drive requirements for this controller are way less than 1W, so there's no reason to use the 2W chip. How much, you ask? $9.83. So that's a total savings of $14 per board. For a total of $35 chopped off the total cost. That brings the total component cost down to about $235 per board in single I-can't-make-even-the-first-price-break quantities.

Nitpick #4: It's still just a brushless DC controller. Well, as it turns out, the microcontroller has plenty of processing power left over. I figured out that running the existing code, the interrupt routine that handles motor commutation wouldn't start to run into problems until scooter speed of Mach 4.5. So most of the time it's just sitting around waiting for something to happen. Well, now there are two current sensors. That, plus some math, is really all you need for full AC vector control. Well, you also need three independent PWM channels per motor to generate the sine waves. Luckily for me, the TI MSP430F2274 has exactly that many:

This is a plot of three sine waves generated by PWM signals from a single timer. They are phase-shifted by 120º, as they would be in a 3-phase motor. Since the controller isn't really fast enough to do trig operations, they are produced by stepping through an 8-bit memory table of sine values. These would be the average voltages sent to the motor, and compared to the square-wave drive of BLDC, it should make for a much smoother start-up.

But that's not the end of the story. Controlling the voltages to be sine waves that are in sync with the rotor is nice, but you still have the problem of inductance causing the motor current to lag at high speed. As the current lags, less of it goes into producing torque. (Current that is in sync with the rotor magnet flux is what produces torque.) One solution is to advance the phase of the voltage wave a bit to make up for it. The trick is, how much? You can be all open-loop about it and just guess, since it will likely be proportional to speed. Or you can literally measure and feedback-control the current at a higher bandwidth than the stator electrical frequency. (Which is the number of pole pairs times the rotor angular velocity.) But that's really, really fast. The scooter motors, which are relatively slow, can get up to nearly 200Hz. So the controller would have to run in the kHz range! And it would have to handle six independent current control loops. There's processing power left over, but not that much.

So, I propose a compromise: A low-bandwidth phase advance control loop. At a leisurely pace, the controller measures the three phase currents (per motor). Using some fancy math, it can convert that into two values: Iq, the quadrature-axis current, which is current that is in sync with rotor flux and therefore producing torque, and Id, the direct-axis current, which is current that is out of phase with rotor flux. Using two separate control loops, the voltage would be adjusted to set Iq (and thus torque) and the phase would be adjusted to set Id. This would be the basic idea, in power-point block diagram form:

The sine wave generator is always running, but the sensing and control happens asynchronously at a much slower rate. So, many electrical periods may pass between updates of the phase and magnitude of the voltage. But that might just be okay. The idea here is that Id is feedback-controlled to be zero by adjusting the phase of the voltage sine waves, while Iq is feedback-controlled by adjusting the magnitude of the voltage sine waves to give the desired torque. If you want to get even fancier, Id can be controlled to be non-zero for field weakening, which uses some of the current to fight the magnets and reduce the back EMF for the purpose of achieving higher top speed. The controllers themselves could be P or PI or PID controllers.

Will this actually work? I have no idea. It has the nice benefit of being completely asynchronous, so I can keep slowing it down until the controller is happy with the processing speeds. Although I think it will have no trouble at 100Hz. I also wonder about the two control loops sort-of fighting each other or oscillating. My hunch is that it can be tuned to run stably. But that's just a hunch.

Anyway, if it works, it will be quite an advanced little board. But even if this low-bandwidth AC control scheme fails miserably, I still get a smaller, lighter, cheaper, and better BLDC version. Win-win.

(As usual, new schematic/documentation to come pending testing.)

Sunday, November 8, 2009

Epic Axial Motor: Epic Axial Update

I don't exactly know what an axial update is, but at least it's an epic update. Dare I say the turning-point. (Every project has one...on the Cap Kart, for example, it was the complete revision of the power circuit at the last minute that made everything simpler and, well, possible.) If I know something can work, sometimes I don't work out the details until I need to. And now I need to.

Detail #1: The rotor. Okay I gave this one to Mike N, master of things that spin dangerously fast. He came up with an awesome design that looks even better in real life than it does in CAD. Something about the aluminum, nickel-plated magnets, and the ground steel back-iron makes it look bad-ass. This does not do it justice at all:

It looks like it should be in outer space somewhere.

Simply epic. The bearings, which neither of us have bothered to model in, are tapered roller bearings that can handle the high thrust load of the magnets. All the parts are fabricated and right now we are assembling the stator and rotor independently. The total width of the assembled motor will be 3-5/8", not including a bearing retainer plate and any sprocket/encoder packages we add. The diameter will be 9". And the total weight is on track to be under 40lbs.

Detail #2: How to get the wires in. This motor will be handling up to 200A of current, so it needs some massive wires. Remember the shaft is stationary, so the wires all come in through its hollow center (ID=0.5"). Turns out the largest three-phase set of wires you can fit in that diameter is 8-gauge, which would be enough to carry about 100A. I opted instead of two sets of 10-gauge fiberglass-insulated wire (McMaster PN 8209K21). It's a smaller diameter conductor than the 8-gauge, but it's rated for high-temperature use up to 100A. The fiberglass will also protect it from sharp edges. The problem is after traveling through the shaft, it has to make a tight turn to come out of the hub in the center of the stator. I thought about this for a while and decided to split the shaft and leave the center of the hub open to give the wires more turning radius room:

Two sets of wires enter through the hub.

The aluminum hub has a much higher Ixx and Izz than the steel shaft anyway. And both common sense and FEA show that the center of the motor does not take much torsional or bending load. It all gets transfered out close to the side plates. This was an easy modification that doesn't require any fancy machining. And to my amazement, all six wires actually fit without much persuasion:

Something that was easier to make than I expected, for once.

What you see there is the current state of the stator. We only have two sets of stator tooth laminations right now, to test windings and maybe back EMF. (I'm starting to doubt whether the backEMF test will give a useful result, since there is a large part of the total magnetic circuit missing.) But anyway we will at least get to see how things physically go together.

Detail #3: How to wind it. The original plan was a strip of copper just a bit under 2" wide and 0.016" thick. It would be covered with Kapton tape and wound in a nested fasion around itself, six layers per tooth. I gave this a try:

Test winding of one stator tooth.

The good news is that it was very easy to wind. I did one layer of Kapton tape to cover the steel, then wrapped the copper/Kapton strip with only hand-tension. Having the tooth out in free space to wind is one of the biggest advantages of this type of motor, in my opinion, and it definitely showed here. I was able to wind a tooth is less than 10 minutes. The 0.016" copper is soft enough to wind without a jig. After compressing the layers with a clamp, it was within the space allowed in the design. The end turns stick out a bit further, because of the sharp radius, but they go out into free radial space, another nice aspect of this design.

The bad news is that after winding this one, I realized how difficult it would be to get to the innermost layer. I knew this would be a problem, but seeing it physically convinced me that any of the potential solutions I had thought of so far would not be clean. So I asked around and thought for a while before coming up with a new idea: Instead of one 2" wide winding, having two 1" wide windings such that the winding starts and ends on the outside. A picture is worth 1,000 words:

Two nested windings.

The two windings are connected to each other at the inner-most layer. This might be hard to visualize, so imagine taking a piece of paper that starts out looking like this...

...and folding it away from you on the dotted lines, then continuing to wrap the strips around something so that they overlap each other. That's how the winding would be created. Except instead of paper, it would be copper. The nice thing about it is that the start and the end of the winding are on the outermost layer, offset from each other axially. No need to make tabs. The interconnections become very easy:

The end of one tooth's winding lines up with the start of the next tooth's winding. You could just solder the ends together, for the most part. I had to think about this for a while, but I'm 99% convinced it would work out. Here's how half of the motor would be connected:

Reference for the winding layout for a 16-pole, 18-slot motor:
Jae-Woo Jung; Jung-Pyo Hong; Young-Kyoun Kim, "Characteristic Analysis and Comparison of IPMSM for HEV According to Pole and Slot Combination," Vehicle Power and Propulsion Conference, 2007. VPPC 2007. IEEE , vol., no., pp.778-783, 9-12 Sept. 2007.

Notice that with the exception of a single jump wire, all of the connections are edge-to-edge and could be done with a quick solder joint. This should make final assembly very straighforward.

But there was one huge problem with all this. That is, now every tooth has 12 turns, and the copper is half its original width. If this was wired up according to the original plan, which was to have all six teeth of a given phase (18/3) in series, it would create a motor with twice the operating voltage for a given speed. Sure, this would be more efficient, and maybe it's something we want to do down the road. But for now, we had been planning to test it as a low-voltage, high current motor, hence the low turns count and massively wide conductor.

The solution to this was actually obvious, although it took me some hours of thinking. Since the motor has 16 slots and 18 poles, the magnet/tooth cycle repeats itself once. (The GCF is two.) To get more current in, I had already put two sets of three input wires. Instead of connecting the two phase-A wires together and then routing the combined current to all six phase-A teeth in series, all I have to do now is connect each of the phase-A wires to it's group of three teeth on one side of the motor. The two phase-A windings will be in parallel. Ditto phase-B and phase-C. This will create two parallel windings, each seeing the same amount of flux (and thus the same voltage) as the original design. And it can carry the same amount of current, split between the two halves of the motor. Problem easily solved. Of course, I still didn't quite trust the analysis so I re-did the FEMM simulation with two parallel windings:

I used circuits {A, B, C, U, V, W} and set IA=IU, IB=IV, and IC=IW. The total current for the parallel set of A and U, therefore, is twice the current of either. What I got was that at IB=IV=-100A and IC=IW =100, the torque produced was 63N-m. The total current for the parallel phases would be 200A. This gives a torque constant of about 0.32N-m/A, very similar to the one I calculated with 6 turns per tooth and all teeth in series.

Side note: The reason the FEMM model looks nothing like the real motor is because FEMM can't do 3D simulation. So, I unwrapped the motor into a semi-infinite linear motor. I can then simulate for x-axis force and use the effective radius at the centeroid of the magnets and stator teeth to caculate the torque. I'm pretty sure this checks out.

Detail #4: What is the continuous power rating of the motor? I can do the thermal capacity calculation that says "I have this much copper mass and it is generating this much dissipated power. How long can this stay under this many degrees, given no heat transfer capability?" (No heat transfer meaning either it is completely insulated, or the time of the event is much shorter than the thermal time constant of the motor.) In fact I did do this and came up with something like a peak torque rating of 120N-m fo 60 seconds, starting from room temperature...

But this is a stupid way to calcuate torque/power. You want to run the motor continuously for some time longer than one minute, and ultimately the limit is how quickly you can get heat out of it. Heat comes out at the surface of the windings. (Yes, some goes into the stator core as well, but since that's going to be generating a good amount of heat itself, and since the path from there out of the motor is much harder, I assume most of the real cooling will occur at the outside of the windings.) Disclaimer: heat transfer and fluid mechanics is not my thing. But I did go back into my notes to find the forced convection equations, before stumbling on this nice efunda calculator. Here are the numbers I put in:

This is for a single side of the outside layer of the copper strip. What this says is that with 5m/s air flow (corresponding to about 200cfm through the entire motor), the copper can transfer out 2.34W per 2" of strip in the airstream. With 18 teeth, 2 sides per tooth, and 2 strips per side, this means it can get rid of about 168W continuously with a winding temperature rise of 50C. Well...that's not very much, now, is it? Let's say we do an insanely good job with the motor and it is 95% efficient. That means that the continuous rating would be just 3.2kW :( This seems to defy my intuition of how much current you can push through something this size. There are obvious analytical ways to improve this. It could run at a higher temperature. If the windings were allowed to go to 125C, the heat transfer would roughly double, allowing a 6.4kW continuous rating. If the air speed is increased by a factor of two, the cooling goes up by 2^0.5 (something about the Nusselt number and the square root of the Reynolds number...). But still, it's not looking good for continuous power rating. Even with the windings allowed to run to 125C and 400cfm air flow, and 95% efficiency, it's only ~10kW continuous as predicted by this method.

Well.... Here is where my analysis is going to stop. I could go do a fluid flow simulation and see what the actual numbers are. My intuition says you can dissipate more than 168W with 5m/s over this geometry and a 50C rise. Also, if you go by even the conservative rating for magnet wire, 5A/mm^2, you get a higher continuous power rating. And I would imagine that Kapton/copper sandwich is better at conducting heat to the surface than a magnet wire winding. (Actually, I don't have to imagine. I did this calculation and it's true.) So something is wrong here. Maybe there is conduction and radiation to add in too? Maybe there is also heat transferred out of the sides of the teeth? Maybe some really does go out through the shaft? Maybe I just don't know anything about heat transfer. But I do know how to pass large amount of current through something and measure its temperature rise over time, so I think I'll do that instead and report back the results!

Things are getting real.

Friday, November 6, 2009

SMMA Fall Technical Conference - Wrap-Up

Well, I don't really have any new pictures, so here's some dessert.

Yesterday wrapped up my trip to the SMMA Fall Technical Conference and I failed to update the "live blog" (which I have decided never to do again) mostly because I spent many hours in the airport and on a plane. But anyway, I am back in Cambridge now. The trip was definitely a good one for me. I expected to learn a lot, and I did. Here's a few things that I came away with:
  • The electric motor industry is very big, reaching out into many markets. The biggest ones seems to be industrial (big constant duty induction motors) and automotive (little accessory PM motors, not traction). But both of those markets took a big hit. The "new markets" are renewable generation (wind) and automotive traction. Almost everyone identified these markets, but few have stepped into them yet, it seems.
  • There was a very interesting idea proposed by EMERF for a pre-competitive research consortium that could maybe focus on some of these new markets, or on PM issues. The thing that comes to mind for me is the FEMMulator. Here's what I mean: The "industry" is slow, and built on a large pool of experience and expertise and data from existing designs. And then there's the FEMMulator...a free program that one person wrote to run an iterative FEA design simulation on a brushless motor. Here's the "disruptive technology," except instead of a technology it's really more of a disruptive methodology. The idea that anyone can get access to enough information and computing power to design a motor these days means that the process is different...and a collaborative research intiative seems to make sense, IMO.
  • On the technical side, there are a lot of things I know now that I will have to look at more closely. For one, segmented drive PWM. I thought I knew all there was to know about PWM in an h-bridge or inverter, but apparently not. So I will look into the more interesting methods and see if they could be applied to my controller at all. Also, there is a commercial sensorless zero-speed-start BLDC controller available call the DPFlex, from Agile Systems. It uses variations in inductance to measure starting position of the rotor. I knew this was possible and had been researched, but it's interesting to see one in production. I wonder if I could get my hands on one for cheap...or else it's good at least to know that it exists.
  • There were also some ideas that were met with a bit of skepticism. There was QM Power, which, well I understand where the skepticism comes from. I actually thought their presentation was pretty good, but after going back and reading their website...their idea is either ridiculous or they do have a clever breakthrough and need to fire their entire marketing/promotional team for making it sound ridiculous. There's also a clever idea for a harmonic drive motor, which is like a harmonic drive gearbox but without the strain wave use electromagnetic forces to move the spline. That one is really clever, and it would certainly work. The question is how efficient it would be. But it would be great for robot actuators, etc.
  • I got some good feedback on the axial motor concept. It's fairly unique even among axial motors, and most people think it could get very good power/torque density. Interesting to see how it works out.
That's pretty much the wrap-up. Lots of new contacts and lots to think about. It was an good trip for me and I think the presentation part went pretty well. (Nobody asked about the that's good...) As promised, a link to the presentation I did (minus videos) and also to the paper. (Overview of the Summer Engineering Workshop with emphasis on the BWD Scooter project, with cool pictures of course.)

Wednesday, November 4, 2009

SMMA Fall Technical Conference - Day 2

Day 2 at the SMMA Fall Technical Conference.

Today was the first day of the conference proceedings. That meant tabletop sessions and parallel presentation sessions from 8AM to 7PM, followed by a nice dinner. The tabletops were very interesting. I didn't get a chance to wonder around much because I had to man my table, but I was right next to the bearing guys:

Bearing sea.

So one of life's mysteries (How do you assemble a ball bearing?) has been answered for me. The answer, it turns out, is far less magical than I thought. Anyway, that was fun. Proto Laminations also had a tabletop across the way with a very flashy poster. Here's a fun picture of our matching tables:

How is it standing up?

That, by the way, is Wally Rippel from AC Propulsion. He was also responsible for the Great Transcontinental Electric Car Race between Caltech and 1968. Yes, 1968. Long before Tesla or the EV1, they raced electric cars across the country in 210 hours, recharging from the grid along the way. Caltech won by 30 minutes, but both cars finished the 1968. So what exaclty have we been doing since then? (Besides landing on the moon and inventing the internet.) Well, batteries are a lot better these days. As are power electronics. Maybe time for another race?

One observation I got from today was that the motor manufacturing industry, as a whole, is relatively conservative. (They describe themselves this doesn't have the same connotation as it does back in's more a deliberate, careful way of doing business, not a political/social position.) But since the economic downturn, things are being shaken up and the big shaker-uppers are energy and transportation. So a lot of the manufacturers need to decide whether they want to take big risks by heading into these markets.

One big deal topic was permanent magnets. Some went as far as to say that they are avoiding permanent magnets altogether as too risky an investment for motors. The logic, which eludes my own sense of the workings of a global economy, is as follows:
  1. China has all the rare earth ore.
  2. They want to make magnets instead of exporting ore.
  3. More value added = more profit for China, less for the US.
Okay, but doesn't that just mean that you get your finished, ready-to-install motor magnets from China instead of from the US? They would probably be cheaper, if anything! It's not like oil...there is no impending shortage. Maybe I just don't understand the market. But here's the next step in the logic I've heard that is the real interesting part to me:
  • If China wants to make magents instead of exporting ore, then they will eventually want to make motors instead of magnets.
Well now I can see why that would be a problem for the motor manufacturers. But I still can't see how that justifies moving away from PM if it is clearly the better design choice for certain types of motors. Isn't the end result there that China makes better motors and we still lose market share? Wouldn't be the first time we've gone down that road.

Interesting, interesting stuff. But a bit outside my expertise, so I'll stick to the technical stuff.

Day 3 coming up.