User Manual
1.
StepLib - Driver for SC-02
1.1 Installation
and Usage
1.2 Description
Of Functions
1.2.1 Int
Set_Base(Int Addr )
1.2.2 Int
Set_Clk(Float Clkspd)
1.2.3 Int
Set_Rmpfreq(Int Rcount)
1.2.4 Int
Set_Rampup(Int Axis, Unsigned Newramp)
1.2.5 Int
Set_Rampdn(Int Axis, Unsigned Newramp)
1.2.6 Int
Set_Fbmode(Int Mode) 0
1.2.7 Int
Set_Convert(Int Mode)
1.2.8 Int
Step_Init(Void)
1.2.9 Int
Step_Close(Void)
1.2.10
Int Drive_Enable(Int Axis)
1.2.11
Int Drive_Disable(Int Axis)
1.2.12
Int Stop_Axis(Int Axis, Int Flag)
1.2.13
Int Set_Iobit(Int Bitno)
1.2.14
Int Reset_Iobit(Int Bitno)
1.2.15
Int Load_Axis(Int Axis, Motor *Values)
1.2.16
Unsigned Readcount(Int Axis)
1.2.17
Unsigned Stepsleft(Int Axis)
1.2.18
Float Read_Speed(Int Axis)
1.2.19
Int Read_Rampstat(Int Axis)
1.2.20
Unsigned Char Read_Input(Void)
1.2.21
Int Set_Startspd(Int Axis,Int Spd)
1.2.22
Int Set_Stopspd(Int Axis,Int Spd)
1.2.23
Void Vtwo(Long Divisor, Int *A, Int *B)
1.2.24
Float Calib_Clk(Void)
1.2.25
Int Zero_Axis(Int *A)
1.2.26
Void Enable_Limits(Int Axis)
1.2.27
Void Disable_Limits(Int Axis)
1.3 Some
Comments
The SC-02 card need powerful programs to realise its versatility in control. From the user manual for SC-02, programming the SC-02 looks formidable and it is so. This can be avoided by using the STEPLIB driver package.
Installation is done
by copying these onto the target computer.
The library module is linkable to Turbo C programs. Part of this library has been coded in C and the rest in ASSEMBLER. The library, when invoked, takes over the system timer for the purposes of ramping. However, the ramping routines alter the frequency of the timer interrupt on the PC and hence the system clock would not be accurate for the period for which the program linked to STEPLIB is active. If accurate time is required then the real time clock (RTC) can be used. It is essential that the library be initialised and closed by the user program after entering and before quitting. The user program should be a LARGE or HUGE memory model program.
This package consists of routines for the following operations :
All programs
using the functions in the library are prototyped in
STEPLIB.H and this file should be included in the source
file. The important data structure defined in this
include file is the MOTOR type structure
which is used for passing data to the
load_axis routine.
Each function description consists of the function name. The variable name given with the function name is a dummy name and given for the purposes of illustration. A short summary of the operations performed by the routine is provided followed by a clear indication of inputs and outputs to the routines. Special considerations are illustrated with examples.
1.2.1
int set_base(int addr)
This function informs
other routines in STEPLIB of the base address that has
been selected on the card
Call with :
addr : Base address of the card
Return Value :
0 if successful
1 if not
Default value of the address is factory set 340 (Hex)
Example :
status = set_base(0x200) /*** Sets base address as 200 (Hex) **/
if ( status ==1)
printf ("Error");
else
printf ("Everything OK");
1.2.2
int set_clk(float clkspd)
If the input frequency source
to the counters has been selected as PC- bus clock, then
this routine is used to inform STEPLIB of
the prescalar and the bus frequency used. This speed
depends upon the jumper setting on the card.
Call with
clkspd : Frequency
used
Return Value :
0
if successful
1
if not
If this function is not called, it is assumed on board crystal is being used and the prescalar is 1/2.
Example :
If the PC clock of 12 MHz with prescalar 8 is used, the resultant frequency is 1.5 MHz. Hence,
status = set_clk(1.5e6) /** 1.5 MHz frequency */
will set the frequency appropriately.
1.2.3
int set_rmpfreq(int rcount)
This function
selects the frequency of ramping up. Ideally
this routine is used to set the ramping frequency while tuning
the drives with the motors. The ramping time
is set to 5*rcount, i.e.. the software outputs
a new speed every 5*rcount milliseconds.
Call with
rcount : Ramping time required
Return Value
0 if successful
1 if not
Default value of ramping frequency is 10 milliseconds.
Example : To set a ramping frequency of 50 milliseconds
status = set_rmpfreq(10) /** sets 50 ms ramping time **/
1.2.4
int set_rampup(int axis, unsigned newramp)
1.2.5
int set_rampdn(int axis, unsigned newramp)
These functions set
the rate of ramping up or down of the motor. The value of newramp
should be steps/s/s. The fresh value of the ramp set is
used only in the next motion programmed and does not affect
any current motion. If newramp is 0, then no ramping is set and the
speed is applied directly as similarly the motor is stopped
immediately on command.
Call with
axis
: Axis number ( 0,1 or 2 )
newramp
: Ramp up(down) rate required in steps/s/s
Return value
0 if successful
1 if not
Default value of the rates are 20 steps/s/s for up and down.
Example : For using low acceleration and high deceleration, in axis 0 and vice versa for axis 1,
setramp(0,10) ;
setramp(0,50) ;
setramp(1,50) ;
setramp(1,10) ;
1.2.6
int set_fbmode(int mode)
This function informs STEPLIB
whether operation is open loop or closed loop.
If mode is 0, then
the board is operated in the open loop mode, else it is operated
in feedback mode.
Call with
mode : 0 ( open loop )
or 1 ( closed loop )
Return Value
0 if successful
1 if not
Note : Jumper Setting for open loop or closed loop is required.
1.2.7
int set_convert(int mode)
This routine is used
to inform STEPLIB that converter card is being used or
not. If mode is 0, then converter card is present, else it is
not.
Call with
mode : 0 (
converter used ) or
1 ( not
used )
Return Value
0 if successful
1 if not
The converter setting determines the actions taken on initialisation of the board. See description of step_init(...) for details.
1.2.8
int step_init(void)
1.2.9
int step_close(void)
The step_init initialises
the SC-02 board. After initialisation :
Call with
No input values
Return values
0
if successful
1 if not
Step_init should be called for the proper functioning. The step_close routine should be called before exiting form main program or else the computer will hang. However the input/output functions will perform normally without calling step_init.
Example :
set_base(mybase) ;
set_clk(myclk) ;
step_init() ;
/** using default modes, ramp values **/
/** Movement routines here **/
step_close() ;
exit() ;
1.2.10
int drive_enable(int axis)
1.2.11
int drive_disable(int axis)
This routine sets (enable)
or resets (disable) the drive enable bit in the control nibble for
axis.
Call with
axis : Axis number ( 0,1 or 2)
Return Value
0 if successful
1 if not
1.2.12
int stop_axis(int axis, int flag)
This routine resets (stops)
the start/stop bit in the control nibble for axis. If
flag is 0 then the motor is ramped down, else the motor is
brought to an immediate stop.
Call with
axis : Axis
number ( 0,1 or 2 )
flag
0 - Ramp down
1
- Immediate stop required
Return Value
0 if successful
1 if not
This routine is used for operations asynchronous to the ramping routines only. Under normal operation, whenever a motion is programmed, the ramping routines operate the motor till the motion is completed and then the motors are stopped. If however a stop operation is required during motion, for e.g. triggered by an input, then this routine can be used.
The action of this routine on the control ports and the counters depends upon whether the converter is used or not and hence care must be taken to use set_convert routine properly.
1.2.13
int set_iobit(int bitno)
1.2.14
int reset_iobit(int bitno)
These routines
set or reset the I/O bits in the digital I/O port.
Since the output ports are accessed through byte
wide operations, these routines retain the status of the other
bits.
Call with
bitno : Bit Number (0 to 7)
Return Value
0 if successful
1 if not
The I/O ports can be accessed asynchronously by user software using directly the outportb, inportb calls. However, once such an asynchronous call has been used by the user, further calls to these routines may not function properly as the information about such modified status is lost. It is advisable that the bits are accessed through calls to set_iobit, reset_iobit only.
1.2.15
int load_axis(int axis, MOTOR *values)
This function programs
the axis with the speed and movement values specified.
The structure MOTOR is defined in steplib.h. This structure is defined
as follows :
typedef struct mot_dat
{
float speed
;
char direction
;
char resolution ;
char rampflg
;
unsigned int movement
;
} MOTOR ;
In this speed is in steps per second, direction is 0 (bit reset) or 1 (bit set), resolution is 0 ( full step,bit reset) or 1 ( half step, bit reset), movement is in number of steps. All these are defined in steplib.h. The background ramping routines will be used for ramping with set rate values depending on whether rampflg is 1 or 0.
Call with
axis : Axis number
values : Pointer to the MOTOR
structure
Return value
0 if successful
1 if not
In case the converter is used, the FULL step option is not valid and will return an error.
Drives are NOT enabled by this routine and the user should enable the drive by a separate call to drive_enable(...), if not already enabled. The values structure passed to the routine is not affected by the function.
Example : For moving axis 1 with speed 500 steps/second for 2000 steps, with ramping in half step mode, the following program will work :
MOTOR m1 ;
char c1 ;
m1.speed = 1000 ;
/** motion is in half steps **/
m1.movement = 4000 ; /** motion is
in half steps **/
m1.direction = CLOCKWISE ; /** CLOCKWISE is defined in
steplib.h **/
m1.resolution = HALF ; /** HALF is defined in steplib.h
**/
m1.rampflg = TRUE ; /** We want to ramp **/
load_axis(1,&m1) ;
/** motion starts**/
c1 = getch() ;
if ( c1== 'Q')
stop_axis(1,1) ; /** Stop immediately if Q **/
else
stop_axis(1,0) ; /** Stop with Ramp down **/
c1 = getch() ;
if (c1== 'C')
restart_axis(1) ; /*** Continue motion **/
1.2.16
unsigned readcount(int axis)
1.2.17
unsigned stepsleft(int axis)
These routines
report the status of a programmed motion, while the motion
is being performed. readcount returns the number of steps moved since
starting, and stepsleft returns the number of steps remaining to
be moved in axis.
Call with
axis
: Axis Number ( 0,1 or 2)
Return Value
Number of Steps
Example : Continuing the example for load_axis, to display the amount of movement made, the following change can be made
MOTOR m1 ;
char c1;
int moved, notmoved ;
m1.speed = 1000 ;
/** motion is in half steps **/
m1.movement = 4000 ;
/** motion is in half steps **/
m1.direction = CLOCKWISE
;
m1.resolution = HALF ;
m1.rampflg = TRUE
;
load_axis(1,&m1)
; /** motion starts **/
/** Changed to display steps
left and steps over **/
while (!bioskey(1))
{
moved = stepsover(1)
;
notmoved = stepsleft(1)
;
printf ("%d,%d\r",
moved,notmoved) ;
}
if ( c1== 'Q')
stop_axis(1,1) ;
/** Stop immediately if Q **/
else
stop_axis(1,0) ;
/** Stop with Ramp down **/
c1 = getch() ;
if (c1 == 'C')
restart_axis(1) ;
/** Continue motion **/
1.2.18
float read_speed(int axis)
This function reports the
current speed of axis
Call with
axis : Axis number (0,1
or 2)
Return Value
Current speed of
axis
The reported value of speed is always the programmed value if no ramping has been requested for.
1.2.19
int read_rampstat(int axis)
This routine reports
the status of ramping operation. This function can
be used if the user wishes to wait for the motor to come
to a stable speed before next operation.
Call with
axis : Axis Number
(0,1 or 2)
Return Value
0 No motion
1
Ramping up
2
Moving at constant speed
3
Ramping down
If ramp rates are zero, this routine always returns 0 if the motor is stopped or 2 if the motor is moving.
Example : Suppose it is required to start axis 0, wait for it to reach stable speed before axis 1 starts.
MOTOR m1 ;
char c1 ;
int moved, notmoved
;
m1.speed = 1000 ;
m1.movement = 4000
;
m1.direction = CLOCKWISE
;
m1.resolution = HALF
;
m1.rampflg = TRUE
;
load_axis(0,&m1) ;
/** Checking for stable speed **/
while (read_rampstat(0)
!= 2) ; /** Stable speed reached,
can move axis 1 now **/
m1.speed = 1000 ;
m1.movement = 4000
;
m1.direction = CLOCKWISE
;
m1.resolution = HALF
;
m1.rampflg = TRUE
;
load_axis(1,&m1)
;
1.2.20
unsigned char read_input(void)
This routine reports the
status of the digital inputs.
Call with
None.
Return Value
Status
of Port
The port can be read directly also without disturbing the operation of this function.
1.2.21
int set_startspd(int axis,int spd)
The routine sets the starting
speed of the motor while ramping up to the required speed. The parameter
spd is to be specified in steps per second. The start speed for each
of the three axes can be set independently. Specifying the start
speed of an axis while a motion is executed in that particular axis, the
next move in that axis will with the new start speed. Specifying a null
start speed will lead to the assumption of the default start speed of 50.
Call with:
axis
: Axis Number (0,1 or 2)
spd : Speed in steps/second.
Return Value:
0 If successful
1 Failure
Example:
To set the start speed of the second axis to a low start speed, perhaps because it is carrying a high inertial load, say 20 steps per second :
status = set_startspd(1,20) ;
1.2.22
int set_stopspd(int axis,int spd)
This routine is similar
to the set_startspd routine, with the difference that it sets the speed
from which the motor drops to a complete stop while ramping down from its
current running speed. The default value is 50 steps per second and operates
similar to the previous routine.
Call with:
axis :
Axis Number (0,1 or 2)
spd : Speed in steps/second.
Return Value:
0 If successful
1 If failed
Example:
To set the stop of the first axis to virtually instant stop, the following can be used:
status = set_stopspd(1,1000) ;
1.2.23
void vtwo(long divisor, int *a, int *b)
This function splits the
number divisor into two integers a and b such that:
divisor = a*b
in an optimal way i.e. such that the residual is minimum. This routine has been provided for splitting the speed divisor into two numbers which can then be programmed in the respective counters of the SC02 card. This function may be used for direct programming the card rather than through the load_axis(...) method.
Call with:
divisor :
number to be split
*a Pointer
to integer a
*b Pointer
to integer b
Returns:
0 Successful
1 Failed
Example:
Suppose the clock frequency selected is F and the speed required is Speed, then to program the speed of motion directly:
unsigned long
divisor ;
int a,b ;
divisor = F/Speed
;
vtwo(divisor,&a,&b)
;
The numbers a,b can now be written to the appropriate counters
1.2.24
float calib_clk(void)
The function uses the counters
of the SC02 cards themselves to determine the basic clock frequency that
has been chosen. The function takes about 5 secs to execute and returns
the value of the basic clock frequency.
Call with:
none
Returns:
The frequency
as a floating point number
Example:
Suppose one does not know the frequency of the clock source used for the clock prescalar selection in hardware, the following code can be used to set the appropriate frequency:
set_clk(calib_clk()) ;
1.2.25
int zero_axis(int *a)
This function takes the
mechanical system to the 0 reference position as determined by lower limit
switch fixed on the mechanism
.
The process is as follows:
*a[3] : pointer to array for specifying axis(es) in which zeroing operation is to be done.
Return value:
0 : Successful
Note that if the limit switches are not fixed or connected or malfunctioning this routine will hang the computer and the motors will continuously rotate in the anti-clockwise direction.
Example:
To search for reference in the 0 and 2 axes,
int a = {1,0,1}
zero_axis(a)
;
1.2.26
void enable_limits(int axis)
1.2.27
void disable_limits(int axis)
The STEPLIB routines provides
for the automatic checking of over driving in either directions beyond
the limits set by the limit switches. The default status of this
checking is OFF for all the axes. The above routines provide for
enabling (disabling) such checking in any specific axis.
In case of running with the limits checking enabled, and the motor hitting the limit switch in the specified direction, the call to read_rampstat(..) will return 0 i.e. indicating that the motor is stopped. However, stepsleft will return the proper values which indicates the number of steps remaining to be moved when the limit was hit.
Call to these functions may be made even while axis is in motion and will be in effect immediately.
Call with:
axis : Axis on which to enable or disable limit operation
Return :
Always 0
Example:
The following piece of code assumes that the motor is to be moved say in a jogging mode and a limit was hit. However, it over travel is required in that direction for other purposes. SOMESPEED, MAX_MOVEMENT are constants denoting the speed at which the motor is to be moved and the maximum movement possible with the mechanism respectively.
MOTOR m ;
m.speed = SOMESPEED
;
m.movement = MAX_MOVEMENT
; . . . enable_limits(0) ;
load_axis(0,&m)
;
while (read_rampstat(0))
;
if (steps_left(0))
/** Is motion complete **/
{
disable_limits(0)
;
m.movement
= MAX_MOVEMENT ; . . }
else
/** Motion was complete **/
An example program EXMPL2.C has been provided which highlights the method of usage of most of the functions.