Movtec XY table driver
This driver controls a Movtec Wacht XY-table using a Nanotec stepper motor controller SMCI33 or compatible serial interface.
This driver implements the sensor interface of the generic data recorder and thus a driver instance can be passed directly to the recorder as a sensor.
Driver configuration
Instantiating the driver requires providing a configuration record of type BRML.Drivers.BioTacCfgT
.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: |
|
PortName
is the serial port the drive is connected to, and PortBaud
is the corresponding baud rate.
Then the parameters of the X and Y axes follow.
They are described as follows.
Id
is the motor id of the axis.
AnglePerStep
is the angle in degree per motor step.
StepMode
is the stepping mode of the motor.
StartVel
is the initial velocity when starting the motor in steps per second.
DegPerMM
is how many degrees the motor must turn to move the table by \(1\mathrm{mm}\).
Home
is the direction of the reference switch and can be StepperCfg.Left
or StepperCfg.Right
.
MaxPos
is the maximum reachable position in \(\mathrm{mm}\).
DefaultVel
is the default movement velocity in \(\mathrm{mm}/\mathrm{s}\).
DefaultAccel
is the default acceleration and deceleration in \(\mathrm{mm} / \mathrm{s}^2\).
HomeVel
is the homing velocity in \(\mathrm{mm}/\mathrm{s}\).
Driver instance
We can now instantiate the driver.
1:
|
|
Initialization and checking of communication is performed automatically. After initialization the driver starts to stream position samples from the XY table.
The driver has overshoot protection and will stop the XY table and terminate the program, if the position of any axis goes below 0 or above MaxPos
specified in the configuration.
Nevertheless, program and computer crashes can cause a dangerous situation; see the caution below.
The tbl.Home
and tbl.DriveTo
instance methods return an Async<_>
instance.
You can perform asynchronous control or pipe all results into the Async.RunSynchronously
to perform immediate command execution and wait for the operation to finish before your program continues.
Homing
The XY table must be homed (finding the zero reference positions) before it can be moved.
Use the tbl.Home
method for that.
Homing is only performed, if the XY table is currently not homed.
1:
|
|
Reading the current position
The current position is available in the tbl.CurrentPos
property.
It is a tuple of X and Y positions in \(\mathrm{mm}\)
1: 2: |
|
Event-based position acquisition
The driver also provides an event-based interface to obtain position samples.
Subscribe to the tbl.PosAcquired
event and you will be notified for each newly acquired sample.
This is the recommended method if you want to record the position of the XY table or perform closed-loop control (using external sensors).
1: 2: |
|
This code will automatically print each new sample as it is acquired.
You can adjust the position sampling interval by setting the tbl.PosReportInterval
property to the desired sampling interval in \(\mathrm{ms}\), but changing this property is usually not necessary.
Moving to a target position
To move to a target position with a fixed velocity and linear acceleration and deceleration ramps use the tbl.DriveTo
method.
1:
|
|
The first argument is the target XY position in \(\mathrm{mm}\) as a tuple.
You can specify additional arguments for the movement velocity, acceleration and deceleration. If they are omitted, the default values from the configuration are used.
1: 2: |
|
Moving with a set velocity
It is also possible to control the movement velocity of the XY table directly. This may be useful when the XY table is to be controlled in a closed loop mode of a larger system.
To enable direct velocity control call the tbl.DriveWithVel
method with the desired velocity in \(\mathrm{mm}/\mathrm{s}\) as argument.
1:
|
|
hide *
1:
|
|
Contrary to the rest of the driver interface, this method returns immediately with a unit return type. It does not wait for the XY table to reach the specified velocity.
CAUTION: If the program crashes in a disadvantageous way or the whole computer crashes or the communication is lost, the XY table will continue to move with the last set velocity and crash into the stop. The only way to stop it in such a situation, is to cut the power of the motor driver.
The movement velocity can be adjusted at any time by calling tbl.DriveWithVel
again with the new velocity.
Use negative velocities to reverse the movement direction.
You can optionally specify an acceleration that should be used to acquire the new velocity.
1:
|
|
To stop the table call the tbl.Stop
method, optionally specifying the deceleration.
1:
|
|
The method does not block until the XY table has stopped.
Disposing
Dispose the driver instance after usage.
1:
|
|
This will stop the table and release the serial port.
Full name: Xytable.cfg
Full name: Xytable.tbl
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken
Full name: Microsoft.FSharp.Control.Async
--------------------
type Async<'T>
Full name: Microsoft.FSharp.Control.Async<_>
Full name: Xytable.x
Full name: Xytable.y
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
type Thread =
inherit CriticalFinalizerObject
new : start:ThreadStart -> Thread + 3 overloads
member Abort : unit -> unit + 1 overload
member ApartmentState : ApartmentState with get, set
member CurrentCulture : CultureInfo with get, set
member CurrentUICulture : CultureInfo with get, set
member DisableComObjectEagerCleanup : unit -> unit
member ExecutionContext : ExecutionContext
member GetApartmentState : unit -> ApartmentState
member GetCompressedStack : unit -> CompressedStack
member GetHashCode : unit -> int
...
Full name: System.Threading.Thread
--------------------
System.Threading.Thread(start: System.Threading.ThreadStart) : unit
System.Threading.Thread(start: System.Threading.ParameterizedThreadStart) : unit
System.Threading.Thread(start: System.Threading.ThreadStart, maxStackSize: int) : unit
System.Threading.Thread(start: System.Threading.ParameterizedThreadStart, maxStackSize: int) : unit
System.Threading.Thread.Sleep(millisecondsTimeout: int) : unit