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.

Speed measurement computation

Other Parts Discussed in Thread: CONTROLSUITE

Hello everyone,

 

I'm using a TMS320 microcontroller, with a PMSM motor, using a FOC control with TI functions. Sometimes, when my motor is at the beginning of movement, the system is a little bit unstable.

I found where the problem is, but I don’t know the reason. I explain step by step:

 

1-. When the motor stops, the currents PID, pid1_iq&pid1_id are quiet (obviously because the set values are 0), but the speed PID is changing (pid1_spd:Ui, Up, Saterr,…).

2.- Following the origin, I finish into the Speed measurement computation (see below)

void speed_frq_calc(SPEED_MEAS_QEP *v)   

{   

  _iq Tmp1;   

// Differentiator     

 // Synchronous speed computation      

if ((v->ElecTheta < _IQ(0.9))&(v->ElecTheta > _IQ(0.1)))   

      // Q21 = Q21*(GLOBAL_Q-GLOBAL_Q)   

 Tmp1 = _IQmpy(v->K1,(v->ElecTheta - v->OldElecTheta));   

else Tmp1 = _IQtoIQ21(v->Speed);   

 // Low-pass filter    

  // Q21 = GLOBAL_Q*Q21 + GLOBAL_Q*Q21   

  Tmp1 = _IQmpy(v->K2,_IQtoIQ21(v->Speed))+_IQmpy(v->K3,Tmp1);     

 if (Tmp1>_IQ21(1))   

  v->Speed = _IQ(1);   

 elseif (Tmp1<_IQ21(-1))   

 v->Speed = _IQ(-1);         

 else

v->Speed = _IQ21toIQ(Tmp1);   

.// Update the electrical angle   

 v->OldElecTheta = v->ElecTheta;   

// Change motor speed from pu value to rpm value (GLOBAL_Q -> Q0)   

// Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q   

 v->SpeedRpm = _IQmpy(v->BaseRpm,v->Speed);    

Why this is happening? Why the result is different if ElecTheta is between _IQ(0.9) and _IQ(0.1?) 

As the encoder angle is 0 à ElecTheta is 0 à Tmp1= _IQtoIQ21(v->Speed); à tmp1  increases à v-speed  increases à tmp1  increases…so the speed PID is in a loop

 

What happens? When I give the order to start to move, my system is unstable. But If  I wait some seconds, the pid1_spd values stop to change, and everything work fine.

 

What is wrong? Maybe I need to reset the speed just before the movement order…I don’t know.

Thank you in advance. No doubt in ask me for more details.

  • Hi Masky,

    We will notify our expert of your question. He should respond soon.

  • May be you could reset the speed feedback until the start command. In any case, there is a bug in the feedback estimation. Replace the first few lines with a code as below

    /* Synchronous speed computation */

    Tmp1 = v->ElecTheta  -  v->OldElecTheta;

    if (Tmp1 < -_IQ(0.5))

       Tmp1 = Tmp1 + _IQ(1.0);

    else if (Tmp1 > _IQ(0.5))

       Tmp1 = Tmp1 -  _IQ(1.0);

    Tmp1 = _IQmpy(v->K1, Tmp1);

    /* Low-pass filter */

    /* Q21 = GLOBAL_Q*Q21 + GLOBAL_Q*Q21 */

     

    This will unconditionally use all angle ranges to estimate speed.

     

    BR,

    Ramesh

  • So the function would as follow? 

    void speed_frq_calc(SPEED_MEAS_QEP *v)

    {

    _iq Tmp1;

    /* Synchronous speed computation */
    Tmp1 = v->ElecTheta - v->OldElecTheta;
    if (Tmp1 < -_IQ(0.5))
            Tmp1 = Tmp1 + _IQ(1.0);
    else if (Tmp1 > _IQ(0.5))
            Tmp1 = Tmp1 - _IQ(1.0);


    Tmp1 = _IQmpy(v->K1, Tmp1);
    /* Low-pass filter */
    /* Q21 = GLOBAL_Q*Q21 + GLOBAL_Q*Q21 */

    if (Tmp1>_IQ21(1))
          v->Speed = _IQ(1);
    else if (Tmp1<_IQ21(-1))
          v->Speed = _IQ(-1);
    else
          v->Speed = _IQ21toIQ(Tmp1);

    // Update the electrical angle
    v->OldElecTheta = v->ElecTheta;

    // Change motor speed from pu value to rpm value (GLOBAL_Q -> Q0)
    // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
    v->SpeedRpm = _IQmpy(v->BaseRpm,v->Speed);

    }

     

    Because my system doesn't work with the las modification. In order to clarify, I copy the values for K1,K2,K3:

    veloc1.K1 = _IQ21(1/(50*000083333));

    veloc1.K2 = _IQ(1/(1+000083333*2*PI*1)); // Low-pass cut-off frequency

    veloc1.K3 = _IQ(000083333*2*PI*1/(1+000083333*2*PI*1));

    Thank you in advance.

     

  • Hi,

    At this point, it is difficult  for us to figure out what the problem is. You may have to try it out loop by loop I guess.

     

    rgds,

    ramesh

  • hello,i meet the same question,i don't know about this code :

    if ((v->ElecTheta < _IQ(0.9))&(v->ElecTheta > _IQ(0.1)))   

          // Q21 = Q21*(GLOBAL_Q-GLOBAL_Q)   

     Tmp1 = _IQmpy(v->K1,(v->ElecTheta - v->OldElecTheta));   

    else Tmp1 = _IQtoIQ21(v->Speed);   

    if you use this,why don't you  use absolute value of the difference?

    i'm wriet the same code ,could you help me to solve this problem?

    thx

    alex

  • Hello,

    This has already been addressed. Update the include options to refer to library files available at

    C:\ti\controlSUITE\libs\app_libs\motor_control\math_blocks\v4.3

    rgds,

    ramesh