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.

PMSM motor identification problem

Expert 1570 points
Other Parts Discussed in Thread: DRV8301, MOTORWARE

Hi,

I'm working on a surface-mount PMSM.

manufacturer data reads:

Rs=40mOhm (L-L), Ls=65 uH (L-L), nominal voltage-28V, power-250W, Ke-0.0123, poles-4.

My user.h file is at the end of this post (pasted "as-is", sorry for all the unnecessary text...)

The motor is unloaded during the identification process.

Now, I'm trying to run through the identification, but getting some trouble figuring out what is happening:

1. Running through RoverL - this works and produces the best results - 0.019 Ohm,32uH.

2. going to Rs id - doesn't give good results - 0.032 Ohm.

3. going to ramp-up - sometimes it works and sometimes it doesn't - I tried playing with the USER_MOTOR_RES_EST_CURRENT and other variables, but I can't seem to understand, even after reading the UG, which parameters effect, and how, on this ramp-up (like to slope etc.). ok, let's assume it's working and it got to the desired frequency...(20Hz)

4. going to flux id - at some point, the frequency drops to about 7Hz (USER_MOTOR_FLUX_EST_FREQ_Hz=20) and it runs for more than a minute.. even though I set the timeouts as follows:

pUserParams->estWaitTime[EST_State_RampUp]          = (uint_least32_t)((1.5F * USER_MOTOR_FLUX_EST_FREQ_Hz / USER_MAX_ACCEL_EST_Hzps) * USER_EST_FREQ_Hz); // was 5.0 + USER_MOTOR_FLUX_EST_FREQ_Hz / USER_MAX_ACCEL_EST_Hzps
  pUserParams->estWaitTime[EST_State_IdRated]         = (uint_least32_t)(10.0 * USER_EST_FREQ_Hz);
  pUserParams->estWaitTime[EST_State_RatedFlux_OL]    = (uint_least32_t)( 0.2 * USER_EST_FREQ_Hz);
  pUserParams->estWaitTime[EST_State_RatedFlux]       = 0;
  pUserParams->estWaitTime[EST_State_RampDown]        = (uint_least32_t)( 2.0 * USER_EST_FREQ_Hz);

5. then, moving to Ls id, the frequency decreases more, and sometimes the rotor stops. I can hear the motor making sounds, so it probably lost synchronization. not sure why. Furthermore, the identified Ls is totally wrong (giving 5-10 times more than is expected).

can you please explain the behavior ?

one thing I thought about is that the control cannot reach the current values specified in user.h for Rs and Ls stages... If I could debug it somehow, to see the Id,Iq feedback :)

thanks a lot

#define USER_IQ_FULL_SCALE_FREQ_Hz        (800.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 meet the following condition: USER_IQ_FULL_SCALE_VOLTAGE_V > 0.5 * USER_MOTOR_MAX_CURRENT * USER_MOTOR_Ls_d * USER_VOLTAGE_FILTER_POLE_rps,
//! \brief WARNING: 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      (36.0)   // 24.0 Example for drv8301_revd typical usage and the Anaheim motor

//! \brief Defines the maximum voltage at the input to the AD converter
//! \brief The value that will be represented 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          (10.0)   // 41.25 Example for drv8301_revd typical usage

//! \brief Defines the maximum current at the AD converter
//! \brief The value that will be represented 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    (4.157922864)
#define   I_B_offset    (4.096167088)
#define   I_C_offset    (4.125657082)

//! \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.3830444813)
#define   V_B_offset    (0.380874753)
#define   V_C_offset    (0.3834980726)


//! \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                (60.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        (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, controller 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 applications 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  (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   (10)   // 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)

// TIMEOUTS
#define USER_CTRL_OFFLINE_TIMEOUT        (1.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 demagnetization)
//! \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     (-4.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 (500)               // 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 calculation 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
#define MY_MOTOR                    113

