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.

CCS/LAUNCHXL-F28069M: Problem integrating an absolute encoder with InstaSpin Motion

Part Number: LAUNCHXL-F28069M
Other Parts Discussed in Thread: MOTORWARE

Tool/software: Code Composer Studio

Hi, I'm having trouble to integrate an absolute encoder with my InstaSpin development board.

I have done all motorware labs and sucessfuly had a ABI encoder to run my motor. I'm running lab 12b (sensored speed control).

My problem is very simmilar to this thread: https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/663317

I mannaged to receive the encoder signal via SPI (20 bits) and already done the "interpolation" to 24bits (_iq24). Now I have a position variable that tells me exactly what is my mechanical angle.

I'm trying to replace the QEP module with my own.

This is the code to get the electrical angle:

void incoderGetElecAngle(){
     uint32_t temp = incAbsPos; //mech angle
     temp += incMechOffset;
     temp *= USER_MOTOR_NUM_POLE_PAIRS;
     elecAngle = (_iq24)(temp & 0x00ffffff);
}

incAbsPos is a global variable that is updated by the SPI readings, incMechOffset is a variable that is, for now, zero. My encoder has a option to set the zero. I power the motor to align it and reset the zero in the encoder.
elecAngle is the output, saved in a global.

I can turn the motor and feel the 21 pole pairs swithcing and the electrical angle correctly apearing in the debug (I did a graphing for absolute and electrical angle and they are perfectly in sync, I can see 21 cycles for electrical for 1 cycle of mechanical).

In mainISR, this is my code:

interrupt void mainISR(void)
{
  static uint16_t stCnt = 0;
  CTRL_Obj *obj = (CTRL_Obj *)ctrlHandle;

  //Do SPI reading of encoder and refresh the global variable(incoder is a brand)
  SPI_ReadIncoder();

  // convert the ADC data
  HAL_readAdcData(halHandle,&gAdcData);


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

   CTRL_run(ctrlHandle,halHandle,&gAdcData,&gPwmData, elecAngle);
  // write the PWM compare values
  HAL_writePwmData(halHandle,&gPwmData);


  // setup the controller
  CTRL_setup(ctrlHandle);

  // if we are forcing alignment, using the Rs Recalculation, align the eQEP angle with the rotor angle

    if((EST_getState(obj->estHandle) == EST_State_Rs) && (USER_MOTOR_TYPE == MOTOR_Type_Pm))
    {
        incMechOffset = incMaxPos - incAbsPos; // same as the QEP, bur here "incAbsPos" is already a mechanical angle,so no need to gain
    }
  HAL_acqAdcInt(halHandle,ADC_IntNumber_1);
  return;
} // end of mainISR() function

and here is my ST_runPosConv code:7

void ST_runPosConv(ST_Handle handle, ENC_Handle encHandle, CTRL_Handle ctrlHandle)
{
	ST_Obj *stObj = (ST_Obj *)handle;

#ifdef INCODERELECANGLE  //if defined, gets encoder elec angle
	STPOSCONV_setElecAngle_erev(stObj->posConvHandle, elecAngle);
#else
	// get the electrical angle from the ENC module
	STPOSCONV_setElecAngle_erev(stObj->posConvHandle, ENC_getElecAngle(encHandle));
#endif

	/*
    if(USER_MOTOR_TYPE ==  MOTOR_Type_Induction) {
      // The CurrentVector feedback is only needed for ACIM
      // get the vector of the direct/quadrature current input vector values from CTRL
      STPOSCONV_setCurrentVector(stObj->posConvHandle, CTRL_getIdq_in_addr(ctrlHandle));
    }
    */

	// run the SpinTAC Position Converter
	STPOSCONV_run(stObj->posConvHandle);
	/*
	if(USER_MOTOR_TYPE ==  MOTOR_Type_Induction) {
	  // The Slip Velocity is only needed for ACIM
	  // update the slip velocity in electrical angle per second, Q24
	  SLIP_setSlipVelocity(slipHandle, STPOSCONV_getSlipVelocity(stObj->posConvHandle));
	}
	*/
}




