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.

TMS320F280049C: Issues with Motor Identification using LAUNCHXL-F280049C with BOOSTXL-DRV8320RS EVM

Part Number: TMS320F280049C
Other Parts Discussed in Thread: LAUNCHXL-F280049C, BOOSTXL-DRV8320RS, C2000WARE, MOTORWARE, DRV8320, DRV8303, DRV8301, DRV832X

Hello, 

I'm having trouble getting my LAUNCHXL-F280049C and BOOSTXL-DRV8320RS EVM setup to identify a particular BLDC motor, as described in the InstaSPIN Lab 5 example project (is05_motor_id).  I'm able to go through the process and get good results for a very small BLDC motor, but when I repeat the process for a larger motor, I haven't been able to get the motor to spin well. 

I've been experimenting with USER_ values in the user.h for the larger motor. I have both motors defined in the user.h file (common to all of the instaSPIN Lab projects). 

The two sets of motor definitions look like this: 

#elif (USER_MOTOR == my_motor_rimfire)
#define USER_MOTOR_INERTIA_Kgm2 (0.00008)*5
#define USER_MOTOR_TYPE MOTOR_TYPE_PM
#define USER_MOTOR_NUM_POLE_PAIRS (6)
#define USER_MOTOR_Rr_Ohm (0.0)
#define USER_MOTOR_Rs_Ohm (0.0192190986)
#define USER_MOTOR_Ls_d_H (2.77999152e-06)
#define USER_MOTOR_Ls_q_H (2.77999152e-06)
#define USER_MOTOR_RATED_FLUX_VpHz (0.00554466015)
#define USER_MOTOR_MAGNETIZING_CURRENT_A (0.0)
#define USER_MOTOR_RES_EST_CURRENT_A (5.0)
#define USER_MOTOR_IND_EST_CURRENT_A (-5.0)
#define USER_MOTOR_MAX_CURRENT_A (15.0)
#define USER_MOTOR_FLUX_EXC_FREQ_Hz (30.0)
#define USER_MOTOR_NUM_ENC_SLOTS (1000) // encoder slots
#define USER_MOTOR_FREQ_MIN_HZ (5.0)
#define USER_MOTOR_FREQ_MAX_HZ (600.0)
#define USER_MOTOR_FREQ_LOW_HZ (20.0)
#define USER_MOTOR_FREQ_HIGH_HZ (400.0)
#define USER_MOTOR_VOLT_MIN_V (4.0)
#define USER_MOTOR_VOLT_MAX_V (24.0)

#elif (USER_MOTOR == my_motor_kde)
#define USER_MOTOR_INERTIA_Kgm2 (0.00008)*50
#define USER_MOTOR_TYPE MOTOR_TYPE_PM
#define USER_MOTOR_NUM_POLE_PAIRS (10)
#define USER_MOTOR_Rr_Ohm (NULL) //ACIM ONLY
#define USER_MOTOR_Rs_Ohm (0.0056) // (0.381334811)
#define USER_MOTOR_Ls_d_H (9.99999997e-07) // (0.000169791776)
#define USER_MOTOR_Ls_q_H (9.99999997e-07) // (0.000169791776)
#define USER_MOTOR_RATED_FLUX_VpHz 0.01 // (0.0398557819)
#define USER_MOTOR_MAGNETIZING_CURRENT_A (NULL)
#define USER_MOTOR_RES_EST_CURRENT_A (2.0)
#define USER_MOTOR_IND_EST_CURRENT_A (-1.95)
#define USER_MOTOR_MAX_CURRENT_A (160.0)
#define USER_MOTOR_FLUX_EXC_FREQ_Hz (40.0)
#define USER_MOTOR_NUM_ENC_SLOTS (1000)
#define USER_MOTOR_INERTIA_Kgm2 ((7.06154e-06)*100)
#define USER_MOTOR_RATED_VOLTAGE_V (68.0)
#define USER_MOTOR_RATED_SPEED_KRPM (2.5)
#define USER_MOTOR_FREQ_MIN_HZ (15.0) // Hz
#define USER_MOTOR_FREQ_MAX_HZ (600.0) // Hz
#define USER_MOTOR_FREQ_LOW_HZ (20.0) // Hz
#define USER_MOTOR_FREQ_HIGH_HZ (400.0) // Hz
#define USER_MOTOR_VOLT_MIN_V (20.0) // Volt
#define USER_MOTOR_VOLT_MAX_V (50.0) // Volt

I'm also using these: 

#define USER_NOMINAL_DC_BUS_VOLTAGE_V ((float32_t)(48.0))

#define USER_ADC_FULL_SCALE_VOLTAGE_V ((float32_t)(57.528))

#define USER_ADC_FULL_SCALE_CURRENT_A ((float32_t)(160)) // was 42.843

The larger motor (the _kde) hardly draws any current while trying to spin-up during the identification process.  Any ideas on what I can do to get this motor identified so we can work with it. 

Thanks in advance, 