// 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 should 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 MY_MOTOR
//#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 == MY_MOTOR)                            // 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       (2)                        // PAIRS, not total poles. Used to calculate user RPM from rotor Hz only
#define USER_MOTOR_Rr                   (NULL)                // Identified phase to neutral in a Y equivalent circuit (Ohms, float)
#define USER_MOTOR_Rs                   (0.01744834)                // Identified phase to neutral in a Y equivalent circuit (Ohms, float)
#define USER_MOTOR_Ls_d                 (0.002372358)            // For Induction, Identified average stator inductance  (Henry, float)
#define USER_MOTOR_Ls_q                 (0.002372358)            // For Induction, Identified average stator inductance  (Henry, float)
#define USER_MOTOR_RATED_FLUX           (0.02087141)        // sqrt(2/3)* Rated V (line-line) / Rated Freq (Hz)
#define USER_MOTOR_MAGNETIZING_CURRENT  (NULL)                    // Identified magnetizing current for induction motors, else NULL
#define USER_MOTOR_RES_EST_CURRENT      (2.5)                    // During Motor ID, maximum current (Amperes, float) used for Rs estimation, 10-20% rated current
#define USER_MOTOR_IND_EST_CURRENT      (-1.5)                    // not used for induction
#define USER_MOTOR_MAX_CURRENT          (10.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     (20.0)

  • are you using proj_lab2c?

    this is required for this type of motor with R/L > 2000.

    Smaller Ls and Flux will also require higher PWM, but your 60 KHz looks ok.

    Also, you have 60 kHz PWM and /3, which puts the main interrupt at 20 kHz.

    With a 90 mHz processor this is right on the edge during motor ID.  

    I try to ID with an inner control loop of 15 kHz with F28069M and 10 kHz with F28027F, even if that means initially having a lower PWM frequency.  I try not to use USER_NUM_ISR_TICKS_PER_CTRL_TICK      at (2) during ID, and only when absolutely necessary during run-time.  We will publish some examples of using a que / scheduler / OS as a way to do this in a better manner.

    although looking at your motor parameters it really shouldn't be necessary to PWM at this rate.  Is there a reason you choose 60 kHz instead of something more like 10-20 kHz?

  • I choose 60kHz because of the control structure I'm implementing.

    I'm still having trouble with IDing the motor, even with 15kHz...

    What I have observed though, is that my offset values are way off from what you expect:

    #define   I_A_offset    (2.772168159)
    #define   I_B_offset    (2.735211909)
    #define   I_C_offset    (2.7460531)

    #define   V_A_offset    (0.3849368691)
    #define   V_B_offset    (0.3834796548)
    #define   V_C_offset    (0.3977444172)

    what do you think ? is that reasonable ?

  • do you still have this value set?

    #define USER_IQ_FULL_SCALE_CURRENT_A          (10.0)  

    Why did you change this to 10A?

    You shouldn't change this value unless you change your

    USER_ADC_FULL_SCALE_CURRENT_A

    The ADC...CURRENT is pi-polar, meaning if this is set to (82.5) you are measuring +/1 41.25 A

    This 41.25A is set by the sense circuitry scaling, meaning 41.25 = 3.3V at the ADC Pin and -41.25 = 0.0V at ADC Pin.

    USER_IQ_FULL_SCALE_CURRENT_A is unipolar and should be set to a value >= 0.5 * ADC...CURENT

    So in the case of the DRV8301 EVM it should be at least (41.25). 

    This is because any value that gets converted from the ADC...CURENT gets divided by this IQ...CURRENT to create a "per unit" value.  To maximize resolution you can make sure that you are using the full -1.0 to 1.0 range.

    If you make IQ...CURRENT too small then you will measure values that go BEYOND the -1.0 to 1.0 per unit range.

    If you make IQ...CURRENT too large then you will reduce the range of per unit you are using (ex: may only be using -0.8 to 0.8)

    These _offset values are also scaled off of this per unit value...

    Can you attach your latest user.h file please?
    What is the maximum speed of the motor?  What is maximum current at rated torque? What Bus Voltage are you using? 

     

  • Well, the 10A is after making lots of tries with the code. I was setting it to 15A, but now I understand that this wasn't good also. I also understand my Voltage settings were not correct. I misunderstood the concept...

    The motor is 56kRPM electrical (2 pole-pair), 28V (this speed was measured no-load, with six-step driver... I hope to get much faster with FOC). max current is 15A.

    In my user.h I went down to 30kHz PWM with /3 for ISR. This is because I had issues with the floating-point, so my algorithms (generated from simulink) run really slow (all calculations are in float). However, I do need faster runs (around 60k for PWM).

    User.h : (fully copy-paste, sorry)

    #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        (1000.0)   // 800 Example with buffer for 8-pole 6 KRPM motor to be run to 10 KRPM with field weakening; Hz =(RPM * Poles) / 120
    #define USER_IQ_NOMINAL_SCALE_FREQ_Hz        (533.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 meet the following condition: USER_IQ_FULL_SCALE_VOLTAGE_V > 0.5 * USER_MOTOR_MAX_CURRENT * USER_MOTOR_Ls_d * USER_VOLTAGE_FILTER_POLE_rps,
    //! \brief WARNING: 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      (40.0)   // 24.0 Example for drv8301_revd typical usage and the Anaheim motor
    #define USER_IQ_NOMINAL_SCALE_VOLTAGE_V      (28.0)   // 24.0 Example for drv8301_revd typical usage and the Anaheim motor

    //! \brief Defines the maximum voltage at the input to the AD converter
    //! \brief The value that will be represented 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          (15.0)   // 41.25 Example for drv8301_revd typical usage
    #define USER_IQ_NOMINAL_SCALE_CURRENT_A          (10.0)   // 41.25 Example for drv8301_revd typical usage

    //! \brief Defines the maximum current at the AD converter
    //! \brief The value that will be represented 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    (2.772168159)
    #define   I_B_offset    (2.735211909)
    #define   I_C_offset    (2.7460531)

    //! \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.3849368691)
    #define   V_B_offset    (0.3834796548)
    #define   V_C_offset    (0.3977444172)


    //! \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                (30.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.3333)    // 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        (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, controller 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 applications 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  (2)   // 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   (10)   // 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)

    // TIMEOUTS
    #define USER_CTRL_OFFLINE_TIMEOUT        (0.5)
    //! \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 demagnetization)
    //! \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     (-6.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.004)     // 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.5)      // 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 calculation 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
    #define MY_MOTOR                    113

    // 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 should 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 MY_MOTOR
    //#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 == MY_MOTOR)                            // 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       (2)                        // PAIRS, not total poles. Used to calculate user RPM from rotor Hz only
    #define USER_MOTOR_Rr                   (NULL)                // Identified phase to neutral in a Y equivalent circuit (Ohms, float)
    #define USER_MOTOR_Rs                   (0.02241766)                // Identified phase to neutral in a Y equivalent circuit (Ohms, float)
    #define USER_MOTOR_Ls_d                 (3.509097e-05)            // For Induction, Identified average stator inductance  (Henry, float)
    #define USER_MOTOR_Ls_q                 (3.509097e-05)            // For Induction, Identified average stator inductance  (Henry, float)
    #define USER_MOTOR_RATED_FLUX           (0.02172359)        // sqrt(2/3)* Rated V (line-line) / Rated Freq (Hz)
    #define USER_MOTOR_MAGNETIZING_CURRENT  (NULL)                    // Identified magnetizing current for induction motors, else NULL
    #define USER_MOTOR_RES_EST_CURRENT      (4.0)                    // During Motor ID, maximum current (Amperes, float) used for Rs estimation, 10-20% rated current
    #define USER_MOTOR_IND_EST_CURRENT      (-3.5)                    // not used for induction
    #define USER_MOTOR_MAX_CURRENT          (10.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     (30.0)


    #elif (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.3918252)
    #define USER_MOTOR_Ls_d                 (0.00023495)
    #define USER_MOTOR_Ls_q                 (0.00023495)
    #define USER_MOTOR_RATED_FLUX           (0.03955824)
    #define USER_MOTOR_MAGNETIZING_CURRENT  (NULL)
    #define USER_MOTOR_RES_EST_CURRENT      (3.0)
    #define USER_MOTOR_IND_EST_CURRENT      (-0.5)
    #define USER_MOTOR_MAX_CURRENT          (20.0)
    #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

    Thanks

  • What are all these _NOMINAL_ variables, things like USER_CTRL_OFFLINE_TIMEOUT, and you mentioned your own simulink code?  Before adding all of these other things please start from a fresh MotorWare install and just get your motor ID'd and the labs to function.

    Start with a fresh install.

    You have a high speed motor, so it will have low flux and probably low inductance / high short circuit current. Due to this you MUST use proj_lab2c for identification.

     

    Use these settings different from what you just posted

    #define USER_IQ_FULL_SCALE_FREQ_Hz        (1900.0) // 56k RPM 4 poles is 1867 Hz

    #define USER_IQ_FULL_SCALE_VOLTAGE_V      (30.0) // with a 28V bus and a small Flux, high speed motor this should be fine.  When you are trying to ID if you are still having issues you may want to try making this value lower, down to 14V

    #define USER_IQ_FULL_SCALE_CURRENT_A          (41.25)  // don't ever change this value unless you change the ADC_FULL_SCALE_CURRENT due to HW change

    *** since you are changing both of these note that your scale factors have changed which means your offsets have changed. You can get these new values again or just insure that you Enable the OffsetCalc before you Run the software  ****

     

    #define USER_PWM_FREQ_kHz                (45.0)  // 45 KHz with (3) PWM _TICKS is fine. You MAY need to increase this in the 60-90 kHz range to improve current ripple/control during operation, but for ID it should work for this motor

    #define USER_NUM_PWM_TICKS_PER_ISR_TICK        (3) // uses ePWM hardware to only trigger the main INT every /3 times, so 45 / 3 = 15 kHz effective clock

    #define USER_NUM_CTRL_TICKS_PER_SPEED_TICK  (15)   // Keep this at 1 kHz effective

    #define USER_NUM_CTRL_TICKS_PER_TRAJ_TICK   (15)  // Keep at 1 kHz effective

    #define USER_ZEROSPEEDLIMIT   (0.0026)   // because you are using 1900 Hz no, set this so the switchover point to FAST is at 5 Hz to start, can lower it after you do some testing.

     

    #define USER_MAX_ACCEL_EST_Hzps           (10.0)         // 5.0 Default, don't change;  Because you are setting an estimation frequency during ID of about 150 Hz, it's possible to time-out before you reach that speed. You can either increase the time-out setting in the controller, or just double the rate at which you accelerate to that speed. Increasing the timer is "safter" but this usually works as well.

    #define USER_MOTOR_RES_EST_CURRENT      (1.5) // Try 1.5A first (10% of rated). Only increase in 0.5-1.0A increments until the motor STARTS spinning during the RampUp state. Once it's spinning you know this is large enough


    #define USER_MOTOR_IND_EST_CURRENT      (-1.5) // Set this as negative 10% of rated. If you have to increase RES_CURRENT to get the motor to RampUp you should in general still leave this value at the -10%

     
    #define USER_MOTOR_MAX_CURRENT          (15.0) // your motor is 15A, set this to 15, not 20.

     

    #define USER_MOTOR_FLUX_EST_FREQ_Hz     (150.0)  // this should be ~10% of your rated 1900 Hz speed. 150Hz is a good high end number, you usually don't need to go higher. 20 Hz you had was much too low, you won't get an effective reading.

     

    These values in MY_MOTOR, where did they come from. Did you ID this at one time for this motor?
    #define USER_MOTOR_Rs                   (0.3918252)
    #define USER_MOTOR_Ls_d                 (0.00023495)
    #define USER_MOTOR_RATED_FLUX           (0.03955824)

    R/L = 1668 Hz
    Isc = Flux / 2pi / Ls = 26.7 A
    Bemf voltage @ 1900 Hz = 75V

    In general this could be possible for this motor.  The R/L is a bit too low to achieve 1900 Hz.  The Isc is well designed, but most high speed (and high acceleration) motors would be larger.   If the Ls is actually <200uH you would get closer to what I would expect.  Running the Motor ID at the higher 150 Hz should hopefully show this.

    The flux is what has me most concerned.  What this says is that at 28V / 0.03955 V/Hz = 700 Hz the Bemf becomes as large as the Vbus.  That means to go faster than 700 Hz you are going to have to reduce the Bemf generation by using field weakening.

    I'm hoping you come back and tell me that these aren't the real values for this motor...because there is no way it will hit 1900 Hz with an FOC or BLDC technique unless you massively weaken that field.

     

  • I just went back and looked at your first post where you stated:

    Rs=40mOhm (L-L), Ls=65 uH (L-L), nominal voltage-28V, power-250W, Ke-0.0123, poles-4

    This would translate to

    R/L = 615 Hz // this is too low to expect 56 KRPM or 1900 Hz

    ke = 0.0123
    is this in Volts / kRPM?  That's impossibly tiny.  it suggests if you could run at 56 KRPM you would only generate 0.6888 Volts Bemf!!!

    that means it has a flux of 0.00036 V/Hz..

    which would generate an Isc = 1.7 A

    that's not possible.

  • Hi Chris,

    I will run today again lab2c with your recommendations for setting all USER_IQ... all _NOMINAL defines are some things I tested. I will post later my results.

    The motor I'm using is 56kRPM ELECTRICAL! not mechanical, so that's about 2kHz electrical frequency. It has 2 pole-pair so mechanical I get 28kRPM (as I said, that velocity is achieved using six-step drive, 100% duty cycle).

    Your approach to PU system is a little bit confusing. Usually PU is defined as 1p.u. for nominal operating conditions, so the appropriate scaling is made according to that operation point. However, from what I understand, in MotorWare everything is scaled to maximum allowed... Is that correct ? so if I get 1-p.u. for current, i.e sqrt(Id^2+Iq^2) = 1, that means I hit my current limit, and not the nominal operation point...


    I have a small remark about the units you use for R/L - that is [rad/sec] and not Hz, from what I know - time constant is L/R, so the 1/ is in rad/sec. Maybe I'm mistaken.

  • henry / ohm = second, 1/ second = Hz, so ohm / henry = Hz

    so in the above example

    Rs=40mOhm (L-L), Ls=65 uH

    65 uh / 40 mOhm = 0.001625 sec = 615 Hz = R / L

     

     

    Where else do you usually use PU?  We have always used per unit as a scale of maximum, this way you try to keep things between -1 and 1, and can easily get back to a real-world value by multiplying by the scaling factor.  This way the real-world, analog conversions, and control code all have the same reference.  It also works well with our IQ24 referencing of variables.

     

     

  • Also, 28 KRPM with 2 pole pairs = 933 Hz electrical, not 2 kHz.

    Your comment about hoping to get higher speeds using FOC is not practical. The only way for FOC to go higher speeds than BLDC is by introducing field weakening as a way to reduce Bemf (hence reduce torque production) to increase speed.

    in just "normal" control most FOC will have a top speed LOWER than BLDC as the space vector modulation scheme doesn't use as much of the bus voltage.  With InstaSPIN-FOC you can increase the modulation index to allow the PWM voltage generation to match that of a 100% duty cycle BLDC Trapezoidal drive.

    Use field weakening to go faster, but note that for field weakening to work well you actually need to have a field to weaken. A low flux motor is already producing so little Bemf and Torque that field weakening won't be very successful.

     

  • Ok, this is what I thought about your p.u.

    In the literature of synchronous motor drives (e.g O.Pyrhonen, Lipo etc), the per-unit is defined differently. see below:

    This has theoretical reason, as it simplifies the motor equations and simulation.

    For example, field weakening will always start when w=1p.u .

    Regarding R/L - well, also rad/sec is actually 1/sec since "rad" has no unit. If you are talking about time constant, then Tau=1/Wn, Tau is in [sec], Wn is in [rad/sec]

    Hz=1/sec when talking about periodic signals, such as sine. This has nothing to do with time constant (since there's no period there...)

    A simple example is taken from your lab 5a:

    do a bode diagram of this function, you'll find that you have a pole at R/L, [rad/sec]. The general structure for the denominator is of course (1+s/wn), but this is well known.

  • Of course you are correct about the 2kHz.. my bad...

    Although six-step utilizes the whole bus, I think it also effects the stator flux linkage, making it bigger than 1p.u (normalized to nominal operation conditions). That said, looking at the relation (w is rotational speed):

    w=Udc/Flux, disregarding the I*R term, you see that when Flux=1p.u and Udc=1 p.u, then w=1 p.u and everything is in place.

    However, if the control system, i.e six-step, makes the Flux > 1 p.u (becuase of armature reaction etc), then w will be lower than 1 p.u

    I never checked the above in simulation, it's my intuition...

  • we aren't putting things like flux into PU. Just the currents and voltages that we measure from the real world, as well as electrical speed.  Look in the user.h at anything that has a "SF" (scale factor) calculation.

    Capture real signals.  Calculate % based on our ADC variables (scale of the HW).  This % times our internal IQ variables (scale of the SW).

     

  • Hi Chris,

    After testing today, I have the following results:

    The settings are in the user.h file at the end of this thread.

    I wasn't successful in generating repeatability in Ls identification. got results from 1e-6 and to 1e-4

    I have observed the following:

    1. Setting the USER_MOTOR_RES_EST_CURRENT to 10% of rated did cause the motor to start spinning, but stoping in the middle of the ramp-up (not issue of timeout, I observed that the state is still ramp-up).

    2. So I concluded that I need more current. at 20% the motor was running as needed at the end of the ramp-up.

    3. However, entering the rated-flux state, the motor reduced the speed by 20%.

    4. entering Ls state, the velocity was reduced even further.

    5. I concluded that I don't have enough Iq current (I assume that at Ls state the Id,Iq controllers work), so I raised by 10% USER_MOTOR_RES_EST_CURRENT.

    6. The motor was running at constant speed through rampup -> rated flux -> Ls - this I assume how it should be.

    7. However, The results are not consistent and vary a lot. I concluded that I miss some Id.. so I raised USER_MOTOR_IND_EST_CURRENT (to the negative side, of course).

    8. Then, again the motor was reducing velocity as in (3),(4)...

    9. Then I started playing with USER_IQ_FULL_SCALE_FREQ_Hz,USER_IQ_FULL_SCALE_VOLTAGE_V and got all kind of results, but this was "blind" testing... I could not figure out a systematic approach to these phenomena. When I changed USER_IQ_FULL_SCALE_FREQ_Hz,USER_IQ_FULL_SCALE_VOLTAGE_V, I maintained the conditions for stability, as described in UG and other threads.

    10. If I check Ls from high-frequency state (with CTRL_getLhf(handle) ) , I get almost the correct value - 38uH. This value is also repeatable in all tests...

    11. I did not get to check the floating point issue, but what about my question regarding the #ifdef in est.h ?

    According to manufacturer:

    Ls = 30uH , R=0.022 ohm

    No load speed - 24000 RPM mechanical, 48000 electrical (800 Hz) @ 28Vdc

    ID results in Flux = 0.022, which is less of the right value (should be 0.035).

    Your help, as always, is highly appreciated.

    user.h (not all copy-paste, for clarity):

    //! \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        (1400.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 meet the following condition: USER_IQ_FULL_SCALE_VOLTAGE_V > 0.5 * USER_MOTOR_MAX_CURRENT * USER_MOTOR_Ls_d * USER_VOLTAGE_FILTER_POLE_rps,
    //! \brief WARNING: 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      (36.0)   // 24.0 Example for drv8301_revd typical usage and the Anaheim motor

    //! \brief Defines the maximum voltage at the input to the AD converter
    //! \brief The value that will be represented 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 represented 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.9939797521)
    #define   I_B_offset    (1.014363647)
    #define   I_C_offset    (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.5020679235)
    #define   V_B_offset    (0.4977650046)
    #define   V_C_offset    (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                (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        (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, controller 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 applications 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 demagnetization)
    //! \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     (-3.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
    //#define USER_ZEROSPEEDLIMIT   (5.0/USER_IQ_FULL_SCALE_FREQ_Hz)     // 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                 (10.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           (10.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 calculation 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

    #if (USER_MOTOR == MY_MOTOR)                            // 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       (2)                        // PAIRS, not total poles. Used to calculate user RPM from rotor Hz only
    #define USER_MOTOR_Rr                   (NULL)                // Identified phase to neutral in a Y equivalent circuit (Ohms, float)
    #define USER_MOTOR_Rs                   (0.02241766)                // Identified phase to neutral in a Y equivalent circuit (Ohms, float)
    #define USER_MOTOR_Ls_d                 (3.509097e-05)            // For Induction, Identified average stator inductance  (Henry, float)
    #define USER_MOTOR_Ls_q                 (3.509097e-05)            // For Induction, Identified average stator inductance  (Henry, float)
    #define USER_MOTOR_RATED_FLUX           (0.022)        // sqrt(2/3)* Rated V (line-line) / Rated Freq (Hz)
    #define USER_MOTOR_MAGNETIZING_CURRENT  (NULL)                    // Identified magnetizing current for induction motors, else NULL
    #define USER_MOTOR_RES_EST_CURRENT      (3.5)                    // During Motor ID, maximum current (Amperes, float) used for Rs estimation, 10-20% rated current
    #define USER_MOTOR_IND_EST_CURRENT      (-1.5)                    // not used for induction
    #define USER_MOTOR_MAX_CURRENT          (15.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     (40.0)

  • Mojo,

    a few things

    1. your Ls expected of 35uH is L-L, so we should get half of that with our Ls ID. And these are usually over rated, so I expect your motor is <15uH Ls line to neutral.  Very small.

    I'd still recommend increasing this value from 40 Hz up towards 140 Hz. You need to be in the 5-15% of Max Hz range to increase consistency of the Ls calculation.

    #define USER_MOTOR_FLUX_EST_FREQ_Hz     (140.0)

    2. The flux you are expecting of 0.035 is also small, but not as small as the tiny hoby motors and dental drills.  But I do suspect there is some correspondance here to the resolution of the flux we can measure, so follow the guidance on the other thread you started on that topic. From that thread I believe I suggested you set

     USER_IQ_FULL_SCALE_VOLTAGE_V      (46.0) 

    3. Stability of entering the RatedFlux state: After you are sure your IQ_VOLTAGE scaling and ID Frequency are correct / working well, the other thing you can try to do is change the gains of the PI speed control as it enters the RatedFlux state. It may be too stiff or soft for your motor.  In proj_lab2c.c look for this section

    Also, to allow a smooth transition into the flux estimation, try modifying this section of lab 2c, try different Ki setting for the speed controller:

      else if(EstState == EST_State_RatedFlux)
        {
          _iq Ki_spd = _IQ(0.5*USER_IQ_FULL_SCALE_FREQ_Hz*USER_CTRL_PERIOD_sec*USER_MOTOR_MAX_CURRENT/USER_IQ_FULL_SCALE_CURRENT_A);

          // Set Ki on closing the feedback loop
          PID_setKi(obj->pidHandle_spd,Ki_spd);

    And test by modifying this value to see if stability improves. Suggest a range of 0.1 to 2.0

     

    Other than that things look good.  I think with these suggestions you will get as close as you can with the HW you have.  The next step would be to improve the sense circuitry to maximize resolution for your particular motor.

     

  • I'm sorry but the values I gave for Ls and Rs (manufacturer) are already phase-neutral. Sorry for not specifing this...

    1. From what I saw,  I had to increase the USER_MOTOR_RES_EST_CURRENT to more than 20% of max, to get to 60Hz. In order to get to 150Hz as you suggest, this will be much higher. It's ok with me, I'm just asking myself is there some correlation to USER_MOTOR_IND_EST_CURRENT ? If I change USER_MOTOR_RES_EST_CURRENT do I also need to change USER_MOTOR_IND_EST_CURRENT ?

    2. You stated in 3. that "After you are sure your IQ_VOLTAGE scaling and ID Frequency are correct / working well" - how can I be sure ? can you give some criterion ?

    3. As written in point (3),(4) in my previous thread, I experienced reduction of speed at the transition from ramp-up to rated flux to Ls. At ramp-up the motor reached the correct speed. Can you explain why that happens ? I read that in the Ls state the system is already in closed loop, but that state takes a long time (around 30 sec). Do you think that changing the Ki will affect the final speed ? what about the gains of the current loop ? I think they are more important for stability....

    4. Does the motor need to spin at the desired speed set by USER_MOTOR_FLUX_EST_FREQ_Hz during the whole process (from ramp-up, of course) ?

    Thanks a lot for your quick response

  • 1. I'm surprised you are having to increase your current that high. Typically with these types of motors once you break the start-up torque they use almost no current unloaded.   I'd do some testing in the 70-120 Hz range and see if the Ls starts to stabilize, increasing your RES_CURRENT if needed  to hit those speeds.  With these types of motors I always leave the IND_CURRENT a bit lower. THe more IND_CURRENT you add the more unstable it can become during Ls estimation.  I would leave it at the 10% mark and see if you can get stable values.

    2. Just that they meet the calculations we discussed.  If you use >42V and 15Khz you are fine (I think that's what was in the other post, I can't remember all of them :)  )

    3. A speed loop is being closed and it sounds like it is not well regulated (probably not stiff enough).  Some drop is normal, as long as it recovers and the flux value stabalizes. This is why I suggested that you could attempt to change the gain on the speed Ki controller during this transition and see if that helps.  The gains of the current loop are done automatically and imperically. As long as you are using proj_lab2c for low flux / low inductance / higher RoverL motors it's taken care of for you.

    4. Yes, if it's not spinning at the commanded EST_FREQ at the end of RampUp until it is finished (some blips are ok during the state transitions as long as it recovers)  then there is an issue (not enough current, timed out due to low acceleration, instability in controllers, etc).

     

     

  • Hi Chris,

    I went directly to lab 5a. I thought to give a try to a current closed loop system.... For Ls I used the data that comes from the initial high frequency state (CTRL_getLhf(handle)). For Rs and Flux I've used the data from the ID.

    The system actually worked fine (until reaching about 16kRPM mechanical, then strange noises started to appear :) , but that's ok.

    The fact that I want to emphasize is that it used IqRef_A=3 to reach 150Hz. But it took a lot of time to accelerate to that point. To get to 40Hz, IqRef_A=2.2.

    Now, coming back to the ID phase, It seems unreasonable to use RES_CURRENT=3.5A for only 40Hz !! This brings me to a conclusion that maybe the angle being used at ramp-up and later in Rated-flux and Ls states is wrong..

    What is the relation of RES_CURRENT to Id,Iq ? I assume it sets only Iq...

    Who sets the Id_ref and Iq_ref for the current controllers ? Does FAST has anything to do with the current controllers ?

    By the way, I think that it's not such a bad method to start with lab 5a, see how much current is needed for some Hz.

  • Mojo,

    "Now, coming back to the ID phase, It seems unreasonable to use RES_CURRENT=3.5A for only 40Hz !! This brings me to a conclusion that maybe the angle being used at ramp-up and later in Rated-flux and Ls states is wrong.."

    This doesn't have anything to do with the angle.  RES_CURRENT is

    DC current injected into the D axis

    and then used for the amplitide of the AC current waveform that will be injected during the RampUp state. 3.5A will be a current waveform of +3.5A and -3.5A.

     

    "What is the relation of RES_CURRENT to Id,Iq ? I assume it sets only Iq..."

    During Rs State it sets an Id current.

    Have you read Chapter 6 of the UG?

    "Who sets the Id_ref and Iq_ref for the current controllers ? Does FAST has anything to do with the current controllers ?"

    During the ID process any current controller gains are calculated by the control system state machine running from ROM.  However, they can be overwritten, see proj_lab2c as this is exactly what we do. See CTRL_recalcKpKi function.

    The same process of calculating and setting the gains is used in all the projects for run-time.  This is done through the calcPIgains() function.  Or you can set new vaues to the PID handle yourself and then use the CTRL_setGains() function for each PID controller you want to change int he CTRL system: