Universal Motor Driver Board Current Sense Questions
Just picked up the universal motor driver board for a new project. It has a DC link current shunt, and it seems like the intention is to wire it directly to a pin and measure with an ADC. However, given the small value (5mOhm), resolution will be pretty low if measuring directly with the internal ADC, unless the ADC is set to the highest 14 bit resolution. Was that the intention of the design? Typically, I would expect there to be a current sense amp before the ADC to use the full scale of the ADC, otherwise the SNR could be pretty bad (especially in a noisy switching application). In my case, I don't need more than 6A peak, 2A typical, which is <1% of the full scale range of the ADC.
Additionally, ADC performance near rails seems to be pretty poor--something like within 15% of VIO or GND the ADC saturates, making it unable to measure small DC signals anyway. So, how was the current sense intended to be measured?
Or, are there another ADC setting that I should be using other than the simple 1x gain mode? My understanding is the higher gain modes are for AC signals only and no good for DC measurements.
I can of course swap out the shunt for a larger value or put a current sense amp, I'm just curious if it can work without any changes and I'm just missing something.
Comments
Do you have a link or a Parallax part number to refer to?
This guy: https://www.parallax.com/product/universal-motor-driver-p2-add-on-board/
It's an interesting question.
Hardware-wise we originally planned on using this part : https://www.ti.com/lit/gpn/ina180
In some aspects it's quite simple, with only a bypass cap and the mOhm resistor required.
But then 2 things happened... layout demands and code success.
On the code side, Chip had success with his early driver in monitoring the current without needing the external amp.
I wonder if sharing that code might answer some questions...
@cgracey do you have something newer that's up and running ? I could also share the earlier file tomorrow here, if that's ok ?
Yeah an INA180 (or a similar part) is what I would have expected, and will probably wire one in. But yes, I am curious what Chip was able to do without any extra amps, and how.
On page 8 of the manual it talks about this sense resistor and how to measure the current.
I = Vsense / Rsense (Rsense = 5 mΩ)
Example: If the voltage measured at Sense Common (Vsense) = 30 mV then the MOSFET
current would be 30 mV / 5 mΩ = 6 Amp.
Mike
Right--I'm concerned with the mechanics of actually measuring the voltage. For a 100mA of resolution, that means I'm trying to measure 500uV with a 3.3V full scale range ADC, which will have a terrible SNR, not to mention it still seems like the ADC can't measure close to 0V... and I'd like better than 100mA resolution. So I think a current sense amp is necessary unless there are some trick in this ADC that I don't know about.
I'll get what I have posted from work tomorrow. I'm sure for a standalone version of this controller it would have an amp, but with this add-on targeting P2 as the controller it always changes things in interesting ways!
I think the motor control demo Chip was working on may have only required broad guidance or relative data, rather than specific numbers from the current sense so the resolution might not have mattered so much at the very low uV levels. The control loop seemed to rely on the hall and channel sense feedback signals. Anyway... I'll get the code shared here unless Chip posts something better overnight.
Edit: And the motors targeted were probably all operating >0.5A
A also wondered about the intended method of how to measure the current. I thought that the current sense resistor was originally designed only for protection to be used with a smart pin in DAC comperator mode. But for good low speed performance I think a precise measurement of the current is essential.
When experimenting with a stepper driver board I had good experiences with measuring the current with a high resolution ADC mode and AC coupling. But that requires a capacitor at the ADC input. And, of course, it doesn't work at 100% duty cycle.
Here goes the files I mentioned.
There's two code snippets. Run with P2 DEBUG windows enabled. (Propeller Tool compatible).
One simply displays the hall values when you manually turn the wheel.
The other code will run the motor.
One noteworthy item... The rate (speed) increment in the "run the motor" code will slowly increase the motor speed with no upper limit (well- until a fault occurs when the driver cannot turn the wheel any faster due to reaching the power limit for the available voltage/current).
Okay, so seems like the way to do it is sample gio and vio before and after, but that still doesn't give great results. 0 is still not truly 0, and there's some amount of noise. I need to quantify both in terms of actual bits, but it seems way to high for a 10 bit adc.
I had an OPA333 lying around so I made my own current sense amp and added it to the board. They have really low input offset voltage, so work great as a current sense amp, so that solves the issue with SNR.
I think the OPA333 is not an ideal choice. Offset voltage does not matter much as you can trim the offset by software. When all MOSFETs are off or the windings are free-wheeling the current through the sense resistor has to be zero. What matters more is the gain bandwidth product. In current measurement applications you need both a high bandwidth and high gain. The current through the motor windings don't change at a high slope because of the inductance. But as the MOSFETs are switching the voltage seen at the shunt resistor changes rapidly. So you want the ADC input to settle within a few microseconds. So at a gain of around 20 you want a gain-bandwidth product of 10MHz or higher.
I'm not doing cycle-by-cycle FOC here (which would be a pain to reconstruct from dc link current, and I'm have a pretty big gear box so I'm spinning fast enough that simple 6 step commutation is enough)--the actual control loop for current only runs at 1Khz--plenty of time for the OPA to settle, which has a GBW of 350KHz, so 35Khz bandwidth at a gain of 100, (which is what I made). still plenty fast. Slew rate of the OPA is 0.16 V/us, so also plenty fast to settle within even a single ADC cycle. In any case--I'd want to filter out the high frequency switching I'd see--I get some through still, since switching frequency is 18Khz, but overall the OPA is performing good enough for me. I also sync the ADC to the middle of the PWM cycle so I'm never measuring during a switching event.
Also can you please clarify your statement:
Ignoring potential situations where both mosfets are on, all current through the shunt must be motor current, which can't change fast (time constant is on the order of ms), so voltage across can't change rapidly either. Am I missing a current path in my mental model? (ignoring parasitic paths to the ADC via power/ground; not through the shunt resistor)
You have either only one shunt resistor in the DC link or two or three in the source legs of the MOSFETs. When the motor spins below full speed you have PWM with alternating phases of free-wheeling and positive voltage on the winding.
I thought we are talking about the Parallax motor driver board which only has one shunt in the DC link. So you only see a signal when there is voltage applied across the windings. During free-wheeling the signal of the shunt is zero.
So zero and positive voltage alternate with the same frequency as the PWM which is in the 10 to 20kHz range. A GBW of 350kHz means only 3.5kHz at a gain of 100 or 35kHz at a gain of 10. 35kHz is still quite low as it means ~2dB damping at 20kHz. This means your accuracy of the current measurement drops to ~20% and depends heavily on the duty cycle of the PWM.
I don't say "this won't work". You just have to select a different OPA. There are lots of affordable OPA with a GBW of 10MHz and more. DC offset is not that important as you can trim it by software. Even offset temperature drift (shunt and MOSFETs get hot) is not critical as you can compensate it by also sampling the off-phases where the voltage is known to be zero.
Yes 3.5, not 35 KHz I promise I can do math…
And ok, I totally ignored the case where all fets are off, my driver will always energize two phases (free-wheeling isn’t possible), even if the two phases are both driven at 0V.
And measuring during the center of the PWM wave means I only measure during a fet ON state, removing that case where I need to worry about fets being off and current running through the phases and not the power supply.
I’ll handle the freewheeling case later, but in my case 3.5KHz is fine since the control loop is still 1Khz and I filter the signal in software pretty aggressively anyway.
Right now I’m more concerned with ADC performance being wonky—I’ll be designing my own board with a good current sense amp eventually anyway, so I’m not concerned about that being perfect right now either way
Ok, it all depends on the schematic and the PWM strategy. There is so called "slow decay" PWM where you have free-wheeling phases and "fast decay" where you apply positive and negative voltage alternatingly to the motor windings. Fast decay and a common shunt resistor is simpler because you always see the current independent from the duty cycle. There are still some pitfalls to consider. The current spikes caused by the reverse recovery of the body diodes of the MOSFETs add an error to the measured current that does not flow to the windings. So if you need precise measurements you have to blank out those spikes and measure only when the voltage at the shunt has settled.
However, the error should be somehow proportional to the winding current. So if a rough guess of the motor load is enough it should work anyway. Never mind if I'm a bit pedantic here. I'm used to industrial servo drives for CNC machines where you need very precise control of position. Applications where you only drive some wheels or propellers are much less demanding.
You really think this?
Drone Helicopter Hybrid
A Swashplateless MAV: Thrust, Roll, Pitch, and Yaw from Only Two Motors
Please do not quote without paying attention to context. Of course there are a lot of propeller & wheel drive application that are really challenging. But they don't require precise measurement of the current and that's what the original topic is about.
For reference, this is a servo application but with a big gearbox, so 6-step commutation and dc current measurement meets my requirements. However, I did design my own control board where I added measurements to each phase and added amplifiers to solve the original problem I posted about. Using the ADC directly won’t be high enough resolution for good torque control
Here is an example schematic how I would solve it. I have shunt resistors in all 3 ground legs and an additional one in the DC+ path to be able to detect shorts in the motor windings to ground.