Let's Make Robots!

Current sensing

Senses current drawn by a motor

This simple circuit will allow your processor to monitor the current being drawn by a motor or any other device. The circuit shown will monitor currents up to 20A which is ideal for the new "Wild Thumper" 6WD chassis.

The LM358 is a dual opamp that will work on voltages down to 3V. If you only want to monitor 1 motor then tie the inputs of the second op-amp to ground via 1K resistors so it doesn't generate electrical noise.

In the schematic I have not drawn a "H" bridge in detail as this circuit will work with any DC load. The important thing is that resistors R1 and R2 go between your load and ground.

How it works:
I have shown two 0.1Ω 10W resistors wired in parallel to make a 0.05Ω 20W "shunt" resistor. If you are using smaller motors then a single 0.1Ω resistor may be adequate. This resistance must be very small so it does not noticeably limit the power to your motor.

As current flows through your motor it also flows through your shunt creating a small voltage drop across the shunt that is proportional to the current being drawn.

In the circuit shown, with 20A being drawn a voltage of 1V would appear across the shunt (20A x 0.05Ω = 1V). The power disapated by the shunt is 20A x 1V = 20W

As many users will control their motor speed with PWM this means the voltage across your shunt would alternate between high and low values very quickly. Resistor R3 and capacitor C1 form an RC filter that averages the PWM voltage across the shunt.

The opamp is configured as a non inverting amplifier with it's gain being set by resistors R4 and R5 using the formula:
Gain = ( R4 + R5 ) / R4 = ( 4.7 + 15 ) / 4.7 = 4.19

In the circuit shown, the output will be aproximately 4.19V when the current drawn is 20A. If you need to change the gain then it is best to change the value of R5. Capacitor C2 is there simply to filter any electrical noise on the output.

As the opamp runs on the same supply voltage as your processor there is no danger of your processors analog input being damaged if the current draw exceeds the design limits. If you set your gain too high then it will simply not measure the current accurately beyond a certain point.

Shunt resistor alternatives:
As mentioned at the start, the shunt resistor in the circuit shown is rated at 20W and therefore can get quite hot. A cheaper but less accurate alternative is to use an automotive fuse with an appropriate current rating. The fuse is smaller, cheaper, doesn't get as hot and can protect your circuit from dangerous shorts. The down side is that you may need to recalibrate your software every time you replace the fuse. You will also need to increase the gain by changing R5.

If you need to measure more than 20A or you want a lower voltage drop across your shunt then you will need to consider buying a heavy duty current shunt such as the one pictured below.

This shunt is rated at 100A and has a resistance of 1mΩ (1/1000 of an ohm).

There are other methods of measuring current drawn by a motor but for most robot hobbyist the circuit shown is the cheapest and simplest.

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

C1 and R3 form an RC filter to smooth out the PWM signal. Depending on your PWM frequency the value of C1 or R3 may need to be bigger. Polarization is not important. Polarized electrolytic capacitors are just the cheapest and readily available.

 

 

Hi @OddBot, great article! Can you weigh in on whether it is important that C1 (10uF) be a polarized / electrolytic capacitor, or would an 10uF 0805 X7R ceramic capacitor do just as well?

Instead of measuring voltage drop across a shunt resistor, couldn't you use a linear hall effect sensor like the Allegro A1302? Then you would simply have to place the A1302 close (hot-glued?) to one of the wires going to the H-bridge.

If you need more sensitivity you simply loop the feed cable a few times around the sensor of if you need less sensitivity you increase the distance.

Sounds simple, but not something I have tried myself, yet.

Yes it is possible to use hall-effect sensors to measure current. In the example you described you would need to align the sensors with the wire correctly and it would be sensitive to other magnetic field such as magnetic quadrature encoders, motors and other high current wires. Some form of magnetic sheilding may be required depending on the design of your robot and the accuracy you wish to achieve.

There are SMD current sensors like this available. The ACS712 from Allegro comes in 3 current ranges from ±5A to ±30A. The advantage is that this small, cheap package offers full isolation and good accuraccy. The disadvantage is that you must be careful about it's placement on the board for sheilding reasons.

 

