After being totally whored out for CPW by giving rides to prefrosh and generally being hooned around campus, I remounted the kart sound system to use as a portable music device and all-around pimpmobile for Mini-Maker Faire the weekend after. But thirty minutes before departing for the Faire, I powered the kart on.
It wasn’t a spectacular explosion. It wasn’t even a smoke column or a quiet sizzling sound. Through a half hour of diagnostics, I only managed to deduce that the gate driver stopped driving the gate. The power FETs appeared to be fine. Whatever – we were late already, so I just pushed the kart a mile or so to the Cambridge Public Library where the event was being held, blasting bad eurodance and girl pop along the way.
Afterwards, I decided to just remake the controller, yet again. The latest iteration, version 5, did work, but was haphazardly put together (i.e. pretty par for the course). I wanted something that had more structure than a bundle of wires. I also wanted to keep advancing on the number of features and simplifying the schematic. This resulted in the great gate driver hunt of 2010, out of which the IR2184s came.
As described, the existing controller core is kind of a kludge. It was just an Arduino with a protoboard shoved onto it which had the gate drive componentry. Alongside was a 12v DC/DC converter. Everything was just packed inside a little box with foam bits, and not otherwise secured.
Running the controls in open air for half an hour to diagnose the latest failure resulted in me discovering that the DC/DC converter got hot. Way hot – hot enough for it to shut itself off, which explained alot of kart flakiness.
So I did what any shady college engineer would do given a totally rigged and quasi-functioning project – rip everything the hell apart.
I dismounted everything and took the mounting board out of the kart.
The big black slick in the righthand corner is from grease and oil being thrown upon it by the drive chain.
Let’s begin again. We start with an epic heatsink:
I found this in the materials cave at MITERS. There are a few reasons why I wanted an Epic Heatsink, the foremost of which is epicness.
The other reason is modularity. At 300 x 200mm, this heat sink had enough area on its back to mount practically all the core componentry. I wanted to move away from point-to-point hardwiring onto something a little more modular, like a commercial controller.
Mechanical issue: Only one side of the heatsink had space for mounting holes or other provisions. The other seems to have been trimmed off by someone else.
It just so happened that removing the bent fin would open up a width on that side of the heat sink equal to the width of the flange on the other.
…so that’s what I did. Remembering a trick someone showed me a while ago, I slammed the heatsink on the mill and cut down the bent fin.
The 3/4″ rod fits into the 5/8″ T-slot on a Bridgeport mill table and provides a straight edge to bump a long part against, for axial trueness without resorting to hammer bashing and a dial indicator. Normally the rod should be precisoin ground or otherwise some length standard, but in this case, “precision” meant “closest one to me that qualified for diameter”.
With the edge cut down but no holes drilled yet, I started laying out the components. There were a few iterations – this is the first. The FETs would be centrally located so one fan can blow on the back of the heatsink to cool them. The Arduino would sit right next to the gate pins.
But that was before I found these cool double capacitor holders, which allowed me to pack on more bus capacitance than the kart currently had (2400uF to 3900uF) and keep it on the heatsink mount. Of course, caps like this don’t need heatsinking themselves, but the mounting surface was there.
Through more cramming, I decided to also move the contactor onboard, such that the unit was essentially self-contained. Other parts of the power system, like the battery cutoff switch, terminal blocks, and power connector, would remain offboard.
I took a quick break and laid out the parts. The heatsink itself already had quite a few holes drilled in it from its previous, more legitimate application, but sadly none of them lined up. Thus, it was back to the mill to drill the mounting holes, which was a rather boring half hour of trying to match a digital readout with a hole chart.
Some screws and washers later, and the pieces are mounted. The contactor is case-grounded, and my intention was to keep the heatsink itself isolated. So, it’s secured by large nylon screws and insulative washers. The Arduino and capacitor block are mounted with nylon standoffs.
The DC/DC converter has an isolated case, so it was bolted straight to the heatsink. It will probably be alot happier this way. It, and the two Ixys gigaFETs, got a liberal coating of Arctic Silver thermal compound on the bottom.
Here’s the new driver board. It’s another Arduino-perfboard assembly that houses two IR21844 dual gate drivers. Unlike Kartroller 5, the high sides are bootstrapped, not supplied via isolated regulator. I decided this was a good simplicity tradeoff. Additionally, it’s much more failsafe – the boostrapped high side can’t maintain 100% duty cycle, so it can never get stuck on like the low side drive can.
The wiring nest on the underside, in typical me-fashion. I’m using some cool 30 gauge solid tinned wire that has very unique insulation properties. It doesn’t smoke or burn when it contacts a soldering tip, but rather just melts out of the way. It’s very thin and easily damaged.
But those same properties let me just mash the wire into the solder joint with the tip and it will automagically fuse with the solder ball that’s already present. This has enabled me to just go pin-to-pin and link up an entire net very quickly.
I think it’s wire-wrapping wire, but I’m not sure. What is it and where can I get more?! MITERS is almost out!
Check out the integrated signal terminal block. I even labeled it so I don’t forget which wire goes where!
Most low power wiring joined. Notice the small 5mm power plug coming out of the DC/DC converter and into the Arduino. I figured it was better than soldering directly to the input pins…
Here’s the gate wiring from the Arduino shield to the FETs. Gate resistors are integrated into the heatshrunk portion of each cable end. I really should have local pulldown resistors too, but elected to keep those on the shield.
The rightmost gate wire got red shrink because I ran out of black.
I began to add other signal interfacing hardware to the shield at this point. First to be completed is the contactor detector. It’s a wire (the red one) connected to the contactor (through a resistor divider) which enables the software to see whether or not the contactor is latched. One of the problems with Kartroller 5 is that it just let me (or someone) gun the throttle even with the contactor was in the precharge state.
This just caused the controller side voltage to fall under 36 volts, resetting the DC/DC converter, thus shutting the logic off. In turn, the FETs turned off, causing the voltage to rise again, which… well, it led to an unhappy cycle of kart-twitching until I reached for the battery switch.
The next few lengths of wire connect the Arduino to the important I/O – throttle, brake, and reverse.
With all the signal side wiring done, I could start on the software. Here’s a makeshift user interface with a throttle pot, a brake pot, and a reverse switch.
Wait, what do you mean “brake pot”?
Does that mean I’m removing the disc brakes?!
Nope. But for the longest time, I’ve been telling people that LOLrioKart has regenerative braking. Now, this is pretty much a total lie, because Kartrollers 3 through 5 (the ones with a proper half-bridge layout) couldn’t actually switch the high side transistor to build up the motor current which allows regen to occur.
Now that I have both the confidence and a driver chip that allows this to happen easily, I’ve run into a smaller but not insurmountable (and actually convenient) problem. The IR21844 is a synchronous rectifier chip that takes one input and internally splits it into two complementary outputs. That means as long as the chip is enabled, the high side and low side are always switching in complement with one another. This is the way it’s supposed to work in a switching power supply.
It works that way in a DC motor too, but the experience is much different. In most vehicles, if you stomp on the accelerator and let the vehicle build speed, it will just coast until friction brings everything to a stop. In an EV with no regen capability or that enabled by another switch, the same is true.
However, in an EV driven by a synchronous regulator that is always on, you’d faceplant into the steering wheel on throttle lift-off because the motor will try its best to brake when the rectifier is in its circulation state.
To put it another way, in an always-active synchronous regulator, the motor is braking some percentage of the time and accelerating the rest of the time, and you just control the percentage. Full stop is just like 100% braking. To get the throttle-coast effect, I’d have to alternately switch the IN and #SD pins on the 21844, instead of just driving IN low. This takes more processing and pin-banging than I care to think about. Additionally, when I do that, I bypass the internal built-in shoot-through protection of the 21844, ruining everything I have ever loved.
So what to do in this case? Now, one method to achieve this coast state is to use current control (instead of voltage control, which is much simpler and what most motor controllers perform) and command a zero current. Zero current necessitates the regulator switching at just the right ratio such that the motor’s back EMF equals the output, and following this zero current state all the way down to a stop.
I didn’t design this system with a current sensor in mind, nor do I feel like making another feedback disaster yet. So I opted to take advantage of the fact that an average speeding shopping cart and the average coasting motor are both readily approximated by a first order system.
Figure 1: Example of first order decay with varying time constants
Refer to the above pretty picture . The pictured time axis is arbitrary. This is a simplified model of “I floor the accelerator on LOLrioKart for a short amount of time, then lift totally off”.
In an ideal, friction-free world, any object accelerated to a certain speed will just stay at that speed forever, represented by the purple line. That doesn’t work in real life without a net power input. Friction, a force dependent on speed, will eventually bring everything to a halt. In an electromechanical system, any opposing force dependent on velocity can be lumped into a “friction” term. Varying this causes the rate of decay to change, resulting in the red, yellow, and green curves. The red curve represents very sharp decay, or high damping. The yellow is an intermediate value, and the green a low value – the system coasts for a long time before stopping.
Now, in an EV, two major forces can dominate the “friction” component. Real mechanical brakes and tire scrubbing with the road, or the electric motor itself. An electric motor can provide a resistive force proportional to the speed of rotation by acting as a generator, extracting work from the system’s kinetic energy. Even better is that this rate of work extraction can be modulated – that’s the whole point of regen braking.
Conjecture 1: By programming in an artificial throttle decay curve, I can simulate the effect of neutral coasting.
This involves interpreting the throttle in the following manner: Follow it exactly if I am depressing the pedal (value increasing), but send it through a digital low pass filter if the direction changes, such as if I back off. This software LPF will slowly ramp the motor down over a long period of time.
In a synchronous rectifier arrangement like I have the gate drivers set to be, regenerative braking occurs automatically if the kart is trying to drive the motor faster than it wants to go given a certain duty cycle of the output. Essentially, the motor acts as the dominant source of “friction” in this case, but instead of dumping the energy as heat, it dumps it back into the battery bank!
Conversely, if the kart wants to coast down slower than the set decay curve, the motor will spend a little energy prolonging it. If I set the decay to zero, it will keep driving the kart at a constant speed forever, at least until I run into the nearest dumptruck. As such, I’ll have to make sure the filter maintains a “minimum decay rate” so it eventually WILL just stop.
Conjecture 2: By making the decay time constant adjustable, I can adjust how much apparent mass the kart has, or modulate the regeneration strength
The job of the “brake pot” is to make true conjecture #2. For now, it will just be on an instrument panel. By adjusting the pot, I can set the coastdown time constant of the kart. Alternatively, if I start with “infinite” coastdown, then increase it, I can rapidly stop the kart through regenerative braking only. This latter effect would be more useful on a brake pedal.
The phenomenon of applying a tiny amount of braking at all times is called “drag braking” in the EV world. The same effect occurs in an automatic transmission car, except it’s not adjustable… on purpose, anyway.
So let’s do it!
Say hello to the ghetto-ass screenshot of my laptop reading an Arduino program through the serial port. I’ve implemented the aforementioned one-way digital LPF in a test program that just makes throttle values.
You can see the variables besides the printout window.
- lastGoodThrVal is just the last output value that the loop calculated
- curThrVal and curBrkVal ought to be self-explanatory – it’s the magnitude of each input.
- brakeFraction and coastFraction are the two components of the digital LPF. coastFraction is the “hold previous value” component, while brakeFraction is the “input component”. That is, coast is the second term and brake is the first term in this equation, which I implement in the program.
This video of it working will save me (30 pictures/s * 1000 words/picture * 30 s) words! Notice:
- with “hard braking”, or curBrkVal high, the output value closely tracking the (scaled) throttle value on the way up as well as down.
- with “slow braking”, or curBrkVal low, the output takes a long time to decay back to zero.
- that if i suddenly hammer the brake while the value is coasting, it will fall very quickly.
Alright, so what’s next after making sure the code works?
HOOK IT UP
I tested from a current and voltage clamped power supply just in case I Did It Wrong™. You can see the result for yourself.
First, I perform a few start-stop cycles with hard “braking” – or high virtual friction, whichever. Next, I toggle the reverse switch while the motor is moving slowly. I do this slowly because if I do so too fast, the voltage spike causes the power supply to crowbar, shutting everything off. Not exciting at all.
Finally, I do a few spindowns with the “virtual inertia”(/slow braking/little friction) effect visible.
The shaking motor is due to my very slow update rate of 100 milliseconds. This is well above the motor’s mechanical time constant, so it actively responds to the stepped changes in the controller’s output. LOLrioKart will have a much higher mechanical time constant, but it might still help for me to increase the refresh frequency.
Here’s a short clip of the regenerative brake effect when I suddenly increase the brake percentage while the motor is coasting. The power supply pegging above 50 volts is the best indicator. If I brake too hard, it goes over 55 volts and the PSU gets mad.
4 quadrants of love.