DC motor current measurement scenario - Page 1
Forum section: electronics / projects

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 03:24:31 am
content: Hello,I'll do my best trying to explain this scenario so that any of you give me some advice.I'm controlling a brushed DC motor via PWM at 5 kHz. Picture attached. Also, I've attached my motor's nameplate. The circuit attached is already a PCB. As you can see, this time, instead of using a shunt resistor, I decided to experiment with theTLI4970-D050T4current sensor. The microcontroller which is sending the PWM and reading the sensor via SPI is a STM32L432KC Nucleo running at 2 MHz. Of course, I can increase this core frequency by far if needed. The SPI clock is prescaled to 1 MHz. Attached you can also find the code snippet I used to calculate the current. I used STMStudio to monitor the current variable. I built the code with HAL Library for a fast test.I tried the circuit with the DC motor, and also with a light bulb. I also used a Fluke 175 RMS multimeter (in DC current mode) to compare with the current measures that I get from the sensor.First test: With the light bulb1- With a duty cycle of 40%, the multimeter says about 0.7A continuously. The current sensor throws an inconsistent value of 1.2A as it is changing very fast.Second test: With the motor1- With a duty cycle of 40%, the meter says about 5A continuously. The current sensor shows changing values between 0 and 6A.So basically there some factors that got me confused:I'm measuring current in a switching element. So I think the meter is giving me the average current, and the sensor is giving the instantaneous values at a certain state of the transistor (ON/OFF).Furthermore, I don't know if I should read the SPI in main loop as shown in the code, or sample the current at a certain frequency.I have confirmed that my SPI interface is well configured. It has the correct clock polarity and phase. The current sensor has the default setting parameters, i.e, 18 kHz bandwidth. The overcurrent detection triggers an interrupt routine.I thought of putting the sensor in series with motor. But it's too late. I'll do it for a next design. In the meantime, I want to see what I can achieve with this setup.I hope I've given enough details. Let me know if you need more. I have some previous posts about this project, but still have issues. So I decided to write this post with more info.To sum up, what do you think I should improve in this actual scenario?Code snippetwhile (1)HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);HAL_SPI_Receive(&hspi1, (uint8_t *)&SPIRx, 2, 10);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);HAL_Delay(10);motorCurrent=motor_current();float motor_current() {float Iout;float BIout;int16_t Bit15;Bit15 = SPIRx&0x8000;if(Bit15==0x8000){HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);}else {BIout= SPIRx&0x1FFF;Iout = (BIout-4096)/80;}return Iout;}

author: H.O
author_rank: Frequent Contributor
timestamp: October 19, 2018, 05:23:04 am
content: What's the purpose of the current sense? Torque control? Overcurrent protection? Energy measurment? I2T protection?I'd probably start with syncronizing reading the sensor with either the start (or end) of the PWM period. Do you know anything about the inductance of that motor?Have you looked at the various filter settings in the current sensor? If "all you want" is to measure the average motor current then perhaps setting a low enough cut off frequency of the filter within the sensor will give you what you need. (I have not used the particular sensor and have just, very briefely, looked at the datasheet).

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 05:40:17 am
content: Quote from: H.O on October 19, 2018, 05:23:04 amI want overcurrent protection. I'm triggering an interrupt when this happens. But I also want to frequently see the current that is going through the motor. I looked the various filter setting, but unfortunately I have to use the default setting which is 18 kHz bandwidth as I don't have how to program that sensor for now.

