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.

Motor Identification Issue

Other Parts Discussed in Thread: MOTORWARE

Hello all,

I added a condition to my code in order to select motor identification mode or normal operation (torque mode or speed mode). Identification mode constantly failed to identify Ls_q and Ls_d and I tried almost every trick in gui universal.pdf with no effect. After many experiments i found that the following line in my main loop was interfered with id process  :

// Dis-able the Library internal PI.  Iq has no reference now
        CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false);

If I comment this line identification works perfect but Torque mode fails. If I let this line as it is torque mode work fine but identification fails. I modified this line like this :

if(gMotorVars.Flag_MotorIdentified    == true)
     {
        CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false);
    }

But I am not sure that this is the right way.

I have two questions :

1) What this line does and why I need it in torque mode ?

2) Which is the right flag to identifies that I am out of any identification procedure (Rs recalculation , ADC offset etc) ?

Here is my code :

//==========================================================================
//					 traction controller test
//					A.Brousalis		Nov 2013
//==========================================================================
//! Based on  PROJ_LAB04A
// **************************************************************************
// 	includes
// **************************************************************************
#include <math.h>
#include "main.h"
// **************************************************************************
//
// **************************************************************************
#define 	TORQUE_MODE
//#define		FULL_MOTOR_ID
#define		PART_MOTOR_ID
//#define		NO_MOTOR_ID



#define LED_BLINK_FREQ_Hz   5
// **************************************************************************
#ifdef FLASH
#pragma CODE_SECTION(mainISR,"ramfuncs");
#endif

// **************************************************************************

// **************************************************************************
static inline bool myDRV_ReadGpio(DRV_Handle handle,const GPIO_Number_e gpioNumber)
{
  DRV_Obj *obj = (DRV_Obj *)handle;

  // set GPIO high
  return( GPIO_read(obj->gpioHandle,gpioNumber));
}

#define 	StartPressed()	(myDRV_ReadGpio(drvHandle,GPIO_Number_9) == 0)
#define 	StopPressed()	(myDRV_ReadGpio(drvHandle,GPIO_Number_7) == 0)

#define 	Led10_ON()		DRV_setGpioHigh(drvHandle,GPIO_Number_12)
#define 	Led10_OFF()		DRV_setGpioLow(drvHandle,GPIO_Number_12)
#define 	Led10_TOG()		DRV_toggleGpio(drvHandle,GPIO_Number_12)

#define 	Led11_ON()		DRV_setGpioHigh(drvHandle,GPIO_Number_15)
#define 	Led11_OFF()		DRV_setGpioLow(drvHandle,GPIO_Number_15)
#define 	Led11_TOG()		DRV_toggleGpio(drvHandle,GPIO_Number_15)

// **************************************************************************
// 		 globals
// **************************************************************************
_iq PotRef_krpm;
_iq TorqueRef;
float vare;

uint_least16_t gCounter_updateGlobals = 0;

bool Flag_Latch_softwareUpdate = true;

CTRL_Handle ctrlHandle;

DRV_Handle drvHandle;

USER_Params gUserParams;

DRV_PwmData_t gPwmData;

DRV_AdcData_t gAdcData;

_iq gMaxCurrentSlope = _IQ(0.0);

#ifdef FAST_ROM_V1p6
CTRL_Obj *controller_obj;
#else
CTRL_Obj ctrl;				//v1p7 format
#endif

ST_Obj st_obj;
ST_Handle stHandle;

uint16_t gLEDcnt = 0;

volatile MOTOR_Vars_t gMotorVars = MOTOR_Vars_INIT;

#ifdef FLASH
// Used for running BackGround in flash, and ISR in RAM
extern uint16_t *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
#endif


#ifdef DRV8301_SPI
// Watch window interface to the 8301 SPI
DRV_SPI_8301_Vars_t gDrvSpi8301Vars;
#endif


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

