Use a periodic task. That is how I do it and I also use Balluf transducers for determing ram velocity.
You can hard code the task period, but you can also determine what the task period is programmatically with GSV(TASK, Velocity_Task_Name, Rate, TaskRate_MicroSeconds) where Velocity_Task_Name is the name of your periodic task and TaskRate_Microseconds is a DINT tag to which the task execution period is stored in microseconds.
I have a UDT that contains the tags needed for the ram piston and velocity as well as other ram control tags. Included in the UDT are the following tags:
CurrentPos Real Current Position of the hydraulic Ram in mm
LastPos Real Position of ram in mm last time velocity was calculated
Velocity Real Velocity of Ram in mm/sec.
I create a tag of the UDT type for each ram.
In ST the routine looks similar to this:
GSV(TASK, Velocity_Task_Name, Rate, TaskRate_MicroSeconds);
Ram.Velocity := (Ram.CurrentPos - Ram.LastPos)/TaskRate_Microseconds/1000000.0); //Units/Sec
Ram.LastPos := Ram.CurrentPos;