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.

DRV8312-C2-KIT: SpeedLoopFlag

Part Number: DRV8312-C2-KIT

Hey there,

I am working with the kit mentioned above and the "InstaSPIN_BLDC_GUI"-project.

I know the SpeedLoopFlag shows if the calculation of speed is finished and enables the speed-controller.
But I have a question about setting the flag:
When the SPEED_PR_MACRO is called the first time, with the code printed below, it gets the actual timestamp.

//while counting up we want positive speed
     if((mod_dir1.Counter==5)&&(PreviousState==4)&&(mod_dir1.TrigInput))
     {
      speed1.TimeStamp = VirtualTimer;
      SPEED_PR_MACRO(speed1);
      SpeedLoopFlag = TRUE;
     }
     //while counting down we want negative speed
     else if((mod_dir1.Counter==0)&&(PreviousState==1)&&(mod_dir1.TrigInput))
     {
      speed1.TimeStamp = VirtualTimer;
      SPEED_PR_MACRO(speed1);
      speed1.Speed = _IQmpy(speed1.Speed,_IQ(-1.0));
      speed1.SpeedRpm = _IQmpy(speed1.SpeedRpm,_IQ(-1.0));
      SpeedLoopFlag = TRUE;
     }

Now inside SPEED_PR_MACRO, code is again printed below:
The OldTimeStamp gets the initialization value of the NewTimeStamp, which means 0. The NewTimeStamp gets the value of the actual timestamp.
Now the EvenPeriod is caluclated by substraction.

#define SPEED_PR_MACRO(v)        \
   if (v.InputSelect == 0)        \
   {           \
     v.OldTimeStamp = v.NewTimeStamp;       \
     v.NewTimeStamp = v.TimeStamp;       \
     v.EventPeriod = v.NewTimeStamp - v.OldTimeStamp;     \
           \
       if (v.EventPeriod < 0)        \
        v.EventPeriod += 32767;   /* 0x7FFF = 32767*/    \
    }           \
           \
     v.Speed = _IQdiv(v.SpeedScaler,v.EventPeriod);     \
                 \
/* Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q*/     \
   v.SpeedRpm = _IQmpy(v.BaseRpm,v.Speed);      \
#endif // __SPEED_PR_H__

And here I see the problem: The EventPeriod has no relation to te motor speed, when it is called the first time.
Later on, OldTimeStamp and NewTimeStamp are displaying the time the motor needs for one revolution.
This is ensured by calling the macro and creating timestamps after every revolution.
Therefore EventPeriod is calculated right from second calling of SPEED_PR_MACRO.
But when calling the first time, the EventPeriod ist just the actual value of vitual timer, which has nothing to do with motor speed.
It is a wrong value for controller.
This is why I thought the SpeedLoopFlag only should be set after second execution of PEED_PR_MACRO.

Can you please explain me the contradiction?