void main(void)
{
  uint_least8_t estNumber = 0;
  TorqueRef = 0;

#ifdef FAST_ROM_V1p6
  uint_least8_t ctrlNumber = 0;
#endif

  // Only used if running from FLASH
  // Note that the variable FLASH is defined by the project
  #ifdef FLASH
  // Copy time critical code and Flash setup code to RAM
  // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
  // symbols are created by the linker. Refer to the linker files.
  memCopy((uint16_t *)&RamfuncsLoadStart,(uint16_t *)&RamfuncsLoadEnd,(uint16_t *)&RamfuncsRunStart);
  #endif

  // initialize the driver
  drvHandle = DRV_init(&drv,sizeof(drv));


  // initialize the user parameters
  USER_setParams(&gUserParams);


  // set the driver parameters
  DRV_setParams(drvHandle,&gUserParams);


  // initialize the controller
#ifdef FAST_ROM_V1p6
  ctrlHandle = CTRL_initCtrl(ctrlNumber, estNumber);  		//v1p6 format (06xF and 06xM devices)
  controller_obj = (CTRL_Obj *)ctrlHandle;
#else
  ctrlHandle = CTRL_initCtrl(estNumber,&ctrl,sizeof(ctrl));	//v1p7 format default
#endif


  Led11_OFF();

  // set the default controller parameters
  CTRL_setParams(ctrlHandle,&gUserParams);

  // setup faults
  DRV_setupFaults(drvHandle);

  // initialize the interrupt vector table
  DRV_initIntVectorTable(drvHandle);

  // enable the ADC interrupts
  DRV_enableAdcInts(drvHandle);

  // enable global interrupts
  DRV_enableGlobalInts(drvHandle);

  // enable debug interrupts
  DRV_enableDebugInt(drvHandle);

  // disable the PWM
  DRV_disablePwm(drvHandle);

//===========================================================================================
//===========================================================================================
#ifdef DRV8301_SPI
  // turn on the DRV8301 if present
  DRV_enable8301(drvHandle);
  // initialize the DRV8301 interface
  DRV_8301_SpiInterface_init(drvHandle,&gDrvSpi8301Vars);
#endif

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

#ifndef TORQUE_MODE
  // initialize the SpinTAC Components
  stHandle = ST_init(&st_obj, sizeof(st_obj));

  // setup the SpinTAC Components
  ST_setupVelCtl(stHandle);
#endif

#ifdef NO_MOTOR_ID

  gMotorVars.Flag_enableOffsetcalc = false;
  gMotorVars.Flag_enableRsRecalc = false;
  gMotorVars.Flag_MotorIdentified = true;

#endif

#ifdef FULL_MOTOR_ID
  gMotorVars.Flag_MotorIdentified = false;
#endif

#ifdef PART_MOTOR_ID
  gMotorVars.Flag_enableOffsetcalc = true;
  gMotorVars.Flag_enableRsRecalc = true;
  gMotorVars.Flag_MotorIdentified = false;
#endif

//  gMotorVars.Flag_enableForceAngle = false;

  for(;;)
  {
	  CTRL_Obj *obj = (CTRL_Obj *)ctrlHandle;
	  ST_Obj *stObj = (ST_Obj *)stHandle;


    // Waiting for enable system flag to be set
	  while(!(gMotorVars.Flag_enableSys))
	      {
	      	if(StartPressed())
	      	{
	      		Led10_ON();
	          	gMotorVars.Flag_enableSys = true;
	          	gMotorVars.Flag_Run_Identify = true;
	          }
	      }
	      
#ifndef FULL_MOTOR_ID
    // Dis-able the Library internal PI.  Iq has no reference now
    //if(gMotorVars.Flag_MotorIdentified	== true)
    // {
    	CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false);
    //}
#endif

    // loop while the enable system flag is true
    while(gMotorVars.Flag_enableSys)
      {
      	
      	// increment counters
      	gCounter_updateGlobals++;
      	
      
#ifdef PART_MOTOR_ID
        CTRL_setFlag_enableUserMotorParams(ctrlHandle,true ) ;										// Use user.h parameters
#endif

#ifdef NO_MOTOR_ID
        CTRL_setFlag_enableUserMotorParams(ctrlHandle,true ) ;										// Use user.h parameters
#endif

      
        if(CTRL_isError(ctrlHandle))
          {
            // set the enable controller flag to false
            CTRL_setFlag_enableCtrl(ctrlHandle,false);

            // set the enable system flag to false
            gMotorVars.Flag_enableSys = false;

            // disable the PWM
            DRV_disablePwm(drvHandle);
          }
        else
          {
            // update the controller state
            bool flag_ctrlStateChanged = CTRL_updateState(ctrlHandle);

            // enable or disable the control
            CTRL_setFlag_enableCtrl(ctrlHandle, gMotorVars.Flag_Run_Identify);

            if(flag_ctrlStateChanged)
              {
                CTRL_State_e ctrlState = CTRL_getState(ctrlHandle);

                if(ctrlState == CTRL_State_OffLine)
                  {
                    // enable the PWM
                    DRV_enablePwm(drvHandle);
                  }
                else if(ctrlState == CTRL_State_OnLine)
                  {
                	Led11_ON();
                    if(gMotorVars.Flag_enableOffsetcalc == true)
                    {
                      // update the ADC bias values
                      DRV_updateAdcBias(drvHandle);
                    }
                    else
                    {
                      // set the current bias
                      DRV_setBias(drvHandle,DRV_SensorType_Current,0,_IQ(I_A_offset));
                      DRV_setBias(drvHandle,DRV_SensorType_Current,1,_IQ(I_B_offset));
                      DRV_setBias(drvHandle,DRV_SensorType_Current,2,_IQ(I_C_offset));

                      // set the voltage bias
                      DRV_setBias(drvHandle,DRV_SensorType_Voltage,0,_IQ(V_A_offset));
                      DRV_setBias(drvHandle,DRV_SensorType_Voltage,1,_IQ(V_B_offset));
                      DRV_setBias(drvHandle,DRV_SensorType_Voltage,2,_IQ(V_C_offset));
                    }

                    // enable the PWM
                    DRV_enablePwm(drvHandle);
                  }
                else if(ctrlState == CTRL_State_Idle)
                  {
                  	Led11_OFF();
                    // disable the PWM
                    DRV_disablePwm(drvHandle);
                    gMotorVars.Flag_Run_Identify = false;
                  }
              }
          }


        if(EST_isMotorIdentified(obj->estHandle))
          {
            // set the current ramp
            EST_setMaxCurrentSlope_pu(obj->estHandle,gMaxCurrentSlope);
            gMotorVars.Flag_MotorIdentified = true;

#ifndef TORQUE_MODE
            // set the speed reference
        	vare = (float) ( (float)((float)PotRef_krpm / 4096) * USER_MOTOR_MAX_SPEED_KRPM);
            gMotorVars.SpeedRef_krpm = _IQ(vare);

            CTRL_setSpd_ref_krpm(ctrlHandle,gMotorVars.SpeedRef_krpm);

            gMotorVars.MaxAccel_krpmps = _IQ(2.0);

            // set the speed acceleration
            CTRL_setMaxAccel_pu(ctrlHandle,_IQmpy(MAX_ACCEL_KRPMPS_SF,gMotorVars.MaxAccel_krpmps));

            // enable the SpinTAC Speed Controller
            STVELCTL_setEnable(stObj->velCtlHandle, true);

            if(EST_getState(obj->estHandle) != EST_State_OnLine)
            {
            	// if the estimator is not running, place SpinTAC into reset
            	STVELCTL_setEnable(stObj->velCtlHandle, false);
            }
#endif


#ifdef TORQUE_MODE
            vare = (float) ( (float)((float)PotRef_krpm / 4096));
            vare *= USER_MOTOR_MAX_CURRENT;
            gMotorVars.IqRef_A = _IQ(vare);
#endif

            if(Flag_Latch_softwareUpdate)
            {
              Flag_Latch_softwareUpdate = false;

#ifdef FAST_ROM_V1p6
              if(CTRL_getFlag_enableUserMotorParams(ctrlHandle) == true)
              {
                  // call this function to fix 1p6
                  softwareUpdate1p6(ctrlHandle);
              }
#endif

              calcPIgains(ctrlHandle);
            }

          }
        else
          {
            Flag_Latch_softwareUpdate = true;

            // the estimator sets the maximum current slope during identification
            gMaxCurrentSlope = EST_getMaxCurrentSlope_pu(obj->estHandle);
          }


        // when appropriate, update the global variables
        if(gCounter_updateGlobals >= NUM_MAIN_TICKS_FOR_GLOBAL_VARIABLE_UPDATE)
          {
            // reset the counter
            gCounter_updateGlobals = 0;

            updateGlobalVariables_motor(ctrlHandle);
          }

      } // end of while(gFlag_enableSys) loop


    // disable the PWM
    DRV_disablePwm(drvHandle);

    // set the default controller parameters (Reset the control to re-identify the motor)
    CTRL_setParams(ctrlHandle,&gUserParams);
  //gMotorVars.Flag_Run_Identify = false;
#ifndef TORQUE_MODE
    // setup the SpinTAC Components
    ST_setupVelCtl(stHandle);
#endif
  } // end of for(;;) loop

} // end of main() function
//===================================================================================
//					RT service routine
//===================================================================================
interrupt void mainISR(void)
{

	static uint16_t stCnt = 0;

  // toggle status LED
  if(gLEDcnt++ > (uint_least32_t)(USER_PWM_FREQ_kHz * 1000 / LED_BLINK_FREQ_Hz)){
    DRV_toggleLed(drvHandle,(GPIO_Number_e)DRV_Gpio_LED2);
    gLEDcnt = 0;

  }

  if(StopPressed())
  {
	  Led10_OFF();
	  Led11_OFF();
      gMotorVars.Flag_enableSys = false;
  }

  // acknowledge the ADC interrupt
  DRV_acqAdcInt(drvHandle,ADC_IntNumber_1);


  // convert the ADC data
  DRV_readAdcData(drvHandle,&gAdcData);


#ifndef   	TORQUE_MODE

  // Run the SpinTAC Components
   if(stCnt++ >= ISR_TICKS_PER_SPINTAC_TICK) {
 	  ST_runVelCtl(stHandle, ctrlHandle);
 	  stCnt = 1;
   }

#endif


  // run the controller
  CTRL_run(ctrlHandle,drvHandle,&gAdcData,&gPwmData);


  // write the PWM compare values
  DRV_writePwmData(drvHandle,&gPwmData);


  // setup the controller
  CTRL_setup(ctrlHandle);


  return;
} // end of mainISR() function