author: Siwastaja
author_rank: Super Contributor
timestamp: October 19, 2018, 05:59:24 am
content: You have wired it as a low-side sense for sensing motor current directly. This is how it's typically done indeed, but you need the bandwidth, and to synchronize it with the PWM, i.e., read the sensor during your IGBT on-time.The 18kHz BW, or the 57us response time is probably just too slow, unless you run at very low PWM frequencies (say 5kHz?), which might be acceptable as the motor is big enough to have some inductance. You'd still need to sync it, in order to not read out zero current during off-time, or even worse, during switching, resulting in some weird average mix, possibly with added noise, so it can be all over the place. I.e., after the PWM generation switches the IGBT on, wait a little bit to let ringing switching noise settle, and trig the conversion; and this has to be quick enough so the conversion ends before the PWM on-time ends.So, I'd consider a faster device. And with a syncing capability, i.e., freerunning doesn't cut it unless it converts very fast and you can only read out at the correct time, ignoring other samples.You typically do this with a shunt resistor or an analog-output hall device, then use the MCU ADC - because any MCU which has motor control timers, also tend to have an ADC which can be easily synchronized with the timer.OTOH, this one has the DAC + comparator mode, which is a lot faster, than the current readout mode. And to regulate current, do you need anything else? I'd say, no. Set the DAC properly and use the overcurrent signal to turn the IGBT off (and / or at least feedback the next cycle PWM setpoint), and off you go:interrupt(overcurr_pin){turn off IGBT;duty_cycle--; // optional feedback, depends on your implementation.}Of course, if your PWM timer has a break input, wire the overcurrent signal to that. It can properly terminate the on-time without CPU latency; then it turns back on when the next on-time starts normally. Now you just simply control the DAC value to set your motor torque, and use the PWM value to set the approximate speed regulation. Whichever hits the limit, wins. You can safely set the PWM to near 100%, and the DAC to a fairly low current to spin up the motor in constant torque mode, for example!

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 06:05:35 am
content: Quote from: Siwastaja on October 19, 2018, 05:59:24 amHow could I do the synchronizing in my program? I would need a kind of pseudocode to learn how to do it in software.

author: Siwastaja
author_rank: Super Contributor
timestamp: October 19, 2018, 06:12:36 am
content: Quote from: XaviPacheco on October 19, 2018, 06:05:35 amNormally, you'd use peripherals to do that to free the CPU for other, less timing-critical tasks.In your case, this is not actually possible at all, since your current measurement device doesn't have a sync input - if I understood correctly, it just sits there converting.But, if your PWM frequency is low enough, you could do it, for example, like this:* Configure the PWM-generating timer to generate DMA request at the same condition you use to start the on-time (might be counter reset)* Configure that DMA request to start the SPI transaction* Configure the DMA to give an interrupt when finished* In that inthandler, look at the current; terminate the cycle manually, and/or feedback your duty cycle based on current measurementBut, this way kinda sucks because it's slow and uncertain. What if you end up reading "too quickly", and get a value before the switch went on? Or what if it's taking too long, and it's already switched off.I'd do it with the fast overcurrent sensing mode which is up to the task:* Write your desired peak motor current (which is fairly close to average motor current) to your TLI4970's DAC register* Wire the OCD output (don't forget a pull-up resistor) to the break input of the timer, configured as active-low, configured to terminate the on-time.* If there is no such break input for that timer, connect it to any GPIO, and from EXTI, configure it as falling edge interrupt source. Write the inthandler which overrides the timer, terminating the pulse, and possibly, in addition, feedback the PWM to a lower value if you want to avoid running that ISRfor every cyclewhen running against the limit.

author: hayatepilot
author_rank: Frequent Contributor
timestamp: October 19, 2018, 09:08:57 am
content: Hi XaviPachecoYou may want to take a look at the filter settings of the measurement chip. Page 12 in the datasheet.The default setting is 18kHz which is much too fast for your 5kHz PWM.It depends on how responsive you want your measurements, but for just overcurrent protection a bandwidth of 70-130Hz is fast enough. This would probably be the best and most accurate way to do it.The other option is to read the sensor at the full rate (18kHz) and do the low pass filtering (IIR) in software on the STM32.Greetings

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 11:05:45 am
content: I will consider the digital filter then. Would a simple RC filter (first order) help if I want the filter in hardware? What should my cutoff frequency be?

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 11:45:55 am
content: Another question, is that correct that I’m reading the SPI in the main loop? or should I create a timer based interrupt to read the SPI at a fixed frequency?

author: hayatepilot
author_rank: Frequent Contributor
timestamp: October 19, 2018, 12:34:29 pm
content: Quote from: XaviPacheco on October 19, 2018, 11:05:45 amOf course a capacitor across Pin 7-8 of the TLI4970 will filter the measurements.But it will probably not be practical as you would want a attenuation of at least 40dB and with the first order filter would result in a cutoff frequency of below 50Hz. This will likely need a huge capacitor.This all depends on the resistance and inductance of the motor.Greetings