Thanks in advance,
Sarah

  • The "SpeedLoopFlag" is only for debugging, and it will be set manually for switching from the startup ramp open loop to closed commutation mode.

    For instaSPIN-BLDC GUI, the control algorithm will check if there are enough commutation matches to switch to closed commutation mode and set "ClosedCommutationFlag" to 1.

    The codes you mentioned that don't need "SpeedLoopFlag" and will be executed always if the judgment conditions are met.
  • Hey,

    I think you are would like to say the following:

    The motor startup needs more than one cycle of MainISR to get finished and in the following the ClosedCommutationFlag only is set after a few executions of MainISR.
    So the SPEED_PR_MACRO is called more than one time, before the ClosedCommutationFlag is set.
    The pid speed controller is enabled by ClosedCommutationFlag AND SpeedLoopFlag.
    And this means the pid speed controller is not called before the SPEED_PR_MACRO was called more than one time.
    Therefore the reference value is correct, when the controller is enabled.

    case CASCADE:
         SpeedRef = Gui.Ref;
         // ------------------------------------------------------------------------------
         //    Connect inputs of the PID_REG3 module and call the PID current controller
         //   macro.
         // ------------------------------------------------------------------------------
         if((ClosedCommutationFlag == 0) || (SpeedLoopFlag == FALSE))
         {
               pid1_idc.term.Ref = _IQmpy(Gui.CurrentStartup,mod_dir1.CntDirection);
         }
         else
         {
          // ------------------------------------------------------------------------------
          //    Connect inputs of the PID_REG3 module and call the PID speed controller
          //   macro.
          // ------------------------------------------------------------------------------
               pid1_spd.term.Ref = SpeedRef;
               pid1_spd.term.Fbk = speed1.Speed;
               PID_GR_MACRO(pid1_spd)
     
               pid1_idc.term.Ref = pid1_spd.term.Out;
         }
         pid1_idc.term.Fbk = _IQmpy(IDCfdbk,mod_dir1.CntDirection);
         PID_GR_MACRO(pid1_idc)
         // ------------------------------------------------------------------------------
         //    Connect inputs of the PWM_DRV module and call the PWM signal generation
         //    update macro.
         // ------------------------------------------------------------------------------
         pwmcntl1.State = (int16)mod_dir1.Counter;
         pwmcntl1.Duty = pid1_idc.term.Out;
         PWM_CNTL_MACRO(pwmcntl1)
         break;

    Could you please confirm or deny?

    Thanks,
    Sarah

  • Hey,

    I think you would like to say the following:

    The motor startup needs more than one cycle of MainISR to get finished and in the following the ClosedCommutationFlag only is set after a few executions of MainISR.
    So the SPEED_PR_MACRO is called more than one time, before the ClosedCommutationFlag is set.
    The pid speed controller is enabled by ClosedCommutationFlag AND SpeedLoopFlag.
    And this means the pid speed controller is not called before the SPEED_PR_MACRO was called more than one time.
    Therefore the reference value is correct, when the controller is enabled.

    case CASCADE:
             			SpeedRef = Gui.Ref;
        				// ------------------------------------------------------------------------------
        				//    Connect inputs of the PID_REG3 module and call the PID current controller
        				//	  macro.
        				// ------------------------------------------------------------------------------
              			if((ClosedCommutationFlag == 0) || (SpeedLoopFlag == FALSE))
        				{
              				pid1_idc.term.Ref = _IQmpy(Gui.CurrentStartup,mod_dir1.CntDirection);
        				}
        				else
        				{
        					// ------------------------------------------------------------------------------
        					//    Connect inputs of the PID_REG3 module and call the PID speed controller
        					//	  macro.
        					// ------------------------------------------------------------------------------
              				pid1_spd.term.Ref = SpeedRef;
              				pid1_spd.term.Fbk = speed1.Speed;
              				PID_GR_MACRO(pid1_spd)
    
              				pid1_idc.term.Ref = pid1_spd.term.Out;
        				}

    Could you please confirm or deny?

    Thanks,

    Sarah

  • As replied to you and the codes you saw, the SPEED_PR_MACRO is called and executed always if a correct commutation is got. The ClosedCommutationFlag or SpeedLoopFlag is used to select which value will be set to the PWM duty or reference current that depends on control mode, and both flags will be set by manual or the open loop running finish.

    You might go through the whole guide and source that could help you to understand this control logic easily.
  • Hey,

    Everything of what you are writing (dated May 4) is clear to me and I had tried to write the same in other words before.

    I bascially understand how the speed calculation works (because I have read and thought through the code and its documentation for many weeks now).

    The question is just for first calling, where the value of speed calculation is incorrect.

    Question was: Why is the first and incorrect value of speed calculation given to the pid speed controller?

    My assumption (dated May 2) was, that it is not given to the pid speed controller, because of motor startup and ClosedCommutationFlag.

    Thanks in advance,

    Sarah

  • As you looked at the code, the feedback is not used in the force run phase (open loop) and the speed controller is not enabled since the "ClosedCommutationFlag" is not set if you are using "VELOCITY" mode.
    Btw, the incorrect speed only appears in the first or second commutation steps, will get the right feedback value in the following steps.