I understant that the current sense resistor needs to be in between the load and ground.  However, if I'm using an h-bridge like above (let's say an SN754410) I would want my resistor between the pins that connect to the motor terminals: so for example

hbridge pin 3 --> motor --> current sense resistor --> hbridge pin 6

in the configuration shown, this is low side current sensing (when current is flowing from pin 3 to 6).  However, because the whole point of using an h-bridge is to be able to reverse the flow of current, wouldn't this circuit turn into high side current sensing when current flows the other way (from pin 6 to 3)? And is it still appropriate in that case?

I'm basically trying to do current sensing on two motors that are hooked up to different sides of a dual h-bridge. I understand I need two current sense circuits like that pictured above (which is easy - I have a quad op-amp) but I don't quite know how to handle the low side/high side current flow that seems inevitable if hooked up right.

Any thoughts?

First problem with your idea is that depending on motor direction your resistor could get pulled to +V for the motor instead of ground. As this voltage can be significantly higher than Vcc of your CPU (and op-amp depending how you wire it) you will smoke it.

To make your idea work, you would need to configure your op-amp differently so it measured the difference across the resistor. Your op-amp would need to be wired to the motor power supply which means it's output could then go high enough to damage the MCU. To fix this you would need a second circuit (or perhaps you can modify the first) to limit the output within a safe range of the MCU's ADC.

All told you end up with a much more complex circuit that could fry your MCU.

 

It would help a lot if you could post a schematic of your motor arrangement. This will eliminate the possibility of mis-understanding. Then we might be able to help you.

Here's the schematic so far. Both current sense circuits are wired to the same op-amp, but other than that it's accurate.  I'm using Adafruit's motor shield.  The current sense resistors are the 1W variety right now so they do not get smoked, but should probably be rated even higher than that.  I didn't move to 4 current sense circuits yet due to time, just wired them so they were configured correctly for the direction I cared most about. I'm not sure if I follow your description above of the rewiring of the op-amp.  Maybe the chips in the doc ignoblegnome pointed to are the way to go instead of rolling my own?  Ideally I'd like a current sense circuit I could plug in line with just about any load and feed a wire to an analog input on the Arduino to read.

I also thought of another issue - I'd like to measure voltage to each motor as well, and although the power supply is a fixed 6 volts, I'm using PWM through the motor shield to control that voltage. So the effective voltage will be somewhere between 0 and 6, but I think I can just scale that by outputting the pwm variable in my code to the serial port and logging it.  So for example, if 0-255 is the full range, then 123 is equivalent to 3V. If you see an issue with that, let me know!

 

The simplest way to convert your PWM to an analog output is to use a simple RC filter. In my original circuit at the start, voltage from the shunt goes through a 10K resistor to charge a 10uF capacitor. As the input impedance of the op-amp input is very high it can be ignored.

Effectively this means the capacitor is being charged via the 10K resistor when the PWM is high and discharged when the PWM is low. The average voltage across the capacitor is a result of the PWM duty cycle.If the PWM is 50% then the average voltage across the capacitor should be half.

A bigger capacitor will cause the voltage across it to be more stable but it will also be slower to change when the PWM changes.

I don't have much more to say on the current sensing itself. I'm anxious to see what you come up with and how it works. Please let us know.

Regarding monitoring the voltage to your motors, PWM doesn't actually change the voltage, only the duty cycle. So if your motor supply is 6V, they will get 6V at some percentage (duty cycle) of the time. PWM of 255 would be 100% duty cycle; 128 would be 50%, and 0 PWM would be 0% duty cycle.

So I suggest you go with your idea of logging the PWM duty cycle.

An alternative would be to pass the PWM signal to the motors thorugh a capacitor to average the signal out. The averaging circuit would also have to get the PWM signal down to 5V maxiumum if you wanted to measure it with the Arduino's ADC. All in all, logging the setting is a lot easier.

That's a good question, and since I directed you here, I'll try to answer. I don't promise the best answer, because op amps have been known to make my head hurt.

I think you will need at least two op amps per motor to get high-side and low-side current sensing. I did find an interesting application note that might help. It certainly explains it better than I would. Jump to the section labeled 'Bidirectional'.

Some very nice h-bridges come with current sense features built in, but not simple jobs like the popular l293 and SN754410.