void updateGlobalVariables_motor(CTRL_Handle handle)
{
  CTRL_Obj *obj = (CTRL_Obj *)handle;
  //**************************************************
  union
  {
    int32_t   long_value;
    float_t float_value;
  } interface;


#ifdef TORQUE_MODE
 
  _iq iq_ref = _IQmpy(gMotorVars.IqRef_A,_IQ(1.0/USER_MOTOR_MAX_CURRENT));

  // get the speed estimate
  gMotorVars.Speed_krpm = EST_getSpeed_krpm(obj->estHandle);


  // set the speed reference so that the forced angle rotates in the correct direction
  // for startup.
  if(_IQabs(gMotorVars.Speed_krpm) < _IQ(0.01))
  {
      if(iq_ref < 0)
          CTRL_setSpd_ref_krpm(handle,_IQ(-0.01));
      else if(iq_ref > 0)
          CTRL_setSpd_ref_krpm(handle,_IQ(0.01));
  }

  // Set the Iq reference that use to come out of the PI speed control
   TorqueRef = iq_ref;
   CTRL_setIq_ref_pu(handle, iq_ref);

#endif

  // get the speed estimate
  gMotorVars.Speed_krpm = EST_getSpeed_krpm(obj->estHandle);

  // get the torque estimate
  gMotorVars.Torque_lbin = EST_getTorque_lbin(obj->estHandle);

  // get the magnetizing current
  interface.long_value = EST_getIdRated(obj->estHandle);
  gMotorVars.MagnCurr_A = interface.float_value;

  // get the rotor resistance
  interface.long_value = EST_getRr_Ohm(obj->estHandle);
  gMotorVars.Rr_Ohm = interface.float_value;

  // get the stator resistance
  interface.long_value = EST_getRs_Ohm(obj->estHandle);
  gMotorVars.Rs_Ohm = interface.float_value;

  // get the stator inductance in the direct coordinate direction
  interface.long_value = EST_getLs_d_H(obj->estHandle);
  gMotorVars.Lsd_H = interface.float_value;

  // get the stator inductance in the quadrature coordinate direction
  interface.long_value = EST_getLs_q_H(obj->estHandle);
  gMotorVars.Lsq_H = interface.float_value;

  // get the flux
  interface.long_value = EST_getFlux_VpHz(obj->estHandle);
  gMotorVars.Flux_VpHz = interface.float_value;

  // get the controller state
  gMotorVars.CtrlState = CTRL_getState(handle);

  // get the estimator state
  gMotorVars.EstState = EST_getState(obj->estHandle);

  // enable/disable the forced angle
  EST_setFlag_enableForceAngle(obj->estHandle,gMotorVars.Flag_enableForceAngle);
  
  // enable or disable power warp
  CTRL_setFlag_enableEpl(handle,gMotorVars.Flag_enableEpl);

  // Get the DC buss voltage
  gMotorVars.VdcBus_kV = _IQmpy(gAdcData.dcBus,_IQ(USER_IQ_FULL_SCALE_VOLTAGE_V/1000.0));

#ifdef DRV8301_SPI
  DRV_8301_SpiInterface(drvHandle,&gDrvSpi8301Vars);
#endif

  return;
} // end of updateGlobalVariables_motor() function
//===========================================================================================
//
//===========================================================================================

