1. ## Calling Battery Percentage

Hi, I'm new to the board and looking for help with a project I'm doing for my robotics team. Currently, we have many talented programmers and builders that are on the team but our work is all for not with the issues we are having with power levels decreasing every time we run our bots. The power output changes with the battery percentage, which causes the bots to run very poorly, especially with multiple motors and sensors on a single robot. I'm here trying to figure out if there's anyway possible to call the battery percentage on these robots and turn them into a coefficient in our programming?
Thank you!

2. Not really a C question, but I'll answer anyway. My suggestion would be to use a battery of higher voltage than your required supply voltage, and then use a switching (not linear!) voltage regulator to bring it down to the required level. Then your supply voltage will remain constant as the battery drains, until it drops below the minimum input voltage for the regulator, at which point it would just likely cut out altogether. You can then use an analog input on your arduino, or whatever type of controller you're using, to monitor the voltage of the battery, and warn when it's getting close to cutoff.

Another possibility might be to have a "limp-mode" in which a relay releases, and returns to a normally-closed position, to bypass the voltage regulator, when the input voltage has dropped far enough that it no longer produces any output. That could also be used as a boolean signal to indicate that the battery is getting weak.

3. *Moved to Tech Board*

4. Personally, I'd use separate batteries for the microcontroller logic and the motors. Battery capacity can be measured from the voltage if there is no current load; the voltage also drops as you draw more current from it.

Let's assume you use PWM to control your DC motors, without any kind of voltage regulation, directly from the dedicated motor battery. Basically, this assumes you've selected your motors to match your battery capabilities.

I would use something like an AttoPilot (max. 51V, 89A) and two differential input ADCs on your robot microcontroller (differentials because the sense outs are relative to motor ground), to continuously measure both the battery voltage, and the current draw from the motor battery.

If you measure both constantly, you can estimate the energy drawn from the battery (in watt-hours, basically), with not too much effort.

If you know the battery chemistry, or if you measure the battery voltage at different current loads at different remaining charge levels, you can map out the function remaining_charge(voltage, current_draw) that describes the remaining charge in the battery given instantaneous measured voltage and current draw. It is a pretty smooth function, but it also evolves as the battery degrades, so it's typically only roughly approximated, based on knowledge of the battery chemistry and setup.

However, you don't really need to know how much charge there is left in the battery, to be able to control your motor power accurately via PWM.

What you need to do, is to look up the motor datasheets, or better yet load your robot to estimated final weight, and measure how much torque/speed you get out of each motor at a given voltage and PWM duty level. Essentially, you measure a few dozen points of the function output = foutput(voltage, pwm_duty). Using the results, you fit an approximate inverse function pwm_duty = fPWM(voltage, output).

This latter function, fPWM(voltage, output), is unique to each (type of) motor on your robot, and you will need to implement on the microcontroller on the robot. It does not need to be extra precise, as long as it is not too noisy (the function implemented should be smooth, not spiky due to rounding errors or some such, or you lose control precision and get jerky motor movement).

Your remote control or guidance logic will describe the desired output level per motor, and the function will convert that to the desired duty cycle, based on the current voltage level obtained from the battery.

Because the battery voltage changes as the current drawn from it varies, you will want to calculate fPWM(voltage,output) really often (I'd say dozens of times per second) even if their desired output level does not change, since the battery voltage level is likely to fluctuate all the time, and thus the 'proper' PWM duty cycle varies for each motor also.

I like the voltage/current draw approach better than e.g. feedback encoders in the motor outputs, as the outputs can get stuck; I feel much more at ease when designing the guidance/control logic when I know the power budget available, and can decide how to spend it.

That said, I'm no robot wizard either, just an occasional hobbyist. A real robotics engineer might laugh their ass off at my ideas above.. but if I had the money, I'd love to try this out myself, but I don't, so I can't, so there.

5. check the voltage before regulation. Tha'ts the best way to do it, use an attenuator if your voltage levels are greater than your controller logic

6. You can use a voltage regulator, but the correct engineering solution in most cases is to use closed loop control.

That way you can make the performance of your robot independent of battery voltage, load level (for example, the motors may require higher voltage to run at the same speed once they age), and other funny things like variations between individual motors even from the same product line. This is the biggest difference between hobbyist designs and professional designs - hobbyists test the parts they have, and design something that works with the parts they have, while professionals design by numbers, so that their designs work with any part within tolerance. The tolerance on speed of motors given the same voltage could be something like 10%.

You can do that by having the code keep track of a motor output level (using PWM), and monitor the current wheel speed (it depends on what kind of motor you are using, but for DC motors an optical encoder is probably the easiest), and adjust the output level in real time so that the speed matches the speed you want.

It's impossible to achieve any kind of precision with open-loop control.

PID is the most commonly used controller for this kind of things. PID controller - Wikipedia, the free encyclopedia

If that's too complicated, you can start with just a proportional controller, too. It will just not respond as fast to setpoint changes.

Code:
```while (every 100ms)
{
error = setpoint - current_speed
pwm = K * error
}```
where setpoint is the speed you want it to run at, current_speed is speed measurement from the wheel (usually by hooking up an optical encoder to a counter input pin on the microcontroller), and K is some constant. You can find K experimentally. If K is too high, the output will oscillate. If K is too low, the output will change too slowly when you change setpoint.

PS. You will find that with just a purely proportional controller, you will never actually reach the setpoint - just somewhere close to it. This is called steady-state error, and the solution is to introduce the I term from PID, and get a PI controller. The derivative term allows you to use higher gain (and hence faster response) without oscillation.