author: H.O
author_rank: Frequent Contributor
timestamp: October 19, 2018, 12:44:48 pm
content: QuoteI thought this was already answered at least once. If you don't low pass filter the signal then you need to syncronize reading the sensor to the PWM signal otherwise you have no idea where, in the PWM period, you're actually measuring. You might measure right before the on period starts (where the current will be "low") or right before the on period ends (where the current will be high). If you know for sure that your main routine runs like 10 times faster than the PWM frequency then you might be able to get a somewhat accurate reading by averaging 100 samples or something like that.If you low pass filter the signal enough then you might get away with reading it in your main loop.Don't forget that if you low pass filter on the hardware side you will also slow down the sensors reaction time to overcurrent - which I suspect you don't want.

author: Siwastaja
author_rank: Super Contributor
timestamp: October 19, 2018, 01:30:20 pm
content: Quote from: hayatepilot on October 19, 2018, 09:08:57 amNooo~. It's not too fast - it's too slow.You don't want to filter the signal. If you do, you'd be measuring the input current, which, while it's better thannothing at all, it's fairly insignificant:1) It can't protect the motor as-is (and you didn't tell how to fix this by software calculation). Motor can still hog, say, 100A at 10% PWM when stalled, and you only read 10A.2) It gives you no idea whatsoever about the torque as is (again, without extra calculation).3) It can't protect the semiconductors from blowing up from the overcurrent, if the motor iron is saturating in stall, because it's too slow.If you do want to measure input current, then do measure input current; move the sensor to the DC link, before the capacitors, and they'll take care of the filtering even further.Now, with your filtered input current measurement, while #3) cannot be solved by software trickery, #1 and #2 can be worked around by multiplying your averaged current by the inverse of your control duty cycle.I.e., with a 25% duty, if the motor current is 4A, it will, after averaging, read 1A, and your input current measured before the DC link caps also reads 1A. Multiply by 1/0.25 = 4 and you have a motor current estimate which is fairly close, but lags too much to protect the semiconductors from motor saturation - but it can still protect the motor if you oversize the semiconductors.Yes, a carefully tuned slow input current measurement works if you know what you are doing, BTDT. You typically blow FETs in corner cases before you know exactly what you are doing. But all of this doesn't make sense. The OP has the right components in the right place, and can do the Right Thing (utilizing the fast overcurrent signal), which gives you a robust solution directly.

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 01:41:59 pm
content: A disadvantage: As my sensor has the default settings, which I can't modify for now, the fast overcurrent detection triggers at 50A according to the datasheet.

author: Siwastaja
author_rank: Super Contributor
timestamp: October 19, 2018, 02:12:03 pm
content: Ah, EEPROM with special programming interface... So you can't modify the current setpoint "on the fly", so it's pretty useless for setting the current setpoint.I'm sorry but I think you need another sensor. But at your slow 5kHz PWM, and your by-default 18kHz BW, maybe you could work the syncing out by just reading the sensor with a correct timing? I.e., read it out when the PWM cycle starts. You could also do continuous reads during the PWM cycle and pick the largest number from the, say, last 4-5 measurements, to find the motor current measurement which happens to coincide with the on-time. But you'd need more BW to do this reliably, especially with low duty cycles. Worth trying, anyway. The issue would be with switching noise coupling, some unfortunately timed conversion may showtoohigh current, messing up the max() algorithm to find the motor current.

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 02:17:53 pm
content: Yeah, choosing this sensor was not the best idea. I just wanted to try it, but it's hard to play with it. I will see what I can accomplish with its default parameters.

