Monday, February 20, 2012

3ph v4.0

I've finally nailed down working Sensorless Sine-Commutated Field-Oriented Current Control (SSCFOCC) for Pneu Scooter, and I promise I will write up this (relatively) simple algorithm sometime soon before moving on to more complex closed-loop observers and other controls-y things that won't be of much practical advantage over this simple one, at least not for a while.

In the mean time, I've also finished the v4.0 design for my scooter-sized (~48V/40A) motor controller, with some tweaks to make it more optimized for SSCFOCC:

It's the same physical dimension as 3ph v3.1 (3.90"x1.55"), so it will be a drop-in replacement for the controller currently in Pneu Scooter. Other things that have not changed:
  • MOSFETs: This design still uses the GWM series miniature 3-phase full bridge modules from IXYS. Specifically, the GWM100-01X1, although it could also use the GWM160-0055X1 or the GWM200-004P3. They're hard to find, but I've stockpiled enough to survive until the end of the world.

  • Logic: Still using the STM32F103 on a Wootstick 2.0 because why would I change that?

  • Current Sensors: Two phase current and one DC current sensor using the ACS714 Hall-effect current sensors. They measure +/-30A, so in order to get to full operating current I can selectively bypass them with one or two 0.001Ω, 1% resistors each.
One thing that has changed is the current sensor layout. SSCFOCC relies on the current measurements to make an estimate of the rotor position, so cleaning up the current sensor signals as much as possible was one of my goals in this design. I know from experience that they pick up massive amounts of PWM noise. Better hardware and software filtering, as well as synchronous current sampling, have definitely helped. But it would be nice to tackle some of the noise at the source, with better layout around the current sensors:

It's a fact of life that the current sensors, particularly the phase current ones, need to be located directly adjacent to high dV/dt switching nodes. High dV/dt leads to capacitive coupling, and one way to protect sensitive traces from capacitive coupling is to shield them with ground planes. So, in an effort to minimize capacitively-coupled PWM noise on the current sensor signal wires, I did my best to shield the signal side of the ACS714's and the traces returning to the logic part of the board with ground. I don't know how much it will help, but it probably can't hurt.

The next big change is a return to optically-coupled gate drive. 3ph v1.x and v2.x, as well as most of my other motor controllers, have used optically-coupled gate drive. 3ph v3.0 and v3.1 used the IR21844 half-bridge drivers instead for compactness and low cost. But, this was before I realized that bootstrapped optically-coupled gate drive is possible and you don't need expensive high-side power supplies for everything. So with cost less of an issue, it just became a matter of stuffing six HCPL-3120 gate drive optocouplers onto the board. The half-bridge unit looks like this:

The input AHI is a 3.3V logic signal directly from the STM32F103. If AHI is high, the high-side optocoupler LED turns on. If AHI is low, the low-side optocoupler LED turns on. If AHI is high impedance, neither LED turns on and the half bridge is disabled. R69 and C54 form a low-pass filter that sets the shoot-through delay. Each gate gets a gate resistor, a pull-down resistor, and a 17V Zener diode. D2 is the bootstrap diode for the high-side driver.

The last big change is the addition of phase voltage sensing. To do this, I added a quad op-amp configured as a differential amplifier to measure Va, Vb, Vc, and the DC bus voltage with respect to power ground. One unit looks like this:

Differential measurement with respect to power ground (COM) should be more accurate when high currents push power ground and signal ground apart.

Phase voltage sensing opens up a number of interesting opportunities for 3ph v4.0. One is simple block-commutated sensorless, where one phase is left undriven (which I can do now, thanks to the tri-state-able optocoupled gate drive) and the back EMF is directly measured. I'm not sure why I would want to do this, other than for direct comparison to more advanced sensorless techniques with the hardware as a control.

Besides block commutation, measuring phase voltage may also be useful for rolling-start, which is something I do a lot on the scooter. Right now, I have to push against the resistance of the shorted motor until the current sensors pick up enough information to derive the rotor position. It finds itself at a very low speed, so this isn't a big deal. But, with phase voltage sensing, I could leave the phases off and use the back EMF measurement to do the same. The practical advantage is that you can freely kick up to any speed before applying power.

Another thing phase voltage sensing might be useful for is online or offline calibration, where the back EMF is measured and used to estimate the motor's torque constant or other parameters. At very least, it could be used as a single-purpose scope to make a plot of the motor's back EMF waveform, which is informative by itself.

All these extra features made the board a bit of a nightmare to route, with one of the highest component densities I've ever done:

I managed to cram the entire 15V and 5V power supply on the bottom layer, this time with ceramic capacitors. The six gate drive optocouplers barely fit on the top layer above the MOSFET. All the filters and logic are on the top layer under the STM32 board. There are also still inputs and filters for Hall effect sensors, even though I mostly plan to use this for sensorless control.

I'll sent these boards out right after the holiday weekend and as usual, post the schematics and other files when I confirm they work. Of course, the first sub-version of my boards are usually doomed to failure (3ph v2.0 and v3.0 didn't last very long, whereas v2.1 and v3.1 were great) so we'll see what happens.


  1. Hey I love your design! It's really neat!

    One thing though - how come you didn't use the TIM1 complementary PWM channels with programmable dead-times instead of the hex inverter/capacitor combination?

  2. Thanks! There were a few reasons I didn't use the TIM1 outputs:

    - The UART TX/RX pins are multiplexed with some of the TIM1 outputs. You can remap the Tx/Rx elsewhere once the program starts, but I also need them for the bootloader and in that case they can't be remapped.

    - The passive deadtime control is a nice feature - it means I can't accidentally create a shoot-through condition by bad programming.

    - In the previous version of this controller, I wanted to play three channels of MIDI music through the motor:

    Turns out that is easier if you put all three PWM inputs on separate timers, so they can have independent frequencies. v4.0 can still do this, I hope, but only in sensored-mode.

    1. Oh I see! I love your MIDI controller - it's such an overkill! Are you planning any future directions with that, e.g. putting an audio (a voice one maybe) stream through it?

      I see you're using the USB-FTDI for the UART bootloader - have you looked into using the onboard USB capability and using that as a serial interface, so you can remove the FTDI chip on board after loading the USB serial interface software on initially?

      BTW Shane, are you doing a PhD or Masters? This all seems to be a tad above an undergrad degree! Just curious...


    2. I might try to improve the MIDI parser a bit, but I don't plan to put voice output on it, at least not for a while. It might not be that hard, I just haven't thought about it much.

      I have thought about using the onboard USB with the Maple bootloader, to make my hardware compatible with the Maple. One catch is that I currently have it set up for wireless bootloading over XBee, which goes straight to the UART.

      I'm a PhD student right now.