#ifdef FAST_ROM_V1p6
void softwareUpdate1p6(CTRL_Handle handle)
{

  CTRL_Obj *obj = (CTRL_Obj *)handle;

  float_t fullScaleInductance = USER_IQ_FULL_SCALE_VOLTAGE_V/(USER_IQ_FULL_SCALE_CURRENT_A*USER_VOLTAGE_FILTER_POLE_rps);
  float_t Ls_coarse_max = _IQ30toF(EST_getLs_coarse_max_pu(obj->estHandle));
  int_least8_t lShift = ceil(log(obj->motorParams.Ls_d/(Ls_coarse_max*fullScaleInductance))/log(2.0));
  uint_least8_t Ls_qFmt = 30 - lShift;
  float_t L_max = fullScaleInductance * pow(2.0,lShift);
  _iq Ls_d_pu = _IQ30(obj->motorParams.Ls_d / L_max);
  _iq Ls_q_pu = _IQ30(obj->motorParams.Ls_q / L_max);


  // store the results
  EST_setLs_d_pu(obj->estHandle,Ls_d_pu);
  EST_setLs_q_pu(obj->estHandle,Ls_q_pu);
  EST_setLs_qFmt(obj->estHandle,Ls_qFmt);

  return;
} // end of softwareUpdate1p6() function
#endif