I tested both with or without the "force alignment" routine, no matter what I do, change polarities, realign the encoder, I cannot put the motor to spin.

I'm I missing something?

Sory for my poor english.

Much thanks in advance.






  • 1. You need to convert the output of the absolute encoder to PU format and replace the"enc_elec_angle" in "enc" object.

    2. You might run lab05c and lab05d to verify the angle from the absolute encoder compare to the angle from the FAST estimator. Use the PWMDAC or Datalog as lab01b or lab01c to check these two angles.

  • I was able to put the motor to spin correctly by changing this line of code in updateGlobalVariables_motor:

    from:

      gMotorVars.SpeedQEP_krpm = _IQmpy(STPOSCONV_getVelocityFiltered(stObj->posConvHandle), _IQ(ST_SPEED_KRPM_PER_PU));

    to:

    gMotorVars.SpeedQEP_krpm = STPOSCONV_getVelocityFiltered(stObj->posConvHandle);

    I'm not using the ENC module (my encoder is absolute via SPI). It seems that spinTac uses this variable to control the speed of the motor, not only the "speedfeedback" variable in "ST_runVelCtl", for some weird reason. In my mind, only in the velocity control loop it was suposed to get speed feedback, but for some reason, the internal controller uses this gmotorVars too. Removing this scale factor solved the problem.

    What I understood from spinTac Velocity control is that it regulates the torque output periodically to achieve a determined speed. In my understanding, the speed variable should be updated each ISR tick, not in the forever loop (much more slow).

    I'm having issues in response time for a gimbal system. The idea is to put the Gyro in the platform, measure the platform speed and command the motor to counteract to make the attached payload steady. It works really well in low frequencies (below 3hz), and it keeps really good with steady rotation, but when I increase the shake speed, the systems presents a delay to counteract, even though accel is at maximum (127 krpm/s2). I'm really trying to understand why this lag is ocurring, my gess is that the "updateGlobalVariables_motor" being called in forever loop is the culprit. The gyro gives the system speed info via SCI.

    I made a simple PD torque controller  and put the gyro directly in the axis, and skipped the Spintac Velocity torque controller. The response was really good, the motor is stabilizing the payload but is not so good at low frequencies, because of the direct approach. My own torque controller should be worse than LineStream's, but for some reason, it's performing way better. This confirmed that the FOC can change torque really quickly, and the bottleneck is in Spintac Velocity anywhere.

    Is there a way to disable speed ramp? I would like to go to the comanded speed ASAP.

    Please note that prior to this SPI encoder, I used a QEP encoder and the result was the same, concerning the lag.

    Trying the direct approach (gyro in the axis) with spintac velocity counter actuating was not so good wither.

    1) I would like to use Spintac velocity control to do a indirect approach but this delay is not helping, any ideas why?

    2) What this specific line of code does?

      // get the real time speed reference coming out of the speed trajectory generator
      gMotorVars.SpeedTraj_krpm = _IQmpy(CTRL_getSpd_int_ref_pu(handle),EST_get_pu_to_krpm_sf(obj->estHandle));

    It seems that the speed from the trakectory is comming from the CTRL moduling, scaled by a estimator constant. Why?

    Thanks to the patience.

  • All information about InstaSPIN-motion and SpinTAC you could find in the user's guide. Except that, we can't provide more answers to the questions on InstaSPIN-motion, you have to resolve the related problems by yourself if you significantly changed the lab code.

    InstaSPIN-FOC and InstaSPIN-MOTION User's Guide (Rev. H)

    http://www.ti.com/lit/ug/spruhj1h/spruhj1h.pdf

    You can set a higher acceleration to get the target speed without disabling the trajectory ramp control.

    2). Yes, all variables of speed and current are using the PU with IQ format, the code converts the PU value to krpm.