Hello,
I have the following problem: We have a custom hardware based on the F28069 CPU. Our software
uses InstaSPIN Foc and InstaSPIN motion to control the BLDC motor. Everything is set up and
works as it should be.
But very rarely it happens that during the motor identification the motor accelerates up to a
point where it gets dangerous and we have to switch off the whole system. I have no idea what
is the cause for this behaviour, but I believe it is a software problem.
The software is based on motorware 12 / proj_lab12. We use an encoder as feedback for the motor
angle.
Also we are using SysBios in our application. That's why I had to refactor the code of proj_lab12,
because in SysBios I do not have any main loop. As far as I know there is no example available
showing how to use the motorware within SysBios, right?
My Software is build up as follows:
- I have a background task, that switches on/off the motor PWM depending on the state of the controller:
void motorTaskFxn(UArg a0, UArg a1) { for(;;) { if(CTRL_isError(ctrlHandle)) { // set the enable controller flag to false CTRL_setFlag_enableCtrl(ctrlHandle,false); // disable the PWM HAL_disablePwm(halHandle); } else { // update the controller state bool flag_ctrlStateChanged = CTRL_updateState(ctrlHandle); if(flag_ctrlStateChanged) { CTRL_State_e ctrlState = CTRL_getState(ctrlHandle); if(ctrlState == CTRL_State_OffLine) { // enable the PWM HAL_enablePwm(halHandle); } else if(ctrlState == CTRL_State_OnLine) { HAL_updateAdcBias(halHandle); // enable the PWM HAL_enablePwm(halHandle); } else if(ctrlState == CTRL_State_Idle) { // disable the PWM HAL_disablePwm(halHandle); } #ifdef FAST_ROM_V1p6 if ((CTRL_getFlag_enableUserMotorParams(ctrlHandle) == true) && (ctrlState > CTRL_State_Idle)) { // call this function to fix 1p6 USER_softwareUpdate1p6(ctrlHandle); } #endif } } updateGlobalVariables_motor(ctrlHandle, stHandle); // sleep for some time (10ms) Task_sleep(MOTOR_TASK_SLEEP_TIME); } }
- Then I have a task that starts the motor identification and steps through each state. The whole process is started with the following function:
static void setupController() { // set the default controller parameters (Reset the control to re-identify the motor) CTRL_setParams(ctrlHandle,&gUserParams); // setup the SpinTAC Components ST_setupVelCtl(stHandle); ST_setupPosConv(stHandle); // Dis-able the Library internal PI. Iq has no reference now CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false); // enable/disable the use of motor parameters being loaded from user.h CTRL_setFlag_enableUserMotorParams(ctrlHandle, true); // enable/disable Rs recalibration during motor startup EST_setFlag_enableRsRecalc(((CTRL_Obj *)ctrlHandle)->estHandle, true); // enable/disable automatic calculation of bias values CTRL_setFlag_enableOffset(ctrlHandle, true); // enable or disable the control CTRL_setFlag_enableCtrl(ctrlHandle, true); }
- The statemachine is called every 1ms and the steps during motor identification are:
switch (m_nCurrState) { case PREPARE_MOTOR_START: { if (EST_isMotorIdentified(obj->estHandle)) { // set the speed acceleration CTRL_setMaxAccel_pu(ctrlHandle,_IQmpy(MAX_ACCEL_KRPMPS_SF, _IQ(1.0))); USER_calcPIgains(ctrlHandle); // initialize the watch window Bw value with the default value velCtlBwScale = STVELCTL_getBandwidthScale(stObj->velCtlHandle); // initialize the watch window with maximum and minimum Iq reference velCtlOutputMax_A = _IQmpy(STVELCTL_getOutputMaximum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A)); velCtlOutputMin_A = _IQmpy(STVELCTL_getOutputMinimum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A)); // wait until estimator and controller is online m_nCurrState = PREPARE_MOTOR_ONLINE; } break; } case PREPARE_MOTOR_ONLINE: { CTRL_State_e ctrlState = CTRL_getState(ctrlHandle); EST_State_e estState = EST_getState(obj->estHandle); // set the SpinTAC (ST) bandwidth scale STVELCTL_setBandwidthScale(stObj->velCtlHandle, velCtlBwScale); // set the maximum and minimum values for Iq reference STVELCTL_setOutputMaximums(stObj->velCtlHandle, _IQmpy(velCtlOutputMax_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)), _IQmpy(velCtlOutputMin_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A))); // enable/disable the forced angle EST_setFlag_enableForceAngle(obj->estHandle, false); if (ctrlState == CTRL_State_OnLine && estState == EST_State_OnLine) { // enable the SpinTAC Speed Controller STVELCTL_setEnable(stObj->velCtlHandle, true); // motor is ready to use
m_nCurrState = PREPARE_FINISH; } break; }
This is really a serious problem for us, as I don't know what is the reason and how to provoke it. So does someone has an idea what can be the cause for this behaviour. Or maybe I did something wrong when using SysBios here?
Sebastian