|
Technical
Support Programmers
Guide
This
text is part of the Servida Motor BOOK. This manual, as well as
the software described in it, is furnished under license and may
be used or copied only in accordance with the terms of such license.The
content of this manual is furnished for informational purposes only,
is subject to change without notice, and should not be construed
as a commitment by Servida. Servida
assumes no responsibility or liability for any errors or inaccuracies
that may appear in this book.
Except as permitted by such license, no part of this publication
may be reproduced, stored in a retrieval system, or transmitted,
in any form or by any means, electronic, mechanical, recording,
or otherwise, without the prior written permission of Servida.
Programming
table of contents:
1.
Creating Motion
Enter
the four commands below in the “Servida Motor Terminal” window,
following each command with a return, and you will see motion:
| Commands |
Comments |
| A=100 |
‘Set
Acceleration |
| V=1000000 |
‘Set
Velocity |
| P=1000000 |
‘Set
Position |
| G |
‘Start
move |
On
power-up the motor defaults to position mode. Once Acceleration
(A) and Velocity (V) are set, you can simply issue new Position
(P) commands, followed by a Go (G) command to execute moves to
new absolute locations. The motor doesn't instantly go to the
programmed position, but follows a trajectory to get there. The
trajectory is bound by the maximum Velocity and Acceleration commands.
This results in a trapezoidal velocity profile, or a triangular
profile if the maximum velocity is never met.
You
can change Position, Velocity and Acceleration at any time during
or between moves. The new parameters will only apply when a new
G command is sent.
Command
Set
Commands
are grouped by function - with the following notations:
| # |
Integer
number |
| exp |
Expression
or signed integer |
| var |
Variable |
| com |
Communication
channel |
A=exp
Set absolute acceleration
Acceleration
must be a positive integer within the range of 0 to 2,147,483,648.
The default is zero forcing you to enter something to get motion.
A typical value is 100. If left unchanged, while the motor is
working, this value will not only determine acceleration but also
deceleration which will form a triangular or trapezoidal velocity
motion profile. This value can be changed at any time. The value
set doesn't get acted upon until the next G command is sent.
If
your motor has a 2000 count encoder (sizes 17 & 23), multiply
your desired acceleration in rev/sec2 by 7.91 to arrive at the
number to set A to. With a 4000 count encoder (sizes 34, 42 &
56) you will need to multiply by 15.82. These constants are a
function of the motors PID rate. If you lower the PID rate, you
must raise these constants proportionally. See “The P.I.D. Filter”
section of this manual for more information.
V=exp
Set maximum permitted velocity
Use
the V command to set a limit to what velocity the motor can accelerate
to. That limit becomes the slew rate for all trajectory based
motion whether in position mode or velocity mode. The value defaults
to zero so it must be set before any motion can take place. The
new value set does not take effect until the next G command is
executed. If your motor has a 2000 count encoder (sizes 17 &
23), multiply your desired velocity in rev/sec by 32212 to arrive
at the number to set V to. With a 4000 count encoder (sizes 34,
42 & 56) you will need to multiply by 64424. These constants
are a function of the motors PID rate.
If you lower the PID rate, you will need to raise these
constants..
P=exp
Set absolute position for move
The
P= command allows the setting of an absolute end position. The
number following is encoder counts and can be positive or negative.
The end position can be set or changed at any time during or at
the end of previous motions.
The
following program illustrates how variables can be used to set
motion values to real-world units and have the working values
scaled for motor units.
| a=100 |
‘Acceleration
in rev/sec*sec |
| v=1 |
‘Velocity
in rev/sec |
| p=100 |
‘Position
in revs |
| GOSUB10 |
‘Initiate
motion |
| END |
‘End
program |
| C10 |
‘Motion
routine |
| A=a*8 |
‘Set
Acceleration |
| V=v*32212 |
‘Set
Velocity |
| P=p*2000 |
‘Set
Position |
| G |
‘Start
move |
| RETURN |
‘Return
to call |
D=exp
Set relative distance for position move
The
D= command will allow you to specify a relative distance, instead
of an absolute position. The number following is encoder counts
and can be positive or negative.
The
relative distance will be added to the current position, either
during or after a move. It is added to the desired position rather
than the actual position so as to avoid the accumulation of small
errors due to the fact that any servo motor is seldom exactly
where it should be
G Go,
start motion
The
G command does more than just start motion. It can be used dynamically
during motion to create elaborate profiles. Since the Servida Motor
allows you to change Position, Velocity and Acceleration during
motion, “on-the-fly”, the G command can be used to trigger the
next profile at any time.
S Abruptly
stop motion in progress
If
the S command is issued while a move is in progress it will cause
an immediate and abrupt stop with all the force the motor has
to offer. After the stop, assuming there is no position error,
the motor will still be servoing.
X Decelerate
to stop
If
the X command is issued while a move is in progress it will cause
the motor to decelerate to a stop at the last entered A= value.
When the motor comes to rest it will servo in place until commanded
to move again.
O=exp Set/Reset
origin to any position
The
O= command (using the letter O, not the number zero) allows the
host or program not just to declare the current position zero,
but to declare it to be any position, positive or negative. The
exact position to be re-declared is the ideal position, not the
actual position which may be changing slightly due to hunting
or variable loading.
OFF
Turn motor servo off
The
OFF command will stop the motor from servoing, much as a position
error or limit fault would.
MP
Position Mode
Position
mode is the default mode of operation for the Servida Motor.
If the mode were to be changed, however, the MP command would
put it back into position mode. In position mode, the P# and D#
commands will govern motion.
Binary
Data Transfer
The
ASCII based command string format, while convenient, is not the
fastest way to communicate data. It can be burdensome when performing
multi-axis contouring. For that reason a special binary format
has been established for the communication of trajectory critical
data such as Position, Velocity and Acceleration. These 32 bit
parameters are sent as four bytes following a code byte that flags
the data for a particular purpose. The code bytes are 252 for
acceleration, 253 for velocity and 254 for position. As an example,
the following byte values communicate A=52, V=-1 & P=2137483648.
A=52 252
000 000 000 052 032
V=-1 253
255 255 255 254 032
P=2137483648 254 127 255 255 255 032
For
further expediency, the commands can be appended with the G command
to start motion immediately. Two examples are as follows (the
ASCII value for G is 71):
P=0 G 254
000 000 000 000 071 032
V=512 G 253 000 000 002 000 071 032
MV
Velocity Mode
Velocity
mode will allow continuous rotation of the motor shaft. In Velocity
mode the programmed position using the P or the D commands is
ignored. acceleration and velocity need to be specified using
the A= and the V= commands. After a G command is issued, the motor
will accelerate up to the programmed velocity and continue at
that velocity indefinitely. In velocity mode as in Position mode,
Velocity and Acceleration are changeable on-the-fly, at any time.
Simply specify new values and enter another G command to trigger
the change. In Velocity mode the velocity can be entered as a
negative number, unlike in Position mode where the location of
the target position determines velocity direction or sign. If
the 32 bit register that holds position rolls over in velocity
mode it will have no effect on the motion.
MT
Torque Mode
In
torque mode the motor shaft will simply apply a torque independent
of position. The internal encoder tracking will still take place,
and can be read by a host or program, but the value will be ignored
for motion because the PID loop is inactive. To specify the amount
of torque, use the T= command, followed by a number between -1023
and 1023.
T=exp
Set torque value, -1023 to 1023
In
torque mode, activated by the MT command, the actual torque value
can be set with the T= command. The following number or variable
must fall in the range between -1023 and 1023. The full scale
value relates to full scale or maximum torque.
Brake
commands
(where optional brake exists)
BRKRLS
Brake release
BRKENG Brake
engage
BRKSRV Release
brake when servo active, engage break when inactive.
BRKTRJ
Release brake when running a trajectory.
Engage under all other conditions.
Turns servo off when the brake is engaged.
Many
Servida Motors are available with power safe brakes. These
brakes will apply a force to keep the shaft from rotating should
the unit lose power. Issuing the BRKRLS command will release the
brake and BRKENG will engage it. There are two other commands
that initiate automated operating modes for the brake. The command
BRKSRV engages the brake automatically, should the motor stop
servoing and holding position for any reason. This might be due
to loss of power, a position error, limit fault, over-temperature
fault, etc..
Finally,
the BRKTRJ command will engage the brake in all of the previously
mentioned circumstances, plus any time the motor is not performing
a trajectory. In this mode the motor will be off, and the brake
will be holding it in position, perfectly still, rather than the
motor servoing when it is at rest,. As soon as another trajectory
is started, the brake will release. The time it takes for the
brake to engage and release is on the order of only a few milliseconds.
The
brakes used in Servida Motors are zero-backlash devices with
extremely long life spans. It is well within their capabilities
to operate interactively within an application. You need to be
careful not to create a situation where the brake will be set
repeatedly during motion. That will reduce the brake's life.
2.
Program Flow
Program
commands are like chores, whether it is to turn on an output,
set a velocity, start a move or whatever. A program is a list
of these chores. When a programmed Servida Motor is powered-up
or its program is reset with the Z command, it will execute
its program in order from the beginning to the end.
RUN
Execute stored user program
If
you reset your program with a Z command you will erase all previous
variables and mode changes for a fresh start. Alternatively
you can use the RUN command to start the program in which case
the state of the motor is unchanged and your program will be
invoked.
RUN?
Halt program if no RUN issued
To
keep your downloaded program from executing at power-up start
your program with the RUN? command. It will prevent the program
from starting when power is applied, but it will not prevent
the program from running when the Servida Motor sees a RUN
command from a host over the RS-232 input.
Once
your program is running, there are a variety of commands that
can redirect program flow and most of those can do so based
on certain conditions. How you set up these conditional decisions
determines what your programmed Servida Motor will do, and
exactly how “Servida ” it will actually be.
GOTO#
Redirect program flow
C# Subroutine
label, C0-C999
The
most basic commands for redirecting program flow, without inherent
conditions, are GOTO# in conjunction with C#. Labels are the letter C followed by a number (#) between
0 and 999 and are inserted in the program almost as place markers.
If a label, C1 for this example, is placed in your program and
you put that same number at the end of a GOTO command, GOTO1,
the program flow will be redirected to label C1 and the program
will proceed from there.
You
can use as many as a thousand labels in your program (0 - 999),
but, the more GOTO commands you use, the harder your code will
be to debug or read. Try using only one and use it to create
the infinite loop necessary to keep your program running indefinitely,
as some embedded programs do. Put a C1 label at the beginning
of your program and a GOTO1 at the end and every time the GOTO1
is reached the program will loop back to label C1 and start
over from that point until the GOTO1 is reached again which
will start the process all over at C1 and so on. You can write
any program with only one GOTO. It might be a little harder,
but it will tend to force you to better organize your program,
which in turn will make it easier for others to read and for
anyone to change.
END
End program execution
If
you want your program to stop, simply send an END command and
execution will stop at that point. An END command can also be
sent by the host to intervene and stop a program running within
the motor. The program in your Servida Motor is never erased
until you download a new one. If you want to erase the program
on your motor download only the END command as if it were a
new program and that's the only command that will be left on
your Servida Motor until you download a new program.
GOSUB#
Execute a subroutine
RETURN
Return from subroutine
Just
like the GOTO# command, the GOSUB# command, in conjunction with
a C# label, will also redirect program execution in the same
way. But, unlike the GOTO# command, the C# label needs a RETURN
command at the end of the subroutine which will return the program
to the location of the GOSUB# command that initiated the command.
As an example; you want your Servida Motor to perform the
same routine periodically throughout your program. For this
we'll use GOSUB5 as an example which will send your program
to the C5 label's subroutine. The subroutine will execute until
the RETURN is reached which will send your program back to the
GOSUB5 point where the diversion occurred and your program will
continue on from there running the commands after the GOSUB5.
If another GOSUB5 command is reached your program will return
to the same subroutine at the C5 label and run the subroutine.
But, now when it reaches the RETURN command it will return to
the latest GOSUB5 command that sent it to the C5 label and forge
on from there. The GOSUB5 command can be invoked as many times
as you need throughout your program and will always return to
the GOSUB5 point where the command was issued last when it reaches
the RETURN command. You can have as many as one thousand different
subroutines (0 - 999) and access each one as many times as you
want throughout your program.
By
encapsulating a piece of code into a subroutine, the code can
be called upon repeatedly and from all different points throughout
the rest of the program. Organizing your code into multiple
subroutines is a good practice.
The
commands that can conditionally direct program flow to different
areas use a constant [#] like 1 or 25, a variable like a or
al[#] or a function involving constants and/or variables a+b
or a/[#]. Only one operator can be used in a function. A list
of those operators is as follows:
+ Addition
- Subtraction
* Multiplication
/ Division
== Equals (use two =)
!= Not equal
< Less than
> Greater than
<= Less than or equal
>= Greater than or equal
& Bitwise AND (see appendix A)
| Bitwise OR (see appendix A)
WHILE,
LOOP
The
most basic looping function is a WHILE command. The WHILE is
followed by an expression that determines whether the code between
the WHILE and the following LOOP command will execute or be
passed over. While the expression is true, the code will execute.
An expression is true when it is non-zero. If the expression
results in a “zero” then it is false. The following are valid
WHILE structures:
WHILE 1 ‘1
is always true
UA=1 ‘Set output to 1
UA=0 ‘Set output to 0
LOOP ‘Will loop forever
a=1 ‘Initialize variable
‘a'
WHILE a
‘Starts out true
a=0
‘Set ‘a' to 0
LOOP ‘This never loops back
a=0 ‘Initialize variable
‘a'
WHILE a<10 ‘a
starts less
a=a+1 ‘a grows by 1
LOOP ‘Will loop back 10x
The
task or tasks within the WHILE loop will execute as long as
the function remains true.
The
BREAK command can be used to break out of a WHILE loop, although
that somewhat compromises the elegance of a WHILE statement's
single test point, making the code a little harder to follow.
The BREAK command should be used sparingly or preferably not
at all in the context of a WHILE.
If
you want a portion of code to execute only once based on a certain
condition then use the IF command.
IF,
ENDIF
Once
the execution of the code reaches the IF command, the code between
that IF and the following ENDIF will execute only when the condition
directly following the IF command is true. For example:
a=UAI ‘Variable
‘a' set 0,1
a=a+UBI ‘Variable ‘a'
0,1,2
IF a==1 ‘Use double = test
b=1 ‘Set ‘b' to one
ENDIF ‘End IF
Variable
b will only get set to one if variable a is equal to one. If
a is not equal to one, then the program will continue to execute
using the command following the ENDIF command.
Notice
also that the Servida Motor language uses a single equal
sign (=) to make an assignment, such as where variable a is
set to equal the logical state of input A. Alternatively, a
double equal (==) is used as a test, to query whether a is equal
to 1 without making any change to a. These are two different
functions. Having two different syntaxes has farther reaching
benefits.
ELSE,
ELSEIF
The
ELSE and ELSEIF commands can be used to add flexibility to the
IF statement. What if you wanted to execute different code for
each possible state of variable a. You could write the program
as follows:
a=UAI ‘Variable
‘a' set 0,1
a=a+UBI ‘Variable ‘a'
0,1,2
IF a==0
‘Use double ‘=' test
b=1 ‘Set ‘b' to one
ELSEIF a==1
c=1 ‘Set ‘c' to one
ELSEIF a==2
c=2 ‘Set ‘c' to two
ELSE ‘If not
0, 1, or 2
d=1 ‘Set ‘d' to one
ENDIF ‘End IF
There
can be many ELSEIF statements, but at most one ELSE. If the
ELSE is used, it needs to be the last statement in the structure
before the ELSEIF. You can also have IF structures inside IF
structures. That is called “nesting” and there is no practical
limit to the number of structures you can nest within one another.
SWITCH,
CASE, DEFAULT, BREAK, ENDS
Long,
drawn out IF structures can be cumbersome, however, and burden
the program, visually. In these instances it can be better to
use the SWITCH structure. The following code would accomplish
the same thing as the previous program:
a=UAI ‘Variable
‘a' set 0,1
a=a+UBI ‘Variable ‘a'
0,1,2
SWITCH a
‘Begin SWITCH
CASE 0
b=1 ‘Set ‘b' to one
BREAK
CASE 1
c=1 ‘Set ‘c' to one
BREAK
CASE 2
c=2 ‘Set ‘c' to two
BREAK
DEFAULT ‘If not 0 or 1
d=1 ‘Set ‘d' to one
BREAK
ENDS ‘End SWITCH
Just
as a rotary switch directs electricity, the SWITCH structure
directs the flow of the program. The BREAK statement then jumps
the code execution to the code following the associated ENDS
command. The DEFAULT command covers every condition other than
those listed. It is optional.
TWAIT
Wait during trajectory
The
TWAIT command pauses program execution while the motor is moving.
Either the controlled end of a trajectory, or the abrupt end
of a trajectory due to an error, will terminate the TWAIT waiting
period. If you had a succession of move commands without this
command, or similar waiting code between them, the commands
would overtake each other because the program advances, even
while moves are taking place. The following program has the
same effect of the TWAIT command, but has the added virtue of
allowing you to program other things during the wait, instead
of just waiting.
WHILE Bt
‘While trajectory
LOOP ‘Loop
back
WAIT=exp
Wait (exp) sample periods
There
will probably be circumstances where you will want to pause
program execution for a specific period of time. Time, within
the Servida Motor, is tracked in terms of servo sample periods.
Unless otherwise programmed with the PID# command, the sample
rate is about 4KHz. WAIT=4000 would wait about one second. WAIT=1000
would wait for about one quarter of a second. The following
code would be the same as WAIT=1000, only it will allow you
to execute code during the wait if you place it between the
WHILE and the LOOP.
CLK=0
‘Reset CLK to 0
WHILE CLK<1000 ‘CLK
will grow
IF UAI==0
‘Monitor input A
GOSUB911 ‘If input low
ENDIF ‘End the IF
LOOP ‘Loop
back
The
above code example will check if input A ever goes low, while
it is waiting for the the CLK variable to count up to 1000.
STACK
Reset the GOSUB return stack
The
STACK is where information is held with regard to nesting of
subroutines (nesting is when one or more subroutines exist within
others). In the event you direct program flow out of one or
more nested subroutines, without executing the included RETURN
commands, you will corrupt the stack. The STACK command resets
the stack with zero recorded nesting. Use it with care and try
to build your program without using the STACK command.
One
possible use of the STACK command might be if your program used
one or more nested subroutines and an emergency occurred, the
program or operator could issue the STACK command and then a
GOTO command which would send the program back to a label at
the beginning. Using this method instead of a RESET command
would retain the states of the variables and allow further specific
action to resolve the emergency.
3.
Variables
Variables
are data holders that you can set and change within the program
or over the communication channel.
The first 26 variables are long integers (32 bits) and are
accessed with the lower case letters of the alphabet, a, b,
c, . . . x, y, z.
a=# Set variable
a to a numerical value
a=exp Set variable
a to value of an expression
A
variable can be set to an expression with only one operator
and two operands. The operators can be any of the following:
+ Addition
- Subtraction
* Multiplication
/ Division
& Bitwise
AND (see appendix A)
| Bitwise
OR (see appendix A)
The
following are legal:
| a=b+c, |
a=b+3 |
a=5+8 |
| a=b-c |
a=5-c |
a=b-10 |
| a=b*c |
a=3*5 |
a=c*3 |
| a=b/c |
a=b/2 |
a=5/b |
| a=b&c |
a=b&8 |
|
| a=b|c |
a=b|15 |
|
Arrays
In
addition to the first 26, there are 52 more long integer variables
accessible with double and triple lower case letters: aa,
bb, cc, . . . xxx, yyy, zzz. The memory space that holds these
52 variables is more flexible, however. This same variable
space can be accessed with an array variable type. An array
variable is one that has a numeric index component, that allows
which variable a program changes to be selected numerically,
and therefore mathematically. This memory space is further
made flexible by the fact that it can hold 51 thirty two bit
integers, or 101 sixteen bit integers, or 201 eight bit integers
(all signed).
The
array variables take the following form:
ab[i]=exp Set
variable to a signed 8 bit
value where index i = 0...200
aw[i]=exp Set
variable to a signed 16 bit value where index i = 0...100
al[i]=exp Set
variable to a signed 32 bit value where index i = 0...50
The
index i may be a number, a variable a thru z, or the sum or
difference of any two variables a thru z (variables only).
The
same array space can be accessed with any combination of variable
types. Just keep in mind how much space each variable takes.
We can even go so far as to say that one type of variable
can be written and another read from the same space. For example,
if you assigned the first four eight bit integers as follows:
ab[0]=0
ab[1]=0
ab[2]=1
ab[3]=0
that
would occupy the same space as the first single 32 bit number,
and due to the way binary numbers work, would make the thirty
two bit variable equal to 256 (see appendix A).
A
common use of the array variable type is to set up what is
called a buffer. In many applications, the Servida Motor
will be tasked with inputting data about an array of objects
and to do processing on that data in the same order, but not
necessarily at the same time. Under those circumstances it
may be necessary to “buffer” or “store” that data while the
Servida Motor processes it at the proper times.
To
set up a buffer the programmer would allocate a block of memory
to it, assign a variable to an input pointer and another to
an output pointer. Both pointers would start out as zero and
every time data was put into the buffer the input pointer
would increment. Every time the data was used, the output
buffer would likewise increment. Every time one of the pointers
is incremented, it would be checked for exceeding the allocated
memory space and rolled back to zero in that event, where
it would continue to increment as data came in. This is a
first-in, first-out or “FIFO”, circular buffer. You need to
be sure that there is enough memory allocated so that the
input pointer never overruns the output pointer.
Storage
of variables
(Not available in SVXXX5 Servida Motors)
Each
Servida Motor has 8K of non-volatile EEPROM memory to store
variables when they need to survive the motor powering down.
EPTR=expression Set
EEPROM pointer, 0-7999
To
read or write into this memory space you first need to properly
locate the pointer. This is accomplished by setting EPTR equal
to the offset.
VST(variable,index) Store variables
To
store a series of variables use the VST command. In the "variable"
space of the command put the name of the variable and in the
"index" space put the number of variables following
that variable that you also want to store. Put a one here
if you only want to store the one variable specified. The
actual sizes of the variables will be handled automatically.
VLD(variable,index) Load variables
To
load variables, starting at the pointer, use the VLD command.
In the "variable" space of the command put the name
of the variable and in the "index" space put the
number of subsequent variables you want loaded.
Fixed
or pre-assigned functions
In
addition to the general purpose variables there are variables
that are gateways into the different functions of the motor
itself.
@P Current
position
@PE Current
position error
@V Current
velocity
ADDR
Motor's self address
CHN0
RS-232 com error flags
CHN1
RS-485 com error flags
CLK
Read/write sample rate counter
CTR
External encoder count variable
I Last
recorded index position
LEN
# of characters in RS-232 buffer
LEN1
# of characters in RS-485 buffer
Report
to host commands
Ra...Rzzz
Report variable a ... zzz, 78 in all
Rab[i]
Report 8 bit variable value Rab[i]
Raw[i]
Report 16 bit variable value Raw[i]
Ral[i]
Report 32 bit variable value Ral[i]
RA Report
buffered acceleration
RAIN{port}{ch} Report
8 bit analog input port=A-H, ch= 1-4
RAMPS
Report assigned maximum current
RBa Report
overcurrent status bit
RBb Report
parity error status bit
RBc Report
communications error bit
RBd Report
user math overflow status bit
RBe Report
position error status bit
RBf Report
communications framing error status bit
RBk Report
EEPROM read/write status bit
RBl Report
historical left limit status bit
RBi Report
index status bit
RBh Report
overheat status bit
RBm
Report negative limit status bit
RBo
Report motor off status bit
RBp
Report positive limit status bit
RBr
Report historical right limit status bit
RBs
Report program scan status bit
RBt
Report trajectory status bit
RBu
Report user array index status bit
RBw
Report wrap around status bit
RBx
Report hardware index input level
RCHN
Report combined communications status bits
RCHN0
Report RS-232 communications status bits
RCHN1
Report RS-485 communications status bits
RCLK
Report clock value
RCTR
Report secondary counter
RCS
Report RS-232 communications check sum
RCS1
Report RS-485 communications check sum
RD
Report buffered move distance value
RDIN{port}{ch} Report
8 bit digital input byte, port=A-H, and
ch=0-63
RE
Report buffered maximum pos. error
RI
Report last stored index position
RKA
Report buffered Kaff coefficient
RKD
Report buffered Kd coefficient
RKG
Report buffered Kg coefficient
RKI
Report buffered Ki coefficient
RKL
Report buffered Kl limit value
RKP
Report buffered Kp coefficient
RKS
Report buffered Ks coefficient
RKV
Report buffered Kvff coefficient
RP
Report measured position
RPE
Report present position error
RMODE
Report present positioning mode:
P Absolute position move
R Relative position move
V Velocity move
T Torque mode
F Follow mode
S Step and Direction mode
C Cam Table mode
W Drive mode
X Follow mode with multiplier
E Position error
O Motor off
H Contouring mode
RS2
Restore RS-232 mode
RS4
Assign UG to RS-485 control
RS
Report status byte (8 system states)
RSP
Report sample period and version number
RT
Report current requested torque
RV
Report velocity
RW
Report status word (16 system states)
4.
Encoder And Pulse Train Following
Through
the two pins, A and B, of the I/O connector, quadrature
or step and direction signals can be fed into the Servida Motor
at high speeds and be followed by the motor itself. This
feature brings about the following capabilities:
1) Mode Follow
2) Mode Step and Direction
3) Mode Follow with ratio
4) Mode Step and Direction with ratio
5) Mode Cam
In
addition to the above embedded modes of operation, the internal
counter can be set to either count encoder signals or step
signals and be accessible to the internal program or a host
through the CTR variable.
When
the Servida Motor is in one of the above five modes it
may also run internal programs and communicate with a host,
all at the same time.
MF1,
MF2 and MF4 Mode Follow
Mode
Follow allows the Servida Motor to follow an external
encoder. In addition to being read in full scale (MF1),
the incoming quadrature wave can be read by the internal
hardware in 2x (MF2) as well as 4x (MF4) resolution.
MF0,
MS0
The
MF0 and MS0 commands must not be issued during one of the
other follow modes. They are used for an entirely different
purpose. If you do not want to directly follow an incoming
encoder or step signal, but rater just want to track them
and use the counter value within your own program or from
a host, then issuing MF0 or MS0 utilizes the maximum resolution
available and makes the value available through the CTR
function. Issuing MF0 or MS0 will zero that variable and
incoming encoder or step signals will increment or decrement
the signed, 32-bit CTR function value.
MFDIV=expression Set
Ratio divisor
MFMUL=expression SetRatiomultiplier
where
-256.0000 < Ratio < 256.0000
After
the appropriate MF# command is issued, or the MS command
has been issued, a floating point ratio can further be applied
by the firmware. Since the Servida Motor is an integer
machine, that floating point ratio is accomplished by dividing
one number by another.
MFR Calculate
Mode Follow Ratio
MSR Calculate
Mode Step Ratio
Once
a numerator and denominator have been specified, and the
appropriate hardware mode is selected, the motor can be
put into ratio mode with the MFR or MSR commands (MSR for
ratioing incoming step and direction signals). The following
example sets up a 10.5:1 relationship:
MF4 ‘Read
in full res.
MFMUL=2 ‘10.5:1=21:2
MFDIV=21
D=0 ‘be
sure D is zero
MFR ‘Invoke
calculation
G ‘Start
Once
in a ratio mode the V=# and D=# commands will still work.
They will invoke a phase shift of length D at a relative
rate determined by V. For that reason, you must zero out
D before issuing an MFR or MSR command or you could find
unexpected shifting taking place. In applications such as
a Web Press, this ability to phase shift can be very useful.
MC Mode Cam
A
cam is a basically round but irregular shape that rotates
and causes a follower to move up and down in a profile determined
by the shape of the cam's exterior.
Since
the beginning of industrialization, cams have been used
to create complex, reciprocating motion. Cams are most often
carved out of steel and changing them, or having them invoke
motion a great distance away are impractical. The Servida Motor
provides an electronic alternative. Putting an encoder on
the rotating part of a machine, sending the signals to a
Servida Motor and programming the cam profile into the
Servida Motor allows for the same complex, repeating
motions to be accomplished, without any of the typical mechanical
limitations.
BASE=expression Base length
Part
of defining a Cam relationship is specifying how many incoming
encoder counts there are for one full cam rotation. Simply
set BASE equal to this number.
SIZE=expression Number of Cam data entries
The
upper variable array space holds the cam profile data. To
instruct the Servida Motor as to how many data points
you have specified, set SIZE equal to that number. The cam
firmware looks at words (16 bit numbers). The maximum number
of words you can use is 100. The cam firmware will perform
linear interpolation between those entries, as well as between
the last and the first as the cam progresses through the
table and back to the beginning. The cam table entries occupy
the same space as variables aa through yyy. Set the values
in the following way:
aw[0]=1234
aw[1]=3456
...etc.
MD50 Drive Mode
The
MD50 command causes the Servida Motor to emulate a traditional
servo and amplifier so it can be used with yet another controller
sending a standard +/-10Volt analog command signal. A small
voltage divider is necessary to convert the +/-10 volts
into the 0 to 5 volt signal the motor takes an additional
device may be desired to take the single ended encoder signals
coming out of the Servida Motor and make them differential
for more noise immunity during their travel back to the
external controller.
The
following binary values can be tested by IF and WHILE control
flow expressions, or assigned to any variable. They may
all be reported using RB{bit} commands. Some may be reset
using Z{bit} commands and some are reset when accessed.
The first 8 states are reported in combination by the RS
command. RW reports sixteen of these flags in combination.
By
writing your program to periodically test these bits, you
can make your Servida Motor application very “Servida ”
about its own inner-workings and doings.
Bo Motor off
status bit 7
Bh Excessive
temperature status bit 6
Be Excessive
position error status bit 5
Bw Wraparound
occurred status bit
4
Bi Index
report available
status bit 3
Bm Real time
negative limit
status bit 2
Bp Real time
positive limit
status bit 1
Bt Trajectory
in progress
status bit 0
Ba Over current
state occurred
Bb Parity
error occurred
Bc Communication
overflow occurred
Bd User math
overflow occurred
Bf Communications
framing error occurred
Bk Program
check sum/EEPROM failure
Bl Historical
left limit
Br Historical
right limit
Bs Syntax
error occurred
Bu User array
index error occurred
Bx Hardware
index input level
If
you do take action based on some of the error flags, you
will need to reset the flag in order to look out for the
next occurence, or in some cases depending on how your code
is written, in order to keep from acting over and over again,
on the same occurence. The flags that need to be reset are
listed. Their letter designator is preceded by the letter
Z.
Reset
system state flags
Za Reset
over current violation occurred
Zb Reset
parity error occurred
Zc Reset
com overflow error occurred
Zd Reset
user math overflow occurred
Zf Reset
communications framing error occurred
Zl Reset
historical left limit occurred
Zr Reset
historical right limit occurred
Zs Reset
syntax error occurred
Zu Reset
user array index error occurred
Zw Reset
wraparound occurred
ZS Reset
all Z{bit} state flags
The
TWAIT command pauses program execution until motion is complete.
Instead of using TWAIT, a routine could be written that
does much more. To start with, the following code example
would perform the same function as TWAIT:
WHILE Bt ‘While
trajectory
LOOP ‘Loop
back
Alternatively,
the above routine could be augmented with code that took
specific action in the event of an index signal as is shown
in the following example
WHILE Bt ‘While
trajectory
IF Bi ‘Check index
GOSUB500 ‘take care of it
ENDIF ‘end checking
LOOP ‘Loop
back
5.
I nput and Output
The
main RS-232 port
| ECHO |
Echo
back all received characters |
| SADDR# |
Set
address (0 to 100) |
| SILENT |
Suppress
print messages |
| TALK |
Re-activate
print message |
| SLEEP |
Ignore
all commands except WAKE |
| WAKE |
Consider
all following commands |
| BAUD19200 |
Set
baud rate to 19200 bps |
OCHN
(RS2,0,N,38400,1,8,D) |
Open
- No parity, 38.4k bps, 1 stop, 8 data, as Data |
OCHN
(RS4,0,N,38400,1,8,C) |
Open
as RS-485 port (with adapter) as Command |
| IF
LEN>0 |
Check
to see if any (or how much)
data is in the 16 byte input buffer, Data mode |
| c=GETCHR |
Get
byte from buffer into variable c for Data mode |
PRINT
(“Char Rcd:”,c,#13) |
Print
text, data and ASCII code for carriage return |
The
G port
| UGI |
Redefine
as general input |
| UGO |
Redefine
as general output (Open collector, pulled
to 5V) |
| UG |
Return
pin to default start function, when low motor starts
motion |
| UG=0 |
Set
G port Low (UG=a to set to variable a) |
| UG=1 |
Set G port High (Open collector, weakly pulled
to 5V internally) |
| a=UGI |
Set
variable a to digital input |
| a=UGA |
Set
a to analog input, 0 to = 0 to 5V |
| UCI |
Redefine
Right Limit as general input (UDI for Left Limit) |
| UCO |
Redefine
Right Limit as general output (UDO for Left Limit) |
| UCP |
Return
pin to limit function (UDM for Left Limit) |
| UC=0 |
Set
Right Limit Low (UD=0 for Left, or UD=a to set to
variable a) |
| UC=1 |
Set
Right Limit High (UD=1 for Left Limit) |
| a=UCI |
Set
variable a to digital input (UDI for Left Limit) |
| a=UCA |
Set
a to analog input, 0 to = 0 to 5V (UDA for Left Limit) |
Counter
functions of ports A and B
| MF4 |
Set
Mode Follow with full quadrature |
| MFR |
Set
Mode Follow with ratio for gearing |
| MS |
Mode
Step and Direction |
| MC |
Mode
Cam |
| MF0 |
Set
follow mode to increment counter only |
| MS0 |
Set
counter mode to increment counter only |
| a=CTR |
Set
variable a to counter value |
General
I/O functions of ports A and B
| UAI |
Set
port A to input (UBI for port B) |
| UAO |
Set
port A to output (UBO for port B) |
| UA=0 |
Set
port A Low (UB=0 for port B, or UB=a to set to variable
a) |
| UA=1 |
Set
port A High (UB=1 for port B) |
| a=UAI |
Set
variable a to digital input (UBI for port B) |
| a=UAA |
Set
a to analog input, 0 to = 0 to 5V (UBA for port B) |
The
anilink port (using i2c protocol)
| AOUTB,c |
Send
variable c out to Analog I/O board addressed as B |
| DOUTB0,c |
Send
variable c out to Digital I/O board addressed as B0 |
| c=AINB2 |
Set
variable c to input 2 from Analog I/O board addressed
as B |
| c=DINB0 |
Set
variable c to input from Digital I/O board addressed
as B0 |
| PRINTB(“Temp:”,c,#32) |
Print
to LCD on network - text, data and ASCII code |
The
anilink port (using rs-485 protocol)
| OCHN(RS4,1,N,38400,1,8,D) |
Open
- No parity, 38.4k bps, 1 stop, 8 data, as data |
| IF
LEN1>0 |
Check
to see if any data is in the 16 byte input buffer |
| c=GETCHR1 |
Get
byte from buffer into variable c |
| PRINT1(“Char
Rcd:”,c,#13) |
Print
text, data and ASCII code |
| ECHO1 |
ECHO
back all received characters |
| SILENT1 |
Suppress
print messages |
| SLEEP1 |
Ignore
all commands except WAKE |
| WAKE1 |
Consider
all following commands |
The
anilink port as general I/O
| UEI |
Set
port E to input (UFI for port F) |
| UEO |
Set
port E to output (UFO for port F) |
| UE=0 |
Set
port E Low (UF=0 for port F, or UF=c to set to variable
c) |
| UE=1 |
Set
port E High (UF=1 for port F) |
| c=UEI |
Set
variable c to digital input (UFI for port F) |
| c=UEA |
Set
c to analog input, 0 to = 0 to 5V (UFA for port F) |
| |
Ports
E and F have internal 5k Ohm resistive pull-ups |
The
Servida Motor brings out 5 volt power and ground, as
well as seven I/O points. Each one has multiple functions.
They are UA, UB, UC, UD, UE, UF and UG and have the following
functions:
UA Digital
Input, TTL, 0 to 5 volts
Digital Output, TTL, 0 to
5 volts
Analog Input, 10 bit, 0 to
External Encoder A Input
Step and Direction, Step
Input
UB Digital
Input, TTL, 0 to 5 volts
Digital Output, TTL, 0 to
5 volts
Analog Input, 10 bit, 0 to
External Encoder B Input
Step and Direction, Direction
Input
UC Digital
Input, TTL, 0 to 5 volts
Digital Output, TTL, 0 to
5 volts
Analog Input, 10 bit, 0 to
Positive Limit Input
UD Digital
Input, TTL, 0 to 5 volts
Digital Output, TTL, 0 to
5 volts
Analog Input, 10 bit, 0 to
Negative Limit Input
UE Digital
Input, TTL, 0 to 5 volts
Digital Output, TTL, 0 to
5 volts
Analog Input, 10 bit, 0 to
AniLink Data I/O
AniLink RS-485 Signal A
UF Digital
Input, TTL, 0 to 5 volts
Digital Output, TTL, 0 to
5 volts
Analog Input, 10 bit, 0 to
1024
AniLink Clock Output
AniLink RS-485 Signal B
UG Digital
Input, TTL, 0 to 5 volts
Digital Output, TTL, 0 to
5 volts
Analog Input, 10 bit, 0 to
1024
Start Motion (or GO) Input
When
used as general I/O, the following commands will select
the port function.
UAI Assign
pin A to input state
UAO Assign
pin A to output state
UA=0 Set
UA to zero volts
UA=1 Set
UA to 5 volts
a=UAI Read
UA digital value, 0 or 1
a=UAA Read
UA analog voltage
UBI Assign
pin B to input state
UBO Assign
pin B to output state
UB=0 Set
UB to zero volts
UB=1 Set
UB to 5 volts
a=UBI Read
UB digital value, 0 or 1
a=UBA Read
UB analog voltage
UCI Assign
pin C to input state
UCO Assign
pin C to output state
UCP Re-assign
pin C to +limit action
UC=0 Set
UC to zero volts
UC=1 Set
UC to 5 volts
a=UCI Read
UC digital value, 0 or 1
a=UCA Read
UC analog voltage
UDI Assign
pin D to input state
UDO Assign
pin D to output state
UDM Re-assign
pin D to -limit action
UD=0 Set
UD to zero volts
UD=1 Set
UD to 5 volts
a=UDI Read
UD digital value, 0 or 1
a=UDA Read
UD analog voltage
UEI Assign
pin E to input state
UEO Assign
pin E to output state
UE=0 Set
UE to zero volts
UE=1 Set
UE to 5 volts
a=UEI Read
UE digital value, 0 or 1
a=UEA Read
UE analog voltage
UFI Assign
pin F to input state
UFO Assign
pin F to output state
UF=0 Set
UF to zero volts
UF=1 Set
UF to 5 volts
a=UFI
Read UF digital value, 0 or 1
a=UFA Read
UF analog voltage
UGI Assign
pin G to input state
UGO Assign
pin G to output state
UG Re-assign
pin G to “GO”
UG=0 Set
UB to zero volts
UG=1 Set
UB to 5 volts
a=UGI Read
UB digital value, 0 or 1
a=UGA Read
UB analog voltage
The
UAA, UBA, UCA, UDA, UEA, UFA and UGA variables reflect
the analog voltages at the port pins regardless of how
the pins are configured. Any time the variable is used
it is loaded with the current value. You can read a pin
without effecting it this way. That can be helpful in
debugging. For example you could be using a pin as an
output and then read the analog input value to see if
it were shorted.
The
encoder and step counting capabilities of ports A and
B are described in the section on External Encoder Modes.
The serial data capabilities of ports E and F are described
in the section on communications.
Anilink
I/O Modules
In
the event the on-board I/O is not enough, additional I/O
can be connected via the AniLink port. A variety of Analog
and Digital I/O cards are available, as well as peripheral
devices like LCD and LED displays, push-wheel input devices,
pendants and more. These products communicate with the
Servida Motor through the AniLink port using I2C protocol.
Output
Assignments
| AOUT{address},exp |
Output
byte to analog address=A-H |
| DOUT{address}{ch},exp |
Output
byte to network,
address=A-H, ch=0-63 |
Input
Assignments
| var=AIN{address}{input} |
8
bit analog input from network,
address=A-H, and input=1-4 |
| var=DIN{address}{ch} |
8
bit digital in from network,
address=A-H, and ch=0-63 |
6.
Communications
While
there are a variety of options, the default mode for
communicating with a Servida Motor is serial RS-232
for the main port. Each Servida Motor is equipped
with a secondary serial port named the AniLink port.
The AniLink port on a Servida Motor can be configured
to communicate with either RS-485 or I2C. The I2C connects
Servida Motor peripherals like LCD displays, I/O
cards, etc., while the RS-485 will interface bar code
readers, light curtains, and other “intelligent” peripherals
including other Servida Motors if desired.
To
maximize the flexibility of the Servida Motor, these
serial communications ports are fully programmable with
regard to bit-rate and protocol.
There
is a sixteen-byte input buffer for the primary RS-232
port and another for the secondary RS-485 port. These
buffers ensure that no arriving information is ever
lost, although when either port is in data mode, it
is the responsibility of the user program within the
motor to keep up with the incoming data.
By
default, the primary RS-232 channel, which shares a
connector with the incoming power, is set up as a command
port with the following default characteristics:
| |
Default: |
Other
Options: |
| Type: |
RS-232 |
RS-485
(w/adapter) |
| Parity: |
None |
Odd
or Even |
| Bit
Rate: |
9600 |
2400
to 38400 |
| Stop
Bits: |
1 |
0
or 2 |
| Data
Bits: |
8 |
7 |
| Mode: |
Command Data |
|
| Echo: |
Off |
On |
If
you do not have a cable, you can communicate with your
Servida Motorby making the connections shown here
and the Servida Motor will execute the commands it
receives.
Because
of the buffers on both sides there is no need for any
hand shaking protocol when commanding the Servida Motor.
Most commands execute in less time than it would take
to receive the next one. Still, you should take some
care to allow processes to complete, particularly relatively
slow processes like printing to a connected LCD display,
or executing a full subroutine. Since the EEPROM long
term memory is slow to write, the terminal software
does employ two way communication to regulate the download
of a new program.
Daisy
chaining RS-232
Multiple
Servida Motors can be connected to a single RS-232
port as shown.
This
diagram could be expanded to as many as 100 motors.
For independent motion, however, each motor must be
programmed with a unique address. In a multi-motor system
the programmer has the choice of putting a host computer
in control or having the first motor in the chain be
in control of the rest.
SADDR# Set motor to new address
The
SADDR# command causes a Servida Motor to respond
exclusively to commands addressed to it. The range of
address numbers is from 1 to 100. Once each motor in
a chain has a unique address, each individual motor
will communicate normally after its address is sent
at least once over the chain. To send an address, add
128 to its value and output the binary result over the
communication link. This puts the value above the ASCII
character set, quickly and easily differentiating it
from all other commands or data. The address needs to
be sent only once until the host computer, or motor,
wants to change it to something else. Sending out an
address zero (128) will cause all motors to listen and
is a great way to send global data such as you would
do to start simultaneous motion in a chain. Once set,
the address features work the same for RS-232 and RS-485
communications.
Unlike
the RS-485 star topology, the consecutive nature of
the RS-232 daisy-chain creates the opportunity for the
chain to be independently addressed entirely from the
host, rather than have a uniquely addressed program
in each motor. Setting up a system this way can add
simplicity because the program in each motor can be
exactly the same. If the RUN? command is the first in
each of the motor's programs, the programs will not
start upon power up. Addressing can be worked out by
the host prior to the programs being started later by
the host sending the RUN command globally.
SLEEP,
SLEEP1 Assert sleep mode
WAKE,
WAKE1 De-assert SLEEP
Telling
a motor to sleep causes it to ignore all commands except
the WAKE command. This feature can often be useful,
particularly when establishing unique addresses in a
chain of motors. A 1 at the end of the command specifies
the AniLink RS-485 port.
ECHO,
ECHO1 ECHO input
ECHO_OFF,
ECHO_OFF1 De-assert ECHO
The
ECHO and ECHO_OFF commands toggle the echoing of data
input. Because the motors do not echo character input
by default, consecutive commands can be presented, configuring
them with unique addresses, one at a time. If the host
computer or controller sent out the following command
sequence, each motor would have a unique and consecutive
address (~0 equals 128, ~1 equals 129, etc.).
~0SADDR1
~1ECHO
~1SLEEP
~0SADDR2
~2ECHO
~2SLEEP
~0SADDR3
~3ECHO
~0WAKE
Commanded
by the first motor, instead of a host, the same chain
could be addressed with the following sequence:
SADDR1
‘Address the first
ECHO ‘Echo
for host data
PRINT(#128,“SADDR2”,#13)
WAIT=10
‘Allow time
PRINT(#130,“ECHO”,#13)
WAIT=10
PRINT(#130,“SLEEP”,#13)
WAIT=10
PRINT(#128,“SADDR2”,#13)
WAIT=10
PRINT(#131,“ECHO”,#13)
WAIT=10
PRINT(#131,“SLEEP”,#13)
WAIT=10
PRINT(#128,“SADDR3”,#13)
WAIT=10
PRINT(#132,“ECHO”,#13)
WAIT=10
PRINT(#128,“WAKE”,#13)
WAIT=10
The
two communications ports have enormous flexibility.
To select from the vast array of options, use the OCHN
command.
OCHN
| |
Options: |
|
| Type: |
RS2,
RS4 |
RS-232
or RS-485 |
| Channel: |
0,
1 or 2 |
0=Main,
1=AniLink |
| Parity: |
N,
O or E |
None,
Odd or Even |
| Bit
rate: |
2400,
4800, 9600, 19200, 38400 baud |
|
| Stop
bits: |
0,
1 or 2 |
|
| Data
bits: |
7
or 8 |
|
| Mode: |
C
or D |
Command
or Data |
For
the AniLink port in I2C mode use IIC for the type, 2
for the channel and either 400 or 1000 for the bit rate.
Use any legal value for the other parameters as place
holders. They will otherwise be ignored. Here is an
example of the OCHN command:
OCHN(RS2,0,N,38400,1,8,D)
If
the primary communication channel (0) is opened as an
RS-485 port, it will assume the RS-485 adapter is connected
to it. If that is the case the UG pin in the same connector
is assigned the task of directing the adapter to be
in Transmit or Receive mode in accordance with the motor's
communication activity.
CCHN(type,channel) Close
a communications channel
Use
the CCHN command to close a communications port when
desired.
BAUD# Set BAUD rate of main port
The
BAUD# command presents a convenient way of changing
only the bit rate of the main channel. The number can
be from 2400 to 38400 bps.
PRINT(
), PRINT1( ) PRINTA-PRINTH Print
to RS-232 or AniLink channel
A
variety of data formats can exist within the parentheses
of the PRINT( ) command. A text string is marked as
such by enclosing it between double quotation marks.
Variables can be placed between the parentheses as well
as two variables separated by one operator. To send
out a specific byte value, prefix the value with the
# sign and represent the value with as many as three
decimal digits ranging from 0 to 255. Multiple types
of data can be sent in a single PRINT( ) statement by
separating the entries with commas. Do not use spaces
outside of text strings because Servida Motors use
spaces as delimiters along with carriage returns and
line feeds.
The
following are all valid print statements and will transmit
data through the main RS-232 channel:
| PRINT(“Hello
World”) |
‘text |
| PRINT(a*b) |
‘exp. |
| PRINT(#32) |
‘data |
| PRINT(“A”,a,a*b,#13) |
‘all |
PRINT1
prints to the AniLink port with RS-485 protocol while
PRINTA prints to the AniLink port using I2C protocol
in such a way as to send data to an LCD display or standard
parallel input line printer (with a DIO-100 card on
the AniLink bus).
SILENT,
SILENT1 Suppress PRINT() outputs
TALK,
TALK1 De-assert silent mode
The
SILENT mode causes all PRINT( ) output to be suppressed.
This is useful when talking to a chain of motors from
a host, when the chain would otherwise be talking amongst
itself because of executing programs containing PRINT(
) commands.
! Wait for RS-232 char. to be received
A
single exclamation mark will cause program execution
to stop until a character is received. This can be handy
under certain circumstances like debugging a program
in real time.
a=CHN0,
a=CHN1 RS-485 communications error flags
The
CHN0 and CHN1 variables hold binary coded information
about the historical errors experienced by the two communications
channels. The information is as follows:
| Bit |
Value |
Meaning |
| 0 |
1 |
Error? |
| 1 |
2 |
|
| 2 |
4 |
|
| 3 |
8 |
|
| 4 |
16 |
|
| 5 |
32 |
|
| 6 |
64 |
|
| 7 |
128 |
|
A
subroutine that printed the errors to an LCD display
would look like the following:
C911
IF CHN0
‘If CHN0 != 0
DOUT0,1 ‘Home LCD cursor
IF CHN0&1
PRINTA(“ERROR1”)
ENDIF
IF CHN0&2
PRINTA(“ERROR2”)
ENDIF
IF CHN0&4
PRINTA(“ERROR3”)
ENDIF
IF CHN0&8
PRINTA(“ERROR4”)
ENDIF
CHN0=0 ‘Reset CHN0
ENDIF
RETURN
a=ADDR Motor's self address
If
the motor's address (addr) is set by an external source,
it may still be useful for the program in the motor
to know what address it is set to. When a motor is set
to an address, the ADDR variable will reflect that address
from 1 to 120.
Getting
data from a COM port
If
a com port is in Command Mode, then the motor will simply
respond to arriving commands it recognizes. If the port
is opened in Data Mode, however, then incoming data
will start to fill the 16 byte buffer until it is retrieved
with the GETCHR command.
a=LEN Number
of characters in RS-232 buffer
a=LEN1 Number
of characters in RS-485 buffer
a=GETCHR Get
character from RS-232 buffer
a=GETCHR1 Get
character from RS-485 buffer
The
buffer is a standard FIFO (First In First Out) buffer,.
This means that if the letter A is the first character
the buffer receives, then it will be the first byte
offered to the GETCHR command. The buffer exists to
make sure that no data is lost, even if your program
is not retrieving the data at just the right time. Two
things are very important when dealing with a data buffer
for the protection of the data:
1) Never GETCHR
if there is no CHR to get.
2) Never let the
buffer overflow.
The
LEN variable holds the number of characters in the buffer.
Your program must observe that the LEN is greater than
zero before issuing a command like: a=GETCHR. Likewise,
you will need to arrange your application such that
overall, you will be pulling data out of the buffer
faster than it comes in.
Being
able to configure the communication ports for any protocol
as well as being able to transmit and receive data allows
the Servida Motor to interface with a vast array
of RS-232 or RS-485 devices. Some of the typical devices
that would interface with Servida Motors over the
communication interfaces are:
1) Other Servida Motors
2) Bar Code Readers
3) Light Curtains
4) Terminals
5) Printers
The
following is an example program that repeatedly transmits
a message to an external device (in this case another
Servida Motor) and then takes a number back from
the device as a series of ASCII letter digits, each
ranging from 0 to 9. A carriage return character will
mark the end of the received data. The program will
use that data as a position to move to.
A=500
‘Preset Accel.
V=1000000
‘Preset Vel.
P=0
‘Zero out Pos.
O0
‘Declare origin
G
‘Servo in place
OCHN(RS2,0,N,19200,1,8,D)
PRINT(“RP”,#13)
C0
IF LEN ‘Check for
chars
a=GETCHR ‘Get char
IF a==13
‘If carriage ret.
G ‘Start motion
P=0 ‘Reset P to zero
PRINT(“RP”,#13) ‘Next
ELSE
P=P*10 ‘Shift P
a=a-48 ‘Adjust for ASCII
P=P+a ‘Build P
ENDIF
ENDIF
GOTO0
‘Loop forever
The
ASCII code for zero is 48. The other nine digits count
up from there so the ASCII code can be converted to
a useful number by subtracting the value of 0 (ASCII
48). The example assumes that the most significant digits
will be transmitted back first. Any time it sees a new
digit, it multiplies the previous quantity by 10 to
shift it over and then adds the new digit as the least
significant. Once a carriage return is seen (ASCII 13),
motion starts. After motion is started, P (Position)
is reset to zero in preparation for building up again.
P is buffered so it will not do anything until the G
command is issued.
7.
The PID Filter
PID
filter control
The
Servida Motor includes a very high quality, high
performance brushless D.C. servomotor. It has a rotor
with extremely powerful rare earth magnets and a stator
(the outside, stationary part) that is a densely wound
multi-slotted electro-magnet.
Controlling
the position of a brushless D.C. servo's rotor with
only electro-magnetism working as a lever is like
pulling a sled with a rubber band. Accurate control
would seem impossible.
The
parameter that makes it happen is found in the PID
(Proportional, Integral, Derivative) filter section.
These are the three fundamental coefficients to a
mathematical algorithm that intelligently recalculates
and delivers the power needed by the motor about 4,000
times per second. The input to the PID filter is the
instantaneous actual position minus the desired position,
be it at rest, or part of an ongoing trajectory. This
difference is called the error.
The
Proportional parameter of the filter creates a simple
spring constant. The further the shaft is rotated
away from its target position, the more power is delivered
to return it. With this as the only parameter the
motor shaft would respond just as the end of a spring
would if you grabbed and twisted it.
If
you twist the spring and let go it will vibrate wildly.
This sort of vibration is hazardous to most mechanisms.
In this scenario a shock absorber is added to cancel
the vibrations which is the equivalent of what the
Derivitive parameter does. If you sat on the fender
of a car it would dip down because of your weight
based on the constant of the car's spring. You would'nt
know if the shocks were good or bad. If you jumped
up and and down on the bumper, however, you could
quickly tell whether the shock absorbers were working.
That's because they are not activated by position
but by speed. The Derivative parameter steals power
away as a function of the rate of change of the overall
filter output. The parameter gets its name from the
fact that the derivative of position is speed. Electronically
stealing power based on the magnitude of the motor
shafts vibration has the same effect as putting a
shock absorber in the system, and the algorithm never
goes bad.
Even
with the two parameters a situation can arise that
will cause the servo to leave its target created by
“dead weight”. If a constant torque is applied to
the end of the shaft, the shaft will comply until
the deflection causes the Proportional parameter to
rise to the equivalent torque. There is no speed so
the Derivative parameter has no effect. As long as
the torque is there, the motor's shaft will be off
of its target.
That's
where the Integral parameter comes in. The integral
of position is time, and the Integral parameter mounts
an opposing force that is a function of time. As time
passes and there is a deflection present, the Integral
parameter will add a little force to bring it back
on target each cycle. There is also a separate parameter
(KL) used to limit the Integral parameter's scope
of what it can do.
Each
of these parameters have their own scaling factor
to tailor the overall performance of the filter to
the specific load conditions of any one particular
application. The scaling factors are as follows:
KP Proportional
KI Integral
KD Derivative
KL Integral
Limit
Tuning
the filter
The
task of tuning the filter is complicated by the fact
that the parameters are so interdependent. A change
in one can shift the optimal settings of the others.
The automatic utility relieves you of this aggravation,
but you still may want to know how to tune a servo.
When
tuning the motor it is useful to have the status monitor
running. This will allow you to monitor various bits
of information that will reflect the motors performance.
KP=exp Set
KP, proportional coeff.
KI=exp Set
KI, time-error coefficient
KD=exp Set
KD, damping coefficient
KL=exp Set
KL, time-error term limit
F Update
PID filter
The
main objective in tuning a servo is to get KP as high
as possible, while maintaining stability. The higher
the KP the stiffer the system and the more under control
it is. A good start is to simply query what to begin
with (RKP) and then start increasing it 10% to 20%
at a time. It is a good idea to start with KI equal
to zero. Keep in mind that the new settings do not
take effect until the F command is issued. Each time
you raise KP, try physically to destabilize the system,
by bumping or twisting it. Alternatively, you could
have a program loop cycling that invokes abrupt motions.
As long as the motor always settles to a quiet rest,
you can keep raising KP.
As
soon as you reach the limit, you need to rediscover
the appropriate derivative compensation. Move KD up
and down until you locate the position that gives
you the quickest stability. If KD is way too high,
you will hear a grinding sound. It is not really grinding,
but it is a sign that you will want to go the other
way. A good tune is not only stable, but reasonably
quiet. After optimizing KD, you may find that you
can raise KP a little more. Keep going back and forth
until you have exhausted all you can do to improve
the stiffness of the system. Then it is time to take
a look at KI.
KI
in most cases is used to compensate for friction.
Without it you will never get exactly on target. Begin
with KI equal to zero and KL equal to 1000. Move the
motor off target and start increasing KI and KL. Keep
KL at least ten times KI during this phase.
Continue
to increase KI until the motor always reaches its
target, and once that happens add about 30% to KI
and start bringing down KL until you notice it hampering
the ability for the KI term to close the position
precisely to target. Once you reach that point, increase
KL by about 30% as well. You want the Integral term
to be strong enough to overcome friction, but you
also want the limit to be set so that an unruly amount
of power will not be delivered if the mechanism were
to jam or simply find itself against one of its ends
of travel.
E=expression Set maximum position error
The
difference between where the motor shaft is and where
it is supposed to be is appropriately called the “error”.
The magnitude and sign of the error is delivered to
the motor in the form of torque, after it is put through
the PID filter. The higher the error, the more out
of control the motor is. Therefore, it is often useful
to put a limit on the allowable error, after which
time the motor will be turned off. That is what the
E command is for. It defaults to 1000 encoder counts,
but can be set from 1 to 32,000.
There
are still more parameters that can be utilized to
reduce the position error of a dynamic application.
Most of the forces that aggravate a PID loop through
the execution of a motion trajectory are unpredictable,
but there are some that can be predicted and further
eliminated preemptively.
KG=expression Set KG, Gravity offset term
KGOFF Kill KG term during error
KGON Maintain KG during error
The
simplest of these is gravity. Why burden the PID loop
with the effects of gravity in a vertical load application,
if it can simply be weeded out. If in a particular
application, motion would occur with the power off
due to gravity, a constant offset can be incorporated
into the filter to balance the system. KG is the term.
KG can range from -8388608 to 8388607. To tune KG
simply issue the KGON command, while the motor is
not servoing, and make changes to KG until the load
equally favors upward and downward motion. If when
there is a position error you want the motor to drop
the load, then issue KGOFF.
KV=expression Set KVff, velocity feed forward
Another
predictable cause of position error is the natural
latency of the PID loop itself. At higher speeds,
because the calculation takes a finite amount of time,
the result is somewhat “old news”. The higher the
speed, the more the actual motor position will slightly
lag the trajectory calculated position. This can be
programmed out with the KV term. KV can range from
zero to 65,535. Typical values range in the low hundreds.
To tune KV simply run the motor at a constant speed,
if the application will allow, and increase KV until
the error gets reduced to near zero and stays there.
KA=expression Set KAff, acceleration feed forward
Force
equals mass times acceleration. If the Servida Motor
is accelerating a mass, it will be exerting a force
during that acceleration. This force will disappear
immediately upon reaching the cruising speed. This
momentary torque during acceleration is also predictable
and need not aggravate the PID filter. It's effects
can be programmed out with the KA term. It is a little
more difficult to tune KA, especially with hardware
attached. The objective is to arrive at a value that
will close the position error during the acceleration
and deceleration phases. It is better to tune KA with
KI set to zero because KI will address this constant
force in another way. It is best to have KA address
100% of the forces due to acceleration, and leave
the KI term to adjust for friction.
KS=expression Set KS, dampening sample rate
You
can reduce the sampling rate of the derivative term,
KD, with the KS term. This can sometimes add stability
to very high inertial loads. Useful values of KS range
from 1 (the default) to 20. Results will vary from
application to application.
PID1 Set
normal PID update rate
PID2 Divide
normal PID update rate by 2
PID4 Divide
normal PID update rate by 4
PID8 Divide
normal PID update rate by 8
The
trajectory and PID filter calculations occur within
the Servida Motor 4069 times per second. That is
faster than is necessary for very good control, especially
with the larger motors. A reduction in the PID rate
can result in an increase in the Servida Motor
application program execution rate. The ‘PID2 command
will divide the PID rate by two, and the others even
more. The most dramatic effect on program execution
rate occurs with PID4. PID8 does little more and is
encroaching on poor control. If you do lower the PID
rate, keep in mind that this is the “sample” rate
that is the basis for Velocity values, Acceleration
values, PID coefficients and wait times. If you cut
the rate in half, expect to do the following to keep
all else the same:
Halve wait times
Double Velocity
Increase Acceleration by a factor of 104
Current
limit control
AMPS=expression Set current limit, 0 to 1000
In
some applications, if the motor misapplied full power
the mechanism could be damaged. It can be useful to
reduce the maximum amount of current available thus
limitimg the torque the motor can put out. Use the
AMPS command with a number, variable or expression
within the range of 0 to 1000. The units are tenths
of percent of full scale peak current, and varies
with the size of your Servida Motor.
|