//===========================================================================================
//
//===========================================================================================
void calcPIgains(CTRL_Handle handle)
{
  CTRL_Obj *obj = (CTRL_Obj *)handle;
  float_t fullScaleCurrent = USER_IQ_FULL_SCALE_CURRENT_A;
  float_t fullScaleVoltage = USER_IQ_FULL_SCALE_VOLTAGE_V;
  float_t ctrlPeriod_sec = CTRL_getCtrlPeriod_sec(handle);
  float_t Ls_d;
  float_t Ls_q;
  float_t Rs;
  float_t RoverLs_d;
  float_t RoverLs_q;
  _iq Kp_Id;
  _iq Ki_Id;
  _iq Kp_Iq;
  _iq Ki_Iq;
  _iq Kd;
  union
  {
    int32_t   long_value;
    float_t float_value;
  } interface;

  interface.long_value = EST_getLs_d_H(obj->estHandle);
  Ls_d = interface.float_value;

  interface.long_value = EST_getLs_q_H(obj->estHandle);
  Ls_q = interface.float_value;

  interface.long_value = EST_getRs_Ohm(obj->estHandle);
  Rs = interface.float_value;

  RoverLs_d = Rs/Ls_d;
  Kp_Id = _IQ(Kp_Scale * (0.25*Ls_d*fullScaleCurrent)/(ctrlPeriod_sec*fullScaleVoltage));
  Ki_Id = _IQ(RoverLs_d*ctrlPeriod_sec);

  RoverLs_q = Rs/Ls_q;
  Kp_Iq = _IQ(Kp_Scale * (0.25*Ls_q*fullScaleCurrent)/(ctrlPeriod_sec*fullScaleVoltage));
  Ki_Iq = _IQ(RoverLs_q*ctrlPeriod_sec);

  Kd = _IQ(0.0);

  // set the Id controller gains
  PID_setKi(obj->pidHandle_Id,Ki_Id);
  CTRL_setGains(handle,CTRL_Type_PID_Id,Kp_Id,Ki_Id,Kd);

  // set the Iq controller gains
  PID_setKi(obj->pidHandle_Iq,Ki_Iq);
  CTRL_setGains(handle,CTRL_Type_PID_Iq,Kp_Iq,Ki_Iq,Kd);

  return;
} // end of calcPIgains() function
//@} //defgroup
// end of file
//===========================================================================================
//
//===========================================================================================

void ST_runVelCtl(ST_Handle sthandle, CTRL_Handle handle)
{

    _iq speedFeedback, iqReference;
    ST_Obj *stObj = (ST_Obj *)sthandle;
    CTRL_Obj *ctrlObj = (CTRL_Obj *)handle;

    // Get the mechanical speed in pu
    speedFeedback = EST_getFm_pu(ctrlObj->estHandle);

	// Run the SpinTAC Controller
	// Note that the library internal ramp generator is used to set the speed reference
    STVELCTL_setVelocityReference(stObj->velCtlHandle, TRAJ_getIntValue(ctrlObj->trajHandle_spd));
	STVELCTL_setAccelerationReference(stObj->velCtlHandle, _IQ(0.0));	// Internal ramp generator does not provide Acceleration Reference
	STVELCTL_setVelocityFeedback(stObj->velCtlHandle, speedFeedback);
	STVELCTL_run(stObj->velCtlHandle);

	// select SpinTAC Velocity Controller
	iqReference = STVELCTL_getTorqueReference(stObj->velCtlHandle);

	// Set the Iq reference that came out of SpinTAC Velocity Control
	TorqueRef = iqReference;																	// just for external monitoring
	CTRL_setIq_ref_pu(ctrlHandle, iqReference);
}
//@} //defgroup
// end of file