Walt 

  • I can't understand why did you change USER_ADC_FULL_SCALE_CURRENT_A  if you don't change the hardware kit and the gain of F280049C PGA. Please don't change anything and just tune the below four parameters first base on your motor.

    #define USER_MOTOR_RES_EST_CURRENT_A (5.0)
    #define USER_MOTOR_IND_EST_CURRENT_A (-5.0)
    #define USER_MOTOR_MAX_CURRENT_A (15.0)
    #define USER_MOTOR_FLUX_EXC_FREQ_Hz (30.0)

  • HI Yanming, thanks for your feedback. I've removed a majority of the #defines but have had to keep the list below so the project will build.  Also, I should note that my progression through these labs was 1, 2, then jumped to 5.  I did this after reading in this forum someone else who wasn't able to get their motor spinning for lab 3 and was told in here that they needed to go through the motor identification process first, done in lab 5.  

    When I use the following #defines, and set everything else up normally, and then set motorVars.flagEnableSys followed by flagRunIdentAndOnLine the whole process stops within about 1/2 second, and won't restart without ending the debug session and restarting a new one.   I don't seen any error conditions reported, but again it won't restart without restarting the debug session.

    #elif (USER_MOTOR == my_motor_kde)  
    #define USER_MOTOR_INERTIA_Kgm2                 (0.00008)*50
    #define USER_MOTOR_TYPE MOTOR_TYPE_PM
    #define USER_MOTOR_MAGNETIZING_CURRENT_A (NULL)
    #define USER_MOTOR_RES_EST_CURRENT_A (5.0)
    #define USER_MOTOR_IND_EST_CURRENT_A  (-5.0)
    #define USER_MOTOR_MAX_CURRENT_A         (15.0)
    #define USER_MOTOR_FLUX_EXC_FREQ_Hz   (30.0)

    #define USER_MOTOR_NUM_POLE_PAIRS      (10)
    #define USER_MOTOR_Rr_Ohm                         (NULL)           //ACIM ONLY
    #define USER_MOTOR_Rs_Ohm                        (NULL)
    #define USER_MOTOR_Ls_d_H                         (NULL)  
    #define USER_MOTOR_Ls_q_H                         (NULL) 
    #define USER_MOTOR_RATED_FLUX_VpHz   0.01  

    #define USER_MOTOR_FREQ_MAX_HZ          (600.0)
    #define USER_MOTOR_NUM_ENC_SLOTS     (1000)

  • I'm using CCS 9.2 with the C2000Ware_MotorControl_SDK - v:2.01.00.00.  For this configuration, the project requires other #defines in order to build.  Can you please review the settings I posted earlier today and comment on that, and if you can suggest anything else I should be trying. 

  • HI Yanming, I've been looking forward to your response. This issue is critical for the project and of course, time is of the essence.

    Again, I'm using a clean install of CCS 9.2 and the MotorWare software, and we're following the InstaSPIN Labs as directed.  The process worked well for a small BLDC outrunner, but when applying it on the larger BLDC outrunning the process doesn't succeed. I've been able to experiment with some parameters to improve spin results slightly, but it still doesn't get good control of the motor.

    With the small motor, I can set the RPM in the Expressions table and watch the system control power to the loaded motor to maintain the speed setting.  With the larger motor, it doesn't get through the calibration process.  

  • Hi 

    What I'm seeing is that a tripFault occurs after setting motorVars.flagRunIdentAndOnLine = 1. 

    This is due to HAL_getTripFaults(halHandle) !=0), in turn setting motorVars.faultNow.bit.moduleOverCurrent = 1 

    ( on Line 544 of is05_motor_id.c )

    When I look at the HAL_getTripFaults() which is in hal.h lines 1226-1233, I see it returns 0x0C (or 1100b). 

    //! - EPWM_TZ_INTERRUPT - Trip Zone interrupt was generated
    //!                                               due to the following TZ events.
    //! - EPWM_TZ_FLAG_CBC - Trip Zones Cycle By Cycle event status flag
    //! - EPWM_TZ_FLAG_OST - Trip Zones One Shot event status flag

    Before drilling into this further, I'd like some guidance if possible, for how to proceed. 

    Again, I'm trying to run the motor identification lab with 'out of the box' software (no changes made).  I'm using the latest version of the tools, recently downloaded from the ti website, and have been following the lab procedures. 

    The motor, while capable of running a high current (~150+ amps at 50V) is being supplied by a power supply that only produces 6A at 50V, however the power never gets anywhere near that level.  The trip fault occurs without the power supply ever registering a single watt.  

    Your support will be greatly appreciated. 

    Best Regards, 

    Walt

  • You are right, the flag is triggered by the on-chip comparator output or nFault pin of DRV8320RS for over-current fault. The over-current fault is generated by the peak current of the motor phase, which is not equal to the maximum current of the power supply. The board will be damaged if you disable this over-current protection. It seems like the maximum current of this kit is not enough for your motor, you have to design your own board if you want to spin a high current motor over 20A.

    Did you remove the load from the motor during identification? Could you please post the spec. of the motor and the user.h you applied?

    You may try to add the following ccode after HAL_setupDRVSPI(halHandle, &drvSPI8320Vars) to increase the limitation current.

    drvSPI8320Vars.Ctrl_Reg_05.VDS_LVL = DRV8320_VDS_LEVEL_1P880_V;

    drvSPI8320Vars.writeCmd = 1;
    motorVars.dacValH = 4096 - 50;
    motorVars.dacValL = 50;

  • Hi Yanming, 

    Thank you for getting back to me on this. 

    Here is the information on the kde motor: www.kdedirect.com/collections/xf-single-rotor-brushless-motors/products/kde700xf-505-g3 

    I have developed a board that implements the higher current drive, by using parelleled N-FETs capable of the current needs of this motor.  The custom board was designed with a DRV8303, and didn't use a processor capable of FOC, but instead it was doing a simple BLDC implementation   I may be able to bridge the LAUNCHXL-F280049C with the custom board to run higher currents with the KDE motor for some short term testing.  However, a new board is needed to support the implementation of FOC, based on this reference design, and setup for this larger motor.  

    Meanwhile, I was looking forward to doing some basic motor testing and software development using power levels that are supported by the LAUNCHXL, namely 50V with less than 15A.  The lab power supply feeding the test system isn't capable of powering more than 6A at 50V so I don't believe there should be a concern about blowing up the LAUNCHXL while running the larger motor.

    I'm not sure I understand the question "Did you remove the load from the motor during identification".  The motor is the load and I don't understand how it could be identified if it is removed from the system?  

    Attached is a copy of the user.h file I'm using, and also the user.c which had a couple minor changes required to build and test (for both the rimfire, and the kde motors). 

    I'll look into the software changes you're describing, to see if I can get the system working at low power using them.  

    I'll follow up once I've looked into this.  

    0160.user.h

    //#############################################################################
    //
    // FILE:   user.c
    //
    // TITLE:  C28x InstaSPIN function for setting initialization data for the
    //         CTRL, HAL, and EST modules (floating point)
    //
    //#############################################################################
    // $TI Release: MotorControl SDK v2.01.00.00 $
    // $Release Date: Mon Nov 11 15:18:08 CST 2019 $
    // $Copyright:
    // Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
    //
    // 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.
    // $
    //#############################################################################
    
    #include "user.h"
    
    #ifdef __TMS320C28XX_CLA__
    #pragma CODE_SECTION(USER_setParams,"Cla1Prog2");
    #endif
    
    #ifdef _F28002x_
    #pragma CODE_SECTION(USER_setParams, "user_code");
    #endif
    
    //*****************************************************************************
    //
    // USER_setParams
    //
    //*****************************************************************************
    void USER_setParams(USER_Params *pUserParams)
    {
        pUserParams->dcBus_nominal_V = USER_NOMINAL_DC_BUS_VOLTAGE_V;
    
        pUserParams->numIsrTicksPerCtrlTick = 1;
        pUserParams->numIsrTicksPerEstTick = 1;
        pUserParams->numIsrTicksPerTrajTick = 1;
    
        pUserParams->numCtrlTicksPerCurrentTick = USER_NUM_ISR_TICKS_PER_CURRENT_TICK;
        pUserParams->numCtrlTicksPerSpeedTick = USER_NUM_ISR_TICKS_PER_SPEED_TICK;
    
        pUserParams->numCurrentSensors = USER_NUM_CURRENT_SENSORS;
        pUserParams->numVoltageSensors = USER_NUM_VOLTAGE_SENSORS;
    
        pUserParams->systemFreq_MHz = USER_SYSTEM_FREQ_MHz;
    
        pUserParams->voltage_sf = USER_VOLTAGE_SF;
    
        pUserParams->current_sf = USER_CURRENT_SF;
    
        pUserParams->dcBusPole_rps = USER_DCBUS_POLE_rps;
    
        pUserParams->offsetPole_rps = USER_OFFSET_POLE_rps;
    
        pUserParams->speedPole_rps = USER_SPEED_POLE_rps;
    
        pUserParams->voltageFilterPole_rps = USER_VOLTAGE_FILTER_POLE_rps;
    
        pUserParams->RoverL_excFreq_Hz = USER_R_OVER_L_EXC_FREQ_Hz;
    
        pUserParams->maxVsMag_pu = USER_MAX_VS_MAG_PU;
    
        pUserParams->motor_type = USER_MOTOR_TYPE;
    
        pUserParams->motor_numPolePairs = USER_MOTOR_NUM_POLE_PAIRS;
        pUserParams->motor_numEncSlots = USER_MOTOR_NUM_ENC_SLOTS;
    
        pUserParams->motor_ratedFlux_Wb = USER_MOTOR_RATED_FLUX_VpHz / MATH_TWO_PI;
    
        pUserParams->motor_Rr_d_Ohm = USER_MOTOR_Rr_Ohm;
        pUserParams->motor_Rr_q_Ohm = USER_MOTOR_Rr_Ohm;
    
        pUserParams->motor_Rs_a_Ohm = USER_MOTOR_Rs_Ohm;
        pUserParams->motor_Rs_b_Ohm = USER_MOTOR_Rs_Ohm;
    
        pUserParams->motor_Rs_d_Ohm = USER_MOTOR_Rs_Ohm;
        pUserParams->motor_Rs_q_Ohm = USER_MOTOR_Rs_Ohm;
    
        pUserParams->motor_Ls_d_H = USER_MOTOR_Ls_d_H;
        pUserParams->motor_Ls_q_H = USER_MOTOR_Ls_q_H;
    
        pUserParams->maxCurrent_A = USER_MOTOR_MAX_CURRENT_A;
    
        pUserParams->IdRated_A = USER_MOTOR_MAGNETIZING_CURRENT_A;
    
        pUserParams->Vd_sf = USER_VD_SF;
        pUserParams->maxVsMag_V = USER_NOMINAL_DC_BUS_VOLTAGE_V;
    
        /*LDRA_INSPECTED 139 S MR12 14.3 ""Its a compile time flag providing user a
           choice to use or bypass motor identification; so OK"*/
        if((USER_BYPASS_MOTOR_ID == 1) && (pUserParams->flag_bypassMotorId == true))
        {
    
    #if (USER_MOTOR == Estun_EMJ_04APB22_A)
            // Estun
            pUserParams->BWc_rps = MATH_TWO_PI * 100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    #elif (USER_MOTOR == Estun_EMJ_04APB22_B)
            // Estun
            pUserParams->BWc_rps = MATH_TWO_PI * 100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #elif (USER_MOTOR == Marathon_N56PNRA10102)
            // Marathon
            pUserParams->BWc_rps = MATH_TWO_PI * 100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #elif (USER_MOTOR == Anaheim_BLWS235D_160V)
            // Marathon
            pUserParams->BWc_rps = MATH_TWO_PI * 100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #elif (USER_MOTOR == Anaheim_BLWS235D)
            // Anaheim_BLWS235D
            pUserParams->BWc_rps = MATH_TWO_PI * (float32_t)100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #elif (USER_MOTOR == Anaheim_BLY172S_24V)
            // Anaheim_BLY172S_24V
            pUserParams->BWc_rps = MATH_TWO_PI * (float32_t)100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    #elif (USER_MOTOR == Teknic_M2310PLN04K)
            // M2310PLN04K
            pUserParams->BWc_rps = MATH_TWO_PI * (float32_t)100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #elif (USER_MOTOR == Marathon_5K33GN2A)
             Marathon 56H17T2001
             pUserParams->BWc_rps = MATH_TWO_PI * 100.0;
             pUserParams->BWdelta = (float32_t)8.0;
    
             // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
             pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                            pUserParams->motor_numPolePairs *
                                            pUserParams->motor_ratedFlux_Wb /
                                         (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #elif (USER_MOTOR == Teknic_MxxxxPLNxxK)
            // MxxxxPLNxxK
            pUserParams->BWc_rps = MATH_TWO_PI * (float32_t)100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #elif (USER_MOTOR == my_motor_kde)
            // MxxxxPLNxxK
            pUserParams->BWc_rps = MATH_TWO_PI * (float32_t)100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #elif (USER_MOTOR == my_motor_rimfire)
            // MxxxxPLNxxK
            pUserParams->BWc_rps = MATH_TWO_PI * (float32_t)100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * numPolesPairs * rotorFlux_Wb / (2.0 * J_kg_m2);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           pUserParams->motor_ratedFlux_Wb /
                                        (float32_t) (2.0 * USER_MOTOR_INERTIA_Kgm2);
    
    #else
    #error No motor type specified
    #endif
    
        }
        else
        {
            pUserParams->flag_bypassMotorId = false;
    
            pUserParams->BWc_rps = MATH_TWO_PI * (float32_t)100.0;
            pUserParams->BWdelta = (float32_t)8.0;
    
            // 3.0 * pUserParams->motor_numPolePairs * 0.1 / (2.0 * 0.00001);
            pUserParams->Kctrl_Wb_p_kgm2 = (float32_t)3.0 *
                                           pUserParams->motor_numPolePairs *
                                           (float32_t)(0.001) /
                                           (float32_t)(2.0 * 0.000001);
        }
    
        pUserParams->angleDelayed_sf_sec = (float32_t)0.5 * USER_CTRL_PERIOD_sec;
    
        pUserParams->fluxExcFreq_Hz = USER_MOTOR_FLUX_EXC_FREQ_Hz;
    
        pUserParams->ctrlWaitTime[CTRL_STATE_ERROR] = 0;
        pUserParams->ctrlWaitTime[CTRL_STATE_IDLE] = 0;
        pUserParams->ctrlWaitTime[CTRL_STATE_ONLINE] = 0;
    
        pUserParams->estWaitTime[EST_STATE_ERROR] = 0;
        pUserParams->estWaitTime[EST_STATE_IDLE] = 0;
        pUserParams->estWaitTime[EST_STATE_ROVERL] =
            (int32_t)(5.0 * USER_EST_FREQ_Hz);
        pUserParams->estWaitTime[EST_STATE_RS] = 0;
        pUserParams->estWaitTime[EST_STATE_RAMPUP] =
            (int32_t)((USER_MOTOR_FLUX_EXC_FREQ_Hz / USER_MAX_ACCEL_Hzps +
                             (float32_t)1.0) * USER_EST_FREQ_Hz);
        pUserParams->estWaitTime[EST_STATE_CONSTSPEED] =
            (int32_t)(1.0 * USER_EST_FREQ_Hz);
        pUserParams->estWaitTime[EST_STATE_IDRATED] =
            (int32_t)(20.0 * USER_EST_FREQ_Hz);
        pUserParams->estWaitTime[EST_STATE_RATEDFLUX_OL] =
            (int32_t)(1.0 * USER_EST_FREQ_Hz);
        pUserParams->estWaitTime[EST_STATE_RATEDFLUX] = 0;
        pUserParams->estWaitTime[EST_STATE_RAMPDOWN] =
            (int32_t)(0.0 * USER_EST_FREQ_Hz);
        pUserParams->estWaitTime[EST_STATE_LOCKROTOR] = 0;
        pUserParams->estWaitTime[EST_STATE_LS] = 0;
        pUserParams->estWaitTime[EST_STATE_RR] =
            (int32_t)(5.0 * USER_EST_FREQ_Hz);
        pUserParams->estWaitTime[EST_STATE_MOTORIDENTIFIED] = 0;
        pUserParams->estWaitTime[EST_STATE_ONLINE] = 0;
    
        pUserParams->FluxWaitTime[EST_FLUX_STATE_ERROR] = 0;
        pUserParams->FluxWaitTime[EST_FLUX_STATE_IDLE] = 0;
        pUserParams->FluxWaitTime[EST_FLUX_STATE_CL1] =
            (int32_t)(10.0 * USER_EST_FREQ_Hz);
        pUserParams->FluxWaitTime[EST_FLUX_STATE_CL2] =
            (int32_t)(0.2 * USER_EST_FREQ_Hz);
        pUserParams->FluxWaitTime[EST_FLUX_STATE_FINE] =
            (int32_t)(20.0 * USER_EST_FREQ_Hz);
        pUserParams->FluxWaitTime[EST_FLUX_STATE_DONE] = 0;
    
        pUserParams->LsWaitTime[EST_LS_STATE_ERROR] = 0;
        pUserParams->LsWaitTime[EST_LS_STATE_IDLE] = 0;
        pUserParams->LsWaitTime[EST_LS_STATE_RAMPUP] =
            (int32_t)(10.0 * USER_EST_FREQ_Hz);
        pUserParams->LsWaitTime[EST_LS_STATE_COARSE] =
            (int32_t)(30.0 * USER_EST_FREQ_Hz);
        pUserParams->LsWaitTime[EST_LS_STATE_FINE] =
            (int32_t)(30.0 * USER_EST_FREQ_Hz);
        pUserParams->LsWaitTime[EST_LS_STATE_DONE] = 0;
    
        pUserParams->RrWaitTime[EST_RR_STATE_ERROR] = 0;
        pUserParams->RrWaitTime[EST_RR_STATE_IDLE] = 0;
        pUserParams->RrWaitTime[EST_RR_STATE_RAMPUP] =
            (int32_t)(1.0 * USER_EST_FREQ_Hz);
        pUserParams->RrWaitTime[EST_RR_STATE_COARSE] =
            (int32_t)(10.0 * USER_EST_FREQ_Hz);
        pUserParams->RrWaitTime[EST_RR_STATE_FINE] =
            (int32_t)(30.0 * USER_EST_FREQ_Hz);
        pUserParams->RrWaitTime[EST_RR_STATE_DONE] = 0;
    
        pUserParams->RsWaitTime[EST_RS_STATE_ERROR] = 0;
        pUserParams->RsWaitTime[EST_RS_STATE_IDLE] = 0;
        pUserParams->RsWaitTime[EST_RS_STATE_RAMPUP] =
            (int32_t)(1.0 * USER_EST_FREQ_Hz);
        pUserParams->RsWaitTime[EST_RS_STATE_COARSE] =
            (int32_t)(2.0 * USER_EST_FREQ_Hz);
        pUserParams->RsWaitTime[EST_RS_STATE_FINE] =
            (int32_t)(10.0 * USER_EST_FREQ_Hz);
        pUserParams->RsWaitTime[EST_RS_STATE_DONE] = 0;
    
        pUserParams->trajWaitTime[EST_TRAJ_STATE_ERROR] = 0;
        pUserParams->trajWaitTime[EST_TRAJ_STATE_IDLE] = 0;
        pUserParams->trajWaitTime[EST_TRAJ_STATE_EST] = 0;
        pUserParams->trajWaitTime[EST_TRAJ_STATE_ONLINE] = 0;
    
        pUserParams->estFreq_Hz = USER_EST_FREQ_Hz;
        pUserParams->ctrlFreq_Hz = USER_CTRL_FREQ_Hz;
        pUserParams->trajFreq_Hz = USER_TRAJ_FREQ_Hz;
    
        pUserParams->pwmPeriod_usec = USER_PWM_PERIOD_usec;
        pUserParams->ctrlPeriod_sec = USER_CTRL_PERIOD_sec;
    
        pUserParams->maxAccel_Hzps = USER_MAX_ACCEL_Hzps;
    
        pUserParams->maxCurrent_resEst_A = USER_MOTOR_RES_EST_CURRENT_A;
        pUserParams->maxCurrent_indEst_A = USER_MOTOR_IND_EST_CURRENT_A;
    
        pUserParams->maxCurrentDelta_A = USER_MAX_CURRENT_DELTA_A;
        pUserParams->maxCurrentDelta_pw_A = USER_MAX_CURRENT_DELTA_PW_A;
    
        pUserParams->IdRated_delta_A = USER_IDRATED_DELTA_A;
    
        pUserParams->forceAngleFreq_Hz = USER_FORCE_ANGLE_FREQ_Hz;
    
        pUserParams->indEst_speedMaxFraction = USER_SPEEDMAX_FRACTION_FOR_L_IDENT;
    
        pUserParams->IdRatedFraction_indEst = USER_IDRATED_FRACTION_FOR_L_IDENT;
    
        pUserParams->pwGain = USER_PW_GAIN;
    
        pUserParams->Kp_min_VpA = (float32_t)0.001;
        pUserParams->Kp_max_VpA = (float32_t)1000.0;
    
        pUserParams->RoverL_Kp_sf = USER_R_OVER_L_KP_SF;
        pUserParams->RoverL_min_rps = MATH_TWO_PI * (float32_t)5.0;
        pUserParams->RoverL_max_rps = MATH_TWO_PI * (float32_t)5000.0;
    
        pUserParams->oneOverDcBus_min_invV = (float32_t)1.0 / (float32_t)400.0;
        pUserParams->oneOverDcBus_max_invV = (float32_t)1.0 / (float32_t)10.0;
    
        pUserParams->Ls_d_H = (float32_t)1.0e-6;
        pUserParams->Ls_q_H = (float32_t)1.0e-6;
        pUserParams->Ls_coarseDelta_H = (float32_t)0.0000001;
        pUserParams->Ls_fineDelta_H = (float32_t)0.00000001;
        pUserParams->Ls_min_H = (float32_t)0.000001;
        pUserParams->Ls_max_H = (float32_t)100.0;
    
        pUserParams->Rr_Ohm = (float32_t)0.0;
        pUserParams->Rr_coarseDelta_Ohm = (float32_t)0.0001;
        pUserParams->Rr_fineDelta_Ohm = (float32_t)0.00001;
        pUserParams->Rr_min_Ohm = (float32_t)0.0;
        pUserParams->Rr_max_Ohm = (float32_t)1000.0;
    
        pUserParams->Rs_Ohm = (float32_t)0.0;
        pUserParams->Rs_coarseDelta_Ohm = (float32_t)0.01;
        pUserParams->Rs_fineDelta_Ohm = (float32_t)0.00001;
        pUserParams->Rs_min_Ohm = (float32_t)0.001;
        pUserParams->Rs_max_Ohm = (float32_t)1000.0;
    
        pUserParams->RsOnLine_DeltaInc_Ohm = (float32_t)0.00001;
        pUserParams->RsOnLine_DeltaDec_Ohm = (float32_t)0.00001;
        pUserParams->RsOnLine_min_Ohm = (float32_t)0.001;
        pUserParams->RsOnLine_max_Ohm = (float32_t)1000.0;
    
        pUserParams->RsOnLine_angleDelta_rad = (float32_t)0.00001;
        pUserParams->RsOnLine_pole_rps = MATH_TWO_PI * (float32_t)0.2;
    
        pUserParams->flag_bypassMotorId = USER_BYPASS_MOTOR_ID;
    
        return;
    } // end of USER_setParams() function
    
    
    // end of file
    

  • I'd also like to discuss these points you've made: 

    1. The over-current fault is generated by the peak current of the motor phase, which is not equal to the maximum current of the power supply.

    2. The board will be damaged if you disable this over-current protection.

    regarding #1) how can we scale the over-current fault, so that we can set it to a known amperage? 

    regarding #2) given I'm using a 6A 50V supply, do I need to worry about burning out parts on the board, if an incorrect software value is used somewhere? 

    Also, I'm looking into making the following change: 

    ------- IS:

    //

    // turn on the DRV8320 if present
    //
    HAL_enableDRV(halHandle);

    //
    // initialize the DRV8320 interface
    //
    HAL_setupDRVSPI(halHandle, &drvSPI8320Vars);

    drvSPI8320Vars.Ctrl_Reg_05.VDS_LVL = DRV8320_VDS_LEVEL_1P300_V;
    drvSPI8320Vars.Ctrl_Reg_05.DEAD_TIME = DRV8320_DEADTIME_100_NS;
    drvSPI8320Vars.writeCmd = 1;

    ------ CHANGE TO:

    drvSPI8320Vars.Ctrl_Reg_05.VDS_LVL = DRV8320_VDS_LEVEL_1P500_V;  // rather than 1P880

    drvSPI8320Vars.Ctrl_Reg_05.DEAD_TIME = DRV8320_DEADTIME_100_NS;

    drvSPI8320Vars.writeCmd = 1;


    //motorVars.dacValH = 4096 - 50;      // currently set to 2048 in hal.c line 673
    //motorVars.dacValL = 50;                  // currently set to 2048 in hal.c line 674

    motorVars.dacValH = 2048+1024;

    motorVars.dacValL = 2048 - 1024; 

  • I looked into the proposed code changes: 

    drvSPI8320Vars.Ctrl_Reg_05.VDS_LVL = DRV8320_VDS_LEVEL_1P880_V;

    drvSPI8320Vars.writeCmd = 1;
    motorVars.dacValH = 4096 - 50;
    motorVars.dacValL = 50;

    It looks like, without making this modification, both the high and low dac settings are set to 2048.  This is noted as mid-point in the code. 

    I'm wondering how I can determine the scale used for these settings, and if I shouldn't start with: 

    motorVars.dacValH = 2048+1024; 

    motorVars.dacValL = 2048 - 1024; 

    Also would like to know if the test setup is using a power supply fed by 6A at 50V, if we need to worry about damaging the LAUNCHXL or BOOST hardware? 

    Can you point me to any literature that describes how the dac scaling is calculated?

    Thanks in advance, 

    Walt White 

  • 1. The motor identification must be run without load or with a light load, so you can't add any load to the motor, if it has, you should take off the load from the shaft of the motor, because the controller doesn't know the exact rotor position to spin the motor with load during the identification process. I think the motor should be identified or run without load using this board.

    2. Change the Vds limitation value of DRV8320 and motorVars.dacValH/motorVars.dacValL  just for increasing the maximum current protection value to avoid the overcurrent fault. The internal reference DAC value for the comparator will be changed in isxx_xx.c as below codes by the motorVars.dacValH/motorVars.dacValL variables, so that's why to do the setting as mentioned above. 

                for(cmpssCnt = 0; cmpssCnt < HAL_NUM_CMPSS_CURRENT; cmpssCnt++)

                {

                    HAL_setCMPSSDACValueHigh(halHandle,

                                             cmpssCnt, motorVars.dacValH);

                    HAL_setCMPSSDACValueLow(halHandle,

                                            cmpssCnt, motorVars.dacValL);

                }

    As the chapter 16 (Comparator Subsystem) of F280049C TRM, the output of the reference DAC can be connected to the negative input of the respective comparator, so set the DACHVALA/DACLVALA  value to adjust the limitation value. 

    The value of DACHVALA/DACLVALA is 2048 that means the reference voltage is 1.65V (half of the VDDA), the limitation current is zero since the PGA of F28049C senses the bi-direction current of the motor using a 1.65V offset, The DACHVALA is set to 4095 that means the positive maximum current is half of USER_ADC_FULL_SCALE_CURRENT_A, and the DACLVALA is set to 0 that means the negative maximum current is half of USER_ADC_FULL_SCALE_CURRENT_A.

    So the positive peak current is +(USER_ADC_FULL_SCALE_CURRENT_A/2) if you set motorVars.dacValH to 4095, and the negative peak current is -(USER_ADC_FULL_SCALE_CURRENT_A/2) if you set motorVars.dacValL to 0. But you have to reserve a little bit buffer for both variables, that's why recommend the value as replied above.

  • I had a similiar problem like you. But I was able to spin the motor for a few seconds when I Start to increase the PWM, then the firmware start to calculate the Ls. At that moment the overcurrent fault turns into 1. So I tried with a small motor and I didn´t have problem.

    When The motorVars.flagMotorIdentified=1  the motorVars.Ls_d_H, motorVars.Ls_q_H shows me (9.99999997e-07)

    I have change the PWM Frequency to 45khz

    USER_NUM_PWM_TICKS_PER_ISR_TICK        (3)

    USER_MOTOR_FLUX_EXC_FREQ_Hz       (80.0)

    USER_MOTOR_RES_EST_CURRENT_A      (4.0)

    USER_MOTOR_IND_EST_CURRENT_A      (-4.0)

    and also I have increase the DC bus Voltage. 

    USER_NOMINAL_DC_BUS_VOLTAGE_V         ((float32_t)(32.0))

    I have read the MotorWare instaSpin Labs . We want to Control a Low inductance Motor , we have to increase the PWM frequency and also

    USER_MOTOR_FLUX_EXC_FREQ_Hz   

    I spent a lot of time trying to identify the motor but When you build the project try first "celan project" and then Build project when you are doing that kind of modifications.

  • Right, low inductance motor must use the higher PWM frequency for identification and spin. The identification variables need to be configured according to the spec. of the motor to keep it spin smoothly during the running period. If not, the identification will be not correct.

     

  • Yet Juan seemingly still had PWM fault trip issues even at higher PWM frequency, only gets system little further prior to same fault.

    We had similar issue with TI ePWM module OR of 3 input fault trips, caused odd comparator behavior. The fix requires to make comparator GPIO output OD and assign WPU for the internal gen Fault inputs. Prior to fix It could be noticed the comparator trip point sensitivity was far greater for two phase legs by >250mV on center and >500mv on last comparator. After the OD change all comparator ignore initial start transient and still protect inverter NFETS at the set trip point.

  • Oddly ePWM fault trip claims to use un-filtered for DCA yet it selects filtered.

     

            // Configure the DCA path to be un-filtered and asynchronous
            EPWM_setDigitalCompareEventSource(obj->pwmHandle[cnt],
                                              EPWM_DC_MODULE_A,
                                              EPWM_DC_EVENT_1,
                                              EPWM_DC_EVENT_SOURCE_FILT_SIGNAL);
    
            // Configure the DCB path to be un-filtered and asynchronous
            EPWM_setDigitalCompareEventSource(obj->pwmHandle[cnt],
                                              EPWM_DC_MODULE_B,
                                              EPWM_DC_EVENT_1,
                                              EPWM_DC_EVENT_SOURCE_FILT_SIGNAL);
    
        //! signal source is unfiltered (DCAEVT1/2)
        EPWM_DC_EVENT_SOURCE_ORIG_SIGNAL = 0,
        //! signal source is filtered (DCEVTFILT)
        EPWM_DC_EVENT_SOURCE_FILT_SIGNAL = 1

  • We use 3 separate ePWM fault source GPIO inputs in our OD configuration from 3 analog comparators. Seemingly Fig.18-1 input Xbar 1,3 were not considered for DRV8320RS withotu current sensors. 

    DRV8320 schematic has no external pointer nFAULT LED indicating signal flows into J1 header below. Why haven't you reviewed the booster pack headers today, who would know? 

  • It would seem odd configuration CMPSS (GPIO TZ2) when TRIP 7,8,9 are the configured fault inputs.

  • So the TZ2 nFault is for DRV8320 does not necessarily indicates an over current condition, since PGA1,3,5 via CMPSS 1,3,5 monitor OC condition. Seemingly the DRV8320 nFault can occur from other conditions and auto disable ePWM drives too.

    The difference is the Booster pack fault LED will light if the DRV8320 drives or a SW command caused the fault. It would seem somewhat redundant to have both DRV8320 and ePWM detecting OC condition. But not some other kind of driver issue such as UVLO if the DC bus voltage drops to rapidly.  Seemingly we need two LED's in order to know what caused the ePWM fault. The alternative is to invoke printf() to indicate the nFault status register of DRV8320. 

  • Both the nFault signal from DRV8320 and the output from CMPSS are linked to EPWM XBAR to disable the PWM output of C2000. The DRV8320RS has some integrated protection features and outputs the status on nFault pin, you might find the details in its datasheet as the following link. Please create a new thread if you want to post a different topic that helps other designers reference the topic easily.

    http://www.ti.com/product/DRV8320R

  • Yanming Luo said:
    Both the nFault signal from DRV8320 and the output from CMPSS are linked to EPWM XBAR to disable the PWM output of C2000. The DRV8320RS has some integrated protection features and outputs the status on nFault pin, you might find the details in its datasheet as the following link.

    Again he point is DRV8320RS does not embedded any OC amplifiers. The DRV datasheet does not clearly identify which fault register bits are disabled in that scenario. So the DRV fault register flag bits do not set the entire fault precedence on the Tz2 input. The PGA amplifiers TripN disable ePWM drives only for motor OC conditions. The DRV8320RS does not post a separate status of the same fault condition since it does not have current amplifiers, how could it.    

    Logically any over current (OC) condition that immediately stops motor run should not enable the LED on BoostXL board! Point being DRV8320RS only report other fault condition via InsaSpin GUI status register view. So OC fault should not trip the BoostXL LED to on state eliminating that as the fault source.

    Again the PWM fault configuration leaves open possibility DRV8320 encountered UVLO or like condition if 6A power supply dips suddenly under load. 

    My posting most definitely relates to this topic. The red box faults are not included and the green faults are

  • I guess you should have a look at both fault status register 1 and 2 already, the overcurrent fault can be detected by the Vds also.

  • Correct that would seem to cause Fault status but not affect Tz2 configured one shot and was thought to be fault minper at the time. Oddly the InstaSpin GUI show the DRV8320Rs fault configured auto retry, checking fault register setting after connecting to target. Perhaps it really doesn't matter since the target PWM will stop once Tz2 one shot is ever tripped. \

    So it has two ways to trip faults and I will get further into that at some later date since it never tripped over current fault and smoked my 2A peak motor. The point of OC fault is to stop motor from catching on fire. Yet the phase voltages dropped from +20v down to +10v when the center phase shorted and no OC fault ever tripped. The target kept modulating funky signals, phase A  had an inverted and different duty cycle from that of phase B.

  • The nFault pin of DRV8320RS is connected to a GPIO of F280049C. The related GPIO is linked to the Input XBAR and configured as TZ for over-current protection. Please refer to the HAL_setupFaults() in hal.c.

    Right, there are two ways to trig the over-current fault to turn off the PWM output. The default value is not good for any motors, you have to change the threshold value in the project according to the maximum tolerance current of the motor and board. 

  • Yanming Luo said:
    The nFault pin of DRV8320RS is connected to a GPIO of F280049C.

    The only time 8320 fault LED blink is on power up and seem to incorrectly set nFault flag in FaultFlags variable. Also never trips Tz2 sub module OSHT to disable the ePWM outputs stay high all the time. Oddly most the drv8320 registers have maximum settings for gate drive and others. The 8320 nFault action is set for retry mode when Tz2 is configured OSHT, seems incorrect.

    Other posters confused to believe 8320 VDS faults represent external NFET IDS currents, VDS only indicate internal totem pole over current conditions. So drv8301 not using 2 internal current amplifiers can not detect 200 amp VDS faults, that's simply ridiculous to even consider possible or accurate.

    Some motor kits have disabled parts of the drv832x fault registers when they opted to use external current amplifiers. Yet the datasheet has to still show all fault registers for all versions of gate driver. Datasheets need to do a better job to clarify when parts of the fault register are valid for each chip option.

  • I think the datasheet should have such functions by setting the control registers since these devices are not supported by this C2000 forum. You might take a look at the datasheet.