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.

Current waveform differences between lab projects and GUI example

Other Parts Discussed in Thread: DRV8301, MOTORWARE, TMS320F28027F, TMS320F28069F, TMS320F28062F

Hi,

I'm using DRV8301-HC-EVM Rev D and the F2806x ISO-controlCard to evaluate instaSPIN on one of our 24V PMSM motor.

With the GUI pre-compiled program, my motor run a 4740RPM (nominal speed) until 18V when overmodulation is set to 1 and until 17V when overmodulation is set to 1.15 (and i can see a regular distorsion on the current waveform). Below this voltage, i can't reach 4740RPM but it is still running.

But with the lab example (lab03b), when the voltage reach 20V, there is some spurious distorsion on the current waveform :

At 21V :

  

At 19.8V :

I have also add 1us dead time but the problem was present before I add the dead time.

There is sometimes some little difference on RS and LS but with exactly the same, there is no change. I also adjust Kp and Ki to have exactly the same but there is no change.

The GUI parameters are :

And now my user.h....

#ifndef _USER_H_
#define _USER_H_
/* --COPYRIGHT--,BSD
* Copyright (c) 2012, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --/COPYRIGHT--*/

//! \file solutions/instaspin_foc/boards/drv8301kit_revD/f28x/f2806xF/src/user.h
//! \brief Contains the public interface for user initialization data for the CTRL, DRV, and EST modules
//!
//! (C) Copyright 2012, Texas Instruments, Inc.


// **************************************************************************
// the includes

// modules
#include "sw/modules/types/src/types.h"
#include "sw/modules/motor/src/motor.h"
#include "sw/modules/est/src/32b/est.h"
#include "sw/modules/est/src/est_states.h"
#include "sw/modules/est/src/est_Flux_states.h"
#include "sw/modules/est/src/est_Ls_states.h"
#include "sw/modules/est/src/est_Rs_states.h"
#include "sw/modules/ctrl/src/32b/ctrl_obj.h"


// platforms
#include "sw/modules/fast/src/32b/userParams.h"

//!
//!
//! \defgroup USER USER
//!
//@{


#ifdef __cplusplus
extern "C" {
#endif

// **************************************************************************
// the defines


//! \brief CURRENTS AND VOLTAGES
// **************************************************************************
//! \brief Defines the full scale frequency for IQ variable, Hz
//! \brief All frequencies are converted into (pu) based on the ratio to this value
//! \brief this value MUST be larger than the maximum speed that you are expecting from the motor
#define USER_IQ_FULL_SCALE_FREQ_Hz (200.0) // 800 Example with buffer for 8-pole 6 KRPM motor to be run to 10 KRPM with field weakening; Hz =(RPM * Poles) / 120

//! \brief Defines full scale value for the IQ30 variable of Voltage inside the system
//! \brief All voltages are converted into (pu) based on the ratio to this value
//! \brief WARNING: this value MUST be larger than the maximum value of any voltage calculated inside the control system otherwise the value can saturate and roll-over, causing an inaccurate value
//! \brief WARNING: this value is OFTEN greater than the maximum measured ADC value, especially with high Bemf motors operating at higher than rated speeds
//! \brief WARNING: if you know the value of your Bemf constant, and you know you are operating at a multiple speed due to field weakening, be sure to set this value higher than the expected Bemf voltage
//! \brief It is recommended to start with a value ~3x greater than the USER_ADC_FULL_SCALE_VOLTAGE_V and increase to 4-5x if scenarios where a Bemf calculation may exceed these limits
//! \brief This value is also used to calculate the minimum flux value: USER_IQ_FULL_SCALE_VOLTAGE_V/USER_EST_FREQ_Hz/0.7
#define USER_IQ_FULL_SCALE_VOLTAGE_V (42.0) // 42.0 Example for drv8301 typical usage and the Anaheim motor

//! \brief Defines the maximum voltage at the input to the AD converter
//! \brief The value that will be represtented by the maximum ADC input (3.3V) and conversion (0FFFh)
//! \brief Hardware dependent, this should be based on the voltage sensing and scaling to the ADC input
#define USER_ADC_FULL_SCALE_VOLTAGE_V (66.32) // 66.32 drv8301_revd voltage scaling

//! \brief Defines the voltage scale factor for the system
//! \brief Compile time calculation for scale factor (ratio) used throughout the system
#define USER_VOLTAGE_SF ((float_t)((USER_ADC_FULL_SCALE_VOLTAGE_V)/(USER_IQ_FULL_SCALE_VOLTAGE_V)))

//! \brief Defines the full scale current for the IQ variables, A
//! \brief All currents are converted into (pu) based on the ratio to this value
//! \brief WARNING: this value MUST be larger than the maximum current readings that you are expecting from the motor or the reading will roll over to 0, creating a control issue
#define USER_IQ_FULL_SCALE_CURRENT_A (41.25) // 41.25 Example for drv8301_revd typical usage

//! \brief Defines the maximum current at the AD converter
//! \brief The value that will be represtented by the maximum ADC input (3.3V) and conversion (0FFFh)
//! \brief Hardware dependent, this should be based on the current sensing and scaling to the ADC input
#define USER_ADC_FULL_SCALE_CURRENT_A (82.5) // 82.5 drv8301_revd current scaling

//! \brief Defines the current scale factor for the system
//! \brief Compile time calculation for scale factor (ratio) used throughout the system
#define USER_CURRENT_SF ((float_t)((USER_ADC_FULL_SCALE_CURRENT_A)/(USER_IQ_FULL_SCALE_CURRENT_A)))

//! \brief Defines the number of current sensors used
//! \brief Defined by the hardware capability present
//! \brief May be (2) or (3)
#define USER_NUM_CURRENT_SENSORS (3) // 3 Preferred setting for best performance across full speed range, allows for 100% duty cycle

//! \brief Defines the number of voltage (phase) sensors
//! \brief Must be (3)
#define USER_NUM_VOLTAGE_SENSORS (3) // 3 Required

//! \brief ADC current offsets for A, B, and C phases
//! \brief One-time hardware dependent, though the calibration can be done at run-time as well
//! \brief After initial board calibration these values should be updated for your specific hardware so they are available after compile in the binary to be loaded to the controller
#define I_A_offset (0.991140902)//(0.9939797521)
#define I_B_offset (0.9958643317)//(1.014363647)
#define I_C_offset (1.009294033)//(1.005615234)

//! \brief ADC voltage offsets for A, B, and C phases
//! \brief One-time hardware dependent, though the calibration can be done at run-time as well
//! \brief After initial board calibration these values should be updated for your specific hardware so they are available after compile in the binary to be loaded to the controller
#define V_A_offset (0.291772902)//(0.5020679235)
#define V_B_offset (0.2910662293)//(0.4977650046)
#define V_C_offset (0.2902891636)//(0.4986107945)


//! \brief CLOCKS & TIMERS
// **************************************************************************
//! \brief Defines the system clock frequency, MHz
#define USER_SYSTEM_FREQ_MHz (90.0)

//! \brief Defines the Pulse Width Modulation (PWM) frequency, kHz
//! \brief PWM frequency can be set directly here up to 30 KHz safely (60 KHz MAX in some cases)
//! \brief For higher PWM frequencies (60 KHz+ typical for low inductance, high current ripple motors) it is recommended to use the ePWM hardware
//! \brief and adjustable ADC SOC to decimate the ADC conversion done interrupt to the control system, or to use the software Que example.
//! \brief Otherwise you risk missing interrupts and disrupting the timing of the control state machine
#define USER_PWM_FREQ_kHz (20.0)// (45.0) //30.0 Example, 8.0 - 30.0 KHz typical; 45-80 KHz may be required for very low inductance, high speed motors

//! \brief Defines the maximum Voltage vector (Vs) magnitude allowed. This value sets the maximum magnitude for the output of the
//! \brief Id and Iq PI current controllers. The Id and Iq current controller outputs are Vd and Vq.
//! \brief The relationship between Vs, Vd, and Vq is: Vs = sqrt(Vd^2 + Vq^2). In this FOC controller, the
//! \brief Vd value is set equal to USER_MAX_VS_MAG*USER_VD_MAG_FACTOR. Vq = sqrt(USER_MAX_VS_MAG^2 - Vd^2).
//! \brief Set USER_MAX_VS_MAG = 1.0 for a pure sinewave with a peak at SQRT(3)/2 = 86.6% duty cycle. No current reconstruction is needed for this scenario.
//! \brief Set USER_MAX_VS_MAG = 2/SQRT(3) = 1.1547 for a pure sinewave with a peak at 100% duty cycle. Current reconstruction will be needed for this scenario (Lab10a-x).
//! \brief Set USER_MAX_VS_MAG = 4/3 = 1.3333 to create a trapezoidal voltage waveform. Current reconstruction will be needed for this scenario (Lab10a-x).
//! \brief For space vector over-modulation, see lab 10 for details on system requirements that will allow the SVM generator to go all the way to trapezoidal.
#define USER_MAX_VS_MAG_PU (1.0) // Set to 1.0 if a current reconstruction technique is not used. Look at the module svgen_current in lab10a-x for more info.


//! \brief Defines the Pulse Width Modulation (PWM) period, usec
//! \brief Compile time calculation
#define USER_PWM_PERIOD_usec (1000.0/USER_PWM_FREQ_kHz)

//! \brief Defines the Interrupt Service Routine (ISR) frequency, Hz
//!
#define USER_ISR_FREQ_Hz ((float_t)USER_PWM_FREQ_kHz * 1000.0 / (float_t)USER_NUM_PWM_TICKS_PER_ISR_TICK)

//! \brief Defines the Interrupt Service Routine (ISR) period, usec
//!
#define USER_ISR_PERIOD_usec (USER_PWM_PERIOD_usec * (float_t)USER_NUM_PWM_TICKS_PER_ISR_TICK)


//! \brief DECIMATION
// **************************************************************************
//! \brief Defines the number of pwm clock ticks per isr clock tick
//! Note: Valid values are 1, 2 or 3 only
#define USER_NUM_PWM_TICKS_PER_ISR_TICK 2//(3)

//! \brief Defines the number of isr ticks (hardware) per controller clock tick (software)
//! \brief Controller clock tick (CTRL) is the main clock used for all timing in the software
//! \brief Typically the PWM Frequency triggers (can be decimated by the ePWM hardware for less overhead) an ADC SOC
//! \brief ADC SOC triggers an ADC Conversion Done
//! \brief ADC Conversion Done triggers ISR
//! \brief This relates the hardware ISR rate to the software controller rate
//! \brief Typcially want to consider some form of decimation (ePWM hardware, CURRENT or EST) over 16KHz ISR to insure interrupt completes and leaves time for background tasks
#define USER_NUM_ISR_TICKS_PER_CTRL_TICK (1) // 2 Example, oontroller clock rate (CTRL) runs at PWM / 2; ex 30 KHz PWM, 15 KHz control

//! \brief Defines the number of controller clock ticks per current controller clock tick
//! \brief Relationship of controller clock rate to current controller (FOC) rate
#define USER_NUM_CTRL_TICKS_PER_CURRENT_TICK (1) // 1 Typical, Forward FOC current controller (Iq/Id/IPARK/SVPWM) runs at same rate as CTRL.

//! \brief Defines the number of controller clock ticks per estimator clock tick
//! \brief Relationship of controller clock rate to estimator (FAST) rate
//! \brief Depends on needed dynamic performance, FAST provides very good results as low as 1 KHz while more dynamic or high speed applicatons may require up to 15 KHz
#define USER_NUM_CTRL_TICKS_PER_EST_TICK (1) // 1 Typical, FAST estimator runs at same rate as CTRL;

//! \brief Defines the number of controller clock ticks per speed controller clock tick
//! \brief Relationship of controller clock rate to speed loop rate
#define USER_NUM_CTRL_TICKS_PER_SPEED_TICK (15) // 15 Typical to match PWM, ex: 15KHz PWM, controller, and current loop, 1KHz speed loop

//! \brief Defines the number of controller clock ticks per trajectory clock tick
//! \brief Relationship of controller clock rate to trajectory loop rate
//! \brief Typically the same as the speed rate
#define USER_NUM_CTRL_TICKS_PER_TRAJ_TICK (15) // 15 Typical to match PWM, ex: 10KHz controller & current loop, 1KHz speed loop, 1 KHz Trajectory

//! \brief Defines the controller frequency, Hz
//! \brief Compile time calculation
#define USER_CTRL_FREQ_Hz (uint_least32_t)(USER_ISR_FREQ_Hz/USER_NUM_ISR_TICKS_PER_CTRL_TICK)

//! \brief Defines the estimator frequency, Hz
//! \brief Compile time calculation
#define USER_EST_FREQ_Hz (uint_least32_t)(USER_CTRL_FREQ_Hz/USER_NUM_CTRL_TICKS_PER_EST_TICK)

//! \brief Defines the trajectory frequency, Hz
//! \brief Compile time calculation
#define USER_TRAJ_FREQ_Hz (uint_least32_t)(USER_CTRL_FREQ_Hz/USER_NUM_CTRL_TICKS_PER_TRAJ_TICK)

//! \brief Defines the controller execution period, usec
//! \brief Compile time calculation
#define USER_CTRL_PERIOD_usec (USER_ISR_PERIOD_usec * USER_NUM_ISR_TICKS_PER_CTRL_TICK)

//! \brief Defines the controller execution period, sec
//! \brief Compile time calculation
#define USER_CTRL_PERIOD_sec ((float_t)USER_CTRL_PERIOD_usec/(float_t)1000000.0)


//! \brief LIMITS
// **************************************************************************
//! \brief Defines the maximum negative current to be applied in Id reference
//! \brief Used in field weakening only, this is a safety setting (e.g. to protect against demagnetizaton)
//! \brief User must also be aware that overall current magnitude [sqrt(Id^2 + Iq^2)] should be kept below any machine design specifications
#define USER_MAX_NEGATIVE_ID_REF_CURRENT_A (-2.0) // -2.0 Example, adjust to meet safety needs of your motor

//! \brief Defines the low speed limit for the flux integrator, pu
//! \brief This is the speed range (CW/CCW) at which the ForceAngle object is active, but only if Enabled
//! \brief Outside of this speed - or if Disabled - the ForcAngle will NEVER be active and the angle is provided by FAST only
#define USER_ZEROSPEEDLIMIT (0.002) // 0.002 pu, 1-5 Hz typical; Hz = USER_ZEROSPEEDLIMIT * USER_IQ_FULL_SCALE_FREQ_Hz

//! \brief Defines the force angle frequency, Hz
//! \brief Frequency of stator vector rotation used by the ForceAngle object
//! \brief Can be positive or negative
#define USER_FORCE_ANGLE_FREQ_Hz (1.0) // 1.0 Typical force angle start-up speed

//! \brief Defines the maximum current slope for Id trajectory during EPL mode
//! \brief For Induction motors only, controls how fast Id input can change under EPL control
#define USER_MAX_CURRENT_SLOPE_EPL (0.3*USER_MOTOR_RES_EST_CURRENT/USER_IQ_FULL_SCALE_CURRENT_A/USER_TRAJ_FREQ_Hz) // 0.3*RES_EST_CURRENT / IQ_FULL_SCALE_CURRENT / TRAJ_FREQ Typical to produce 1-sec rampup/down

//! \brief Defines the starting maximum acceleration AND deceleration for the speed profiles, Hz/s
//! \brief Updated in run-time through user functions
//! \brief Inverter, motor, inertia, and load will limit actual acceleration capability
#define USER_MAX_ACCEL_Hzps (20.0) // 20.0 Default

//! \brief Defines maximum acceleration for the estimation speed profiles, rad/sec^2
//! \brief Only used during Motor ID (commission)
#define USER_MAX_ACCEL_EST_Hzps (5.0) // 5.0 Default, don't change

//! \brief Defines the maximum current slope for Id trajectory during estimation
#define USER_MAX_CURRENT_SLOPE (USER_MOTOR_RES_EST_CURRENT/USER_IQ_FULL_SCALE_CURRENT_A/USER_TRAJ_FREQ_Hz) // USER_MOTOR_RES_EST_CURRENT/USER_IQ_FULL_SCALE_CURRENT_A/USER_TRAJ_FREQ_Hz Default, don't change

//! \brief Defines the fraction of IdRated to use during rated flux estimation
//!
#define USER_IDRATED_FRACTION_FOR_RATED_FLUX (0.5) // 0.5 Default, don't change

//! \brief Defines the fraction of IdRated to use during inductance estimation
//!
#define USER_IDRATED_FRACTION_FOR_L_IDENT (0.5) // 0.5 Default, don't change

//! \brief Defines the IdRated delta to use during estimation
//!
#define USER_IDRATED_DELTA (0.0001) // 0.0001 Default, don't change

//! \brief Defines the fraction of SpeedMax to use during inductance estimation
//!
#define USER_SPEEDMAX_FRACTION_FOR_L_IDENT (1.0) // 1.0 Default, don't change

//! \brief Defines flux fraction to use during inductance identification
//!
#define USER_FLUX_FRACTION (1.0) // 1.0 Default, don't change

//! \brief Defines the EPL (Efficient Partial Load) gain for computing Id reference
//! \brief Induction motors only
#define USER_EPL_GAIN (1.0) // 1.0 Default, don't change

//! \brief Defines the R/L estimation frequency, Hz
//! \brief User higher values for low inductance motors and lower values for higher inductance
//! \brief motors. The values can range from 100 to 300 Hz.
#define USER_R_OVER_L_EST_FREQ_Hz (300) // 300 Default


//! \brief POLES
// **************************************************************************
//! \brief Defines the analog voltage filter pole location, Hz
//! \brief Must match the hardware filter for Vph
#define USER_VOLTAGE_FILTER_POLE_Hz (335.648) // 335.648, value for drv8301_revd hardware

//! \brief Defines the analog voltage filter pole location, rad/s
//! \brief Compile time calcuation from Hz to rad/s
#define USER_VOLTAGE_FILTER_POLE_rps (2.0 * MATH_PI * USER_VOLTAGE_FILTER_POLE_Hz)

//! \brief Defines the software pole location for the voltage and current offset estimation, rad/s
//! \brief Should not be changed from default of (20.0)
#define USER_OFFSET_POLE_rps (20.0) // 20.0 Default, do not change

//! \brief Defines the software pole location for the flux estimation, rad/s
//! \brief Should not be changed from default of (100.0)
#define USER_FLUX_POLE_rps (100.0) // 100.0 Default, do not change

//! \brief Defines the software pole location for the direction filter, rad/s
#define USER_DIRECTION_POLE_rps (6.0) // 6.0 Default, do not change

//! \brief Defines the software pole location for the speed control filter, rad/s
#define USER_SPEED_POLE_rps (100.0) // 100.0 Default, do not change

//! \brief Defines the software pole location for the DC bus filter, rad/s
#define USER_DCBUS_POLE_rps (100.0) // 100.0 Default, do not change

//! \brief Defines the convergence factor for the estimator
//! \brief Do not change from default for FAST
#define USER_EST_KAPPAQ (1.5) // 1.5 Default, do not change

// **************************************************************************
// end the defines


//! \brief USER MOTOR & ID SETTINGS
// **************************************************************************

//! \brief Define each motor with a unique name and ID number
// BLDC & SMPM motors
#define Estun_EMJ_04APB22 101
#define Anaheim_BLY172S 102
#define My_Motor 104
#define hobby_3p5T 105
#define hobby_4p5T 106
#define small_hobby 107
#define teknic_2310P 108
#define hobbywing_ezrun_8p5T 109
#define eflite_helicopter_420 110
#define Bodine_34B3FEBL 114
#define Pittman_elcom_5233B599 115
#define medical_instrument 117

// IPM motors
// If user provides separate Ls-d, Ls-q
// else treat as SPM with user or identified average Ls
#define Belt_Drive_Washer_IPM 201

// ACIM motors
#define Marathon_5K33GN2A 301

//! \brief Uncomment the motor which shold be included at compile
//! \brief These motor ID settings and motor parameters are then available to be used by the control system
//! \brief Once your ideal settings and parameters are identified update the motor section here so it is available in the binary code
//#define USER_MOTOR Estun_EMJ_04APB22
//#define USER_MOTOR Anaheim_BLY172S
//#define USER_MOTOR hobby_3p5T
//#define USER_MOTOR hobby_4p5T
#define USER_MOTOR My_Motor
//#define USER_MOTOR small_hobby
//#define USER_MOTOR Belt_Drive_Washer_IPM
//#define USER_MOTOR Marathon_5K33GN2A
//#define USER_MOTOR teknic_2310P
//#define USER_MOTOR hobbywing_ezrun_8p5T
//#define USER_MOTOR eflite_helicopter_420
//#define USER_MOTOR Bodine_34B3FEBL
//#define USER_MOTOR Pittman_elcom_5233B599
//#define USER_MOTOR medical_instrument


#if (USER_MOTOR == Estun_EMJ_04APB22) // Name must match the motor #define
#define USER_MOTOR_TYPE MOTOR_Type_Pm // Motor_Type_Pm (All Synchronous: BLDC, PMSM, SMPM, IPM) or Motor_Type_Induction (Asynchronous ACI)
#define USER_MOTOR_NUM_POLE_PAIRS (4) // PAIRS, not total poles. Used to calculate user RPM from rotor Hz only
#define USER_MOTOR_Rr (NULL) // Induction motors only, else NULL
#define USER_MOTOR_Rs (2.303403) // Identified phase to neutral resistance in a Y equivalent circuit (Ohms, float)
#define USER_MOTOR_Ls_d (0.008464367) // For PM, Identified average stator inductance (Henry, float)
#define USER_MOTOR_Ls_q (0.008464367) // For PM, Identified average stator inductance (Henry, float)
#define USER_MOTOR_RATED_FLUX (0.38) // Identified TOTAL flux linkage between the rotor and the stator (V/Hz)
#define USER_MOTOR_MAGNETIZING_CURRENT (NULL) // Induction motors only, else NULL
#define USER_MOTOR_RES_EST_CURRENT (1.0) // During Motor ID, maximum current (Amperes, float) used for Rs estimation, 10-20% rated current
#define USER_MOTOR_IND_EST_CURRENT (-1.0) // During Motor ID, maximum current (negative Amperes, float) used for Ls estimation, use just enough to enable rotation
#define USER_MOTOR_MAX_CURRENT (3.82) // CRITICAL: Used during ID and run-time, sets a limit on the maximum current command output of the provided Speed PI Controller to the Iq controller
#define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0) // During Motor ID, maximum commanded speed (Hz, float), ~10% rated

#elif (USER_MOTOR == My_Motor)
#define USER_MOTOR_TYPE MOTOR_Type_Pm
#define USER_MOTOR_NUM_POLE_PAIRS (2)
#define USER_MOTOR_Rr (NULL)
#define USER_MOTOR_Rs (0.0561226)//(0.1281301)//(0.1076983)
#define USER_MOTOR_Ls_d (0.0001031196)//(0.0002003067)//(0.000254845)
#define USER_MOTOR_Ls_q (0.0001031196)//(0.0002003067)//(0.000254845)
#define USER_MOTOR_RATED_FLUX (0.0490102)//(0.07455059)
#define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
#define USER_MOTOR_RES_EST_CURRENT (2)
#define USER_MOTOR_IND_EST_CURRENT (-2)
#define USER_MOTOR_MAX_CURRENT (15.0)
#define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0)


#else
#error No motor type specified
#endif

#ifndef USER_MOTOR
#error Motor is not defined in user.h
#endif

#ifndef USER_MOTOR_TYPE
#error The motor type is not defined in user.h
#endif

#ifndef USER_MOTOR_NUM_POLE_PAIRS
#error Number of motor pole pairs is not defined in user.h
#endif

#ifndef USER_MOTOR_Rr
#error The rotor resistance is not defined in user.h
#endif

#ifndef USER_MOTOR_Rs
#error The stator resistance is not defined in user.h
#endif

#ifndef USER_MOTOR_Ls_d
#error The direct stator inductance is not defined in user.h
#endif

#ifndef USER_MOTOR_Ls_q
#error The quadrature stator inductance is not defined in user.h
#endif

#ifndef USER_MOTOR_RATED_FLUX
#error The rated flux of motor is not defined in user.h
#endif

#ifndef USER_MOTOR_MAGNETIZING_CURRENT
#error The magnetizing current is not defined in user.h
#endif

#ifndef USER_MOTOR_RES_EST_CURRENT
#error The resistance estimation current is not defined in user.h
#endif

#ifndef USER_MOTOR_IND_EST_CURRENT
#error The inductance estimation current is not defined in user.h
#endif

#ifndef USER_MOTOR_MAX_CURRENT
#error The maximum current is not defined in user.h
#endif

#ifndef USER_MOTOR_FLUX_EST_FREQ_Hz
#error The flux estimation frequency is not defined in user.h
#endif


// **************************************************************************
// the functions


//! \brief Sets the user parameter values
//! \param[in] pUserParams The pointer to the user param structure
extern void USER_setParams(USER_Params *pUserParams);


#ifdef __cplusplus
}
#endif // extern "C"

//@} // ingroup
#endif // end of _USER_H_ definition

There must be a difference but i can't find it because we don't have the source parameter of the GUI application.

Thanks if someone can help me.

Regards.

Emmanuel

  • Manu,

    First try using lab10a where you can change the Modulation and are using the latest SVPWM.

     

  • to be clear on this topic, lab10a is where the current reconstruction algorithms are first applied (and necessary).

    The GUI uses Firmware that is over 1yr old, and as you see it's basically all the features lumped together (torque mode, modulation, field weakening, motion profiles, SpinTAC, etc).  It's too hard to keep up to date as we make incremental improvements, so the GUI firmware is "frozen".

    We have made several changes to the functions, especially the Modulation starting in release _09.  These are part of proj_lab10x, and if you want to use a higher modulation than 1 (and most will) you should probably start your own project based on proj_lab10x to take advantage.

    There is one remaining "hole" in this modulation update that we have recently solved, and it looks like you have found it.  At the exact spot in the waveform of the glitch is where the current sampling windows close for at least one of the currents.  That's usually fine and we can sample the other two phases.  But what happens is that the un-samplable phase causes cross-coupling switching noise into the other two phases.  The cross-coupled noise is exactly at the center of the sampling point for the other two. 

    We just finished an updated current regen algorithm that always stays away from non-sampled switching events.  Still, there are instances when only one current can be sampled.  For this case, we used a filtering scheme and now  have a smooth current sample all the way to 4/3 overmodulation.  This solved all the modulation problems we have seen and this solution is now running reliability / longevity testing in a real application.  We'll be adding this to MotorWare in one of the next releases, either _12 or _13.

     

  • Thanks for the answer,

    The problem is not present with the "old" GUI even if I use overmodulation (1.15max, there is a driver fault if i go over), and the example I use (lab3) doesn't use overmodulation. I have try lab 10 but i did'nt focus on this problem so I will try again today and I will let you know.

    Regards.

    Emmanuel

  • Manu,

    I noticed this in your user.h

    #define USER_NUM_PWM_TICKS_PER_ISR_TICK 2//(3)

    please change to

    #define USER_NUM_PWM_TICKS_PER_ISR_TICK (2)

    this is putting the main interrupt at 20 kHz / 2 = 10 kHz.  Just FYI you have your speed and trajectory at (15).  You may want to set these to (10).  It probably doesn't hurt to have them at (15), but doesn't help much either. 

     

    So, to summarize the original problem:

    With the GUI

    • everything runs fine at rated speed and 24V.
    • it keeps rated speed down to 18V and modulation of 1.0
    • at 17V modulation is increased to 1.15 to keep speed, and waveform has a normal distortion

    with lab3b

    • with modulation at 1.0 (only modulation possible in lab3b), as voltage is reduced below 20V you start to see a spurious current distortion

    is that correct?

    Try lab10 and let me know results

  • ChrisClearman said:

    So, to summarize the original problem:

    With the GUI

    • everything runs fine at rated speed and 24V.
    • it keeps rated speed down to 18V and modulation of 1.0
    • at 17V modulation is increased to 1.15 to keep speed, and waveform has a normal distortion

    with lab3b

    • with modulation at 1.0 (only modulation possible in lab3b), as voltage is reduced below 20V you start to see a spurious current distortion

    is that correct?

    Try lab10 and let me know results

    Yes you are right.

    ChrisClearman said:

    #define USER_NUM_PWM_TICKS_PER_ISR_TICK 2//(3)

    please change to

    #define USER_NUM_PWM_TICKS_PER_ISR_TICK (2)

    I don't understand the difference but I will try.

    I will also try lab10 but i'm not sure It will be done today.

    Many thanks.

    Emmanuel

  • Hi, I try lab10 as you advise me and I also made the others change. So with lab10 it is... different... The spurious current distorsion begin at a higher voltage (22.5V) but it seems lower than the distorsion I have with lab03. I also try to increase overmodulation to 1.15, so overmodulation works correctly (speed is correct at 17V) but it doesn't change the distorsion. Others change doesn't seems to impact the current distorsion. Regards. Emmanuel
  • Manu,

    You can try increasing your PWM frequency up to 45 kHz and current controller to 15 kHz and see if it helps at all.  I don't suspect it will, but it's worth trying.

    #define USER_PWM_FREQ_kHz                (45.0)

    #define USER_NUM_PWM_TICKS_PER_ISR_TICK        (3)

    #define USER_NUM_ISR_TICKS_PER_CTRL_TICK       (1)

    #define USER_NUM_CTRL_TICKS_PER_CURRENT_TICK   (1)  

    #define USER_NUM_CTRL_TICKS_PER_EST_TICK       (1) 

    #define USER_NUM_CTRL_TICKS_PER_SPEED_TICK  (15)  

    #define USER_NUM_CTRL_TICKS_PER_TRAJ_TICK   (15)

     

    I suspect it is more likely that you are running into two issues

    1. The hardware layout for current sampling isn't ideal. The traces are quite long from the OPA to the ADC pin, so it's picking up noise and there is some cross coupling of the switching going on.

    2. The "hole" I mention in my previous post, which requires a new algorithm

     

  • I will try your avdvice (not today) but I don't understand why it works better with the GUI? This morning i'have made some test of input voltage fluctuation, results were very goods. Regards. Emmanuel
  • Manu,

    To be honest I don't understand why you are getting better results with the GUI either.  There is no reason you should.  I believe you have all the scaling variables essentially identical between the GUI and your user.h, and your decimation with 20 kHz PWM is the same.

     

  • Hi Chris, Following your advices, I have increase PWM frequency to 45kHz. The result was worse. So I try to reduce it to 15kHz with the followings parameters : #define USER_PWM_FREQ_kHz (15.0) #define USER_NUM_PWM_TICKS_PER_ISR_TICK (2) #define USER_NUM_ISR_TICKS_PER_CTRL_TICK (1) #define USER_NUM_CTRL_TICKS_PER_CURRENT_TICK (1) #define USER_NUM_CTRL_TICKS_PER_EST_TICK (1) #define USER_NUM_CTRL_TICKS_PER_SPEED_TICK (10) The result at 15kHz is clearly better (but not the noise....), the current waveform is good, no spurious distorsion. After this I have try overmodulation on LAB10 and 15k PWM but as previously with lab10, at 22V there is some spurious distorsions. For the moment lab03 with 15kHz seems the best.... Regards. Emmanuel
  • Manu36,

    let's look at the decimation so you understand what you have done

    #define USER_PWM_FREQ_kHz (15.0) // set PWM rate to 15 kHz
    #define USER_NUM_PWM_TICKS_PER_ISR_TICK (2) // sets the HW ADC SOC to every 2nd event, giving the ADC Conversion done Intertupt an effective rate of 7.5 kHz


    #define USER_NUM_ISR_TICKS_PER_CTRL_TICK (1) // 7.5 kHz
    #define USER_NUM_CTRL_TICKS_PER_CURRENT_TICK (1) // 7.5 kHz
    #define USER_NUM_CTRL_TICKS_PER_EST_TICK (1)  // 7.5 kHz
    #define USER_NUM_CTRL_TICKS_PER_SPEED_TICK (10) // 7.5 kHz / 10 = 750 Hz

    This isn't "wrong" per se, I just want you aware of what you are doing.  You have a motor with a ~60A short circuit current (Flux / 2pi / Ls).  Typically the higher the Isc the faster you want to PWM to try to reduce the current ripple, and the faster you want to try to close the current loop, especially as you accel/decel and variably load the machine.  But 15 kHz isn't necessarily wrong for your motor and power stage.

    Personally, I would increase the 7.5 kHz  to 15 kHz, especially since you have a 90 MHz device and have the MIPS to spare

    #define USER_NUM_PWM_TICKS_PER_ISR_TICK (1)

    If you need to reduce some MIPS loading you can run the estimator slower

     #define USER_NUM_CTRL_TICKS_PER_EST_TICK (2)

    and I would always run the _SPEED and _TRAJECTORY at 1 kHz effective, so

    USER_NUM_CTRL_TICKS_PER_SPEED_TICK (X)

    X = USER_NUM_ISR_TICKS_PER_CTRL_TICK effective kHz / 1 kHz

     

  • Hi Chris,

    I understand, thanks for the advice, I will try.

    I have another question, I need to suppress short Ton pulse on PWM outputs (<100ns) because the driver I plan to use can have trouble with such small pulse. With some competitors products, this can be done in PWM module but I didn't find anything in the 2802x PWM. What is the simple way to do this?

    Regards.

    Emmanuel 

  • Manu,

    Unfortunately we do not have this feature in hardare of our PWM modules. You would have to use SW logic to adjust or saturate/clip the duty or deadband values before writing to the PWM register.  It is a good idea for something to add in HW.

     

  • Hi,

    Bad news on my current waveform:

    I have receive the F28027F controlCARD, to evaluate InstaSpin with the TMS320F28027F because it is the CPU I will use on my personnal board and i start to run programs....

    With this control board, I discover the same problem than previously with the F28069, I have current distorsion when my input voltage reach 20V.

    I have solve this distorsion with 28069 control card by reducing PWM frequency from 20k to 16kHz. But the problem was not present when I was using the GUI (see my firt posts).

    My user.h are the same, only the USER_SYSTEM_FREQ_MHz is different (60MHz vs 90MHz).

    I feel that there is a timing problem, perhaps with ADC wich will be too long when I reach modulation around 1(overmodation is not activated), and so the current reading will be wrong. I think about this because the first time i solve this by reducing PWM frequency and now with a slower CPU, I discover the same problem.

    What do think about this? Is there a way to accelerate ADC with F28027F? Do you think about something else?

    You will find bellow my user.h for information.

    Regards.

    Emmanuel

    #ifndef _USER_H_
    #define _USER_H_
    /* --COPYRIGHT--,BSD
    * Copyright (c) 2012, Texas Instruments Incorporated
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * * Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    *
    * * Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the distribution.
    *
    * * Neither the name of Texas Instruments Incorporated nor the names of
    * its contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    * --/COPYRIGHT--*/

    //! \file solutions/instaspin_foc/boards/drv8301kit_revD/f28x/f2806xF/src/user.h
    //! \brief Contains the public interface for user initialization data for the CTRL, DRV, and EST modules
    //!
    //! (C) Copyright 2012, Texas Instruments, Inc.


    // **************************************************************************
    // the includes

    // modules
    #include "types.h"
    #include "motor.h"
    #include "est.h"
    #include "est_states.h"
    #include "est_Flux_states.h"
    #include "est_Ls_states.h"
    #include "est_Rs_states.h"
    #include "ctrl_obj.h"


    // platforms
    #include "userParams.h"

    //!
    //!
    //! \defgroup USER USER
    //!
    //@{


    #ifdef __cplusplus
    extern "C" {
    #endif

    // **************************************************************************
    // the defines


    //! \brief CURRENTS AND VOLTAGES
    // **************************************************************************
    //! \brief Defines the full scale frequency for IQ variable, Hz
    //! \brief All frequencies are converted into (pu) based on the ratio to this value
    //! \brief this value MUST be larger than the maximum speed that you are expecting from the motor
    #define USER_IQ_FULL_SCALE_FREQ_Hz (200.0) // 800 Example with buffer for 8-pole 6 KRPM motor to be run to 10 KRPM with field weakening; Hz =(RPM * Poles) / 120

    //! \brief Defines full scale value for the IQ30 variable of Voltage inside the system
    //! \brief All voltages are converted into (pu) based on the ratio to this value
    //! \brief WARNING: this value MUST be larger than the maximum value of any voltage calculated inside the control system otherwise the value can saturate and roll-over, causing an inaccurate value
    //! \brief WARNING: this value is OFTEN greater than the maximum measured ADC value, especially with high Bemf motors operating at higher than rated speeds
    //! \brief WARNING: if you know the value of your Bemf constant, and you know you are operating at a multiple speed due to field weakening, be sure to set this value higher than the expected Bemf voltage
    //! \brief It is recommended to start with a value ~3x greater than the USER_ADC_FULL_SCALE_VOLTAGE_V and increase to 4-5x if scenarios where a Bemf calculation may exceed these limits
    //! \brief This value is also used to calculate the minimum flux value: USER_IQ_FULL_SCALE_VOLTAGE_V/USER_EST_FREQ_Hz/0.7
    #define USER_IQ_FULL_SCALE_VOLTAGE_V (42.0) // 42.0 Example for drv8301 typical usage and the Anaheim motor

    //! \brief Defines the maximum voltage at the input to the AD converter
    //! \brief The value that will be represtented by the maximum ADC input (3.3V) and conversion (0FFFh)
    //! \brief Hardware dependent, this should be based on the voltage sensing and scaling to the ADC input
    #define USER_ADC_FULL_SCALE_VOLTAGE_V (66.32) // 66.32 drv8301_revd voltage scaling

    //! \brief Defines the voltage scale factor for the system
    //! \brief Compile time calculation for scale factor (ratio) used throughout the system
    #define USER_VOLTAGE_SF ((float_t)((USER_ADC_FULL_SCALE_VOLTAGE_V)/(USER_IQ_FULL_SCALE_VOLTAGE_V)))

    //! \brief Defines the full scale current for the IQ variables, A
    //! \brief All currents are converted into (pu) based on the ratio to this value
    //! \brief WARNING: this value MUST be larger than the maximum current readings that you are expecting from the motor or the reading will roll over to 0, creating a control issue
    #define USER_IQ_FULL_SCALE_CURRENT_A (41.25) // 41.25 Example for drv8301_revd typical usage

    //! \brief Defines the maximum current at the AD converter
    //! \brief The value that will be represtented by the maximum ADC input (3.3V) and conversion (0FFFh)
    //! \brief Hardware dependent, this should be based on the current sensing and scaling to the ADC input
    #define USER_ADC_FULL_SCALE_CURRENT_A (82.5) // 82.5 drv8301_revd current scaling

    //! \brief Defines the current scale factor for the system
    //! \brief Compile time calculation for scale factor (ratio) used throughout the system
    #define USER_CURRENT_SF ((float_t)((USER_ADC_FULL_SCALE_CURRENT_A)/(USER_IQ_FULL_SCALE_CURRENT_A)))

    //! \brief Defines the number of current sensors used
    //! \brief Defined by the hardware capability present
    //! \brief May be (2) or (3)
    #define USER_NUM_CURRENT_SENSORS (3) // 3 Preferred setting for best performance across full speed range, allows for 100% duty cycle

    //! \brief Defines the number of voltage (phase) sensors
    //! \brief Must be (3)
    #define USER_NUM_VOLTAGE_SENSORS (3) // 3 Required

    //! \brief ADC current offsets for A, B, and C phases
    //! \brief One-time hardware dependent, though the calibration can be done at run-time as well
    //! \brief After initial board calibration these values should be updated for your specific hardware so they are available after compile in the binary to be loaded to the controller
    #define I_A_offset (0.991140902)//(0.9939797521)
    #define I_B_offset (0.9958643317)//(1.014363647)
    #define I_C_offset (1.009294033)//(1.005615234)

    //! \brief ADC voltage offsets for A, B, and C phases
    //! \brief One-time hardware dependent, though the calibration can be done at run-time as well
    //! \brief After initial board calibration these values should be updated for your specific hardware so they are available after compile in the binary to be loaded to the controller
    #define V_A_offset (0.291772902)//(0.5020679235)
    #define V_B_offset (0.2910662293)//(0.4977650046)
    #define V_C_offset (0.2902891636)//(0.4986107945)


    //! \brief CLOCKS & TIMERS
    // **************************************************************************
    //! \brief Defines the system clock frequency, MHz
    #define USER_SYSTEM_FREQ_MHz (60.0)

    //! \brief Defines the Pulse Width Modulation (PWM) frequency, kHz
    //! \brief PWM frequency can be set directly here up to 30 KHz safely (60 KHz MAX in some cases)
    //! \brief For higher PWM frequencies (60 KHz+ typical for low inductance, high current ripple motors) it is recommended to use the ePWM hardware
    //! \brief and adjustable ADC SOC to decimate the ADC conversion done interrupt to the control system, or to use the software Que example.
    //! \brief Otherwise you risk missing interrupts and disrupting the timing of the control state machine
    #define USER_PWM_FREQ_kHz (16.0)//(20.0)// (45.0) //30.0 Example, 8.0 - 30.0 KHz typical; 45-80 KHz may be required for very low inductance, high speed motors

    //! \brief Defines the maximum Voltage vector (Vs) magnitude allowed. This value sets the maximum magnitude for the output of the
    //! \brief Id and Iq PI current controllers. The Id and Iq current controller outputs are Vd and Vq.
    //! \brief The relationship between Vs, Vd, and Vq is: Vs = sqrt(Vd^2 + Vq^2). In this FOC controller, the
    //! \brief Vd value is set equal to USER_MAX_VS_MAG*USER_VD_MAG_FACTOR. Vq = sqrt(USER_MAX_VS_MAG^2 - Vd^2).
    //! \brief Set USER_MAX_VS_MAG = 1.0 for a pure sinewave with a peak at SQRT(3)/2 = 86.6% duty cycle. No current reconstruction is needed for this scenario.
    //! \brief Set USER_MAX_VS_MAG = 2/SQRT(3) = 1.1547 for a pure sinewave with a peak at 100% duty cycle. Current reconstruction will be needed for this scenario (Lab10a-x).
    //! \brief Set USER_MAX_VS_MAG = 4/3 = 1.3333 to create a trapezoidal voltage waveform. Current reconstruction will be needed for this scenario (Lab10a-x).
    //! \brief For space vector over-modulation, see lab 10 for details on system requirements that will allow the SVM generator to go all the way to trapezoidal.
    #define USER_MAX_VS_MAG_PU (1.0) // Set to 1.0 if a current reconstruction technique is not used. Look at the module svgen_current in lab10a-x for more info.


    //! \brief Defines the Pulse Width Modulation (PWM) period, usec
    //! \brief Compile time calculation
    #define USER_PWM_PERIOD_usec (1000.0/USER_PWM_FREQ_kHz)

    //! \brief Defines the Interrupt Service Routine (ISR) frequency, Hz
    //!
    #define USER_ISR_FREQ_Hz ((float_t)USER_PWM_FREQ_kHz * 1000.0 / (float_t)USER_NUM_PWM_TICKS_PER_ISR_TICK)

    //! \brief Defines the Interrupt Service Routine (ISR) period, usec
    //!
    #define USER_ISR_PERIOD_usec (USER_PWM_PERIOD_usec * (float_t)USER_NUM_PWM_TICKS_PER_ISR_TICK)


    //! \brief DECIMATION
    // **************************************************************************
    //! \brief Defines the number of pwm clock ticks per isr clock tick
    //! Note: Valid values are 1, 2 or 3 only
    #define USER_NUM_PWM_TICKS_PER_ISR_TICK (1)//(2) //(3)

    //! \brief Defines the number of isr ticks (hardware) per controller clock tick (software)
    //! \brief Controller clock tick (CTRL) is the main clock used for all timing in the software
    //! \brief Typically the PWM Frequency triggers (can be decimated by the ePWM hardware for less overhead) an ADC SOC
    //! \brief ADC SOC triggers an ADC Conversion Done
    //! \brief ADC Conversion Done triggers ISR
    //! \brief This relates the hardware ISR rate to the software controller rate
    //! \brief Typcially want to consider some form of decimation (ePWM hardware, CURRENT or EST) over 16KHz ISR to insure interrupt completes and leaves time for background tasks
    #define USER_NUM_ISR_TICKS_PER_CTRL_TICK (1) // 2 Example, oontroller clock rate (CTRL) runs at PWM / 2; ex 30 KHz PWM, 15 KHz control

    //! \brief Defines the number of controller clock ticks per current controller clock tick
    //! \brief Relationship of controller clock rate to current controller (FOC) rate
    #define USER_NUM_CTRL_TICKS_PER_CURRENT_TICK (1) // 1 Typical, Forward FOC current controller (Iq/Id/IPARK/SVPWM) runs at same rate as CTRL.

    //! \brief Defines the number of controller clock ticks per estimator clock tick
    //! \brief Relationship of controller clock rate to estimator (FAST) rate
    //! \brief Depends on needed dynamic performance, FAST provides very good results as low as 1 KHz while more dynamic or high speed applicatons may require up to 15 KHz
    #define USER_NUM_CTRL_TICKS_PER_EST_TICK (2)// (1) // 1 Typical, FAST estimator runs at same rate as CTRL;

    //! \brief Defines the number of controller clock ticks per speed controller clock tick
    //! \brief Relationship of controller clock rate to speed loop rate
    #define USER_NUM_CTRL_TICKS_PER_SPEED_TICK (15)//(10) // 15 Typical to match PWM, ex: 15KHz PWM, controller, and current loop, 1KHz speed loop

    //! \brief Defines the number of controller clock ticks per trajectory clock tick
    //! \brief Relationship of controller clock rate to trajectory loop rate
    //! \brief Typically the same as the speed rate
    #define USER_NUM_CTRL_TICKS_PER_TRAJ_TICK (15) // 15 Typical to match PWM, ex: 10KHz controller & current loop, 1KHz speed loop, 1 KHz Trajectory

    //! \brief Defines the controller frequency, Hz
    //! \brief Compile time calculation
    #define USER_CTRL_FREQ_Hz (uint_least32_t)(USER_ISR_FREQ_Hz/USER_NUM_ISR_TICKS_PER_CTRL_TICK)

    //! \brief Defines the estimator frequency, Hz
    //! \brief Compile time calculation
    #define USER_EST_FREQ_Hz (uint_least32_t)(USER_CTRL_FREQ_Hz/USER_NUM_CTRL_TICKS_PER_EST_TICK)

    //! \brief Defines the trajectory frequency, Hz
    //! \brief Compile time calculation
    #define USER_TRAJ_FREQ_Hz (uint_least32_t)(USER_CTRL_FREQ_Hz/USER_NUM_CTRL_TICKS_PER_TRAJ_TICK)

    //! \brief Defines the controller execution period, usec
    //! \brief Compile time calculation
    #define USER_CTRL_PERIOD_usec (USER_ISR_PERIOD_usec * USER_NUM_ISR_TICKS_PER_CTRL_TICK)

    //! \brief Defines the controller execution period, sec
    //! \brief Compile time calculation
    #define USER_CTRL_PERIOD_sec ((float_t)USER_CTRL_PERIOD_usec/(float_t)1000000.0)


    //! \brief LIMITS
    // **************************************************************************
    //! \brief Defines the maximum negative current to be applied in Id reference
    //! \brief Used in field weakening only, this is a safety setting (e.g. to protect against demagnetizaton)
    //! \brief User must also be aware that overall current magnitude [sqrt(Id^2 + Iq^2)] should be kept below any machine design specifications
    #define USER_MAX_NEGATIVE_ID_REF_CURRENT_A (-2.0) // -2.0 Example, adjust to meet safety needs of your motor

    //! \brief Defines the low speed limit for the flux integrator, pu
    //! \brief This is the speed range (CW/CCW) at which the ForceAngle object is active, but only if Enabled
    //! \brief Outside of this speed - or if Disabled - the ForcAngle will NEVER be active and the angle is provided by FAST only
    #define USER_ZEROSPEEDLIMIT (0.020)//(0.002) // 0.002 pu, 1-5 Hz typical; Hz = USER_ZEROSPEEDLIMIT * USER_IQ_FULL_SCALE_FREQ_Hz

    //! \brief Defines the force angle frequency, Hz
    //! \brief Frequency of stator vector rotation used by the ForceAngle object
    //! \brief Can be positive or negative
    #define USER_FORCE_ANGLE_FREQ_Hz (1.0) // 1.0 Typical force angle start-up speed

    //! \brief Defines the maximum current slope for Id trajectory during EPL mode
    //! \brief For Induction motors only, controls how fast Id input can change under EPL control
    #define USER_MAX_CURRENT_SLOPE_EPL (0.3*USER_MOTOR_RES_EST_CURRENT/USER_IQ_FULL_SCALE_CURRENT_A/USER_TRAJ_FREQ_Hz) // 0.3*RES_EST_CURRENT / IQ_FULL_SCALE_CURRENT / TRAJ_FREQ Typical to produce 1-sec rampup/down

    //! \brief Defines the starting maximum acceleration AND deceleration for the speed profiles, Hz/s
    //! \brief Updated in run-time through user functions
    //! \brief Inverter, motor, inertia, and load will limit actual acceleration capability
    #define USER_MAX_ACCEL_Hzps (20.0) // 20.0 Default

    //! \brief Defines maximum acceleration for the estimation speed profiles, rad/sec^2
    //! \brief Only used during Motor ID (commission)
    #define USER_MAX_ACCEL_EST_Hzps (5.0) // 5.0 Default, don't change

    //! \brief Defines the maximum current slope for Id trajectory during estimation
    #define USER_MAX_CURRENT_SLOPE (USER_MOTOR_RES_EST_CURRENT/USER_IQ_FULL_SCALE_CURRENT_A/USER_TRAJ_FREQ_Hz) // USER_MOTOR_RES_EST_CURRENT/USER_IQ_FULL_SCALE_CURRENT_A/USER_TRAJ_FREQ_Hz Default, don't change

    //! \brief Defines the fraction of IdRated to use during rated flux estimation
    //!
    #define USER_IDRATED_FRACTION_FOR_RATED_FLUX (0.5) // 0.5 Default, don't change

    //! \brief Defines the fraction of IdRated to use during inductance estimation
    //!
    #define USER_IDRATED_FRACTION_FOR_L_IDENT (0.5) // 0.5 Default, don't change

    //! \brief Defines the IdRated delta to use during estimation
    //!
    #define USER_IDRATED_DELTA (0.0001) // 0.0001 Default, don't change

    //! \brief Defines the fraction of SpeedMax to use during inductance estimation
    //!
    #define USER_SPEEDMAX_FRACTION_FOR_L_IDENT (1.0) // 1.0 Default, don't change

    //! \brief Defines flux fraction to use during inductance identification
    //!
    #define USER_FLUX_FRACTION (1.0) // 1.0 Default, don't change

    //! \brief Defines the EPL (Efficient Partial Load) gain for computing Id reference
    //! \brief Induction motors only
    #define USER_EPL_GAIN (1.0) // 1.0 Default, don't change

    //! \brief Defines the R/L estimation frequency, Hz
    //! \brief User higher values for low inductance motors and lower values for higher inductance
    //! \brief motors. The values can range from 100 to 300 Hz.
    #define USER_R_OVER_L_EST_FREQ_Hz (300) // 300 Default


    //! \brief POLES
    // **************************************************************************
    //! \brief Defines the analog voltage filter pole location, Hz
    //! \brief Must match the hardware filter for Vph
    #define USER_VOLTAGE_FILTER_POLE_Hz (335.648) // 335.648, value for drv8301_revd hardware

    //! \brief Defines the analog voltage filter pole location, rad/s
    //! \brief Compile time calcuation from Hz to rad/s
    #define USER_VOLTAGE_FILTER_POLE_rps (2.0 * MATH_PI * USER_VOLTAGE_FILTER_POLE_Hz)

    //! \brief Defines the software pole location for the voltage and current offset estimation, rad/s
    //! \brief Should not be changed from default of (20.0)
    #define USER_OFFSET_POLE_rps (20.0) // 20.0 Default, do not change

    //! \brief Defines the software pole location for the flux estimation, rad/s
    //! \brief Should not be changed from default of (100.0)
    #define USER_FLUX_POLE_rps (100.0) // 100.0 Default, do not change

    //! \brief Defines the software pole location for the direction filter, rad/s
    #define USER_DIRECTION_POLE_rps (6.0) // 6.0 Default, do not change

    //! \brief Defines the software pole location for the speed control filter, rad/s
    #define USER_SPEED_POLE_rps (100.0) // 100.0 Default, do not change

    //! \brief Defines the software pole location for the DC bus filter, rad/s
    #define USER_DCBUS_POLE_rps (100.0) // 100.0 Default, do not change

    //! \brief Defines the convergence factor for the estimator
    //! \brief Do not change from default for FAST
    #define USER_EST_KAPPAQ (1.5) // 1.5 Default, do not change

    // **************************************************************************
    // end the defines


    //! \brief USER MOTOR & ID SETTINGS
    // **************************************************************************

    //! \brief Define each motor with a unique name and ID number
    // BLDC & SMPM motors
    #define Estun_EMJ_04APB22 101
    #define Anaheim_BLY172S 102
    #define My_Motor 104
    #define hobby_3p5T 105
    #define hobby_4p5T 106
    #define small_hobby 107
    #define teknic_2310P 108
    #define hobbywing_ezrun_8p5T 109
    #define eflite_helicopter_420 110
    #define Bodine_34B3FEBL 114
    #define Pittman_elcom_5233B599 115
    #define medical_instrument 117

    // IPM motors
    // If user provides separate Ls-d, Ls-q
    // else treat as SPM with user or identified average Ls
    #define Belt_Drive_Washer_IPM 201

    // ACIM motors
    #define Marathon_5K33GN2A 301

    //! \brief Uncomment the motor which shold be included at compile
    //! \brief These motor ID settings and motor parameters are then available to be used by the control system
    //! \brief Once your ideal settings and parameters are identified update the motor section here so it is available in the binary code
    //#define USER_MOTOR Estun_EMJ_04APB22
    //#define USER_MOTOR Anaheim_BLY172S
    //#define USER_MOTOR hobby_3p5T
    //#define USER_MOTOR hobby_4p5T
    #define USER_MOTOR My_Motor
    //#define USER_MOTOR small_hobby
    //#define USER_MOTOR Belt_Drive_Washer_IPM
    //#define USER_MOTOR Marathon_5K33GN2A
    //#define USER_MOTOR teknic_2310P
    //#define USER_MOTOR hobbywing_ezrun_8p5T
    //#define USER_MOTOR eflite_helicopter_420
    //#define USER_MOTOR Bodine_34B3FEBL
    //#define USER_MOTOR Pittman_elcom_5233B599
    //#define USER_MOTOR medical_instrument


    #if (USER_MOTOR == Estun_EMJ_04APB22) // Name must match the motor #define
    #define USER_MOTOR_TYPE MOTOR_Type_Pm // Motor_Type_Pm (All Synchronous: BLDC, PMSM, SMPM, IPM) or Motor_Type_Induction (Asynchronous ACI)
    #define USER_MOTOR_NUM_POLE_PAIRS (4) // PAIRS, not total poles. Used to calculate user RPM from rotor Hz only
    #define USER_MOTOR_Rr (NULL) // Induction motors only, else NULL
    #define USER_MOTOR_Rs (2.303403) // Identified phase to neutral resistance in a Y equivalent circuit (Ohms, float)
    #define USER_MOTOR_Ls_d (0.008464367) // For PM, Identified average stator inductance (Henry, float)
    #define USER_MOTOR_Ls_q (0.008464367) // For PM, Identified average stator inductance (Henry, float)
    #define USER_MOTOR_RATED_FLUX (0.38) // Identified TOTAL flux linkage between the rotor and the stator (V/Hz)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL) // Induction motors only, else NULL
    #define USER_MOTOR_RES_EST_CURRENT (1.0) // During Motor ID, maximum current (Amperes, float) used for Rs estimation, 10-20% rated current
    #define USER_MOTOR_IND_EST_CURRENT (-1.0) // During Motor ID, maximum current (negative Amperes, float) used for Ls estimation, use just enough to enable rotation
    #define USER_MOTOR_MAX_CURRENT (3.82) // CRITICAL: Used during ID and run-time, sets a limit on the maximum current command output of the provided Speed PI Controller to the Iq controller
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0) // During Motor ID, maximum commanded speed (Hz, float), ~10% rated

    #elif (USER_MOTOR == Anaheim_BLY172S)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (4)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.3968007)
    #define USER_MOTOR_Ls_d (0.0006708066)
    #define USER_MOTOR_Ls_q (0.0006708066)
    #define USER_MOTOR_RATED_FLUX (0.03433958)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (1.0)
    #define USER_MOTOR_IND_EST_CURRENT (-1.0)
    #define USER_MOTOR_MAX_CURRENT (5.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0)

    #elif (USER_MOTOR == small_hobby)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (6)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (1.277921)
    #define USER_MOTOR_Ls_d (0.0001230481)
    #define USER_MOTOR_Ls_q (0.0001230481)
    #define USER_MOTOR_RATED_FLUX (0.004417491)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (0.5)
    #define USER_MOTOR_IND_EST_CURRENT (-0.5)
    #define USER_MOTOR_MAX_CURRENT (5.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (200.0)

    #elif (USER_MOTOR == teknic_2310P)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (4)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.3654691)
    #define USER_MOTOR_Ls_d (0.0002068772)
    #define USER_MOTOR_Ls_q (0.0002068772)
    #define USER_MOTOR_RATED_FLUX (0.04052209)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (1.0)
    #define USER_MOTOR_IND_EST_CURRENT (-1.0)
    #define USER_MOTOR_MAX_CURRENT (5.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0)

    #elif (USER_MOTOR == hobby_3p5T)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (4)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.0149275)
    #define USER_MOTOR_Ls_d (2.575126e-06)
    #define USER_MOTOR_Ls_q (2.575126e-06)
    #define USER_MOTOR_RATED_FLUX (0.003589415)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (15.0)
    #define USER_MOTOR_IND_EST_CURRENT (-5.0)
    #define USER_MOTOR_MAX_CURRENT (30.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (60.0)

    #elif (USER_MOTOR == hobby_4p5T)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (4)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.01420126)
    #define USER_MOTOR_Ls_d (6.466606e-06)
    #define USER_MOTOR_Ls_q (6.466606e-06)
    #define USER_MOTOR_RATED_FLUX (0.004845501)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (5.0)
    #define USER_MOTOR_IND_EST_CURRENT (-5.0)
    #define USER_MOTOR_MAX_CURRENT (10.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (60.0)

    #elif (USER_MOTOR == hobbywing_ezrun_8p5T)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (1)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.01366183)
    #define USER_MOTOR_Ls_d (1.556967e-05)
    #define USER_MOTOR_Ls_q (1.556967e-05)
    #define USER_MOTOR_RATED_FLUX (0.009272549)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (3.0)
    #define USER_MOTOR_IND_EST_CURRENT (-2.0)
    #define USER_MOTOR_MAX_CURRENT (10.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (60.0)

    #elif (USER_MOTOR == eflite_helicopter_420)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (3)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.01953091)
    #define USER_MOTOR_Ls_d (2.998549e-06)
    #define USER_MOTOR_Ls_q (2.998549e-06)
    #define USER_MOTOR_RATED_FLUX (0.003449948)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (3.0)
    #define USER_MOTOR_IND_EST_CURRENT (-3.0)
    #define USER_MOTOR_MAX_CURRENT (15.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (80.0)

    #elif (USER_MOTOR == Bodine_34B3FEBL)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (2)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.1749963)
    #define USER_MOTOR_Ls_d (0.000843199)
    #define USER_MOTOR_Ls_q (0.000843199)
    #define USER_MOTOR_RATED_FLUX (0.1139098)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (1.0)
    #define USER_MOTOR_IND_EST_CURRENT (-1.0)
    #define USER_MOTOR_MAX_CURRENT (10.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0)

    #elif (USER_MOTOR == Pittman_elcom_5233B599)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (2)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.3675933)
    #define USER_MOTOR_Ls_d (0.0001611779)
    #define USER_MOTOR_Ls_q (0.0001611779)
    #define USER_MOTOR_RATED_FLUX (0.1274101)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (0.5)
    #define USER_MOTOR_IND_EST_CURRENT (-0.5)
    #define USER_MOTOR_MAX_CURRENT (5.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0)

    #elif (USER_MOTOR == medical_instrument)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (2)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.3858043)
    #define USER_MOTOR_Ls_d (9.675411e-06)
    #define USER_MOTOR_Ls_q (9.675411e-06)
    #define USER_MOTOR_RATED_FLUX (0.006834516)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (0.5)
    #define USER_MOTOR_IND_EST_CURRENT (-0.5)
    #define USER_MOTOR_MAX_CURRENT (10.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (100.0)

    #elif (USER_MOTOR == My_Motor)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (2)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (0.0572026)//(0.1281301)//(0.1076983)
    #define USER_MOTOR_Ls_d (0.0001222555)//(0.0002003067)//(0.000254845)
    #define USER_MOTOR_Ls_q (0.0001222555)//(0.0002003067)//(0.000254845)
    #define USER_MOTOR_RATED_FLUX (0.0485342)//(0.07455059)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (2)
    #define USER_MOTOR_IND_EST_CURRENT (-2)
    #define USER_MOTOR_MAX_CURRENT (20.0) //courant instantané max dans le bob
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0)

    #elif (USER_MOTOR == Belt_Drive_Washer_IPM)
    #define USER_MOTOR_TYPE MOTOR_Type_Pm
    #define USER_MOTOR_NUM_POLE_PAIRS (4)
    #define USER_MOTOR_Rr (NULL)
    #define USER_MOTOR_Rs (2.832002)
    #define USER_MOTOR_Ls_d (0.0115)
    #define USER_MOTOR_Ls_q (0.0135)
    #define USER_MOTOR_RATED_FLUX (0.5022156)
    #define USER_MOTOR_MAGNETIZING_CURRENT (NULL)
    #define USER_MOTOR_RES_EST_CURRENT (1.0)
    #define USER_MOTOR_IND_EST_CURRENT (-1.0)
    #define USER_MOTOR_MAX_CURRENT (4.0)
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (20.0)

    #elif (USER_MOTOR == Marathon_5K33GN2A) // Name must match the motor #define
    #define USER_MOTOR_TYPE MOTOR_Type_Induction // Motor_Type_Pm (All Synchronous: BLDC, PMSM, SMPM, IPM) or Motor_Type_Induction (Asynchronous ACI)
    #define USER_MOTOR_NUM_POLE_PAIRS (2) // PAIRS, not total poles. Used to calculate user RPM from rotor Hz only
    #define USER_MOTOR_Rr (5.508003) // Identified phase to neutral in a Y equivalent circuit (Ohms, float)
    #define USER_MOTOR_Rs (10.71121) // Identified phase to neutral in a Y equivalent circuit (Ohms, float)
    #define USER_MOTOR_Ls_d (0.05296588) // For Induction, Identified average stator inductance (Henry, float)
    #define USER_MOTOR_Ls_q (0.05296588) // For Induction, Identified average stator inductance (Henry, float)
    #define USER_MOTOR_RATED_FLUX (0.8165*220.0/60.0) // sqrt(2/3)* Rated V (line-line) / Rated Freq (Hz)
    #define USER_MOTOR_MAGNETIZING_CURRENT (1.378) // Identified magnetizing current for induction motors, else NULL
    #define USER_MOTOR_RES_EST_CURRENT (0.5) // During Motor ID, maximum current (Amperes, float) used for Rs estimation, 10-20% rated current
    #define USER_MOTOR_IND_EST_CURRENT (NULL) // not used for induction
    #define USER_MOTOR_MAX_CURRENT (2.0) // CRITICAL: Used during ID and run-time, sets a limit on the maximum current command output of the provided Speed PI Controller to the Iq controller
    #define USER_MOTOR_FLUX_EST_FREQ_Hz (5.0) // During Motor ID, maximum commanded speed (Hz, float). Should always use 5 Hz for Induction.


    #else
    #error No motor type specified
    #endif

    #ifndef USER_MOTOR
    #error Motor is not defined in user.h
    #endif

    #ifndef USER_MOTOR_TYPE
    #error The motor type is not defined in user.h
    #endif

    #ifndef USER_MOTOR_NUM_POLE_PAIRS
    #error Number of motor pole pairs is not defined in user.h
    #endif

    #ifndef USER_MOTOR_Rr
    #error The rotor resistance is not defined in user.h
    #endif

    #ifndef USER_MOTOR_Rs
    #error The stator resistance is not defined in user.h
    #endif

    #ifndef USER_MOTOR_Ls_d
    #error The direct stator inductance is not defined in user.h
    #endif

    #ifndef USER_MOTOR_Ls_q
    #error The quadrature stator inductance is not defined in user.h
    #endif

    #ifndef USER_MOTOR_RATED_FLUX
    #error The rated flux of motor is not defined in user.h
    #endif

    #ifndef USER_MOTOR_MAGNETIZING_CURRENT
    #error The magnetizing current is not defined in user.h
    #endif

    #ifndef USER_MOTOR_RES_EST_CURRENT
    #error The resistance estimation current is not defined in user.h
    #endif

    #ifndef USER_MOTOR_IND_EST_CURRENT
    #error The inductance estimation current is not defined in user.h
    #endif

    #ifndef USER_MOTOR_MAX_CURRENT
    #error The maximum current is not defined in user.h
    #endif

    #ifndef USER_MOTOR_FLUX_EST_FREQ_Hz
    #error The flux estimation frequency is not defined in user.h
    #endif


    // **************************************************************************
    // the functions


    //! \brief Sets the user parameter values
    //! \param[in] pUserParams The pointer to the user param structure
    extern void USER_setParams(USER_Params *pUserParams);


    #ifdef __cplusplus
    }
    #endif // extern "C"

    //@} // ingroup
    #endif // end of _USER_H_ definition

  • Manu,

    I'm kind of stumped.  Considering the original GUI works so much better I'm looking for things we added since original release. Our overmodulation and ADC triggering is the one that stands out.  I've asked an expert to investigate some more.

    You can confirm that you get the desired waveforms and everything is just as you would like and expect with F28069M + InstaSPIN-FOC or -MOTION GUI?

     

  • Manu,

    With the drv8301 + F28027F controlCARD you need to conect a jumper to connect a GPIO to the ENABLE signal of the DRV8301 per page 8 of

    C:\ti\motorware\motorware_1_01_00_11\docs\boards\drive\drv8301kit_revD\docs\qsg_hw_drv8301_revd.pdf

    However, it looks like in software we moved this from GPIO28 to GPIO29

    C:\ti\motorware\motorware_1_01_00_11\sw\drivers\drv\boards\drv8301kit_revD\f28x\f2802x\src\drv.c

    but we never updated the document.

    So please Connect pin 2 of J12 (GPIO-29) to pin 6 of J5 (EN_GATE).

  • Hi,

    First of all, I use motorware 10 because I start my test with this version and If I want to switch to 11 version, I need to do again a lot of qualification tests.

    I connect pin 1 of J12 to pin 6 of (J5) (without this connection, the motor doesn't run).

    Regarding software GPIO 28 is used:

    static inline void DRV_disablePwm(DRV_Handle handle)
    {
    DRV_Obj *obj = (DRV_Obj *)handle;

    // dis-able the drv8301
    GPIO_setLow(obj->gpioHandle,GPIO_Number_28);

    PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_1]);
    PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_2]);
    PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_3]);

    return;
    } // end of DRV_disablePwm() function

    static inline void DRV_enablePwm(DRV_Handle handle)
    {
    DRV_Obj *obj = (DRV_Obj *)handle;

    // Enable the drv8301
    GPIO_setHigh(obj->gpioHandle,GPIO_Number_28);

    PWM_clearOneShotTrip(obj->pwmHandle[PWM_Number_1]);
    PWM_clearOneShotTrip(obj->pwmHandle[PWM_Number_2]);
    PWM_clearOneShotTrip(obj->pwmHandle[PWM_Number_3]);

    return;
    } // end of DRV_enablePwm() function

    About your question :

    "You can confirm that you get the desired waveforms and everything is just as you would like and expect with F28069M + InstaSPIN-FOC or -MOTION GUI?"

    I can confirm that all is OK with GUI "pre-compiled" program and F28069 and 20kHz PWM. With lab 03b and F28069, I need to reduce PWM to 16kHz and with lab03b and F28027even at 16kHz, I have current distorsion.

    When the voltage is about 22V (no current distorsion) the speed I can read in debug session fluctuate between 4731 and 4749 RPM, when I reduce the voltage, distorsion appears and the speed fluctuation increase (from 4830 to 4700), those speed are close enough to the one I can read with speed sensor.

    Thank you very much for your support.

    Emmanuel

  • Apparently there was a contention with GPIO28, that's why we moved it to GPIO29 (though I can't find the contention in the code at all, it may be outside of the MCU's domain??).

    I recommend trying version _11 with GPIO29 to see if the performance improves. It should only take a few minutes, so worth a shot.

     

  • One other thought...

    when you are changing the bus voltage, are you doing this dynamically?  While the motor is already running?

    The Offset Calibration is done with a static bus voltage. You should re-run the OffsetCalc at the new Vbus.

    Do you have Bus Compensation turned on or off?

     

  • Here is the reason we moved from GPIO28 to 29.  This reall shouldn't affect what you are doing in _10.

    The issue is with the controlCARD design.

    GPIO-28 is connected to an output of the IS7221 chip. This chip isn't populated - that’s why it hasn’t caused any issues yet -  but it is safer to connect it to GPIO-29 so there is no contention in the future, etc.  Just a good practice.

     

     

  • Hi,

    OK I will try version _11.

    The change on bus voltage is done dynamically but slowly. With the 28069, I have done voltage step test (from 18 to 33V by switching 2 power supply, this is a part of the specification) and results where very very good. I don't remember if the test was made with the GUI or with lab03 @ 16kHz.

    Regarding GPIO-28/GPIO29,on the board I have,  the chip ISO7221 (U3) IS POPULATED, as R10 !!!!!

    I don't think this is the cause of the distorsion but it is not good.

    Bus compensation is ON:

    // enable DC bus compensation
    CTRL_setFlag_enableDcBusComp(ctrlHandle, true);

    I also will try to disable it.

    Regards.

    Emmanuel

     

  • Result of the test :

    First test with version 10 and R10 removed => distortion at low voltage

    Second test :

    DC bus compensation disabled : => distortion at low voltage

    3rd test :

    DC bus compensation enabled and speed at 50% and then at 75% of nominal speed : =>No distortion at low voltage, so it isn’t directly linked to low voltage.

    4th test :

     version 11 (lab03b with my user.h), so I strapp GPIO29 to EN_GATE according to the software modification between version 10 and version 11 => distortion at low voltage

    5th test :

    same condition than 4 but instead of starting at 24V and then reducing the input voltage, I start directly at a low voltage (19V), so at low speed no distortions, distortions appears only when I reach the nominal speed (so when modulation is near 1)

     I always think it is linked to bad current sample near 100% or 0% duty cycle but I'me very surprised if I'me the first to face this problem, I can't see why my specific motor could impact on this!

    Could it be linked to the current or voltage scaling (during my test the peak current reach 10Amps but i'm not exactly at full load )?

    For my project the price difference between the 2 CPU is not acceptable,  we need to use the 28027.

    Regards.

    Emmanuel

  • I have also try to disable the bus compensation with motorware 11 but the result is the same that the result with motorware 10.

    Regards.

    Emmanuel

  • It doesn't make sense to me that you are seeing this only with the F28027F and NOT the F28069M controlCARD.

    Can you post 69M good waveforms doing the same test that show bad waveforms with 27F?

    For your tests where you start with a lower voltage and can recreate the bad waveforms with 27F, are you loading the offsets from user.h or enabling the OffsetRecalc?  I'd like you to try OffsetRecalc if you are not.

    The things that would most come to mind would be the offset calibration as you are varying bus or general current sense noise from the inverter layout (and we know DRV8301 EVM isn't ideal), but both of those would effect both controlCARDs.

    That makes me suspect something different with the ADC inputs to the controlCARD....

  • When I found the problem with the 28027, i go back to 28069 to see if i was'nt dreaming and I capture the waveform and store it :

    For this :

    "For your tests where you start with a lower voltage and can recreate the bad waveforms with 27F, are you loading the offsets from user.h or enabling the OffsetRecalc?  I'd like you to try OffsetRecalc if you are not."

    I have try both, and also when i was reducing the voltage, but there was no change.

    About the offset calibration, don't forget that with 28069F at the beginning with the GUI there was no problems but with the labs I have to reduce PWM frequency to 16kHz to eliminate distortion.

    Perhaps the problem with 28027 is not the same, could it be a CPU usage problem?

    The cpu usage percentage i can read with 28027 are :

    gCpuUsagePercentageAvg : 41%

    gCpuUsagePercentageMax : 75%

    Regards.

    Emmanuel

  • Manu,

    Just so I understand: with the reduced voltage, the current waveform looks good until you get near a certain speed and Vs / modulation range, correct?  It is only when you go a bit higher that you start seeing the issue?

    Do this test:
    Run your motor just to the problem speed.  Then add some field weakening (add negative Id_A)

    See proj_lab09 for how to do this, you just need to add this line

    CTRL_setId_ref_pu(ctrlHandle, _IQmpy(gMotorVars.IdRef_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)));

    before

      // setup the controller

    at the end of your mainISR.

     

    does that improve the waveform?

     

    We have seen something like this before and have an update for the over modulation code (probably not ready for _12, so it wil be May for _13).

     

  • Hi, I'have been some days without working on this project.

    "Just so I understand: with the reduced voltage, the current waveform looks good until you get near a certain speed and Vs / modulation range, correct?  It is only when you go a bit higher that you start seeing the issue?"

    => yes you are right

    "Run your motor just to the problem speed.  Then add some field weakening (add negative Id_A)"

    I have done test with motorware 10:

    In the firt test I have done, I add a positive Id, so it was worse (the distorsion start at a higher voltage).

    Readind your post, then I correct it to a negative id and the result is better (in fact the voltage at which the distorsion begins is lower, about 1V). I don't know how many negative Id I could add. I made test untill -3A. Can you advice me a maximum value?

    If I undertand correctly, by adding field weakening, for the same speed and the same input voltage, the modulation is lower, that's why the problem is always present when I reduce the voltage. In fact this does'nt solve the problem but only hide it, isn'it? The efficiency will also be lower with field weakening?

    I want to remember you that I have 1us dead time (rising and falling) :

    //! \brief Defines the PWM deadband falling edge delay count (system clocks)
    //!
    #define DRV_PWM_DBFED_CNT 60 //60 =1us


    //! \brief Defines the PWM deadband rising edge delay count (system clocks)
    //!
    #define DRV_PWM_DBRED_CNT 60 //

    I will try to modify this to see it impacts.

    Reagards.

    Emmanuel

     

     

  • I have made some tests with and without deadtime.

    For the same input voltage it seems that with 1us deadtime, I can reach a higher speed without having distorsion. The difference is a little more than 100RPM for a speed around 4000 RPM.

    I was waiting for a opposite result because I was thinking that the deadtime needs higher voltage modulation to correct the dead time...

    Anyways, with or without dead time, the distorsion is existing.

    Regards.

    Emmanuel 

  • " I don't know how many negative Id I could add. I made test untill -3A. Can you advice me a maximum value?"

    When doing field weakening you must self-insure that sqrt (Iq ^2 + Id ^2) = Is <= maximum allowed current for your motor.  This means that as you field weaken with high load you MUST insure your Iq command (usually from your speed controller) saturates to a lower value to keep Is at the limit.

    "In fact this does'nt solve the problem but only hide it, isn'it? The efficiency will also be lower with field weakening?"

    Yes. I wasn't suggesting this was a solution for you. I suggested the test to verify that your problem was with modulation.  I think our next update in May will help/solve, but I don't have anything sooner for you.

    "For the same input voltage it seems that with 1us deadtime, I can reach a higher speed without having distorsion. The difference is a little more than 100RPM for a speed around 4000 RPM."

    Hmmm. I would want to see the test done on this with proj_lab5a (torque control only w/o the speed loop) before I made any judgements. I agree it's anti-intuitive if true...

     

  • ChrisClearman said:
    I think our next update in May will help/solve, but I don't have anything sooner for you.

    This answer is quite ambiguous... If you think the last update will help/solve, it make me think that you know a part of the problem (perhaps i'm wrong).

    I was thinking it was linked to ADC delay, do you think I'm wrong? If not could we increase ADC on lab example?

    I'm very disappointed because the result of all the test we have done were exceeding our expectancy.

    I will propose to switch to 28069 but the cost will be a problem...

  • Manu,

    If this is the same issue that we have seen in a compressor application in over-modulation (and it seems like it) the problem is with current sampling.  You can confirm that when this occurs you are always close to Vs = 1.0 ?

    As mentioned, we have solved this in one case, but it takes some time to test and get this code into MotorWare and ready for public, broad release.

     

     

     

  • ChrisClearman said:
    You can confirm that when this occurs you are always close to Vs = 1.0 ?

    Yes I did'nt read the Vs value but regarding the speed and input voltage, we are close to 1.

    Emmanuel

  • Hi Chris,

    Regarding the problem I'm facing, one way to solve is to use TMS320F28069F, the control board with this CPU is working correctly.

    For a cost reason, the TMS320F28062F will be a better solution for us, but I need to be sure that the problem will not be present with it. As there is no control card with 28062F, if it doesn't work correctly, I will see it only when I will test my prototypes.

    Do you think there is a risk?

    Regards.

    Emmanuel

  • Manu,

    The 62F is the same silicon as the 69M, so from that persepective you don't have to worry.

    However, the issue you are seeing is due to bad samples in the modulation region. The first step is to get better sampling from the layout/hardware side.  The DRV8301 EVM is marginal in this operating range as it is. We have learned ourselves on this topic in the last few years.  There are also obviously are some minor differences between the 6x controlCARD and the much older 2x controlCARD that you are seeing. Perhaps in the filtering for the ADC pins.

    What I'm trying to say is that you could go make your own inverter, do a poor layout, and both 62F or 69M could show the problem.  On the flip side, with a good layout the 27F can give good results as well.

    There is also a SW component that I mention. We have solved a similar iissue with a compressor company and those SW techniques will be added to MotorWare.  This helps when the HW isn't perfect.

    We do not think there are inherrent differences between the 6x and 2x chips themselves  that is causing  you to see the issue with the 2x and not with the 6x.

     

  • Hi Chris,

    To keep you informed about the current distorsion :

    With the 6x I have solve the problem by reducing the WPM frequency to 16kHz so I have try to reduce again the PWM frequency with the 2x.

    The current distorsion disapear at 10kHz. It is interesting to note that 10kHz is 16kHz * 60Mhz/90Mhz.

    The current ripple at 10kHz is still good, we would perform acoustic test but this could be for us a temporary solution, waiting a new Motorware.

    Regards.

    Emmanuel

  • Very interesting. Seems clear it is a "smallest pulse detection issue".  We are going to look deeply into this for the MotorWare _13 release.  As mentioned previously, we believe the solution we have provided directly to a customer will be released in MotorWare for all and should solve this issue.

     

  • Is there a way to have the SW before the _13 release?

    Emmanuel

  • probably not, Emmanuel, and I apologize for that. It isn't effective for our schedules to try to give out SW in the middle of developing/testing.