Other Parts Discussed in Thread: DRV8305
I am using Launchpad 28069M + EVM DRV8305 to control a outer-rotor PMSM with InstaSPIN FOC. Now I add a 3600P/R incremental encoder to read the speed and position information based on the example of lab11a. The documents of enc.c, enc.h, qep.c and qep.h are got from lab 12b without any modification.
To read the speed, I follow the previous answers.
In main void, the ENC is initialized and setted up;
// initialize the ENC module encHandle = ENC_init(&enc, sizeof(enc)); // setup the ENC module ENC_setup(encHandle, USER_ENC_SAMPLE_PERIOD, USER_MOTOR_NUM_POLE_PAIRS, USER_MOTOR_ENCODER_LINES, 0, USER_IQ_FULL_SCALE_FREQ_Hz, USER_ISR_FREQ_Hz, 8000.0);
In hal.h, two functions are added.
//! \brief Return the index info from the QEP module
//! \param[in] encHandle Handle to the ENC object
//! \return The flag that indicate the index of encoder (true or false)
static inline uint16_t HAL_getQepIndex(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *)handle;
return (uint16_t)((QEP_QEPSTS_FIMF & QEP_read_status(obj->qepHandle[0]))>>1);
}
//! \brief Return the direction info from the QEP module
//! \param[in] encHandle Handle to the ENC object
//! \return The flag that indicate the direction of rotation (true for negative direction or false for positive direction)
static inline uint16_t HAL_getQepDirection(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *)handle;
return (uint16_t)((QEP_QEPSTS_QDF&QEP_read_status(obj->qepHandle[0]))>>5);
}
The result from ENC_getSpeedRPM has a same number with the FAST speed feedback, but it is always positive. Hence, I add these in MainISR
// run the ENC module ENC_run(encHandle, HAL_getQepPosnCounts(halHandle), HAL_getQepIndex(halHandle), HAL_getQepDirection(halHandle), true); //get speed from ENC dirFlag = HAL_getQepDirection(halHandle); if(dirFlag==1) ENCSPEEDRPM = - ENC_getSpeedRPM(encHandle); if(dirFlag==0) ENCSPEEDRPM = ENC_getSpeedRPM(encHandle);
Is it correct way to solve the problem?
Second, I also want to get the position. Therefore, in MainISR, I read the Position Counter (QPOSCNT) Register and try to find how many resolutions have been done.
//write at the beginning of proj_lab11a.c
_iq MechPosCount;
float MechanicalPos = 0;
//in MainISR
uint16_t dirFlag;
_iq PosCount_delta = 0;
_iq MechPosCount_z1 = 0;
MechPosCount = HAL_getQepPosnCounts(halHandle);
//calculate position in revolution
MechanicalPos= MechPosCount/(USER_MOTOR_ENCODER_LINES*4);
PosCount_delta = MechPosCount - MechPosCount_z1;
if ((dirFlag == 0) && (PosCount_delta < 0))
{
MechanicalPos = MechanicalPos + 1;
}
else if ((dirFlag == 1) && (PosCount_delta > 0))
{
MechanicalPos = MechanicalPos - 1;
}
MechPosCount_z1 = MechPosCount;
But the value of MechanicalPos is random. Even the motor speed reference is set to 0, that is, the motor doesn't rotate, the value of MechanicalPos is still changing randomly.
What is wrong with my method?