author: hayatepilot
author_rank: Frequent Contributor
timestamp: October 19, 2018, 02:38:22 pm
content: @SiwastajaWith such a big DC motor you don't care what the instantaneous current is.They are inherently slow, both thermally (mass), mechanically (inertia) and also electrically (winding inductance). You can stall such a motor for a few seconds without damage.They are often switched with a simple mechanical switch. So on each startup they effectively stall for a fraction of a second.For the torque you always use the average current.So to protect the motor from overload a temperature sensor would probably be the better solution.The more I think about it the less sense it makes that the OP is measuring from 0-6A. The inductance of the windings should already smooth the ripple considerably at 5kHz PWM frequency.I see he is using a bipolar transistor with a flyback diode only across the motor.Putting an additional diode across the transistor would probably give much more stable current readings.

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 03:03:38 pm
content: Quote from: hayatepilot on October 19, 2018, 02:38:22 pmI'm using a power IGBT. Perhaps it measures 6A because I tested it with load.

author: schmitt trigger
author_rank: Super Contributor
timestamp: October 19, 2018, 03:29:23 pm
content: Do you have access to a current probe and a scope?If so, that would help you understand what the current waveform actually looks like.An 4 HP, 125VDC motor is not a hobby motor. It has been long time since I last worked with those motors, but if I remember correctly you should not chop the DC faster than 360 Hz, which is the frequency resulting from from three phase SCR control.I could be wrong, but that is the reason that you should monitor the actual current waveform. Hint: it will change SIGNIFICANTLY with load. At the very least you should check it unloaded and at full load.EDIT: I remember now, that among other things, there is a lot of stray capacitance from the armature to the frame. That is the reason, the motor plate clearly indicates that the case MUST be grounded. If anything, increasing the chopping frequency will increase the leakage current.

author: Siwastaja
author_rank: Super Contributor
timestamp: October 19, 2018, 03:52:11 pm
content: Quote from: hayatepilot on October 19, 2018, 02:38:22 pm... to the motor.Dangerous and totally incorrect advice.For semiconductor switches, you need to design for the worst case peak current, and semiconductors blow in tens of microseconds.QuoteBut now it isn't, so it's irrelevant. A mechanical switch is OK forsecondson overload. A FET or an IGBT dies in tens of microseconds (look at the SOA curve for specifics).QuoteWe need to protect the semiconductors primarily. Motor is OK with very slow response. Still, you need to measure the motor current in one way or another for the "slow" protection as well, and your advice of filtering the signal for average doesn't do that; you need to multiple by 1/duty as well.Another way to "protect" the semiconductors is to simply rate them for the resistance-limited peak current at rotor stall, but for anything over a few hundred watts of motor power, especially high-efficiency motors, that's quickly totally nuts, since this typically means you are using semiconductors dimensioned for 5-10x more current than you'd otherwise do; this basically means that for a 4HP motor, you'd be building a controller with components suitable for a small EV passenger car, so large and expensive semiconductors with powerful gate drivers! This strategy is used in small gadgets with motors so small and inefficient, that their resistance limits the current below causing any issues even with the smallest, cheapest MOSFETs!QuoteThere's absolutely nothing weird going on. The OP measures different currents depending on whether the switch is on, or off during the measurements; when he measures during switching, he gets some kind of weighted average + switching noise. Because he's measuring instantaneous motor winding currentbelow the switch. Motor winding current is naturally a triangle wave, but the decaying freewheeling current goes through the freewheeling diode, powering the motor itself during the off-time of the switch.QuoteHe's using an IGBT, not a bipolar transistor. The flyback diode is exactly in the right position.QuoteAdditional diode (if not already present in the IGBT module) would catch currents stored in the parasitic inductance of the main switching loop, possibly improving EMI, and hence, could improve the current readings. This doesn't change the fact they still jump between 0 and the actual motor current, if the conversion freeruns and takes measurement during the PWM offtime.And finally,QuoteIf by averaged, you mean what you adviced the OP to do: no, no, and no!Torque is related to the motor current. If you average the low-side measurement during the cycle, you end up with the DC link (input) current, which isn't the torque.

