This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C2000WARE-MOTORCONTROL-SDK: Sensorless FOC speed problems with TMS320F280049C

Part Number: C2000WARE-MOTORCONTROL-SDK
Other Parts Discussed in Thread: DRV8320, INA240, LAUNCHXL-F280049C, BOOSTXL-DRV8320RS, MOTORWARE, LAUNCHXL-F28379D, BOOSTXL-3PHGANINV

Hello!

I've been developing sensorless motor controler using InstaSPIN-FOC and FAST observer for couple months now.
I did similar design before using non-TI MCU, but I had so many problems with full-load startup and tuning motor + observer + foc parameters that i decided to try InstaSPIN, despite the fact i was scared of the different MCU architecture, etc.

I've faced many problems during the design, while one of them is major and project mucking.

Custom PCB:
F280049C, DRV8320 + Infineon metal FETs
Triple 1mΩ in-line shunts with INA240 CSAs.
Plenty of bulk+decoupling capacitor on the board.

Vph +Vm sensing #1: 4.7k, 42.2k, 47nF Vph sens: 33V max, 800.7Hz.
Vph +Vm sensing #2: 82nF -> 459Hz.
Iph sensing: +/-82.5A range.

Motor parameters:
800W, 12n14p SM-PMSM / hobby BLDC, "quasi"-sinusoidal BEMF, sinusoidal current,
~22-25mΩ, 25-30µH, 300kV (~2.9mWb)

Load:
Speed-varying exponentially / Air/Fan Propeller
No load: 0.8A DC 6000RPM (700Hz)
Static: 1.4 Nm, 800W, 40A DC @ 4500RPM (525Hz),
With airflow: ~400-500W @5000RPM (580Hz; space for overmodulation/field-weakening)
Dynamic on steps: 1.5 Nm, 1100W, 60A DC.
(Values above tested with 6-step BLDC controller and 5-cell battery)

Battery:
5-cell Lithium 18.5V, 21.0V max

Software:
It's based on is05_motor_id lab example for motor identification procedure and is13_fw_mtpa lab example for the main working code.
PWM/ISR frequency set to 20/20 kHz. Current loop bandwidth is set to 1kHz. Max Vs modulation is < 0.57. FWC set off.
Also, I didn't modify ADC triggering for better in-line shunt utilization and it runs default, same as with low-side.

My problems/questions:

1. Starting from LAUNCHXL-F280049C + BOOSTXL-DRV8320RS I wasn't able to run motor at speed higher than ~330-350Hz, which was close to Vph filters cutoff frequency. I changed the circuit and set those filters to about ~1000Hz and the problem was solved (sort of). Using that knowledge, the custom PCB was designed with Vph sensing #1 (800Hz).
InstaSPIN-FOC User's Guide recommends to set the cutoff in 300-400Hz range, even if the motor is spinning much quicker and there are some reference guides with similar approach with drone motor running at 1600Hz. There are also numerous repeating forum threads (especially with 28004x chips) with the same problem I had.
As papers are quite outdated and misleading, can someone "with access" explain what's hidden behind it and how this filter affect the estimator?

2. Even with filters set to 800Hz, the controller was still loosing stability under load at around 480-500Hz, causing huge current spikes. Without load I was able to spin the motor up to 600-700Hz depending on overmodulation and field-weakening settings. I've done multiple tests trying to find the problem and eliminated:

  • PID loops: The same problem was occuring at closed speed loop, closed torque loop, open loop controlling Vq and closed Id=0, dual open loop controlling Vq and Vd=0.
  • DC bus utilization: Problem was occuring around the same speed when testing at 5 or 6-cell battery at different current levels.
  • Overmodulation was set to off
  • Field-weakening was off
  • Tested at multiple PWM switching frequencies
  • Same limit applied to LAUNCHXL-F280049C + BOOSTXL-DRV8320RS, but I thought It was related to dc bus utilization limit and hoped that in-lines could solve the problem.

This is 60A Iq datalog graph from eval board with huge current spikes:


And these are graphs from the dyno using custom pcb. I have limited debugging options so I can't provide more detailed signals until i receive current probes and set up the equipment safely for tests under the load.
Current is measured on battery leads.

Full load startup at 5S:

Sweep at 5S +  current chart:

Full load startup at 6S:

Sweep at 6S +  current chart:

3. SDK 3.01.00.00 update provided additional access to hidden estimator parameters through fluxHF.lib functions: EST_setOneOverFluxGain_sf(), EST_setFreqLFP_sf(), EST_setBemf_sf().
There is no documentation about these parameters, what exactly do these change and no information how to tune or test them.
I found some threads on this forum which helped me to tune them a little and they seemed to partially fix problem nr. 1. - so I was able to use Vph sensing #2 (459Hz) circuit and partially fix problem nr. 2.

Even after the fluxHF fix, the controller still works far from the optimal point.

Full load startup at 5S:

And sweep at 6S still showing some twitch around ~4000RPM and performance/efficiency drop after that:

Also after i tuned those 3 parameters, i tried different motor, performed motor identification procedure and wasn't able to achieve the same performance as with previous motor, unless i tuned the 3 parameters again! Second motor was spinning up to 3700 rpm. It's unacceptable for me to tune those parameters for each motor separately.

A. How are those parameters connected to nr. 1 problem? Is it more optimal to stay on #1 Vph sensing, which works doesn't require fluxHF parameters or #2, closer to values that user guide suggests.
B. How can i debug and tune those parameters perfectly to not loose performance?
C. Are there still some parameters that can be tuned inside the estimator that could fix those issues?

Until SDK 3.01.00.00 release I thought the problem was related to my HW and SW modifications, but this clearly shows that stability problem is mainly related to the built-in FAST estimator and i've lost the hope that i'm able to fix it on my own.

4. Are InstaSPIN ROM estimators tuned differently between TI's MCUs? If switched to different MCU, maybe with "-MOTION" one, could the estimator work better with my motor? If yes, what are the options?

5. How can i optimize the code for in-line current sensing? Can it provide any benefits over low-side ones? Seems that INA240 amplifiers are quite slower than low-side shunts and built-in PGAs. I want to utilize as much battery as i can, because i'm switching from 6-step drive to FOC, while can't change the battery and must keep the performance level. That's why I went for the in-lines, but I think I'd need to modify the ADC triggering to really use them.

