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
2. Program Flow
3. Variables
4. Encoder and Pulse Train Following
5. Input and Output
6. Communications
7. The PID Filter


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.

 

    Copyright © 2003 Servida Corporation. All rights reserved       •     For more information contact us request@servida.com