Working on the motion instruction set for you-know-what. It's deviated enough from CTRIO2 that I would really appreciate some feedback. I'll list out what we're doing. Y'all bless it or poke holes in it.
High level design: The basic motion device is an Axis. It always has a velocity output, which can optionally drive the associated pulse output. It can optionally use an external input like an encoder, or just a raw position register, but that isn't required. For basic stepper control you probably would not. The axis has modes independent of PLC instructions and runs on a separate co-processor. Probably the biggest difference with CTRIO2 is that the axis runs independently of the instructions and modes are persistent between instructions. That is two-edged in that it allows you to string multiple instructions together to create complex behaviors, but that might be confusing for some since killing the box leg doesn't terminate anything (see .Enable if that scares you).
The Axis has an associated structure that currently looks like this:
.Enable - master axis enable. Turning this off kills everything and returns the axis to Idle mode. Almost all instructions are edge triggered mode selections, so if you need to abort anything for any reason, you turn this off instead of dropping the input leg. Any active instructions will immediately terminate with an error indication.
.Suspend - decel to 0, leaving all modes untouched and all instructions still active and pending.
.TargetVelocity - Sets the axis target velocity while in velocity mode.
.AtVelocity - currently at target velocity
.TargetPosition - Sets the axis target position while in position mode.
.AtPosition - currently at target position
.CurrentVelocity - umm, you know.
.CurrentPosition - ditto
1. AXCONFIG
Initializes an axis by specifying axis output type (basically pulse out or not) and optional input (none, external register, or encoder). Initialized internal Position, MinFreq, MaxFreq, Accel, Decel, Deadband, and ScaleFactor properties. Sets .Enable upon configuration of axis and leaves axis in Idle mode.
2. AXPOSMODE
Sets axis to position mode. Initializes .TargetPosition (which can subsequently be changed in code). Allows optional changing of up to 8 properties (like in AXCONFIG). Can terminate immediately upon entering position mode or when at the initial .TargetPosition. When termination at .TargetPosition is selected, you can optionally return to Idle on completion or remain in position mode for subsequent moves via .TargetPosition. While in position mode, .TargetPosition is live and controls the axis until the mode is changed.
3. AXVELMODE
Sets axis to velocity mode. Initializes .TargetVelocity (which can subsequently be changed in code). Allows optional changing of up to 8 properties. Can terminate immediately upon entering velocity mode or when at the initial .TargetVelocity. Once in velocity mode, .TargetVelocity is live and controls the axis until the mode is changed.
4. AXJOG
Three leg jog box with specified jog velocity. Leaves axis in Idle mode.
5. AXHOME
Single limit, limit to limit, or limit to position. Can zero axis position on Limit1 or completion. Leaves axis in Idle mode.
6. AXSETPROP
Sets up to 8 properties.
7. AXSCRIPT
Up to 50 steps, including mode change, property change, wait for event, and action.
Modes: Idle, Velocity, Position.
Properties: All
Events: Fire on Axis position, Timer/Counter register value, Local input change, Program block completion, Stage completion, Axis Timer expiration, or bit input value.
Actions: Run a program, Set a stage, Set Axis timer, Set/Reset a bit
You could implement a typical AXHOME behavior thusly:
SETMODE VELOCITY InitialFreq
WAIT LIMIT RisingEdge X0
SETMODE POSITION Offset (relative)
WAIT AtPosition
SETMODE Idle
SETPROP Position = 0
...or...
SETMODE VELOCITY InitialFreq
WAIT LIMIT RisingEdge X0
SETMODE VELOCITY CreepFreq (which could be negative)
WAIT LIMIT FallingEdge X0
SETMODE Idle
SETPROP Position = 0
Our goal is not to become a motion controller, just to do simple positioning easily, and stretch it a bit with the scripting. So with that in mind, what are we missing?