Phase current limiting interface for RC esc

Hornet dave

10 mW
Joined
Nov 15, 2011
Messages
27
Hi guys. Im working on a project that isnt a bike but does use an RC motor and controller, usually runs well below full throttle, and has a load that is quite variable in nature. Peak power of 2 or 3 kw. This sounds much like an ebike.

In an attempt to safeguard the esc and make my setup more or less bulletproof, it seems like the esc must either be sized to handle the peak phase currents, and/or the peak phase currents must be controlled. Im going to be exploring the latter, trying to control phase currents in a simplistic manner. This has probably been tried before but my searches have come up empty.

Here is the concept: it seems phase currents on a brushless motor can be approximated by battery current divided by the duty cycle of the current going to the motor windings. This duty cycle can be approximated by the throttle signal going to the ESC. Battery current is easy enough to measure with a shunt. So, take your battery current, divide by the throttle position, and you have an easy approximation of phase current. Use a simple controller to reduce your throttle when the phase current exceeds the amp rating of your controller. And add some input capacitors.

So, whats the catch? This group is a smart bunch of guys and the ebike bunch does not seem to be doing this, so there must be something reason why this doesnt work. $40 for an arduino and a few other little odds and ends, stone simple software that will let you do other things like current limiting or fancy throttle schemes, and a good candidate for open source design.
 
Hornet Dave (love the name). Welcome, you have stumbled upon one of the problems for the ages that has not yet been solved on a mass scale. There have been attempts, but none have satisfied thus far. I know of one in the works, maybe it will be unveiled soon, but here is a link to one that I happen to have but have never used. It might be a little different in that it limits the current not control it:

http://endless-sphere.com/forums/viewtopic.php?f=28&t=8160&hilit=fechter+current+limit


And here is an old thread (wow you guys there is a lot of post from Safe in this one):

http://endless-sphere.com/forums/viewtopic.php?f=2&t=78&hilit=fechter+current+limit
 
Hornet dave said:
Here is the concept: it seems phase currents on a brushless motor can be approximated by battery current divided by the duty cycle of the current going to the motor windings. This duty cycle can be approximated by the throttle signal going to the ESC. Battery current is easy enough to measure with a shunt. So, take your battery current, divide by the throttle position, and you have an easy approximation of phase current. Use a simple controller to reduce your throttle when the phase current exceeds the amp rating of your controller. And add some input capacitors.
Welcome Dave,

That is the way that the CycleAnalyst does it:
http://www.endless-sphere.com/forums/viewtopic.php?f=28&t=29846

Alternatively:
http://www.endless-sphere.com/forums/viewtopic.php?p=416416#p416416
http://www.endless-sphere.com/forums/viewtopic.php?f=2&t=28935
 
Hornet dave said:
Here is the concept: it seems phase currents on a brushless motor can be approximated by battery current divided by the duty cycle of the current going to the motor windings. This duty cycle can be approximated by the throttle signal going to the ESC. Battery current is easy enough to measure with a shunt. So, take your battery current, divide by the throttle position, and you have an easy approximation of phase current. Use a simple controller to reduce your throttle when the phase current exceeds the amp rating of your controller.

that is exactly how our $100-$150 12 fet 2/3kw controllers do it.
they only measure battery current, and usually limit that, but with a low resistance motor you also get a much lower limit (lower that is, when your watching just battery current) stepping in only at low speed when the phase currents are huge, and i remember maby jeremy harris? (maby spelt wrong) saying they work by the exact same approximation method you suggest. -buy one.
 
Im glad this concept has merit. I started this trek with something similar to Fetchers analig controller, modified for my throttle input requirements. However, after collecting some data it became obvious that phase current limiting would be needed in addition to battery current limiting, and i just couldnt figure out how to do that in an analog manner. Once i realized the arduino had analog inputs, $25 for one seemed like quite a bargain.

The controller should show up any day now and i have already procurred some high side current monitors. Now its time to try my hand at smd soldering. The current monitors may be the biggest barrier for people, i couldnt find anything in a DIP pakage but it sure looks easier than messing with op amps. This project should move pretty slowly, just to warn everyone.
 
The parts have arrived. The SMD chip was easy to solder, the arduino is super easy to use and program, i got one of those dlux 120 hv escs to dedicate to the project, now i just need for it to fast forward to April for some good weather.

Im chipping away at the code, ill give it a shot with just proportional control to keep things simple. With any kind of luck ill be able to test a little over the holiday.
 
Moderate success! I've got the interface seemingly working as desired, but I won't have a chance to give it a real-world test until spring. I'll scribble up a circuit diagram in the next day or two, but the code i'll post here right now. First I need to explain my application a little. I'm using this for a brushless powered (63-74-200kv) RC glider winch. Here's a sample I found on youtube:

http://www.youtube.com/watch?v=UGimKxzWe2I&feature=related

