|« New toys! Davinci 3d printer!||Announcing the Mcuplace Store! (and some new projects to come) »|
Let me start by telling a little about myself. Ever since I arrived at Stony Brook I've been involved in the Solar Boat club. Were basically an organization that designs, builds and races solar powered boats. Now, when I tell people we build solar powered boats, they think RC race boats; no, we build typically around 14ft vessels meant for speed (At least we hope). Also by build, I mean we build pretty much everything from scratch including the hull, drive train and other systems. Anyway, not too long into when i joined the club i toyed with making our own motor controllers. Little did i know this design would take almost 2 years. What i want to now share with the everyone are the lessons that i have learned while working on this design. It began as something that i would expect to be done with quickly, but has turned into something which i still work on.
So why build a motor controller? There are companies that already offer plenty of solutions for electric vehicles that will work in a variety of voltage ranges and currents right? Well the truth is, not really. At our competition all the controller are either.. AllTrax, Curtis or 4QD. And all of them either are: Stuck in the 70's in terms of logic and control signals or have a micro but don't actually allow you to usefully use the information they spit out. This being a custom race boat, we want specific information so knowing how the controller is operating at all times is crucial for our boat. That is, if we design the micro system that controls the controller, we can get whatever information we want and use it however we want. We would have digital freedom, which doesn't limit our design(Hello iPhone controlled solar boat?). Secondly, if you actually design a motor controller you know the specifications on the controller are completely artificial. Can a Curtis 1205 actually only source 400 amps? Well... no, the mosfet bank is rated for quite a bit more than that. But due to thermal limitations, they manufacturer sets these limits. Same goes for voltage, most controller have over-voltage ratings to limit the input voltage, despite the fact all the components on the inside are rated for much higher voltages. When you actually design a system from the ground up, you can set those limits and maximize performance of your system. You aren't limited to designing a product specifically for consumer use. You can test the limits of your hardware and learn more about your system in the long run.(for real world design, i suggest against this, but we are racing, so we can take some things to their limits in a blaze of glory :P) These two reasons were the main reasons why i decided to begin this design. Now i would like to go over a little bit about the basics of the design of a switching motor controller
A switching motor controller, at its heart is super simple; We have a battery source, motor and mosfet bank like such:
When we apply a positive voltage on the gate(with respect to the source) The mosfets are fully conducting and the motor turns on. When we apply 0 or a negative voltage, the motors turn off. Yay! we finished our design and we can all go home, the controller works perfectly! Well... not really, we have 0 RPM and Max RPM, when the hell did you ever use a vehicle where you could only go full speed and 0 speed? The technology that we use is called pulse width modulation. I am not going to bore everyone with what it is, it's fairly simple. We have a square wave of frequency x and we vary the time that is is on, versus off. this is called the Duty Cycle and varies from 0 to 1. We can roughly estimate that Iavg = DC * Imax. Since we know P = t*w = I*v, with a constant supply voltage by changing the average current, we change the average power, and therefor for a constant torque load, we change the RPM.
To do this with any mircocontroller is fairly trivial, all decent micro's have some way of outputting a PWM wave at a specified frequency. For a PIC microcontroller, we use a single timer and we compare TMRx to the CCPRxH register, when they are equal, we have a transition from HI/LOW or LOW/HI (settable in the control register). When the TMRx register equals the PRx register we have another transitional and a new period starts. Operation is pretty simple, we have two registers, one for the Period of the wave PR2 and one for the Duty Cycle of the wave CCPRxH. The same is true for the AVR, its just different register names. So with this in mind our updated schematic is now: With this design, we have exactly what we want, we have a micro-controller that can adjust the average power going through a DC motor from a full stop to maximum RPMs. We can add various sensors to adjust the duty cycle and we can chose our mosfets however big to pass as much current we want! There is one small problem..... This setup would NEVER work.
Models and why they are important
A model is a way of representing a very complicated system with one which is much more manageable and well defined. An extreme example of a model is the law of gravitational forces:
This model allows us to tell what two forces an object will see on each other separated by a distance R. As far as well can tell, this is a very accurate model which works for most cases. However, it doesn't represent reality perfectly. We know that the law of gravity doesn't hold for the quantum scale and it especially doesn't hold true for black holes and, even when we calculate a force using this law, we only know this force to a certain amount of uncertainty. How fitting an equation the law of gravitational forces to nature is also a matter of interpretation. for a MUCH better explanation o this subject I recommend those to Richard Feynman's lecture on the character of physical law: http://research.microsoft.com/apps/tools/tuva/ The one thing that annoys me about many engineers is that many of them take a schematic as a golden rule. It exactly shows how a circuit is to operate and if you follow a schematic you will get precisely the operation you desire. This is simply not true. Lets take a simple system of a 9 volt battery with a resistor attached to it:
Now, we want to find the current so we use , great. For most applications this works great, we find what we need and now we can move on with our design. However, lets think about this, what if R is 0? Well then , which is undefined, so that means every time you short your common 9v battery, universe should explode, no? How come it doesnt? Ok, R=0 is a little extreme, but you'll also find, even with small resistances where R!=0, the system wont behave as expected. The above schematic, is only a model to a certain degree, it doesn't tell us everything about the system. For most batteries, there is an internal resistance. This internal resistance, is in series with our load resistance and limits the total output current. We can add this resistance to our schematic and improve our model by a degree:
If we keep digging we can find more and more parameters we can add to our model. One important thing is to realize when we work with REAL components vs ideal components. What makes an inductor? an inductor is a coil of wire...a coil.. of WIRE. Every piece of wire in our circuit has an inductance. What makes a capacitor? two of anything with area, separated by a distance with a potential between them, everything has capacitance, and unless you're working with superconductors, everything has a resistance. These are called parasitic components and for the most part, they have such low values, we arent concerned since they don't affect our circuit in a region we are operating it. Lets add some of these components to our schematic and we get (and yes i know i may be "missing" a few):
Whats great about this model, is that well know exactly the frequency of oscillation when an incident photon strikes the body of the resistor creating a mobile electron.We can even go further! If we add quantum mechanics we'll have a decent idea of what any individuality electron might do. Do we need this? When making a model, you have to define what you NEED to know and you design your model accordingly, for 99% of us, our simple schematic will do. When your designs start failing, and you don't know why, chances are, its because of the parasitics. For high power electronics, the parasitics own your design and your job is to constantly fight them and try to tame them.
Where we stand
Our job is to take a look at our design and find where the parasitics are, the most obvious place to start looking is the electric motor. For our motor we use either a Lynch permanent magnet dc motor or a mars e-tek electric motor. If you're curious about motors check out:
its a good video with some well made diagrams and doesn't move at too fast a pace. At the end of the day, the simplest model we can apply to our motor is an inductor in series with the armature resistance. Four our cabling we use 00 gauge welding wire, if you haven't worked with large gauge welding cable, its the most fantastic cable you can ever hope to work with, its awesome stuff, but i digress. Our wire has both inductance and resistance to it. Adding to original schematic we get:
Now to get back to the "switching" part of this design. We are using a bank of NMOS transistors to turn on and off the motor. When the bank is on, it has a resistance of RDSon/nmosfets . When it is off, the resistance is a few mega-ohms. When the mosfet is going from off to on, it is a resistance between those two. To minimize the power dissipated in the mosfets, we want to switch them as fast as possible. Once again we must look at the inside of a mosfet and understand what makes it tick. A Metal Oxide Field Effect Transistor works by using an electric field to change the concentration of carriers in a semiconductor bulk. On the gate pin, there is no physical connection to the body of the device, it is separated by a later of oxide. This gate, is analogous to a capacitor, and to apply any voltage, it must be charged. Every mosfet has a gate capacitance, and to turn on the device, we have to charge this capacitor.
We know to charge a capacitor C to a voltage of V through a resistor of R is:
where is the RC time constant. Here we can find the time it takes to charge the gate capacitor to a voltage V. To charge this capacitor we generally use an IC called a mosfet driver, we do this simple because the pins of a microcontroller can only source 20mA. At that rate it would simply take too long to turn on/off and we would waste alot of energy in our fets switching. Ok, so that problem is solved, whats next? well, lets get back to that schematic of the motor controller with the inductors, once equation you may recall is the following:
this is the equation for voltage across an inductor, is the same as saying how fast the current changes over time, now we have a mosfet that's trying its absolute hardest to turn on and off as fast as possible, di is the same as the magnitude of on current and off current and dt is how fast it takes to go from on to off. well crap.. it doesn't matter how small L is, is HUGE, it dominates that term. and everywhere in that schematic where we have an inductor, we have a very large spike in voltage. Below is an old capture of a probe across the mosfet bank. I would see spikes well past 100V on a 24V system! I essentially made a really nice boost converter! (Add output caps in the right place, and this IS how you make a boost converter)
Crap, what do we do
Because i didn't set out to design a boost converter, those spikes are unpleasant, plus they'll destroy about every component in the controller if i don't control them. Now, if we have a large positive voltage across the mosfet bank, and the input to the motor is a smaller positive voltage, we have a negative voltage across the motor (with respect to current flow). If anyone has ever worked with inductive loads before, you know the answer to this problem, we need a flyback diode. A very large bank of flyback diodes. A flyback diode does miracles to take care of the motor but we also need something to take care of the inductors in the wires, the short answer is we use a bank of capacitors on the input of the controller. The bank of capacitors act as a low impedance short to "ground" for any spikes in the wires, keeping the voltage across the controller very stable. It isn't perfect, since we have to deal with alot of energy, but it makes things safe enough that we wont unnecessarily kill anything.
This schematic represents closely what I did on the actual controller, replace the diodes, capacitors and mosfets with many in parallel and you got the basic picture of the real thing.
Now, flyback diodes are only one possible solution, another is making a synchronous half bridge controller, This is something that i am also working on, but i wanted to perfect the passive system before i moved onto an active one.
So lets dive into what the motor controller has evolved into, this is the 3(or fourth) major revision of my design and so far it is the best operating version I have.
Below is a picture of the PCB mostly populated and the mosfet bank:
Here is a picture of it connected and ready to be used!:
Picture of the watercooling:
It has the following features:
-pic18f26K22 runs the show, all pins and power are broken out to a set of headers which allow the use of "shields"
-TX Shield has filtered and buffered inputs, 3.3v supply for xbee
-Inputs for various current, temperature, tachometer, battery voltage and other sensors
-Dual independent logic and drive power supplies, coupled optically
-4 layer PCB
-Large bank of schottky high current diodes for flyback
-Bank of 12 high capacitance electrolytic capacitors, Hexagonal closed packed D.
-Breakout for 10 high power mosfets each with own gate resistor connected to two mosfet drivers in parallel
-Watercooled Mosfet Drain bus bar
I used the following components:
-PIC18F26K22 Microcontroller : http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
-FOD220 optocoupler: http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
- UCC27424 Low side mosfet driver: http://www.ti.com/lit/ds/symlink/ucc27424.pdf
-LM2796 Simple switcher: http://www.ti.com/lit/ds/symlink/lm2596.pdf
-SBR60a200ct rectifier: http://www.diodes.com/datasheets/sbr/SBR60A200CT.pdf
-FDP036n10a N channel mosfets: http://www.fairchildsemi.com/ds/FD/FDP036N10A.pdf
Two logic signals from the microare sent to the mosfet drivers, the PWM and Enable signal. everything has external pull down resistors to ensure reliable operation in case something goes wrong with the micro. Like i mentioned above, the pins of the microcontroller are broken out into two 14 pin headers, +5V and +12V are available to any header accessories. There is also a 5 pin programming port for the micro.
The header "shield" board looks like this:
Each sensor input goes to a low pass filter and an op amp buffer. This keeps the signal low noise ans allows me to temporarily ignore any real need for DSP at the moment.
Finally, the mosfet bank is watercooled using PC watercooling supplies i had lying around. This allows me to push them a little further than what you could normally get from just air cooling, ans allows me to reach the datasheet speced currents a little easier.
The code is written entirely in assembly. As of now it is 6 asm files:
main.asm - Just a file which includes all the other .ASM files.
Setup.asm - Includes the setup routine and configures on board peripherals.
FSM.asm - Contains the code for the Finite State machine.
int.asm - Contains interrupt code.
subs.asm - Contains all the subroutines.
A finite state machine was chosen because it allows very robust control loop. As long as next state/current state are in bounds, you wont have your code running out of boundaries. There is no checking to see if the next state variable is in range, but this can be easily added.
The state machine handles all the motor controller functions, including ensuring safe operation. Some of the safety features includes are to limit the change in throttle, disable the throttle when first turning on, and use of a key/killswitch. Any hazardous operation return to an idle default state which waits for key input. The code is incredibly modular and adding/removing states is relatively simple. The state diagram is shown below:
The interrupt routine simply polls all the analog inputs, stores each 10 bit a2d in two 8 bit registers and then transmits the data wirelesly to be processed off board. Also existing in the interrupt routine is limit code which defaults the controller to safe operation if it exceed software set limits.
Some features i plan to include are addition of code to read a tachometer output, and the ability to receive commands.
As of now, don't trust my comments too much, always best to look in the data sheet or ask me a question if you are confused.
Below is a video of the controller running a MARS permamemnt magnet DC motor connected by chain to a lynch motor with it's terminals shorted by a piece of welding cable. I only go to about 50% duty cycle. I am still in the process of testing and verifying the current output of the controller. I have been using the Allegro acs758 hall effect current sensor, but i haven't been getting reliable data from them. I hope that i can refine my current measurement procedure to get a better estimate of the current through the controller. Regardless, I have verified peak currents of 250 amps and continuous current of around 100-150 amps. The main limitation is cooling of the flyback diodes as they get very hot. In the video they are passively cooled with a failed waterblock, in the next revision they will be actively cooled and should allow me to push thing a little harder.
Also a little note about the setup, We made a simple dynometer to put load on our controller, its pretty simple, Motor controller drives the Mars motor, lynch motor provides load for it. By varying the restive load on the Lynch, we can vary the load on the Mars. So far we have two settings, no load and full load :P seems makng a many-KW power resistor is not simple...
Conclusion and things to improve
I am far from done with this project, but this is the first major milestone and i think most of the hard work is done. The micro code is very mature and very adaptable, the TX shield does what is suppose to, the XBEE sends data effortlessly. The Mosfet bank remains very cool and i feel safe pushing it further, the biggest limitation right now are my diodes and keeping them cool. I have reduced the switching frequency to around 250hz and this seems to be working. I will be pushing another revision of the PCB to make mounting the lugs easier, i want to also look into diodes that can be mounted on the bus bar directly with the mosfets (they are hard to find, most diodes are wired backwards of what i want).Another alternative is to make a full half bridge controller and using a back of mosfets for the back emf, this is much better than using a bank of diodes as power dissipated in a bank of mosfets is proportional to Rdson and not a constant voltage drop. However, this adds much complexity to design as I now have to make the two banks of mosfets synchronous. Even worse, you cannot find PMOS transistors of these current ranges (In a cheap, useful package) so its best to use NMOS transistors on the high side with a boost cap mosfet driver. I've used them in the past and they can be unreliable, but i will be looking into the possibility of using them in my next design.
As with all my project, files are below, if you take from my design, give me credit. I dont mind you taking and improving where I leave off.
Form is loading...
|<< <||> >>|