EVAL-KIT-ROBOT-1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-03-11 6: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.
- Labels:
-
Motor Control Hardware
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-03-11 7:37 AM
Hi @DBrag.1
For obtaining this operation mode you need to follow few steps:
- Open the MCWB project provided with the source code (STSW-ROBOT-1) and configure the speed control algorithm instead of the positioning
- Click on the "generate" button
- Select "Update" targeting you preferred IDE and selecting LL library
- At the end of code-generation process, open the IDE project file
- In the stm32f0xx_mc_it.c file, replace the automatically generated EXTI0_1_IRQHandler function with the custom one available in the USER CODE 1 section. (in between /* USER CODE BEGIN 1 */ and /* USER CODE END 1 */ lines)
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:
- mb_api.c: it maps holding registers, coils and direct inputs with specific commands (e.g. getting the target position from the holding registers)
- main.c: in the infinite loop the state machine manages the command's execution
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2021-03-11 7:37 AM
Hi @DBrag.1
For obtaining this operation mode you need to follow few steps:
- Open the MCWB project provided with the source code (STSW-ROBOT-1) and configure the speed control algorithm instead of the positioning
- Click on the "generate" button
- Select "Update" targeting you preferred IDE and selecting LL library
- At the end of code-generation process, open the IDE project file
- In the stm32f0xx_mc_it.c file, replace the automatically generated EXTI0_1_IRQHandler function with the custom one available in the USER CODE 1 section. (in between /* USER CODE BEGIN 1 */ and /* USER CODE END 1 */ lines)
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:
- mb_api.c: it maps holding registers, coils and direct inputs with specific commands (e.g. getting the target position from the holding registers)
- main.c: in the infinite loop the state machine manages the command's execution
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2022-02-04 5: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