6. How to tune IDRIVE settings? I did some tests without motor connected and
Observed distortion graphs with the default settings, Isource=1A, Isink=2A:
CH1: VGL, CH2: VDSL, CH3: VGH, CH4:VDSH
High-side rise:

Low-side rise:

So I've tuned it down to Isource=0.44A for Tr=100ns on HS, Isource=0.33A for Tr=133ns on LS and left Isink=2A for Tf=22ns for both, which eliminated the distortions without the motor.
It is the right way? With the motor, those graphs looks smooth even at default settings.

Also, how to properly set switching deadtime? I set it to 200ns for safety, but with smart gate driver "handshakes" could i set it to 50 or 100ns and still be safe while keeping max performance?

6. Is +/- 82.5A current sense range enough for this motor? I'm close to maxing it out with about Iq =~60A, but when i tried doubling it up with 0.5mΩ shunts to avoid saturation, the controller wouldn't run due to extra noise and lack of precision.

7. Did anyone observe that B phase currents are less noisy than the other two? I've tested it on both custom hardware and eval board, also changing probes, motor wires... with same observations. Is there some current injection causing that?

8. Is 20kHz optimal for the motor? I'd want to run it at higher frequency, but then inverter requires quite more switching current and there is less sampling time for current measurements. Also on higher PWM frequency, the motor becomes audibly noisier (shouldn't be the opposite?), especially on current offset calibration (50% modulation) and there are more disturbances on Iq current when the motor is on standstill. What could have caused that? The tests were done keeping the ISR frequency: PWM20/ISR20, 40/20 and 60/20 kHz.

Sum up:

That's quite a few complicated questions, but i hope to receive as many answers as possible and get this project going. I plan to provide more tests with proper signal graphs when I'll receive current probes. Those would also help identifying potential HW sensing problems etc.

I really like TI's built-in motor identification, easy tuning (despite fluxHF) and I'm very impressed with 0/low speed performance. But It's all for nothing if I can't achieve required full-power performance. Until the SDK update, I was close to giving up. After that, i think It's quite close to solve it and push the performance even further with OVM and FW algorithms.