Thanks in advance

  • Hello Angelo,

    I am not expert. But while waiting the expert to reply you, I will try to help.

    I guess you have read spruhj1 (the user guide for InstaSPIN-FOC and InstaSPIN-MOTION).

    http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=spruhj1&fileType=pdf

    If not yet, I suggest you to read this document and you can find the explanation about the APIs in chapter 3.

    CTRL_setFlag_enableSpeedCtrl is for enabling speed control mode (true) or enabling torque control mode (false).

    EST_isMotorIdentified is the one you need to check whether the motor is identified or not.

    I don't know why CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false); in your code doesn't work.

    Can you explain more detail, what you mean by torque mode works fine and does not work? (I mean, how you know it works fine and how you know it doesn't work?)

    And let's wait the expert to comment about this.

    Best regards,

    Maria

  • Hello again,

    As I understand by reading your code, you tried to combine lab 4 (torque control) and lab 5d (SpinTAC Velocity Control) from Motorware projects, but I don't understand why in your updateGlobalVariables_motor(), you didn't use the one in lab 5d (missing some updates for SpinTAC variables, for example: gMotorVars.SpinTAC.VelCtlStatus,  gMotorVars.SpinTAC.Inertia_Aperkrpm, etc).

    Have you tried lab 4 and success?

    Have you tried lab 5d and success?

    Also, in your updateGlobalVariables_motor(), you used:

     _iq iq_ref = _IQmpy(gMotorVars.IqRef_A,_IQ(1.0/USER_MOTOR_MAX_CURRENT));

    instead of:

    _iq iq_ref = _IQmpy(gMotorVars.IqRef_A,_IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)); (this is the one in lab 4)

    What value do you put in USER_MOTOR_MAX_CURRENT and USER_IQ_FULL_SCALE_CURRENT_A?

    You should check these values.

    Best regards,

    Maria

  • Hello Maria,

    If CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false) is present in my code motor identification cycle fails to calculate Ls_q and Ls_d. If I comment this line, torque mode behaves erratically probably because Iq remains connected to the output of the unused speed controller. In this case rotor has some torque but it doesn't respond to any input changes and it doesn't spin.

    Best regards

    Angelo

  • And, if you change:

     _iq iq_ref = _IQmpy(gMotorVars.IqRef_A,_IQ(1.0/USER_MOTOR_MAX_CURRENT));

    to be:

    _iq iq_ref = _IQmpy(gMotorVars.IqRef_A,_IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)); (this is the one in lab 4)

    What is the result?

    Best regards,

    Maria

  • Angelo,

    You can't disable speed mode and then identify.  The identification process uses a full FOC system (including a speed controller feeding the torque control system) to run through the ID states.

    You need to set-up your system logic in a way that is more structured.  You should be able to follow our labs as this is very similar to how we have already done things.

    Initialize everything.
    Take some system input to enable the system.
    gMotorVars.Flag_enableSys


    Take some system input to decide if you are loading from stored values or identifying
    CTRL_setFlag_enableUserMotorParams(ctrlHandle,gMotorVars.Flag_enableUserParams);

    Load from user.h or go through the ID process. Success on either of these will set the flag which you can check:
    EST_isMotorIdentified(obj->estHandle)

    If you loaded from user.h and are using FASTv1p6 (F2806x) make sure that you run
    softwareUpdate1p6(ctrlHandle)

    Then take some system input to check on which mode you should be running in Torque or Speed mode.
    If Torque, follow proj_lab5b where you do the following key actions:
    CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false);
     _iq iq_ref = _IQmpy(gMotorVars.IqRef_A,_IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A));

      if(_IQabs(gMotorVars.Speed_krpm) < _IQ(0.01))
      {
          if(iq_ref < 0)
              CTRL_setSpd_ref_krpm(handle,_IQ(-0.01));
          else if(iq_ref > 0)
              CTRL_setSpd_ref_krpm(handle,_IQ(0.01));
      }

      // Set the Iq reference that use to come out of the PI speed control
      CTRL_setIq_ref_pu(handle, iq_ref);