This being a glider winch, my user control interface is not a proportional throttle but rather an on-off switch that is foot activated. So if you use this code for a bike application, you'll have to re-write the throttle input section so that it takes your throttle range and scales it appropriately. Next, depending on your ESC, you may have to treat the throttle endpoints from the arduino to the ESC in a different manner than what i've done. With a Castle ESC, absolutely do NOT use the auto-calibrating endpoints as you have to calibrate the endpoints on every power-up. Use fixed endpoints instead, it's a lot easier to deal with. Lastly, this is pretty hacked together and i'm not looking for the most elegant code on the planet, i'm just looking for something that works! So, that being said, go ahead and use this for any purpose you may desire, I make no guarantees about anything, just realize that this is a work in progress, it may be full of bugs, dangerous, it may blow stuff up, etc.

As far as the circuit goes, it's bone simple:
1) My on-off switch goes into a digital input with a (pull-down?) resistor. You'll probably want to route your throttles to an analog pin instead. If you want to use a hybrid control scheme that uses half throttle position and half current control, it would be easy to implement. So would a current only control scheme.
2) The high-side current monitor output connects to an analog pin. The monitor connects to a shunt in the + wire of the battery (this particular chip will work on 60v batteries if I recall correctly. The monitor measures the delta-V across the shunt and multiplies this by X100 and the X100 voltage is then read by the analog input on the arduino. A capacitor and resistor smooths out the voltage from the shunt. Size your shunt to get .02 - .04V drop at the battery currents which you want to control.
3) The arduino outputs an RC signal to the ESC.

One last thing, this code will result in battery current overshoots and phase current overshoots, so leave yourself an ample margin and take some measurements to check your work. I have no idea what a "safe" phase current limit would be for a given controller, so you're on your own when it comes to finding performance limits. Also... the phase current computation is very simplified and does not account for any expo-curves that may be used by the ESC. If you want to look at duty cycles vs ESC throttle inputs and develop a curve or correction of some sort, that would be nice for the rest of us without an o-scope!

// winch_a by Dave Wolfe
// this is a work in progress R/C ESC interface that is intended to control
// phase current and battery current.
// This example code is in the public domain.


#include <Servo.h>

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int throttleOut = 1000; // variable to store the servo position
int throttleReq = 1150; // the throttle setting requested by user via pedal
int throttleCurrent = 0; // throttle setting to achieve current limit
int throttlePhase = 0; // throttle setting to achieve phase current limit
long phaseCurrent = 0; // phase current variable; 10X actual
int buttonState = 0; // variable for reading the pushbutton status
long current = 0; // variable for current from shuntInputPin

const int throttleZero = 1150; // initialization/zero endpoint for controller
const int throttleMin = 1245; // min setting for current or phase-current limited
// throttle output, microseconds
const int throttleMax = 1900; // max throttle output, microseconds

const int currentMax = 400; // maximum current *10 (set to 400 for 40 amps)
const int currentGain = 25; // proportional gain setting for current limiting

const int phaseMax = 300; // maximum phase current *10 (set to 900 for 90 amps)
const int phaseGain = 6; // proportional gain for phase current limiting

const long currentScaling = 110; // adjust this so current is 10X actual current
const long currentOffset = 28; // corrects for min shunt voltage not being zero
const int buttonPin = 10; // the number of the pin for the input on/off switch
const int shuntInputPin = A0; // analog input pin from current monitor (shunt)

void setup()
{
myservo.attach(4); // attaches the servo on pin 4 to the servo object
Serial.begin(9600);
// initialize the pushbutton (pedal) pin as an input:
pinMode(buttonPin, INPUT);
}


void loop()
{
// read the amplified shunt voltage from the current monitor, scale it, offset it
// (i should probably offset the raw input and then scale it rather than what i've done..)
current = (analogRead(shuntInputPin) * currentScaling / 100) - currentOffset;
current = max(0,current); // do not allow negative currents, it causes errors later!


// this converts the pedal taps to a throttle signal.
// for an ebike, replace this with a routine to read your throttle
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH)
{
throttleReq += 10; // 10
throttleReq = min(throttleReq,throttleMax);
// throttleReq = min(throttleReq,1300);
}
else
{
throttleReq -= 14; //14
throttleReq = max(throttleReq,throttleZero);
}
// end of the throttle input routine


// this routine computes the throttle output required for current control
throttleCurrent = throttleOut - currentGain*(current - currentMax)/100;
throttleCurrent = max(throttleCurrent,throttleMin);

// compute the phase current phase current = shunt current/throttle
phaseCurrent = current * (throttleMax - throttleMin)/max((throttleOut - throttleMin),20); //set last term to be appx 2.5% of throttle max - throttle min
throttlePhase = throttleOut - phaseGain*(phaseCurrent - phaseMax)/100;
throttlePhase = max(throttlePhase,throttleMin);


throttleCurrent = min(throttleCurrent,throttlePhase); //choose lower of phase or current throttle
throttleOut = min(throttleReq,throttleCurrent); // use the lower of current-limited or user requested throttle value
myservo.writeMicroseconds(throttleOut); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
// (not very elegant, I should synch this with the RC throttle signal frequency somehow)


// DEBUG! Pick whatever variables you want to see, use the Arduino serial monitor
// to view your values in real time. Tools -> Serial Monitor

// Serial.print("position:");
Serial.print(throttleOut);
Serial.print(" ");
// Serial.print(", pc:");
Serial.println(phaseCurrent);
// Serial.println(current);

}


(edit - fixed a couple lines of code)
 
Back
Top