author: Siwastaja
author_rank: Super Contributor
timestamp: October 19, 2018, 03:56:16 pm
content: Quote from: schmitt trigger on October 19, 2018, 03:29:23 pmWhere does this kind of ridiculous figure come from?Even 1MW motors are chopped at 5 or 10 kHz just fine. Such a small motor would work well with probably any PWM frequency between about 1 kHz and 25kHz, but typically modern IGBT or MOSFET PWM drives at this power level vary from about 2-3kHz to slightly over 20kHz for non-audible whine systems.Go too low and you have more current and torque ripple.Go too high and you have more switching losses overall, and you cannot go for arbitrarily high edge rates due to EMI and capacitive coupling.

author: Siwastaja
author_rank: Super Contributor
timestamp: October 19, 2018, 04:03:05 pm
content: Guys,The OP is genuinely building a motor controller, and is doing just fine. What he needs is actual, correct advice.If you have no idea whatsoever what you are talking about, giving made-up fake advice only causes damage, by endless confusion, and we others need to do damage control.It's nice to get help, and giving help gives that nice warm feeling, but you are not helping here.

author: XaviPacheco
author_rank: Regular Contributor
timestamp: October 19, 2018, 06:09:12 pm
content: Quote from: Siwastaja on October 19, 2018, 04:03:05 pmExactly.As for my first real design, I think I'm not doing that bad. I haven't posted the whole project so not to make this post long. Before the PCB was made, I tried to carefully select all the components from a theoretical point of view, i,e, I calculated the driver gate peak currents for my switching frequency, gate resistors, power consumption, etc. In general, I have a series of calculations for all the devices I have chosen. Now the circuit has been operating in real life, I'm realizing about some practical shortcomings that I might have not seen from the theory. But that's part of the process. For this application, I realized, for example, that an IGBT worked better than a MOSFET. I had chosen incorrectly the FET, so I blew up two of them. I reconsidered the transistor selection, and I haven't blown up any IGBT so far.The current sensing part is the one that is giving me issues, that's why I'm looking for some advices. I know perhaps I didn't select a proper sensing method, but I'm trying to do the best I can with it. I will think of the advices you all have given me.

author: Siwastaja
author_rank: Super Contributor
timestamp: October 20, 2018, 09:39:26 am
content: To prevent semiconductors from blowing up:1) Rate the Vds(max) sufficiently; this is harder to protect against, and some ringing cause by the layout is always inevitable. If you want to play safe, go for 2x the DC bus voltage. An experienced designer who's good with layouts may be fine with 1.2x or 1.3x the worst case DC bus. I tend to go for 1.4x, but start the prototyping at lower voltage, measuring the ringing.2) The FIRST thing you do, implement the QUICK (read: microseconds, maybe up to 50 µs is acceptable on a motor controller due to the large inductance, but the faster, the better) overcurrent shutdown logic. Test this by not powering the DC link at all, but only power the logic and inject external current through the shunt/hall device, use a scope to measure the injected current rise, and using another channel, measure the gate drive enable signal. Measure the latency. There are two ways typically to implement this:a) Use a break input of the PWM-generating peripheral, if available,b) if not possible, use general purpose input, configured as interrupt source, and use the highest priority, non-maskable interrupt to turn it off. On an ARM clocked at, say, 50MHz, you'd be looking at around 0.5µs delay which is just fine, you just need to be careful with interrupt priorities and not disabling interrupts.3) Now apply power.Note that depending on the design, motor controllers may produce bidirectional currents, and in this case, you need a sensor capable of sensing them, and a comparator that can trig to both directions.Even the smallest STM32 controllers implement fast ADCs (at least 1MSPS), analog comparators, and Advanced Control Timers (aka. motor control timers) with break inputs, and internal matrix to connect these together; i.e., you can synchronize the ADC to read the currents during switch on-time.Even the smallest STM32F0 devices are capable of doing this in 3-phase; or run possibly three separate DC motors from one controller with a half-bridge; or drive one DC motor with a full bridge with reversibility.

author: schmitt trigger
author_rank: Super Contributor
timestamp: October 20, 2018, 05:10:56 pm
content: Siwastaja;Have a couple of whiskeys. Or some Prozac. But by all means calm down your aggressive responses.You can educate people without being rude.My advice may not be 100% up to date or accurate. But I did provide with some valuable advice. To check the actual current waveform with a scope and current probe. And that higher frequencies also cause higher leakage currents to the frame.