Using ACP10 motion control platform I want to control the velocity of an axis on the fly based on another input in the PLC. I can use either absolute or additive moves as long as I am able to adjust the velocity during its path. Please suggest with code examples. Thanks
I think your question may require a bit more detail for the proper answer.
You are saying you want to control the velocity of an axis but you can only use absolute or additive moves?
If you are just trying to control the velocity of an axis the function block MC_BR_MoveCyclicVelocity would be the way to go help GUID 2d57d9a8-a86f-4a8f-a095-0d9ee093ae1d.
If the axis needs to reach a certain position and you need to modify the velocity while it’s moving to its target position you can use the regular MC_MoveAbsolute and keep changing the Velocity input and trigger the Execute input. This will update the instructions for the axis but depending on the frequency of the changes leads to a lot of network traffic and could potentially fail if the frequency is too high.
The MC_MoveAdditive works the same way but it would restart the positioning to the target position every time you trigger Execute.
So maybe you can provide a bit more detail about the application and we can help find the best solution!
I am just trying to control the velocity of an axis. I was trying MC_MoveAbsolute. I do keep triggering the MC_MoveVelocity.execute input but it doesn’t make a difference, the velocity stays at what it started at. Is changing the velocity once every couple of seconds too often for this mode? Or maybe I was supposed to keep triggering the MC_MoveABsolute??
I just tried triggering MC_MoveAbsolute.Execute and it didn’t work
I will look in to MC_BR_MoveCyclicVelocity but I hope I can keep it simple
A GUID is a help page ID in the offline help. Just press the key combination Ctrl + G in the Help Explorer and then enter the GUID code. This will then jump to the help page.
The MoveCyclicVelocity function block allows you to adjust the velocity of a moving axis cyclically. While it is moving, you can send a new velocity to the drive every PLC cycle and the drive will update the velocity of the motor immediately. This contrasts with a simple MoveVelocity command which is just a one-off command telling the drive to spin the motor until told otherwise. However, all this command does is move the drive. In order to use it, the drive must be powered on and referenced (homed).
The mappMotion Getting Started guide shows you how to use a function block called MpAxisBasic. There is a version of this function block available for ACP10 as well. This function block allows you to power an axis, home it, and the initiate basic movements all-in-one. Since it seems like you’re new to motion control with B&R I recommend adding this block to a project so that you can become familiar with the available commands/parameters/statuses and get your motor moving.
In order to use the MoveCyclicVelocity function block, you’ll have to first power on and home your axis. This can be accomplished with MpAxisBasic, or it can be done with independent PLCopen function blocks (MC_Power and MC_Home). If you want to see a sample program using PLCopen function blocks, open your project and click inside the Logical View. Your Toolbox will then show software-related items. Find Library Samples in the Toolbox and add it to your Logical View. This will allow you to choose various available sample programs. Expand the Motion folder and then the Single Axis folder. You should see three samples available. One in C, one in Structured Text (ST) and one in Ladder (LD). Double click on one of them to add it to your project. These samples do not contain MoveCyclicVelocity, but you can add that function to the program and use it in place of the MoveVelocity function block.
The Power and Homing is already taken care of, the axes are homing and otherwise running fine. It is just the part that I am asking about is not working. The code below is not making a difference in the velocity and it is giving the error 29206: The controller is OFF. If I pulse the Enable signal to force it the PLC is crashing.
I think you’re probably having issues because that code always calls MoveCyclicVelocity with the Enable set True, even if the axis is powered off. Additionally, you’re calling the function block twice every cycle (once before the IF statement and once during either the IF or ELSE condition). Try something like this instead:
This ensures that the function block is only called once per cycle. Additionally, you can use the Watch Window to set the Enable input after the axis is powered on and homed.
It’s a good idea to use a State Machine with your motion control to ensure that nothing is set before you want it to be set. That motion sample does not contain MoveCyclicVelocity, but it does contain the structure you should use when creating your program. If you replace the MoveVelocity block in that program with a MoveCyclicVelocity block, and update all of the related code/parameters, your program will step through each discrete state and trigger the movement only when the axis is ready for movement.
Have you called an MC_Power command yet? From your comments it looks as if that’s the case but that error number is pretty specific to that root cause hence my asking. Perhaps you could share a section of your code for reference?
I realized now that the MoveAbsolute and MoveCyclicVelocity are exclusive to each other and Move Absolute takes precedence. I was trying to reach an absolute position but with variable velocity, I guess I cannot so I will have to manage the last leg of the travel with MoveAbsolute.
That makes sense. You can’t use multiple move commands at the same time. If you want to share more about the application, we may be able to suggest a cleaner solution. If you’d prefer not to post that here, you can also reach out to your local B&R office or distribution partner to see if an Application Engineer would be able to help you.
If you want to change the Velocity while an “MoveAbsolute” is acitve, you can override the active movement with an new one with different Parameters. If you want to do it without delay you need two “MoveAbsolute” Instances “MoveAbsolute0” and “MoveAbsolute1”, this behaviour is descriped in AS-Help GUID c9729b12-dab4-48d9-9107-7a88ec4e43b1 ( see Picture at the Bottom of Post). How ever you can also do this with one Instance of “MoveAbsolute” but in this case we lose 1 SPS Cycle as we have to reset the Execute-Flag one cycle to genereate a new positive Edege on the Functionblock.
See Code Example below, in Steps 30…41 the Axis is moved between two Positions 0 and 200.
While the move is active you can change the Velocity “SetVelocity” and the axis will change the Speed with the given Acceleration and Deceleration.
VAR
MC_Home_0 : MC_Home;
MC_Power_0 : MC_Power;
MC_MoveAbsolute_0 : MC_MoveAbsolute;
SetVelocity : REAL;
Step : INT;
Power : BOOL;
END_VAR
PROGRAM _INIT
(* Insert code here *)
SetVelocity := 10.0;
END_PROGRAM
PROGRAM _CYCLIC
CASE Step OF
0:
IF Power THEN
Step := 10;
END_IF
10:
MC_Power_0.Enable := 1;
Step := 11;
11:
IF MC_Power_0.Status = 1 THEN
Step := 20;
END_IF
20:
MC_Home_0.HomingMode := mcHOME_DIRECT;
MC_Home_0.Execute := 1;
Step := 21;
21:
IF MC_Home_0.Done = 1 THEN
MC_Home_0.Execute := 0;
Step := 30;
END_IF
30:
MC_MoveAbsolute_0.Position := 200.0;
MC_MoveAbsolute_0.Direction := mcPOSITIVE_DIR;
MC_MoveAbsolute_0.Velocity := SetVelocity;
MC_MoveAbsolute_0.Acceleration := 50.0;
MC_MoveAbsolute_0.Deceleration := 50.0;
MC_MoveAbsolute_0.Execute := 1;
Step := 31;
31:
MC_MoveAbsolute_0.Execute := 1;
IF MC_MoveAbsolute_0.Velocity <> SetVelocity THEN
MC_MoveAbsolute_0.Execute := 0;
MC_MoveAbsolute_0.Velocity := SetVelocity;
ELSIF MC_MoveAbsolute_0.Done THEN
MC_MoveAbsolute_0.Execute := 0;
Step := 40;
END_IF
40:
MC_MoveAbsolute_0.Position := 0.0;
MC_MoveAbsolute_0.Direction := mcPOSITIVE_DIR;
MC_MoveAbsolute_0.Velocity := SetVelocity;
MC_MoveAbsolute_0.Acceleration := 50.0;
MC_MoveAbsolute_0.Deceleration := 50.0;
MC_MoveAbsolute_0.Execute := 1;
Step := 41;
41:
MC_MoveAbsolute_0.Execute := 1;
IF MC_MoveAbsolute_0.Velocity <> SetVelocity THEN
MC_MoveAbsolute_0.Execute := 0;
MC_MoveAbsolute_0.Velocity := SetVelocity;
ELSIF MC_MoveAbsolute_0.Done THEN
MC_MoveAbsolute_0.Execute := 0;
Step := 30;
END_IF
END_CASE
MC_Power_0(Axis:= ADR(gAxis01));
MC_Home_0(Axis:= ADR(gAxis01));
MC_MoveAbsolute_0(Axis:= ADR(gAxis01));
END_PROGRAM
PROGRAM _EXIT
(* Insert code here *)
END_PROGRAM
if a Post was helpfull to your question, can you mark it please as a Solution, so other Users can faster get the info which helped you most. And see the whole topic as Solved in the overview.
due to the FUB being Edge-sensitive, the loss of 1 PLC Cycle is not inevitable.
The code can basically set the Execute back to False as soon as the MoveAbsolute-FUB started the execution (which can also be seen as a possibility from the Timing Diagram you added)
Full Step 31
31:
IF MC_MoveAbsolute_0.Busy THEN
MC_MoveAbsolute_0.Execute := 0;
END_IF
IF MC_MoveAbsolute_0.Velocity <> SetVelocity THEN
MC_MoveAbsolute_0.Execute := 1;
MC_MoveAbsolute_0.Velocity := SetVelocity;
ELSIF MC_MoveAbsolute_0.Done THEN
MC_MoveAbsolute_0.Execute := 0;
Step := 40;
END_IF
this is a good remark to speed up the reaction. Thanks for this post.
But your code allows in some bad timing, the velocity to not beeing updated. If in the cycle the Movement Starts , the SetVelocity is changed, it will not be used, as the code will not correctly add a new Edge.
Not much difference but now it will generate a correct edge in any case. There is now mostly no
lose of cycle, only if you hit the Velocity-Change to the one cycle we need to reset the Execute.
Hello @michael.bertsch,
I’m also working on something simular where I want to connect setVelocity to an analog potenciometer to control the speed of servo. I have an old code from 2010 B&R engineer which I am customizing and want to ask you if this is the right way and if it’s gonna work.
(********************* START VELOCITY MOVEMENT ********************)
STATE_MOVE_VELOCITY: ( STATE: Start velocity movement )
MC_MoveVelocity_0.Velocity := Axis[AXIS_INDEX].Parameter.Velocity;
MC_MoveVelocity_0.Acceleration := Axis[AXIS_INDEX].Parameter.Acceleration;
MC_MoveVelocity_0.Deceleration := Axis[AXIS_INDEX].Parameter.Deceleration;
MC_MoveVelocity_0.Direction := Axis[AXIS_INDEX].Parameter.Direction;
MC_MoveVelocity_0.Execute := 1;
( change of speed on go ) IF MC_MoveVelocity_0.Velocity <> Axis[AXIS_INDEX].Parameter.Velocity THEN
MC_MoveVelocity_0.Execute := 0;
MC_MoveVelocity_0.Velocity := Axis[AXIS_INDEX].Parameter.Velocity;
END_IF;
( end)
IF (Axis[AXIS_INDEX].Command.Halt = TRUE) THEN
Axis[AXIS_INDEX].Command.Halt := FALSE;
MC_MoveVelocity_0.Execute := FALSE;
AxisStep := STATE_HALT;
ELSIF (MC_MoveVelocity_0.InVelocity = TRUE) THEN
MC_MoveVelocity_0.Execute := FALSE;
AxisStep := STATE_READY;
END_IF
(* check if error occured *)
IF ((MC_MoveVelocity_0.Error = TRUE) OR (MC_MoveVelocity_0.CommandAborted = TRUE)) THEN
MC_MoveVelocity_0.Execute := FALSE;
AxisStep := STATE_READY;
END_IF
Hello,
The upper example with MC_MoveAbsolute can be easily replaced with MC_MoveVelocity, they have the same behaviour in updating the Parameters.
As far as i remember, but can’t currently check is that the InVelocity might not be set if you combine it with an Override <> 100%. If this is an possibility in your application you should check this testcase.
But as you want to cyclicaly update the velocity you should not jump out of this step with InVelocity. You only jump out of it if you want to halt.
But if its only the Velocity you need, no Position. And to have a cyclical Update of the Velocity due to the potentiometer. I would recomend to use MC_BR_MoveCyclicVelocity and stay in the State as long as the coupling shall be active. Then you don’t need the new Edges and the Communication to the acopos is prepared for continous Value changes.