2021-03-11 06:48 AM
Hi,
i would like use the speed mode FW with modbus, it is possible? For to do this i should change the source code or i can put the parameter (rpm) in a specific register?
@Enrico Poli
Solved! Go to Solution.
2021-03-11 07:37 AM
Hi @DBrag.1
For obtaining this operation mode you need to follow few steps:
This is more or less the same procedure described in the User Manual of the software for software customization.
Now you need to map somehow the MODBUS API with the MotorControl API. This is performed in two files:
In the mb_api.c you could add the following functions converting holding registers' content into parameters for the speed command:
// Read target speed (rpm) from Holding Reg #0
int16_t getFinalSpeed()
{
return (int16_t)usRegHoldingBuf[0];
}
//Read speed ramp duration (ms) from Holding Reg #2
uint16_t getRampDuration_ms()
{
return usRegHoldingBuf[2];
}
In the main.c you should remove the code managing the position initialization:
setZeroReached(0); // Slave indicate that the alignment is not completed
LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-on LED
MC_StartMotor1();
while(MC_GetAlignmentStatusMotor1() != TC_ALIGNMENT_COMPLETED)
{
if (MC_GetOccurredFaultsMotor1() != 0)
{
MC_AcknowledgeFaultMotor1();
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-off LED
HAL_Delay(500);
MC_StartMotor1();
LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-on LED
HAL_Delay(500);
}
} // PAUSE THE MAIN LOOP UNTIL THE ENCODER IS ALIGNED
HAL_Delay(100);
setZeroReached(1);
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-off LED
and modify the state machine as following:
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (MC_GetOccurredFaultsMotor1() != 0)
{
LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-on LED
setMovementCompleted(1); // Slave indicate that the movement is aborted
clearCommand();
MC_AcknowledgeFaultMotor1();
comState = idle;
}
else
{
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-off LED
}
switch (comState) {
case idle:
{
if(getNewCommand()) // If new command arrived
{
int16_t speed = getFinalSpeed();
if (speed == 0)
{
MC_StopMotor1();
}
else
{
MC_ProgramSpeedRampMotor1( speed, getRampDuration_ms() );
MC_StartMotor1();
}
comState = commandExecuted;
}
}
break;
case commandReceived:
{
if (isMovementComplete()) // If the movement has been completed
{
setMovementCompleted(1); // Slave indicate that the movement is completed
comState = commandExecuted;
}
}
break;
case commandExecuted:
{
clearCommand();
comState = idle;
}
break;
}
/* ---------------------- DEMO ----------------------- */
// if (isMovementComplete())
// {
// if (fTargetPos == 0)
// {
// fTargetPos = ((float)(3*360) * (float)(M_PI)) / 180.0f;
// }
// else
// {
// fTargetPos = 0;
// }
// MC_ProgramPositionCommandMotor1(fTargetPos, 1);
// }
/* --------------------------------------------------- */
}
/* USER CODE END 3 */
}
This is just an example. You can play with the MODBUS API and state machine in different ways in order to find the solution fitting your needs.
2021-03-11 07:37 AM
Hi @DBrag.1
For obtaining this operation mode you need to follow few steps:
This is more or less the same procedure described in the User Manual of the software for software customization.
Now you need to map somehow the MODBUS API with the MotorControl API. This is performed in two files:
In the mb_api.c you could add the following functions converting holding registers' content into parameters for the speed command:
// Read target speed (rpm) from Holding Reg #0
int16_t getFinalSpeed()
{
return (int16_t)usRegHoldingBuf[0];
}
//Read speed ramp duration (ms) from Holding Reg #2
uint16_t getRampDuration_ms()
{
return usRegHoldingBuf[2];
}
In the main.c you should remove the code managing the position initialization:
setZeroReached(0); // Slave indicate that the alignment is not completed
LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-on LED
MC_StartMotor1();
while(MC_GetAlignmentStatusMotor1() != TC_ALIGNMENT_COMPLETED)
{
if (MC_GetOccurredFaultsMotor1() != 0)
{
MC_AcknowledgeFaultMotor1();
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-off LED
HAL_Delay(500);
MC_StartMotor1();
LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-on LED
HAL_Delay(500);
}
} // PAUSE THE MAIN LOOP UNTIL THE ENCODER IS ALIGNED
HAL_Delay(100);
setZeroReached(1);
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-off LED
and modify the state machine as following:
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (MC_GetOccurredFaultsMotor1() != 0)
{
LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-on LED
setMovementCompleted(1); // Slave indicate that the movement is aborted
clearCommand();
MC_AcknowledgeFaultMotor1();
comState = idle;
}
else
{
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin); // Turn-off LED
}
switch (comState) {
case idle:
{
if(getNewCommand()) // If new command arrived
{
int16_t speed = getFinalSpeed();
if (speed == 0)
{
MC_StopMotor1();
}
else
{
MC_ProgramSpeedRampMotor1( speed, getRampDuration_ms() );
MC_StartMotor1();
}
comState = commandExecuted;
}
}
break;
case commandReceived:
{
if (isMovementComplete()) // If the movement has been completed
{
setMovementCompleted(1); // Slave indicate that the movement is completed
comState = commandExecuted;
}
}
break;
case commandExecuted:
{
clearCommand();
comState = idle;
}
break;
}
/* ---------------------- DEMO ----------------------- */
// if (isMovementComplete())
// {
// if (fTargetPos == 0)
// {
// fTargetPos = ((float)(3*360) * (float)(M_PI)) / 180.0f;
// }
// else
// {
// fTargetPos = 0;
// }
// MC_ProgramPositionCommandMotor1(fTargetPos, 1);
// }
/* --------------------------------------------------- */
}
/* USER CODE END 3 */
}
This is just an example. You can play with the MODBUS API and state machine in different ways in order to find the solution fitting your needs.
2022-02-04 05:01 AM
Hello,
Thanks for the help.
I have configured Speed Control Successfully.
I have a doubt, I am unable to achieve continous rotation for lower speed using speed control.
For example, the motor works continously for the Minimum speed of 1.5 Hz which is too fast for my application.
If the speed is less than 1.5 Hz(90 RPM), the motor achieves speed by delaying its rotation. I wanted to achieve continous rotation for lesser speed.
Is there a Controller setting to be changed to achieve minimum RPM like maximum RPM?
Regards,
Chandan