Regards,
Mateusz

  • Q1~3: The fluxHF is just a patch for low inductance high-speed motor, and the default value should be enough in most cases. I don't think you need to tune these parameters for your motor. 

    Q4: Two different versions, Instaspin-foc is for the motor drive without position sensor and generic speed and torque control. Instaspin-motion is for position or motion control using a position sensor in servo drive applications.

    Q5: Any filter on the current deal circuit? we recommend the filter frequency is far higher than the filter frequency of the voltage sensing circuit.

    Q6: That depends on the FETs, please refer to the specification of the FET and gate driver. The following application note could be a reference.

    https://www.ti.com/lit/ml/slua618a/slua618a.pdf

    The dead time setting depends on the FET and gate driver, make sure the dead time is enough for turn-off/on FET safely as smaller as possible.

    Q6: That depends on your system. It seems like it is not enough for your motor.

    Q7: The issue should be from the current sensing and power module, please check the hardware design.

     Q8: A higher PWM switching frequency should be better for a low inductance motor, you may select the right value according to the power module.

    You might increase the dc-link voltage to test the motor with the same load and speed compare to the low dc-link voltage if possible, and see if there are different test results and more stability in high dc-link voltage.

  • By accident i clicked "this resolved my issue". Can i undo this?

    Yanming Luo said:
    Q1~3: The fluxHF is just a patch for low inductance high-speed motor, and the default value should be enough in most cases. I don't think you need to tune these parameters for your motor. 

    Then what should i do? And why can't I run motor quicker than Vph filter cutoff?
    What are the defaults? It's described to be 1.0, 1.0, 1.0 by default, but in all the lab examples these are set to:

    //! \brief Defines the scale factor for the flux estimation
    //! the default value is 1.0f, change the value between 0.1f and 1.25f
    //!
    #define USER_EST_FLUX_HF_SF                 ((float32_t)(0.12f))
    
    
    //! \brief Defines the scale factor for the frequency estimation
    //! the default value is 1.0f, change the value between 0.5f and 1.5f
    //!
    #define USER_EST_FREQ_HF_SF                 ((float32_t)(1.0f))
    
    
    //! \brief Defines the scale factor for the bemf estimation
    //! the default value is 1.0f, change the value between 0.50f and 1.25f
    //!
    #define USER_EST_BEMF_HF_SF                 ((float32_t)(0.75f))

    In my case 1.0, 1.0, 1.0 do not work, and I had to set these to FLUX:0.05-0.1, FREQ:1.2 and BEMF:0.6-0.8 to run stable enough to perform dyno test in the first picture in nr.3.

    Yanming Luo said:
    Q4: Two different versions, Instaspin-foc is for the motor drive without position sensor and generic speed and torque control. Instaspin-motion is for position or motion control using a position sensor in servo drive applications.

    This is not exactly what i meant. If i focus only on InstaSPIN-FOC devices, do they vary in ROM implementation? So: Is it possible that i can't run my motor higher than 500Hz on F280049C, but other InstaSPIN-FOC (for example: F280069F or F280027F) would?

    Yanming Luo said:
    Q5: Any filter on the current deal circuit? we recommend the filter frequency is far higher than the filter frequency of the voltage sensing circuit.

    I have 100Ω + 4.7nF RC filter on the INA240 output. The cutoff should be at around 338kHz.

    Yanming Luo said:
    Q7: The issue should be from the current sensing and power module, please check the hardware design.

    As written earlier, I observed the same on the LAUNCHXL + BOOSTXL board, not only on the custom HW. I'll try to redo the test with the current probes later then.

    Yanming Luo said:
    You might increase the dc-link voltage to test the motor with the same load and speed compare to the low dc-link voltage if possible, and see if there are different test results and more stability in high dc-link voltage.

    As written, I've tested this on 5 and 6-cell battery (18.5V vs 22.2V nominal or 21.0V vs 25.2V at full charge), having oscillations at similar speeds. Wasn't that test enough? Can't lower than 5-cell, because it would reach the speed it trips and can't have more than ~30V because i'll fry ADC.

  • Q1: We have tested the default value recommended in user.h for most motors on the TI EVM kit, which also includes the old inductance high-speed motor you used. It enables the user to change these three variables according to the tuning state if they want. Only the USER_EST_FLUX_HF_SF is more critical and the other two variables don't need to tune for most motors.

    Q4: The same algorithm is for instaspin-foc enabled device, fixed-point format for F2802x/05x/06xF in motorWare, floating-point format for F28004xC in motorControlSDK you are using.

    Q5: Recommend half of the resistance and capacitance. Any RC filter on the input of INA240?

    Q7: As mentioned in Q1, we have tested some drone motors on DRV8320 up to 1000 or 2000Hz.

  • Yanming Luo said:
    Q5: Recommend half of the resistance and capacitance.


    Then the cutoff will be 1.447MHz, which is beyond INA240 bandwidth, but I'll test that.
    Yanming Luo said:
    Any RC filter on the input of INA240?

    No, resistors sense pins are directly connected to IN+ and IN-.

  • You might use a high current DC power supply for this test, and increase the dc-link voltage to near maximum voltage of your board, to see if there is any difference to run the motor at the same speed with a full load. I think the issue should be from the current sensing or the motor parameters will be changed significantly with high phase current.

  • Mice said:
    7. Did anyone observe that B phase currents are less noisy than the other two? I've tested it on both custom hardware and eval board, also changing probes, motor wires... with same observations. Is there some current injection causing that


    I fixed that. Turned out that i caused some timers sync issues or sth when i was using motor coils as a buzzer to indicate motor states before spinning. Weird, but i didn't dig deeper into that after i found the bug and fixed it.

    CH1 - Ia current probe, CH2 - Ib current probe, Ch3 - Ic current probe, CH4 - Ia DAC output


    Mice said:
    8. Is 20kHz optimal for the motor? I'd want to run it at higher frequency, but then inverter requires quite more switching current and there is less sampling time for current measurements. Also on higher PWM frequency, the motor becomes audibly noisier (shouldn't be the opposite?), especially on current offset calibration (50% modulation) and there are more disturbances on Iq current when the motor is on standstill. What could have caused that? The tests were done keeping the ISR frequency: PWM20/ISR20, 40/20 and 60/20 kHz.

    Q7 above helped with that a little, allowing me to run the motor at higher PWM. Current disturbances are quite lower at no load:

    20kHz PWM on the left, 50kHz on the right.
    CH1 and CH2 are Ia and Ib phase currents measured by scope. CH3 and CH4 are Ia and Ib DAC outputs from MCU.
    And with light load:

    Plots were made spinning at around 5kRPM.


    Now coming back to problems 1. to 3.
    I've tested 99nF Vph filter version (~380Hz cutoff) with 25.2V battery and done 30 - 60 A Iq sweep test.

    With default EST settings, USER_EST_FLUX_HF_SF=0.12, USER_EST_FREQ_HF_SF=1.0, USER_EST_BEMF_HF_SF=0.75:

    Efficiency and Power Draw / RPM:


    RPMs:

    DC current:

    Iq current:


    With settings USER_EST_FLUX_HF_SF=0.05, USER_EST_FREQ_HF_SF=1.0, USER_EST_BEMF_HF_SF=0.75:





    Then, with settings tweaked: USER_EST_FLUX_HF_SF=0.08, USER_EST_FREQ_HF_SF=1.0, USER_EST_BEMF_HF_SF=0.8:

    Which still seems far from optimum. These EST params impact is huge.


    I moved back to stock controller with 47nF 800Hz Vph filter and tested it on 40A Power supply, as suggested. I could only go up to 27V because of TVS switch, but should be enough. Tests shows that Vs output voltage modulation goes up to 90% on full load. I've used DAC outputs to show internal controller variables.

    Default EST settings, 0.012, 1.0, 0.75.

    CH1 - Ia current probe, CH2 - Ib current probe, CH3 - Ia DAC output, CH4 - Ib DAC output:

    CH1 - Ia current probe, CH2 - Ib current probe, CH3 - Vb DAC output, CH4 - Va DAC output:

    CH1 - Ia current probe, CH2 - Ib current probe, CH3 - Iq DAC output, CH4 - foc_angle DAC output:

    RPMs:

    Iq going from 30 to 60A:

    And comparing with  99nF Vph filter version (~380Hz cutoff), with default EST settings 0.12, 1.0, 0.75:

    CH1 - Ia current probe, CH2 - Ib current probe, CH3 - Id DAC output, CH4 - foc_angle DAC output:

    which shows ugly current disturbances on phases.

    RPMs:

    Not reaching the speed with 800Hz Vph version.

    Iq:

    Improved when settings set to 0.08, 1.0, 0.8:

    CH1 - Ia current probe, CH2 - Ib current probe, CH3 - Iq DAC output, CH4 - foc_angle DAC output:

    RPMs:

    Iq:

    CH1 - Ib current probe, CH2 - Ia current probe, CH3 - Va DAC output, CH4 - Vb DAC output:


    I've also did similar test using earlier design with non-TI MCU and it shows, that current waveforms are way more sinusoidal than InstaSPIN one.
    Same inverter, same motor, same load, supply voltage didn't matter.

    CH1 - Ia current probe, CH2 - Ib current probe, CH3 - Ia DAC output, CH4 - Ib DAC output:

    What could be the cause of this?


    I'll probably perform some more tests, but these are very time consuming and I'm getting out of ideas...

  • Hi Mice,

    Mice said:
    Same inverter, same motor, same load, supply voltage didn't matter.

    Reading you have chosen INA240-A1? to monitor phase current with 100 ohm 47nf filter? Seemingly there is an possible impedance mismatch into ADC channels causing sharp ringing peaks. The INA output likes to ring when >1nf exists on output, check datasheet. Noting large filter spike transients may also occur and relative to chosen shunt resistance values.  

    240-A1 realized well shaped sinusoidal current wave forms by limiting open loop current gain via 4K8 to 5K6 no decoupling filter cap. Perhaps remove the 47nf and recheck the wave forms?

     

  • Gl said:
    Reading you have chosen INA240-A1? to monitor phase current with 100 ohm 47nf filter? Seemingly there is an possible impedance mismatch into ADC channels causing sharp ringing peaks. The INA output likes to ring when >1nf exists on output, check datasheet. Noting large filter spike transients may also occur and relative to chosen shunt resistance values.

    The cap is 4.7nF, not 47nF.
    I think 1nF datasheet value is for cap directly on the output pin, not when separated by a resistor. I've also tried 50Ω 2.2nF setup, as suggested, with no noticable difference.

    Also notice that ADC measured values displayed with DAC outputs are on par with isolated current probes. And earlier design controller uses the same current sense circuit.

    Anyway i'll try without the cap and put the results here later.
    edit: No cap result below:
    CH1 - Ia current probe, CH2 - Ib current probe, CH3 - Ia ADC measured/DAC output, CH4 - Ib ADC measured/DAC output

  • Mice said:
    The cap is 4.7nF, not 47nF.

    Further up post scope captures shows 47nf, reason to ask. So what was the series resistance when you removed the filter cap? Capture looks like the 3rd harmonic followed by overshoot peak, almost as if ADC sample is out of sync. Beside 5K6 also have ferrite chip after R near 240 to reduce ringing and lastly 300nH choke near ADC input but no capacitors confused this with another custom PCB.

    Edit: Checked the 49c launch pad had 3 filter caps for this capture, perhaps 1.0nf or 2.2nf, no ferrite chips R=6K8

  • All,

    Just want to give an update from the TI side that our responses to the E2E will be delayed due to the weather here in Texas, many of our experts(including Yanming) don't have power or access to the internet at this time. 

    We will reply as soon as things allow, but it may be until Monday that things are back to normal based on what we are being told by the utilities.  Appreciate your patience here as we work through this.

    Best,

    Matthew

  • Gl said:
    Further up post scope captures shows 47nf, reason to ask.


    47nF is on phase voltage filter. I manipulate with phase voltage sensing, because it + EST_setOneOverFluxGain_sf(), EST_setFreqLFP_sf(), EST_setBemf_sf() functions make biggest difference.

    Mice said:
    I have 100Ω + 4.7nF RC filter on the INA240 output. The cutoff should be at around 338kHz.


    And also tried 51Ω + 2.2nF version.

    I realize that It's closed loop and bad INA240A1 output could cause some distortions, but in that case i think the disturbances are sourced to the motor - then measured correctly by CSA.
    Messing with CSA circuit would probably be even harder to debug, so i'll pass on that.

    Thanks for the waveform, but 150Hz is not even close to 500Hz 125A Pk-pk i have problem with. At lower load waveforms look much better.

    CH1: Ia, CH2: Ib, CH3: measured Ia, CH4: measured Ib

    (That's an animated GIF below showing current waveforms at different speeds 330-460Hz)




    I tried to repeat the test with 3.00.01.00 SDK version - without fluxHF.lib and 1/flux, freqlfp, bemf gain settings (left at 1.0, 1.0, 1.0?)
    On 99nF (380Hz) Vph filter controller, it was loosing stability around the cutoff frequency.

    CH1: Ia, CH2: Ib, CH3: measured Ia, CH4: measured Ib



    And on 47nF (800Hz) Vph filter controller, it was starting to oscillate around 460-480Hz:
    CH1: Ia, CH2: Ib, CH3: Iq, CH4: angle


    I've also tried changing ADC triggering to be on high-side turned on but it didn't do much difference.

  • Hi Mice,

    I realize that It's closed loop and bad INA240A1 output could cause some distortions,

    According to INA forum it's open loop gain into the ADC via single ended channel, not sure about differential gain. From past use of INA It seems low side shunt current somehow propagates into the output, invades ADC samples. Our custom PCB must use 5k6 to arrest over current peaks and false tripping CMP shut down of PWM. 

    Lastly figured the 282 output impedance was similar to 240 (1.5Ω), perhaps loads CMOS coupling into SAR ADC. Oddly I too started with 100Ω coupling but found the SNR was impacted at the Nyquist sample frequency. Also noisy EMF messed with the acquisition window, hence ferrite chips help reduce ringing oscillations, BW filter starts near 20MHz.  Last scope captures seem as if motor current somehow invades ADC samples, perhaps via the EMF side?

     Have a look at the BoostXL-DRV8320RS schematic input filter design, though 49c PGA to sample current the impedance match is much >100Ω.

    This just in: INA240: Output impedance, load capability - Amplifiers forum - Amplifiers - TI E2E support forums

  • Hi Mice,

    Let's check if the issue is from the current sensing, estimator, or the motor model is variable at high current. Could you please try to run the motor at the following different conditions to see what happens in these cases?

    1. Run the motor to a high speed without load.

    2. Run the motor to a high speed using a small propeller.

    3. Increase the dc-bus voltage and limit the maximum Vs modulation to 0.5, and use lab07 to disable the over-modulation.

    Do you have the inductance vs current curve of the motor? If not, could you please check if the motor manufacturer has such a curve for you?

    Can you post the schematic in pdf format and the user.h files to this forum? So we can have a look at these files to understand the settings.

  • I performed tests below using base HW with 800Hz Vph filters and default est parameters: flux: 0.12, lfp: 1.0, bemf: 0.75 in torque mode.

    1. Motor runs to ~570Hz at 21V 0.5modulation, ~660Hz at 21V 0.57modulation, ~850Hz at 27V 0.57modulation

    21V 0.50 modulation, CH1: Ia current probe, CH2: Ib current probe, CH3: ADC measured Ia DAC output, CH4: ADC measured Ib DAC output:

    21V 0.57 modulation, CH1: Ia current probe, CH2: Ib current probe, CH3: ADC measured Ia DAC output, CH4: ADC measured Ib DAC output:

    27V 0.57 modulation, CH1: Ia current probe, CH2: Ib current probe, CH3: ADC measured Ia DAC output, CH4: ADC measured Ib DAC output:

    27V 0.57 modulation, CH1: Ia current probe, CH2: Ib current probe, CH3: ADC measured Va DAC output, CH4: ADC measured Vb DAC output

    21V 0.57 modulation, CH1: Ia current probe, CH2: Ib current probe, CH3: ADC measured Va DAC output, CH4: ADC measured Vb DAC output

    21V 0.57 modulation, CH1: Ia current probe, CH2: Ib current probe, CH3: Measured Iq DAC output, CH4: Estimator angle DAC output

    27V 0.57 modulation, CH1: Ia current probe, CH2: Ib current probe, CH3: Measured Iq DAC output, CH4: Estimator angle DAC output


    2. CH1: Ia current probe, CH2: Ib current probe, CH3: ADC measured Ia DAC output, CH4: ADC measured Ib DAC output
    At 21V with 0.5 modulation


    At 21V with 0.57 modulation

    At 27V with 0.5 modulation:

    At 27V with 0.57 modulation:



    3. CH1: Ia current probe, CH2: Ib current probe, CH3: ADC measured Ia DAC output, CH4: ADC measured Ib DAC output

    Yanming Luo said:
    Do you have the inductance vs current curve of the motor? If not, could you please check if the motor manufacturer has such a curve for you?

    No, there's almost no detailed info for the motor. It's "hobby" outrunner motor. Could i possibly make such curve by myself?

    Do you suspect the motor is saturating? I think we've had it saturating at about ~65-70A DC current on 6-step ESC controller at 21V battery under heavy accelerations.

    After tests with the smaller propeller, It seems that problem is output current dependent. If i think of some more tests isolating the problem, i'll post them here.

    Yanming Luo said:
    Can you post the schematic in pdf format and the user.h files to this forum? So we can have a look at these files to understand the settings.

    I cannot post full schematic file, but i'll be able to provide critical elements if you specify which parts are interesting to you (analog sensing? inverter? mcu side?).
    User.h file attached.

    2350.user.h

  • Hi Mice,

    "800W, 12n14p SM-PMSM / hobby BLDC, "quasi"-sinusoidal BEMF,"

    Oddly my 22 pole motor produce similar un-powered EMF cogging quasi (trapezoidal) wave form you seem to show in last post. Some MCU vendors suggest they can not get exact rotor position from such data. Also they suggest may be unable to spin a motor unless it produces pure sinusoidal EMF. My test 8 pole Nidec SPMM (25H series) produces pure un-powered sine wave and easily reaches 11KRPM (unloaded) via 6 step FOC, configured as 6 poles. Nidec 25H series is listed as 8 poles but it would only reach roughly 6KRPM as 8 poles.

    Oddly Nidec 25H575K030 refuses to accelerate after ID with custom DC inverter connected to LAUNCHXL-49c.

  • The EMF of the UNCONNECTED motor - driving it with 1kRPM handrill and scope probes connected to the phase leads, looks like this:

    Almost the same motor, just with different magnets and airgap looks like this:

  • Mice,

    Thanks for providing so many testing waveforms for analysis. Are the last four waveforms tested with the smaller propeller? It looks like the other current waveforms are not good in the testing conditions, which could impact the motor control without a correct rotor position estimation.

    No, it's difficult to make the inductance/current curve directly. The motor manufacturer should have this curve based on the design. If the inductance is significantly changed for the d-axis and q-axis current increasing, which will cause the motor model is inaccurate to estimate the correct rotor position. We have to online change the inductance for the estimator. The six-step trapezoidal control doesn't need such motor electrical parameters, so it's not sensitive to the current increasing and saturation.

    Did you try to run the motor identification for each motor? And did you change the user.c file since you are using the "Wb" unit for the flux of the motor in the user,h?

    You might just need to show the current and voltage sensing circuit, and inverter drives circuit for the motor.

  • Yanming Luo said:
    Are the last four waveforms tested with the smaller propeller? It looks like the other current waveforms are not good in the testing conditions, which could impact the motor control without a correct rotor position estimation.

    In 2. all the tests were done using smaller propeller which require less torque, and the controller is BEMF limited. The current waveform was distorted when the speed raised so the torque and current raised with speed^2, because I've increased power supply voltage or modulation

    In 3. test was done using previous, end-product target propeller at 27V 0.5 modulation.

    Yanming Luo said:
    No, it's difficult to make the inductance/current curve directly. The motor manufacturer should have this curve based on the design.

    I'll try asking manufacturer for this curve. I doubt they'll have one, because it seems that in "hobby" it's more common to design things by experimenting, trial and error than by theoretical design.

    Yanming Luo said:
    Did you try to run the motor identification for each motor?

    Motor identification is implemented so it saves all the required params in flash and reuse them later. User.h contains average, starting values for the motor.
    Real Rs value is between 20-22mΩ (depending on the motor piece), Ls between 22-30µH (more depending on the L meter), and the motor id estimates them ~23-25mΩ and ~26-32µH.

    Yanming Luo said:
    And did you change the user.c file since you are using the "Wb" unit for the flux of the motor in the user,h?

    Seemed that the end unit was Wb anyway and it was more convenient for us to use Wb units. VpHz/MATH_TWO_PI dividing is removed from user.c code.

    Yanming Luo said:
    You might just need to show the current and voltage sensing circuit, and inverter drives circuit for the motor.

    INA240 pin 1. was mistakenly left unconnected in the design, but fixing it with kynar cable didn't improve on our problem.

  • Hi Mice,

    Your unpowered motor wave forms are trapezoidal in the +/-peaks noted by small bump at both peaks. According to Cypress text trapezoidal EMF causes issues with true rotor position SPV data.

    Having just removed three 240 filters from lanuchXL, actually 2.2nF(2200pF) with 6K8 series. In any case the Rs/Ron input impedance of the x49c ADC channels are >100 ohms recalling 1K2 500R, check the x49c TRM. Note the PGA gain is only 13 12 via SDK hal.c so 240 gain 20 seems an overkill, hence Rs impedance coupling somehow effects FAST estimator run time values as noted in my recent post.

  • Mice,

    It seems like you didn't use the internal PGA of F28004xC. Could you please post eh ADC configuration codes? I want to know what ADC clock and sample window are you using, the RC filter for current sensing depends on these settings. It seems like the capacitance on the ADC input pin may be too high if you use a small ACQPS for a fast ADC sample.

  • Hi Mice,

    Mice said:
    Almost the same motor, just with different magnets and air gap looks like this:

    That second motor has much better chance at reaching top speed under load. The flat tops on the first one are sure to give odd problems. My un-powered 22 pole has crazy looking but pure sinusoidal waveform, more like your last few top captures when powered. I'm getting ready to test BoostXL-drv8320rs with both motors since jumper wired test inverter refused to work with SPV after motor ID..

  • Yes, i do not use internal PGAs, because CSA gain is already high (x20). CMPSS are also disabled because it was triggering too often and needed to tune the timings.

    The clocking is left default, as in the lab examples, 50 MHz ADC and HAL_ADC_SAMPLE_WINDOW is left at 14 (15 system clocks). This may indeed be actually too short. If I understand it correctly, the RC time constant is about ~ 470ns in my setup. I already tried 51Ω 2.2nF setup without improvement, but I'll retry that + adjust the ACQPS.

    //! configure the sample window to 15 system clock cycle wide by assigning 14
    //! to the ACQPS of ADCSOCxCTL Register for correct ADC operation
    #define HAL_ADC_SAMPLE_WINDOW           14
    HAL_Obj *obj = (HAL_Obj *)handle;
    
        SysCtl_delay(100U);
        ADC_setVREF(obj->adcHandle[2], ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
        ADC_setVREF(obj->adcHandle[1], ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
        ADC_setVREF(obj->adcHandle[0], ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
        SysCtl_delay(100U);
    
        // Configure internal reference as 1.65V*2 = 3.3V
        ASysCtl_setAnalogReference1P65(ASYSCTL_VREFHIA |
                                       ASYSCTL_VREFHIB |
                                       ASYSCTL_VREFHIC);
    
        // Enable internal voltage reference
        ASysCtl_setAnalogReferenceInternal(ASYSCTL_VREFHIA |
                                           ASYSCTL_VREFHIB |
                                           ASYSCTL_VREFHIC);
    
        // Set main clock scaling factor (50MHz max clock for the ADC module)
        ADC_setPrescaler(obj->adcHandle[0], ADC_CLK_DIV_2_0);
        ADC_setPrescaler(obj->adcHandle[1], ADC_CLK_DIV_2_0);
        ADC_setPrescaler(obj->adcHandle[2], ADC_CLK_DIV_2_0);
    
        // set the ADC interrupt pulse generation to end of conversion
        ADC_setInterruptPulseMode(obj->adcHandle[0], ADC_PULSE_END_OF_CONV);
        ADC_setInterruptPulseMode(obj->adcHandle[1], ADC_PULSE_END_OF_CONV);
        ADC_setInterruptPulseMode(obj->adcHandle[2], ADC_PULSE_END_OF_CONV);
    
        // enable the ADCs
        ADC_enableConverter(obj->adcHandle[0]);
        ADC_enableConverter(obj->adcHandle[1]);
        ADC_enableConverter(obj->adcHandle[2]);
    
        // set priority of SOCs
        ADC_setSOCPriority(obj->adcHandle[0], ADC_PRI_ALL_HIPRI);
        ADC_setSOCPriority(obj->adcHandle[1], ADC_PRI_ALL_HIPRI);
        ADC_setSOCPriority(obj->adcHandle[2], ADC_PRI_ALL_HIPRI);
    
        // delay to allow ADCs to power up
        SysCtl_delay(1000U);
    
        // configure the interrupt sources
        // configure the ample window to 15 system clock cycle wide by assigning 14
        // to the ACQPS of ADCSOCxCTL Register.
        // RB2/B3
        ADC_setInterruptSource(obj->adcHandle[1], ADC_INT_NUMBER1, ADC_SOC_NUMBER2);
    
        // configure the SOCs for hvkit_rev1p1
        // ISENA - C1->RC0
        ADC_setupSOC(obj->adcHandle[2], ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,
                     ADC_CH_ADCIN1, HAL_ADC_SAMPLE_WINDOW);
    
        // ISENB - A2->RA0
        ADC_setupSOC(obj->adcHandle[0], ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,
                     ADC_CH_ADCIN2, HAL_ADC_SAMPLE_WINDOW);
    
        // ISENC - B2->RB0
        ADC_setupSOC(obj->adcHandle[1], ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,
                     ADC_CH_ADCIN2, HAL_ADC_SAMPLE_WINDOW);
    
        // VSENA - A4->RA1
        ADC_setupSOC(obj->adcHandle[0], ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM1_SOCA,
                     ADC_CH_ADCIN4, HAL_ADC_SAMPLE_WINDOW);
    
        // VSENB - B4->RB1
        ADC_setupSOC(obj->adcHandle[1], ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM1_SOCA,
                     ADC_CH_ADCIN4, HAL_ADC_SAMPLE_WINDOW);
    
        // VSENC - C3->RC1
        ADC_setupSOC(obj->adcHandle[2], ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM1_SOCA,
                     ADC_CH_ADCIN3, HAL_ADC_SAMPLE_WINDOW);
    
        // VSENVM - A10->RA2. Board has capacitor on Vbus feedback, so
        // the sampling doesn't need to be very long to get an accurate value
        ADC_setupSOC(obj->adcHandle[0], ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA,
                     ADC_CH_ADCIN10, HAL_ADC_SAMPLE_WINDOW);
    
        // FET_TEMP - B3->RB2.
        ADC_setupSOC(obj->adcHandle[1], ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA,
                     ADC_CH_ADCIN3, HAL_ADC_SAMPLE_WINDOW);

    I can also see, that B3 pin is extra ~120pF Cp because of internal reference decoupling. Shouldn't matter for temperature readings... The rest is  6-10pF without comparators.

    Gl said:
    That second motor has much better chance at reaching top speed under load. The flat tops on the first one are sure to give odd problems. My un-powered 22 pole has crazy looking but pure sinusoidal waveform, more like your last few top captures when powered. I'm getting ready to test BoostXL-drv8320rs with both motors since jumper wired test inverter refused to work with SPV after motor ID...

    I actually tested that second motor yesterday and the results were much worse than with the main one. It destabilizes much quicker and uglier. But I have to double check if it's not some kind of loose contact on the motor leads.

  • Mice said:
    This may indeed be actually too short. If I understand it correctly, the RC time constant is about ~ 470ns in my setup. I already tried 51Ω 2.2nF setup without improvement, but I'll retry that + adjust the ACQPS.

    I replaced 100Ω resistors and 4.7nF caps to 51Ω + 2.2nF without improvement. Also, after doubling ACQPS to 29 it didn't make any difference.

    Then I tried to run it on LAUNCH-XL board for and observed almost the same. So current sense circuit shouldn't be the problem there.
    (note. BOOSTXL-DRV8320RS was modified for 800Hz Vph filters, +/- 110A current sense range with 3mΩ shunts, PGA gain set to 6 - 5x in real.)

  • I found similar motor for additional comparison: 22N24P so 11 pole pairs, 280kv, identified params: ~2.0mWb, 19-20µH, 40-45mΩ.
    I've run it on 27V, 0.5modulation with main propeller and It shows the same behaviour - distorted/non-sinusoidal currents, but as the frequency is higher, the Iq current ripple stays bit lower.

  • One more test with higher kv similar size motor: 12N14P, 7 pole pairs, 490kv, identified params: 1.63mWb, 12.5µH, 21.6mΩ.
    Had to increase target Iq to 70A, because of unoptimal Nm/A for this propeller.

  • Hi Mice,

    Oddly the better sine wave motor should be easier to derive sector position data from.

    Quote "I already tried 51Ω 2.2nF setup without improvement, but I'll retry that + adjust the ACQPS." I reported the datasheet example use of SYSCLK 100Mhz for ACQPS times when ADCCLK is/was 50Mhz (20ns). 

    If we use the ADC clock rate 50Mhz to determine sample window time from the perspective of the ADC channel input, ACQPS-14 is 280ns and not 140ns.

    Also that strange acquisition example TRM page 1505 is nonsense, replace decimal value commas with decimal points to represent nanoseconds. Proper RC time constant formula is Fo=1/2piRC. The CPMSS trips zones from very low channel input impedance, relative to EMF kickback upon sudden field collapse in phase coils.

  • Yanming Luo said:
    ACQPS for a fast ADC sample.

    TRM Figure 13.1 analog to digital core shows sample hold (S/H) circuit ADCSOC thus ACQPS times should be evaluated at ADC clock speed not the arbitration section, perhaps running at sysclk speed. Who knows there is not a single clock input documented in this very important figure and likely no main clock tree figure exists in TRM to prove/disprove correct arbitration values for ACQPS setting in software. Nobody on earth can determine without question proper sample acquisition hold times from what has been documented. 

    Edit: Table 3-7 shows ADCA-C = PERx_SYSCLK as a specific clock domain not directly part of or in SYSCLK domain.

    Note: ADC module Fig.13-13 shows 22 SYSCLK cycles late for SOC interrupt (Table13-9) Yet S+H should be SYSCLK prescale/2 or 50Mhz. The timing diagram shows no PERx_SYSCLK domain or pulses for S+H. seems incorrect. Seemingly SYSCLK time was added for SOC triggering and Late interrupts for pre-scaler events. 

  • MIce,

    You might refer to chapter 13.13.2 to select the Rs and Cs value or to select the ACQPS value according to the RC value on your board.  You might try to use a higher ACQPS to increase the ADC S/H window. I am not sure that this can solve the issue you met. But I try to run a similar drone motor as you used with a light load in lab, I can't repeat the same issue.

  • Yanming Luo said:
    You might try to use a higher ACQPS to increase the ADC S/H window. I am not sure that this can solve the issue you met.


    Yeah, already tried without success.

    Yanming Luo said:
    But I try to run a similar drone motor as you used with a light load in lab, I can't repeat the same issue.

    As shown earlier, the issue start to develop at >=50% max load of the motor and phase currents are being distorted on the peaks and following downslope at the point, where is the next phase peak. I can repeat this issue on every motor i get my hands on by driving it harder.

    The only idea i have atm. is to use FAST for the start-up, then switch to some other observer, Luenberger or EKF, but it would need additional time to implement and tune it while i'm already over the deadlines with that project...

  • Perhaps try 5k6 with 1nF for the current filters, Fo = 2.842052555212416710158638631652e-8 or 284ns Ch charge time. Hence I used parts of the same math the TRM shows but don't truncate capacitor values 2.2nF=2200pF or 1nF=1000pF, commas are not considered decimal places in western math formulas.

    Note the PGA's inputs to the ADC have (0) capacitors little to no series resistance.

  • Mice,

    I think that could be a good idea. The FAST estimator needs a precise motor model to get better performance. It seems like the issue could be that the current sensing is not correct or the motor model is changed at high speed with high current. If you have the stator inductance vs. current and resistance vs. temperature curve, you can add a function to online change the motor parameters that could be solved this problem.

  • Ok, I currently think I've eliminated the estimator.

    I used BOOSTXL-DRV8320 board, first identyfing the motor with lab05, then used lab06 and connected encoder to it, bypassing the angle estimation and problem still exists.

    I plan to perform more tests testing the current loops. Maybe there are some issues with the delay? Or could it be SVM problem?
    Meanwhile, I tried contacting the motor manufacturer for the inductance data and manufacturer was willing to help at first, but I'd still have to wait, and Idk if they'll be able to provide it.

    PS.  Would you be interested in testing our motor+load setup on your own and try helping to find the problem with it's cooperation with InstaSPIN? It probably would be much easier to debug than through the forum, remotely.

    Edit. After more tests i think the current loop performance is too low for the motor. That's why it oscillate and cause disturbances on phase sinewaves. And that's also why non-TI MCU was able to run it perfectly on that load (50kHz PWM/50kHz ISR current loop with 2000Hz+ bandwidth). I tried to tune it a little bit but i had not enough room to get rid of the distortions (too much delay in the system?).


  • Hi Yanming,

    We have recently made a controller using the F280049C and we were having a very similar issue to the one being discussed here. We are also running a low inductance BLDC motor at high speed. We saw your recommendation on dynamic inductance vs current. We have implemented a function that adjusts the inductance based on the current and it appears to be a step in the right direction. However, we do not have an inductance vs current curve and will not be able to get one from the manufacturer. So the function is just arbitrarily being adjusted in an attempt to get the motor spinning faster. We have a few questions to try understanding the problem better:

    1. We have in the past has success with the F28069M running the same motor, what made it able to run these motors at high speed and the F280049C unable? Were there changes made to the instaspin algorithms?
    2. Is there a recommended setup that will allow us to measure the inductance vs current on out motor?
    3. Does the inductance of the motor change with current even when there is no rotor attached (i.e. a function of the magnetic properties of the core) or is it something that happens only when there is a rotor spinning?
    4. Is there any way we could send you one of our motors to test with the F280049C to get it running more reliably?
  • 1. The mathematical models of the FAST estimator are the same between F2806xF/M and F280049C. The major difference is that the algorithm codes of the F2806xF/M are designed with IQmath and PU  format, but the codes of the F280049C are designed with floating-point and SI absolute format.

    2. I just got this curve from the motor manufacturer since the motor designer can calculate this when they design the motor. I didn't use any tools to measure this.

    3. I don't think it's necessary to spin the motor for measuring the inductance, but the rotor must be attached and the stator inductance must be measured in the motor. 

    4.  What's the motor specification? The maximum current and speed? Can the motor run with load at high speed in our lab?

  • Mice,

    I don't think the problem is from the SVM since you didn't use the over-modulation with a <0.5 value for the USER_MAX_VS_MAG_PU and low-side shunt resistor for current sensing.

    That could be good for me to repeat this issue and try to find the root cause if possible. What's the maximum current and speed of the motor? And what current and voltage does the DC power supply have for the testing?

  • 1. Is there any reason that with almost the same hardware besides the microcontroller that they might perform differently?

    2. We are unable to get this curve from the manufacturer so we need another way. Are you able to give us an example of a inductance v current curve or where to find one?

    4. The motor is capable of roughly 35A max and 5000RPM max at 48V supply. It has 21 pole pairs. We have been using a 28" propeller to load it. I am not sure if you would have a way to run it in this configuration.

  • 1. Is there any reason that with almost the same hardware besides the microcontroller that they might perform differently?

    I asked the same question at the beggining in this thread, as It also seemed to me that non-FPU chips was reportedly worked better for the users and *49C was causing issues with the speed or sth.
    If internally the ROM model is the same, then main differences that are coming into my mind are the software package (SDK vs MotorWare) and fixed point > floating point operations accuracy.

    What's the maximum current and speed of the motor? And what current and voltage does the DC power supply have for the testing?

    The motor was rated for at least 800W or 35A DC by the winding. In our setup It spins up to 4400RPM with the load on 21V lithium battery taking up to 35-40A at full thrust. I did most of my previous tests using 40A power supply at 27V output and It was consuming ~25-30A DC.

  • then main differences that are coming into my mind are the software package (SDK vs MotorWare) and fixed point > floating point operations accuracy.

    RDKv3.1 now supports both eabi floating point  precision functions projects and older legacy COFF are separate builds. The older versions were only legacy COFF builds.

  • We have also tried switching to V3.1, mostly because it has the FluxHF and one over flux stuff in it already and it didn't fix the problem.

  • Mice,

    That's fine. I have two DC power supplies (30V/50A) and 800V/70A) in the lab to test the motors.

  • Hello Yangming Luo,

    I have a question about LAUNCHXL-F28379D and BOOSTXL-3PhGaNInv, I have post a thread here https://e2echina.ti.com/question_answer/microcontrollers/c2000/f/56/p/200439/625531#625531

    I know you have write the SPRACO3, there are really some problem confused me. but it's hard to find you to answer.

    So can you give me some advice  if it is convenient to you .

    sorry to answer on the other thread.

    Thank you so much!

  • We can reply to your questions in the thread you created if it's not closed or resolved.

  • In all sensorless SDK examples there is angle delay compensation:

    //
    // compute angle with delay compensation
    //
    angleDelta_rad = userParams.angleDelayed_sf_sec *
                         estOutputData.fm_lp_rps;
    
    angleWithDelay_rad = MATH_incrAngle(estOutputData.angle_rad,
                                        angleDelta_rad);

    Shouldn't it use ELECTRICAL speed rather than mechanical?

  • Which FP version did you import to CCS, COFF or Eabi? I noticed a few messages after project build how to improve precision via optimizations only for Eabi builds. The default project optimizations are minimal it seems.

  • The motor is capable of roughly 35A max and 5000RPM max at 48V supply. It has 21 pole pairs.

    Perhaps odd number pole pairs are the issue since 21 is not divisible by 2? There are motors with uneven number of pole pairs?

  • Which FP version did you import to CCS, COFF or Eabi?

    I was using using COFF at the beginning, then i switched to EABI about 3 weeks ago to search for any improvements. It didn't help to my problem.

    The motor is capable of roughly 35A max and 5000RPM max at 48V supply. It has 21 pole pairs.

    Perhaps odd number pole pairs are the issue since 21 is not divisible by 2? There are motors with uneven number of pole pairs?

    You meant about pole number not divisible by 2? I don't see an issue with pairs number. I am using 7 pole pairs = 14 poles, and 21 pole pairs is 42 poles - divisible by 2.
    BTW. With that pole number, at 5000RPM electrical frequency is 1750Hz which might be high for the FOC. TI specifies that the control loop should be at least 10x the el. freq which is 17.5kHz so should be fine, but close to the limit, i guess...

  • The eabi optimizations can be improved. Seems I was thinking poles but swear the word pairs was not there before. Some other FOC software will not allow an uneven pole count entry, likely the reason.

  • Mice,

    You might try to use a higher control ISR and PWM frequency like 50Khz PWM /25kHz control frequency if the hardware can support this PWM frequency, which could improve the current control bandwidth and performance.

  • I'm already using 50/25kHz PWM/ISR with custom HW and I was using the defaults with launchpad examples (40/20kHz).

    I tuned the current loop manually by forcing the rotor el.angle to 0° and fixing it to eliminate any rotation. I was using up and down Iq step inputs and tuned for quickest no-overshoot response time, but i couldn't raise Kp enough to improve the bandwidth. I had about ~20Hz increased maximum speed with that, but the spikes were still there so the efficiency is bad.

    CH1: Ia current probe, CH2: Ib current probe, CH3: Iq DAC, CH4: Id DAC

    CH1: Ia current probe, CH2: Ib current probe, CH3: Iq DAC, CH4: Vq-out DAC

    CH1: DC battery current, CH2: Ib current probe, CH3: Iq DAC, CH4: Id DAC


    Kp is set to 0.095 so it's about ~570Hz or 3600rad/s bandwidth (assuming 27µH), and Ki is set to 0.1 - about 3x times the value which is calculated from R/L/ISR_freq parameters.

    It looks nice below ~ 40A Iq / ~400Hz speed. Maybe i have to test it with higher torque / lower speed load.

  • Yes, it looks like the current and angle waveforms are very nice in the last two pictures. You might try to use a variable and different Kp for d and q-axis current, and limit the error in the PI controller.

    Btw, you might try to implement a control method that controls reference Id to zero, but adjust the Vq directly based on the throttle input if you don't need an accurate speed control.