Power PMAC Users Manual
Power PMAC Users Manual
Power PMAC Users Manual
Power PMAC
^4 050-PRPMAC-0U0
^6 O014-E-01
Copyright Information
© 2021 Delta Tau Data Systems, Inc. All rights reserved.
This document is furnished for the customers of Delta Tau Data Systems, Inc. Other uses
are unauthorized without written permission of Delta Tau Data Systems, Inc. Information
contained in this manual may be updated from time-to-time due to product improvements,
etc., and may not conform in every respect to former issues.
To report errors or inconsistencies, call or email:
Delta Tau Data Systems, Inc. Technical Support
Phone: (818) 717-5656
Fax: (818) 998-7807
Email: support@deltatau.com
Website: http://www.deltatau.com
Operating Conditions
All Delta Tau Data Systems, Inc. motion controller products, accessories, and amplifiers
contain static sensitive components that can be damaged by incorrect handling. When
installing or handling Delta Tau Data Systems, Inc. products, avoid contact with highly
insulated materials. Only qualified personnel should be allowed to handle this equipment.
Safety Instructions
Qualified personnel must transport, assemble, install, and maintain this equipment. Properly qualified
personnel are persons who are familiar with the transport, assembly, installation, and operation of
equipment. The qualified personnel must know and observe the following standards and regulations:
IEC364resp.CENELEC HD 384 or DIN VDE 0100
IEC report 664 or DIN VDE 0110
National regulations for safety and accident prevention or VBG 4
Incorrect handling of products can result in injury and damage to persons and machinery. Strictly adhere
to the installation instructions. Electrical safety is provided through a low-resistance earth connection. It
is vital to ensure that all system components are connected to earth ground.
This product contains components that are sensitive to static electricity and can be damaged by incorrect
handling. Avoid contact with high insulating materials (artificial fabrics, plastic film, etc.). Place the
product on a conductive surface. Discharge any possible static electricity build-up by touching an
unpainted, metal, grounded surface before touching the equipment.
Keep all covers and cabinet doors shut during operation. Be aware that during operation, the product has
electrically charged components and hot surfaces. Control and power cables can carry a high voltage,
even when the motor is not rotating. Never disconnect or connect the product while the power source is
energized to avoid electric arcing.
Caution
REVISION HISTORY
REV. DESCRIPTION DATE CHG APPVD
1 New Manual Generated 11/28/2011 SS Curt Wilson
2 Updating Table of Contents 01/19/2012 SS Curt Wilson
3 Updating the manual for firmware version 1.5 release 08/10/2012 SS Curt Wilson
4 Updating the manual for firmware version 1.6 release 03/17/2014 SS Curt Wilson
5 Updating the manual for firmware version 2.0 release 01/16/2015 SS Curt Wilson
6 Updating the manual for firmware version 2.1 release 04/11/2016 SS Curt Wilson
7 Added Omron Part Number 07/15/2016 Sgm Sgm
8 Updating the manual for firmware version 2.2 release 10/25/2016 SS Curt Wilson
9 Updating the manual for firmware version 2.3 release 10/20/2017 EH Curt Wilson
10 Updating the manual for firmware version 2.4 release 5/4/2018 SM Curt Wilson
11 Updating the manual for firmware version 2.5 release 3/22/2019 SM Curt Wilson
12 Added bookmarks 4/24/2019 SM RN
13 Fixed spline move mode section 5/15/2019 SM RN
14 Updating the manual for firmware version 2.6 release 10/05/2020 SM RN
Updated the following manual sections:
- Setting Up the Servo Loop
15 3/22/2021 SM RN
- Making Your Power PMAC Application Safe
- Setting Up Coordinate Systems
Power PMAC User’s Manual
Table of Contents
POWER PMAC FAMILY OVERVIEW.................................................................................. 26
What Is Power PMAC? .............................................................................................................26
Power PMAC Configurations.....................................................................................................26
Power UMAC......................................................................................................................................... 26
Compact Power UMAC ......................................................................................................................... 27
CK3M (µUMAC) ................................................................................................................................... 27
Power PMAC Etherlite .......................................................................................................................... 27
CK3E (µPowerPMAC) .......................................................................................................................... 28
Power Brick Configurations .................................................................................................................. 28
Power Clipper........................................................................................................................................ 30
Power PMAC on Sysmac IPC................................................................................................................ 30
What Power PMAC Does ..........................................................................................................31
Execute Sequenced Motion Programs ................................................................................................... 31
Execute Asynchronous PLC Programs .................................................................................................. 31
Perform Kinematic Transformations ..................................................................................................... 31
Process Feedback and Master Position Data........................................................................................ 31
Compute Commanded Motor Trajectories ............................................................................................ 32
Calculate Compensation Table Corrections.......................................................................................... 32
Calculate Cam Table Motions ............................................................................................................... 32
Close Motor Position/Velocity Servo Loops .......................................................................................... 32
Perform Electronic Phase Commutation ............................................................................................... 32
Close Motor Current Loops ................................................................................................................... 32
Provide Synchronous Data Gathering................................................................................................... 33
Perform General Housekeeping and Safety Checks .............................................................................. 33
Respond to Host Computer Commands ................................................................................................. 33
Execute Independent C Applications ..................................................................................................... 33
Key Hardware Components ......................................................................................................34
CPU Section........................................................................................................................................... 34
Machine Interface ICs ........................................................................................................................... 35
Table of Contents vi
Power PMAC User’s Manual
Table of Contents ix
Power PMAC User’s Manual
Table of Contents x
Power PMAC User’s Manual
Table of Contents xi
Power PMAC User’s Manual
Table of Contents xv
Power PMAC User’s Manual
USING GENERAL PURPOSE DIGITAL I/O WITH POWER PMAC ............................. 564
Note on Using “Dedicated” I/O for General Purpose Use ........................................................564
Digital I/O Hardware and Configuration ...................................................................................564
UMAC Digital I/O Boards ................................................................................................................... 564
Compact UMAC ACC-11C Digital I/O ............................................................................................... 565
UMAC ACC-5E Digital I/O ................................................................................................................. 566
UMAC ACC-5E3 Digital I/O ............................................................................................................... 566
Power Brick Digital I/O....................................................................................................................... 567
Power Clipper Digital I/O ................................................................................................................... 567
ACC-34 Family Multiplexed Digital I/O ............................................................................................. 568
Software Configuration for Digital I/O Use ...............................................................................570
UMAC Digital I/O Boards ................................................................................................................... 570
Compact UMAC ACC-11C Digital I/O ............................................................................................... 572
UMAC ACC-5E Digital I/O ................................................................................................................. 572
UMAC ACC-5E3 Digital I/O ............................................................................................................... 574
Power Brick Digital I/O....................................................................................................................... 575
Power Clipper Digital I/O ................................................................................................................... 575
ACC-34 Family Multiplexed Digital I/O ............................................................................................. 576
Accessing Digital I/O Points in the Script Environment ............................................................580
Accessing Output Points at Different Priority Levels .......................................................................... 580
UMAC Digital I/O Boards ................................................................................................................... 581
Compact UMAC ACC-11C Digital I/O ............................................................................................... 582
UMAC ACC-5E Digital I/O ................................................................................................................. 582
UMAC ACC-5E3 Digital I/O ............................................................................................................... 583
Power Brick Digital I/O....................................................................................................................... 584
Power Clipper Digital I/O ................................................................................................................... 584
ACC-34 Family Multiplexed Digital I/O ............................................................................................. 585
Using Cyclic Scanned Buffered Inputs and Outputs ................................................................586
Enabling Cyclic Scanned I/O............................................................................................................... 586
Specifying Scanned Input Registers ..................................................................................................... 587
Override “Forcing” of Inputs ............................................................................................................. 588
Table of Contents xx
Power PMAC User’s Manual
WRITING AND EXECUTING SCRIPT PROGRAMS IN THE POWER PMAC ........... 642
Classes of Script Programs .....................................................................................................642
Motion Programs ................................................................................................................................. 642
Rotary Motion Programs ..................................................................................................................... 642
PLC Programs ..................................................................................................................................... 642
Subprograms ........................................................................................................................................ 643
Kinematic Subroutines ......................................................................................................................... 643
Script Language Syntax Features ...........................................................................................643
Mathematical Capabilities................................................................................................................... 643
Program Flow Control ........................................................................................................................ 644
Motion Specification ............................................................................................................................ 649
Program Direct Commands ................................................................................................................. 652
Downloading Rules for Script Programs ..................................................................................654
Motion Programs ................................................................................................................................. 654
Rotary Motion Programs ..................................................................................................................... 654
PLC Programs ..................................................................................................................................... 655
Subprograms ........................................................................................................................................ 655
Power UMAC
The Power UMAC is a modular rack-mounted configuration of the Power PMAC. It consists of a
set of 3U-format (100mm x 160mm) boards in a Euro-Card rack. Along with the required Power
PMAC CPU board, a customized set of interface boards can be added, communicating over a
common backplane. These include digital and analog servo interface boards, digital and analog
general-purpose I/O boards, machine network interface boards, and industrial fieldbus interface
boards. A power supply installed in the rack can be used, or an external supply.
Because of its modular nature, the Power UMAC provides the most flexible configuration for
Power PMAC systems.
CK3M (µUMAC)
The CK3M is a small modular rack-mounted configuration of the Power PMAC, with similar
form factor to the Omron NJ/NX PLCs. Along with the required Power PMAC CPU module, a
customized set of interface boards can be added, communicating over a common backplane
within one rack (line), and extensible to up to 4 lines through expansion modules and cables.
The Power PMAC Etherlite is commonly used for large systems where networked connections
are important to simplify system wiring.
CK3E (µPowerPMAC)
The µPowerPMAC [CK3E] controller is a packaged single-board controller that interfaces to
servo drives and I/O devices through the EtherCAT network.
All of these configurations can support multiple styles of position feedback: digital incremental
(quadrature) encoders, serial encoders, analog incremental (sinusoidal) encoders, and resolvers.
All configurations provide a standard set of “flags” (e.g. limit, home, and user) for each axis, with
a set of general-purpose digital I/O. General-purpose analog I/O is also available.
Power Brick AC
The Power Brick AC combines a Power PMAC controller with integrated 3-phase motor
amplifier circuits for 4, 6 or 8 axes. The AC power input for the amplifiers can be up to 240VAC.
Power Brick LV
The Power Brick LV combines a Power PMAC controller with integrated motor amplifier circuits
for 2-phase and 3-phase motors for 4 or 8 axes. It accepts a DC power input for the amplifiers of
up to 60VDC. Each axis can be configured by the user for 2-phase or 3-phase motors, open-loop
(stepper) or closed-loop (servo).
Power Clipper
The Power Clipper is a compact and cost-effective configuration of the Power PMAC for
embedded applications. It combines the Power PMAC CPU, 4 channels of axis interface circuitry,
32 general-purpose digital I/O points, and 4 optional analog inputs onto a single small circuit
board. A second Clipper board, built without the CPU, provides another set of axis and general-
purpose I/O.
The interface to the servo drives and I/O devices on these PC-based systems is done through the
EtherCAT network.
See the chapters Setting Up Feedback and Master Position Sensors and Setting Up the Encoder
Conversion Table for details.
current levels. These phase voltage commands are usually encoded as PWM duty cycles, with the
PWM signals directly driving the amplifier power transistors. See the chapter Setting Up Power
PMAC-Based Commutation and/or Current Loop for more details.
CPU Section
The core of the Power PMAC is the central processing unit (CPU), consisting of a
microprocessor, active memory, and non-volatile memory. The following figure shows the block
diagram of the Power PMAC CPU for the UMAC rack-mounted controller. Other configurations
are similar.
Video Card
Vision System Card
Disk Fieldbus Cards,
Drive etc...
Expansion Port
USB USB 2.0 Device
(User Expansion)
Processor
Initial hardware implementations of the Power PMAC use an embedded Power PC RISC
microprocessor. This 32-bit processor has relatively low heat dissipation requiring only limited
cooling, and it has a substantial number of peripherals built in, keeping the parts count of the
CPU section small. The processor has a dedicated hardware floating-point math engine, capable
of processing mathematical operations directly on both single-precision (32-bit) and double-
precision (64-bit) floating-point values.
Single-core processors running at 800 MHz and 1.0 GHz are available. Dual-core processors
running at 1.2 GHz are available.
When Power PMAC software runs on a PC, such as Omron’s IPC, the processor is of the x86
architecture.
Users can provide additional NAND flash capacity through USB-stick and/or SD card modules,
depending on the configuration of the Power PMAC.
The DSPGATE1 IC also has on-board software-configurable clock generation circuitry. It can
generate the “servo” and “phase” clocks for the entire Power PMAC system (only one IC will do
this; the others will accept these as inputs). It also generates the clock signals that drive its own
circuitry: encoders, DACs, ADCs, PWM and PFM (pulse-frequency-modulation).
9
Flag 1 ADCIN1 A,B 2
2
9
Flag 2 ADCIN2 A,B 2
2
9
Flag 3 ADCIN3 A,B 2
2
9
Flag 4 ADCIN4 A,B 2
2
Encoder/Flag Output/ADCIN
Status & Control Control 2
2 Clock, PLL
24-bit 6-bit
DATA BUS ADDRESS BUS
of the command and feedback data required for the servo and commutation of a motor. Six of the
nodes can be used for general-purpose I/O, each node supporting 72 bits of hard real-time I/O in
each direction. Two of the nodes are for non-real-time communications, including “broadcast”
mode in which a master controller can talk to all of its slave devices simultaneously.
The DSPGATE2 IC also has on-board software-configurable clock generation circuitry. It can
generate the “servo” and “phase” clocks for the entire Power PMAC system (only one IC will do
this; the others will accept these as inputs).
32
Servo Channel 1 Servo Channel 3
(Chan[0]) (Chan[2])
32
32
I/O Bank 1 I/O Bank 3
(Gpio[0]) (Gpio[2])
To
MACRO
Configuration
MACRO B Nodes Ring
Control
Data 32 9 Address
Bus Bus
It provides 4 servo channels, with each servo channel supporting the following features:
The DSPGATE3 IC also provides 4 banks of 32 general-purpose digital I/O points, with each I/O
point individually selectable for direction and software polarity. The first bank has dedicated pins
on the IC; the second, third, and fourth banks share pins with the second, third, and fourth servo
channels, respectively, with each pin individually selectable with regard to function.
In addition, it provides a 32-node bi-directional interface for the MACRO ring. Of these nodes,
16 can be used as “servo nodes”, each of which can transfer all of the command and feedback
data required for the servo and commutation of a motor. 12 of the nodes can be used for general-
purpose I/O, each node supporting 72 bits of hard real-time I/O in each direction. Four of the
nodes are for non-real-time communications, including “broadcast” mode in which a master
controller can talk to all of its slave devices simultaneously.
Finally, it has on-board software-configurable clock generation circuitry. It can generate the
“servo” and “phase” clocks for the entire Power PMAC system (only one IC will do this; the
others will accept these as inputs).
Communications Security
Communication with Power PMAC is intended to be done within a secure communications
environment. Any cybersecurity measures must be taken on the devices and networks that are in
communication with the Power PMAC.
OMRON SHALL NOT BE RESPONSIBLE AND/OR LIABLE FOR ANY LOSS, DAMAGE, OR
EXPENSES DIRECTLY OR INDIRECTLY RESULTING FROM THE INFECTION OF OMRON
PRODUCTS, ANY SOFTWARE INSTALLED THEREON OR ANY COMPUTER EQUIPMENT,
COMPUTER PROGRAMS, NETWORKS, DATABASES OR OTHER PROPRIETARY MATERIAL
CONNECTED THERETO BY DISTRIBUTED DENIAL OF SERVICE ATTACK, COMPUTER
VIRUSES, OTHER TECHNOLOGICALLY HARMFUL MATERIAL AND/OR UNAUTHORIZED
ACCESS.
It shall be the users sole responsibility to determine and use adequate measures and
checkpoints to satisfy the users particular requirements for (i) antivirus protection, (ii) data
input and output, (iii) maintaining a means for reconstruction of lost data, (iv) preventing
Omron Products and/or software installed thereon from being infected with computer
viruses and (v) protecting Omron Products from unauthorized access.
Physical Interface
Power PMAC utilizes an Ethernet interface for its main communications channel. Its Ethernet
ports are capable of 1 gigabit-per-second (1Gbps, 1000-Base-T) communications, but can also
communicate at lower speeds (e.g. 100Mbps, 100-Base-T), if that is all that the network or the
linked computer is capable of.
Power PMAC’s “ETH0” port is reserved for communications with the host computer(s)/network.
(Its “ETH1” port is reserved for Ethernet-based “fieldbus” communications that are not the
subject of this chapter.) It accepts a standard Ethernet cable with an RJ-45 jack. The connection
can be direct to the host computer or through a network, including through hubs and routers.
Link Layer
The “link layer” is the lowest of these abstraction layers, operating just above the physical layer.
It handles specific networking requirements on the local link. Common link layer protocols
include ARP (Address Resolution Protocol), NDP (Neighbor Discovery Protocol), and MAC
(Media Access Control – for Ethernet, DSL, and FDDI).
Power PMAC employs the MAC link-layer protocol on its Ethernet interface. Each Power PMAC
has a unique MAC address for its Ethernet interface that makes it identifiable at any physical
location. This MAC address is not changeable by the user.
Internet Layer
The “internet layer” provides for basic datagram transmission between (potentially) different, and
different types, of networks (hence, “internetworking”, or “Internet”). The common protocols for
this layer have been Version 4 of the Internet Protocol (IPv4), Version 6 of the Internet Protocol
(IPv6), and Internet Control Message Protocol (ICMP).
Power PMAC employs Internet Protocol Version 6 (IPv6). Each Power PMAC has an IP address.
This is set at the factory to the default IP address of 192.168.0.200. The user can change this
address. (See Changing the Power PMAC IP Address, below.) If there are multiple Power
PMACs on the same network, each must have a unique address.
Transport Layer
The “transport layer” establishes data channels between host ports, providing end-to-end
communications services for applications. Common transport-layer protocols include UDP (User
Datagram Protocol), TCP (Transmission Control Protocol), RDP (Reliable Datagram Protocol),
and DCCP (Datagram Congestion Control Protocol).
Power PMAC employs the most common on these protocols, TCP. The use of TCP permits
communications with Power PMAC over indirect links, across networks, and even between
networks. Data packets can arrive out of order and be properly re-ordered by the recipient, and
packets with errors can be detected and retransmitted.
Application Layer
The “application layer” implements process-to-process communications across networks.
Different types of applications (“processes”) use different protocols at this layer. Telnet
implements “open text” (unsecured) communications by a virtual terminal. SSH (Secure Shell)
implements protected communications by a virtual terminal. FTP (File Transfer Protocol)
implements the movement of entire files across the network. DHCP (Dynamic Host
Configuration Protocol) permits the automatic assignment of IP addresses at execution time. POP
(Post Office Protocol) and SMTP (Simple Mail Transfer Protocol) are commonly used for e-mail
transmission.
Power PMAC uses the FTP protocol for transfers of files to and from the Power PMAC,
including the applications project files, and gathered-data files.
If the program does find the Power PMAC, it will display the response from the Power PMAC.
The first line of this response identifies the Power PMAC. The second line requests a user login.
At the login prompt, type “root” and hit Enter to request communications at the root
(administrator) level.
Next, Power PMAC will request the password. At this prompt, type “deltatau” and hit Enter.
This will provide the program with access to fundamental communications with the Power
PMAC computer. The following screen capture shows the communications so far:
At this point, you are talking to the computer operating system (Linux), not the control
application within the computer. You can use standard Linux commands to perform various tasks
on the computer.
The following screen capture shows the Linux “dir” (directory) command given at the
opt/ppmac prompt, showing that the gpascii communications application is present in that
directory, followed by the command to execute the gpascii application. The Power PMAC
response (shown) is “STDIN Open for ASCII Input”
At this point, you are talking to the Power PMAC control application within the computer, and
you can issue Power PMAC commands and view the responses. You might start by issuing
several query commands to find out basic information about the Power PMAC. The following
screen shot shows the response to the Power PMAC commands cpu, date, vers, size, and
free. The “spade” figure at the end of each Power PMAC response is the ACK (acknowledge)
character (ASCII value 07), which Power PMAC uses as its “end of transmission” character.
Basic Commands and Responses with the Power PMAC Control Application
Most users will retain the default SSH underlying communications protocol, which automatically
selects virtual port number 22. Similarly, most users will select the default “Apply All Controls”
setting of “True”, which is the most convenient setting in the vast majority of cases where there is
only one Power PMAC in the system.
If you leave “Select Device at Startup” at its default setting of “True”, you will be presented with
this control window every time you start the IDE. If you set this to “False”, the IDE will
automatically try to establish communications at startup using the last settings you have made.
Click on “Connect” to attempt to establish communications with the Power PMAC at the
specified IP address. If the IDE is successful in establishing communications with the Power
PMAC computer, it will execute the gpascii application so it can communicate with the Power
PMAC control application.
Of course, you must select an IP address that is unique on your network and will not conflict with
any other IP address. You may need to consult with your network administrator to select a
permitted address.
To do this, first create a directory folder named “PowerPmacIP” at the root level on the memory
device. This is usually done on a PC. The memory device must employ the FAT32 file system,
which is by far the most common system for these devices. The folder can be left empty at this
point; no files need to be created in it. Make sure the device is safely removed from the computer
so the file system cannot be corrupted.
Install this device in your Power PMAC, and apply power to the Power PMAC to turn it on. Wait
for the boot sequence to complete – you will hear a relay click – or just allow a full minute to
elapse. Then turn off the Power PMAC and remove the memory device.
Next, install this device back in your PC and view the contents of the new “interfaces” text file in
the “PowerPmacIP” folder. This will contain the IP address. You can then use this address to
establish Ethernet communications using the IDE or your communications program (and
subsequently change this address if you wish).
To do this, connect a PC’s RS-232 serial port to Power PMAC’s RS-232 serial port. Start a
terminal utility program, such as HyperTerminal for Windows XP systems, or PuTTY for
Windows 7 systems, telling it to use the connected COM port. The settings for Power PMAC’s
serial port are:
115,200 baud
8 data bits, 1 stop bit
No parity
No handshake, no XON/XOFF flow control
Turn on the Power PMAC, and wait for the command prompt to appear in the terminal window.
Log in as “root”, then enter the password (“deltatau”) at the next prompt. Power PMAC will then
transmit information to the terminal window, including the IP address. You can then use this
address to establish Ethernet communications using the IDE or your communications program
(and subsequently change this address if you wish).
PowerPmacNoRTLoad Folder
If a folder with the name “PowerPmacNoRTLoad” is present, Power PMAC will run as a generic
Linux computer without loading the Power PMAC application. No files need to be present in this
folder.
PowerPmacFactoryReset Folder
If a folder with the name “PowerPmacFactoryReset” is present, Power PMAC will start up in
factory reset mode, equivalent to executing a $$$*** command. In this mode, the Power PMAC
application will be loaded, but no saved project will be loaded into active memory from flash
memory. All saved setup elements will be set to factory default values. No files need to be
present in this folder.
PowerPmacConfigLoad Folder
If a folder with the name “PowerPmacConfigLoad” is present, Power PMAC will copy the
project from the files and sub-folders available in this folder to Power PMAC’s own flash
memory, replacing any existing project there. The project should be under the
“/PowerPmacConfigLoad/usrflash” sub-folder.
PowerPmacFirmwareInstallandConfigLoad Folder
If a folder with the name “PowerPmacFirmwareInstallandConfigLoad” is present, Power PMAC
will install the firmware for the Power PMAC application and copy the project from the files and
sub-folders available in this folder to Power PMAC’s own flash memory, replacing any existing
project there. The firmware should be in a file with a name like “powerpmac.deb” in the main
folder. The project should be under the “/PowerPmacConfigLoad/usrflash” sub-folder.
PowerPmacIp Folder
If a folder with the name “PowerPmacIP” is present with no “interfaces” file in the folder, Power
PMAC will automatically copy its internal interfaces file into this folder, along with a boot.log
file. This is useful if the present IP address of the Power PMAC is not known.
If a folder with the name “PowerPmacIP” is present with an “interfaces” file in the folder, Power
PMAC will use the IP address in that file for communications instead of the address in Power
PMAC’s internal interfaces file.
There are two fundamental classes of Script commands to the Power PMAC control application:
on-line commands, and buffered program commands. These two classes of commands are
documented in separate chapters in the Software Reference Manual. It is very important to
understand the distinction between these two types of commands.
Note that some on-line commands are also valid as buffered program commands, so if a program
buffer is open when such a command is sent, the command will be stored in the buffer instead of
being immediately executed.
1. Thread-specific commands, which only affect the action of subsequent commands on the
same communications thread
4. Global commands, whose effect is the same regardless of any addressing modes.
In the On-Line Commands chapter of the Software Reference Manual, each command is
classified into one of these types under the “Scope” descriptor.
For example, the IDE terminal window can modally address a certain motor and coordinate
system, while the watch window, utilizing a separate communications thread, addresses a
different motor and coordinate system.
It is therefore not required to precede each motor-specific on-line command with a motor
addressing command. Working in terminal mode, you may type #1j+ to start Motor 1 jogging in
the positive direction. You can then simply type j/ to stop this same motor, as Motor 1 is still the
addressed motor in the thread. However, when generating motor-specific on-line commands in
software for Power PMAC, you are strongly advised to address the motor before each command
to avoid possible intervening changes in the modally addressed motor.
Note that at power-on/reset, Motor 0 (#0) is addressed by default in all communications threads.
Since this is generally not used as a real motor, it is usually necessary to explicitly address a
motor before issuing any motor-specific commands.
It is possible to “list” multiple motors to be affected by a single on-line command. For example,
#2,4,6hm starts homing-search moves on Motors 2, 4, and 6 simultaneously. When multiple
motors are specified this way, the addressing is not modal; only the immediately following
command is affected. (Contrast this with #2hm#4hm#6hm, which leaves Motor 6 as the modally
addressed motor.) The #* command non-modally causes the immediately following motor-
specific command to affect all active motors on the Power PMAC.
An on-line motor “action” command, such as jogging, homing, or open-loop output, is not
permitted if the motor is assigned to an axis in a coordinate system that is running a motion
program, even if the motion program is not directly commanding any axis assigned to that motor.
Such a command will be rejected with an error.
It is therefore not required to precede each motor-specific on-line command with a motor
addressing command. Working in terminal mode, you may type &1b5r to start Coordinate
System 1 execution of motion program 5. You can then simply type q to stop motion program
execution in this same coordinate system, as Coordinate System 1 is still the addressed coordinate
system in the thread. However, when generating coordinate-system-specific on-line commands in
software for Power PMAC, you are strongly advised to address the coordinate system before each
command to avoid possible intervening changes in the modally addressed coordinate system.
Global Commands
The effect of some on-line commands does not depend on which motor or coordinate system is
addressed. For instance, the command P1=1 sets the value of global variable P1 to 1 regardless
of what is addressed. Among these global commands are the global buffer-management
commands (motion-program, PLC program, and subprogram buffers), and the saving and
resetting commands.
For numbered variables (e.g. I, P, Q, M, L), the list can specify a continuous range (e.g.
P100..199, or Q0..8191), or a set of evenly spaced variables (e.g. P100,10 or
I122,5,100). In both cases, the starting variable is specified first. In the case of a continuous
range, the number of the last variable in the continuous range is specified after two periods. In the
case of a set of evenly spaced variables, the next value specified (after a comma) is the quantity
of variables in the list, and the following value (after another comma) is the numerical spacing of
the variables. If there is no following value, the spacing is taken to be 1.
For indexed data structure elements, the list can specify a set of evenly spaced indices for the
element (e.g. Motor[1].Servo.Kp,4 or Coord[2].ProgActive,6,2). The next value
specified (after a comma) is the quantity of elements in the list, and the following value (after
another comma) is the numerical spacing of the indices for the list. If there is no following value,
the spacing is taken to be 1.
Power PMAC merely causes the command to be loaded into the open program buffer; the
command will not actually be executed until that program is run.
Power PMAC has many Script program buffers – 1023 regular motion program buffers, 1 rotary
motion program buffer for each coordinate system, 1 forward-kinematic and 1 inverse-kinematic
program buffer for each coordinate system, 32 PLC program buffers, and 1023 subprogram
buffers.
Before commands can be entered into a program buffer, that buffer must be opened (e.g. open
prog 3, open plc 7, open subprog 1000, &3 open rotary). Note that buffered
commands can only be entered into the buffer through the same communications thread that
issued the open command. Only one communications thread at a time may have an open
program buffer.
With the exception of the rotary motion program buffers, the act of opening the buffer
automatically clears the contents of the buffer, so the next buffered program command sent
becomes the first command in the program buffer. For rotary motion program buffers, it is
possible to add commands to follow the already loaded commands after a new open rotary
command. If it is desired to clear the contents of a rotary motion program buffer, the clear
rotary command should be issued.
Note that some buffered program commands (e.g. P1=1) are also valid as on-line commands, and
will be executed as such if sent when no program buffer is open on the communications thread.
Note that some of these commands will have completely different actions as on-line or buffered
commands. Other buffered program commands (e.g. X100Y100) are not valid as on-line
commands; if such a command is sent when no program buffer is open on the communications
thread, this command will be rejected with an error.
Comments
Any characters in a command line after a double-slash (//) are considered comments, and are
ignored by the Power PMAC. The IDE downloader treats all characters between “slash-star” (/*)
and “star-slash” (*/) as comments and will not download them to Power PMAC. However, if
Power PMAC receives these from another source, it will not recognize them as comments, and
will try to interpret them as commands, leading to errors.
Command Acknowledgement
Power PMAC acknowledges commands with the ACK character (ASCII value 07 hex) – this
character was shown as the “spade” figure in the terminal emulator examples above. (However,
the commands that restart the Power PMAC – $$$ (reset), $$$*** (re-initialize), and reboot
– are not acknowledged with the ACK character.)
If the command requires no data response, only the ACK character is sent. If the command does
require a data response, this response comes before the ACK character. In this way, the ACK
character acts as an “end-of-transmission” character for any Power PMAC command response,
also indicating that any actions specified by the command have been executed.
Data Response
If the command does require a data response (i.e. an on-line “query” command), each item of the
response is provided as ASCII text followed by a carriage-return character, forming a “line” of
the response on a terminal screen. There can be multiple data response items, each followed by a
carriage-return character, forming multiple lines in response to a single command. After the last
line of the response, the ACK character is sent.
Motor[1].JogSpeed
Motor[1].JogSpeed=32
With echoing disabled, the same query command will create a response such as:
32
Each communications thread (e.g. each window in the IDE) can have its own echo mode. Many
users will want echoing enabled in the Terminal window, but not in the Watch window (where
the command is already displayed).
The echo mode for a communications thread is set by the echo n on-line command. The value
n has a range of 0 to 15 with 4 independent control bits.
Bit 0 (value 1) controls whether the command is echoed back in a query for the value of a data
structure element. If the bit is set to 1, echoing is disabled.
Bit 1 (value 2) controls whether the command is echoed back in a query for the value of a
numbered variable. If the bit is set to 1, echoing is disabled.
Bit 2 (value 4) controls whether the command is echoed back in a query for the definition of a
pointer variable. If the bit is set to 1, echoing is disabled.
Bit 3 (value 8) controls whether the values of “bit-field” and “address” data structure elements are
reported as hexadecimal or decimal numbers. If the bit is set to 1, they are reported in decimal.
Bits 4, 5, and 6 control how data is reported in response to backup commands. Refer to the
description of the echo{constant} command for details.
The power-on default echo-mode value is 0, which enables echoing in all these queries, and
reports bit-field and address element values in hexadecimal. IDE control windows have a saved
echo-mode setting, which can be viewed or changed by right-clicking on the window, then
clicking on “Properties”, “Control”, and “General”.
nonsensecommand
stdin:3:1: error #20: ILLEGAL CMD: nonsensecommand
motor[333].JogSpeed
stdin:4:1: error #21: ILLEGAL PARAMETER: motor[333].JogSpeed
The following table shows the implemented command error numbers and messages:
Processors (CPUs)
Different Power PMAC platforms use a variety of processors. For many purposes, the differences
between these processors are invisible to the user. However, there are a few reasons why it may
be important to understand which CPU family is used.
Power PC
The first Power PMAC implementations have processors that use the Power PC architecture.
These include the AMCC 460EX single-core CPU and the AMCC 465 (APM86xx) single or
dual-core CPU.
ARM
Newer embedded Power PMAC controllers have processors that use the ARM architecture. These
include the Freescale 1021A dual-core CPU and the Freescale 1043A quad-core CPU.
X86
Omron Industrial PCs (IPCs) with PMAC firmware installed have processors that use the “x86”
architecture. This include the Intel i7 and Celeron CPUs.
Memory
Power PMAC systems use both active and non-volatile memory. It is important to understand
how they work together.
NOR flash
Embedded Power PMACs use a NOR flash IC to store the Linux operating system. The user does
not write to the NOR flash in any normal operation.
NAND flash
Power PMACs use NAND flash “solid-state disks” (SSDs) to store user application information
when power is not applied.
The first step in this process simply copies the project files with Script commands from the PC
into a directory (/var/ftp/usrflash) in Power PMAC’s RAM. If there are C routines or applications,
the IDE cross-compiles them for the Power PMAC processor, and transfers the executable code
files. The source code files are not transferred to the Power PMAC in the default project
configuration. However, the project properties can be changed to include the source code files in
the download
The second step is to internally issue the PMAC Script commands (both on-line and buffered
program) just as if they had been externally issued from the terminal command window. This can,
and usually does, include commands to set the values of savable setup elements. The project is
now ready for execution.
Pr oject
HostComputer Commands
Download (1)
Re set (2)
Active Re set (3) Program &
Saved
Project Table
Project Files
Files
/opt/ppmac/usrflash/ Buffers
/var/ftp/usrflash/
save(2)
Download (2)
Commands
PowerPMAC
Re set (1)
Saved
Setup Active
Elements Setup
/usrflash/projects/ Elements
configuration/ppsave.cfg save(1)
Non volatile Volatile
Flash Active
Memory RAM
Note that if you transfer any programs, tables, etc. to the Power PMAC outside of the project (for
example, a CNC “part program” that is only intended to be used temporarily), it will not be
copied to flash memory in a save operation.
Second, the most recent set of project files that has been saved in flash memory is copied into the
matching directory in active memory, just as it would have been in the download process from
the PC IDE program.
Third, the PMAC Script commands (on-line and buffered program) in these files are internally
issued, just as in the download process. Note that if any of the on-line commands in a file set the
value of a saved setup element, this will overwrite the value that was just copied directly from
flash memory for that element.
General Configuration
A Power PMAC system can report key aspects of its configuration to the user. Typically the best
way to see this information is in the “CPU Information” window of the IDE’s Task Manager
(selected from the “Tools” menu). A sample is shown here:
This window uses several basic query commands to obtain its information, such as cpu, type,
vers, date, and free.
Each of these variables is a bit field. Bit i of the variable is set to 1 if the IC of that index number
has been detected, to 0 if it has not. For example, if Sys.Gate1Autodetect had a value of $150,
where bits 4, 6, and 8 were set to 1, this means that DSPGATE1 IC represented by data structures
Gate1[4], Gate1[6], and Gate1[8] were detected, and no others.
Note that the old ACC-11E UMAC digital I/O card cannot be auto-detected by the processor,
even though it has an IOGATE IC, because it lacks the circuitry required for auto-detection.
Interface IC Addresses
In addition, Power PMAC will report the offset from the start of memory-mapped I/O (which is
found in Sys.piom) of the base address of each interface IC it finds in the following status data
structure elements:
These address offsets can be useful for creating pointer variables in C to hardware registers in the
ICs. The (absolute) register address is the sum of Sys.piom, this base address offset, and the
register offset from this base (which can be found in the Power PMAC ASIC Register Element
Addresses chapter of the Software Reference Manual). A value of 0 is reported for any IC not
found.
Note that many of the PMAC2-style digital I/O cards can be represented by the GateIo[i] data
structure, but the analog I/O cards cannot. They must be represented by their own data structures,
such as Acc28E[i], Acc36E[i], and Acc59E[i].
Here, n is ‘1’ for DSPGATE1 ICs, ‘2’ for DSPGATE2 ICs, and ‘Io’ for IOGATE ICs. The same
status elements are available for the Acc28E[i], Acc36E[i], and Acc59E[i] analog I/O structures.
Change in Configuration
If, during the auto-detection process at power-on/reset, the Power PMAC CPU discovers that the
physical configuration is different from the configuration that was present the last time a save
command was issued to store configuration and project information to non-volatile flash memory,
it will automatically set the Sys.HWChangeErr status bit and re-initialize the system to factory
defaults.
This detection of a configuration change can occur if a card has been added or removed, or if
there is a hardware problem that prevents something in the configuration from being detected
properly. The re-initialization is performed because it is very likely that the saved settings and
project are no longer appropriate for safe and effective operation.
The CPU cannot output servo or phase clock signals, so if there are Servo ICs and/or MACRO
ICs in this setting, their hardware operation will not be synchronous to the software operation of
the CPU.
Note that it is strongly recommended that all Servo and MACRO ICs in the system be set up for
the same phase and servo clock frequencies as the IC that is generating the system clock signals.
When these ICs are set up to receive external clock signals, they are still generating internal clock
frequencies, but are pulled into synchronization with the external signals through phase-locked-
loop (PLL) circuits. Intermediate signals, such as those used in PWM generation, operate better if
the PLLs are only making small corrections.
Phase Clock
Servo Clock
PSD: Gaten[i].PhaseServoDir
Saved setup element Gaten[i].PhaseServoDir controls the “direction” of the clock signal for
each of these DSPGATEn ICs. If the variable value is 0, the IC generates its own clock signals
and outputs them. If the variable value is 3, the IC accepts the clock signals from a source
external to it. Only one of these ICs can have this variable at a value of 0; the rest must be set to
3.
If more than one of these ICs is set up to use its own clock
signals and to output them, the processor will be interrupted by
multiple sources and will not operate normally – it is possible
that the watchdog timer will trip. (Because the outputs are
Note open-collector types, there will be no hardware damage from
signal contention, but system software operation will be
compromised.)
With the Etherlab EtherCAT stack (Sys.EcatType = 0), ECAT[i].DistrClocks must be set to 1 to
enable DC mode. With the Acontis EtherCAT stack (Sys.EcatType = 1), the EtherCAT Network
Information (ENI) initialization file created by the configuration program must contain the
command to enable DC mode.
synchronization. If the reference device is the EtherCAT master (Power PMAC), all of the slaves
must adjust; this is called “bus shift mode”. If the reference device is one of the slaves, the master
must adjust; this is called “master shift mode”.
In most configurations, either bus shift or master shift mode can be used. However, some
EtherCAT slave devices do not synchronize properly in one or the other mode, and this can force
the user to choose a particular mode for the network. If Power PMAC is the master on multiple
EtherCAT networks simultaneously, all of the networks must be operated in bus shift mode.
In master shift mode, the Power PMAC must be set up to specify how it will adjust its servo
clock frequency to stay synchronized to the reference slave. There are two adjustment methods.
The first method is a PID feedback algorithm that has variable adjustments each cycle. The
second method is a hysteresis loop with a fixed adjustment rate outside of a deadband.
Both of these methods can be used whether the servo clock is generated by a Servo or MACRO
ASIC, or by the processor itself. If the servo clock is generated by a DSPGATE1 or DSPGATE2
IC, the value in Gaten[i].PwmPeriod is adjusted. If the servo clock is generated by a
DSPGATE3 IC, the value in Gaten[i].PhaseFreq is adjusted. If the servo clock is generated
inside the processor, the value in an internal timer register (originally set from Sys.ServoPeriod)
is adjusted.
The PID algorithm is selected by setting the proportional (P) gain term ECAT[i].DCKp greater
than 0.0. Then the integral (I) gain term ECAT[i].DCKi, derivative (D) gain term
ECAT[i].DCKd, integration limit ECAT[i].DCiLimit, and maximum correction
ECAT[i].DCMaxAdjust are used as well. The default settings of these terms work well for most
configurations.
The hysteresis loop is selected by setting ECAT[i].DCKp to 0.0 (not its default). Then the fixed
adjustment rate terms ECAT[i].DCRefPlus and ECAT[i].DCRefMinus, and deadband
ECAT[i].DCRefBand are used. The default settings of these terms work well for most
configurations.
In Power UMAC systems, the phase and servo clocks are shared across the “UBUS” backplane
board in differential format among the different 3U-format cards inserted into that backplane.
Each card has differential buffer ICs for these signals as they interface to the backplane. On cards
that are potential sources of the phase and servo clock signals, such as the ACC-24E/C axis
boards or the ACC-5E MACRO board, these buffers can be configured as either inputs or
outputs.
On each UMAC board with a PMAC2-style Servo IC that could be a clock source, there is a
jumper that controls the configuration of the clock-direction buffers. In one setting, the board can
only input the clock signals. This setting is required for the older UMAC MACRO, in which the
clock signals always come from the MACRO interface board. It is permissible, but not
recommended, for boards in UMAC Turbo systems that will be not be generating their own phase
and servo clock signals. This setting is not permissible for the UMAC board that is generating the
system phase and servo clocks.
In the other setting (the factory default setting), the direction of the clock-signal buffers can be
reversed by the CPU. This setting is required for the board that is generating the system clocks; it
is recommended for the other boards as well (so the source can be changed without moving any
buffers). At power-up/reset, the CPU will configure the buffers the board containing the Servo IC
or MACRO IC that is specified by the saved configuration to generate the system clocks as
outputs to the UBUS backplane; it will configure the buffers on all other boards to be inputs from
the UBUS backplane.
It will set the Gaten[i].PhaseServoDir element for this IC to 0, and for all of the other ICs to 3.
The global status element Sys.ClockSource indicates the type and index of the selected IC.
If the hardware configuration the CPU finds on power-up/reset is not the same as that in the last
valid saved configuration, the Power PMAC will come up in an error condition, setting global
status bit Sys.HWChangeErr to 1. In this case, the user must make the software system
configuration match the new hardware configuration (usually by using the $$$*** re-
initialization command), save this configuration, and reset the system before proceeding.
If the CPU does not receive phase and servo clock signals after it configures the Servo and
MACRO ICs and bi-directional clock buffers, it will come up in an error condition not permitting
control, and set global status bit Sys.NoClocks to 1.
The change involves changing the setting of Gaten[i].Chan[j].PhaseServoDir for the default
source from 0 to 3 and for the new source from 3 to 0. In addition, for any PMAC2-style
DSPGATE1 IC (as on an ACC-24E2x board) or DSPGATE2 IC (as on an ACC-5E board), a
separate parameter Cid[x].Dir must be changed as well to turn around the direction of an external
bi-directional buffer IC. (This is done automatically with PMAC3-style DSPGATE3 ICs.)
Cid[x].Dir must be set to 0 when the IC is not a source, so it can accept the clock signals as
inputs, and to 1 when the IC is a source, so it can output the clock signals. The Software
Reference Manual chapter Power PMAC I/O Address Offsets has a table of the x index values for
all Gaten[i] IC values. The most commonly used are Cid[2] for Gate1[4] and Cid[4] for
Gate2[0].
For example, to change the clock source from an ACC-5E at Gate2[0] to an ACC-24E3 at
Gate3[0], the following command line could be used:
These changes must be saved to maintain the settings through a reset or power cycle. After this,
global status element Sys.ClockSource should reflect the IC you have chosen as the source of the
system clocks. (If it reports a negative value, you have multiple clock sources, and you must
correct this before you can continue.)
Note that there are no phase tasks executed on PMACs that do not support Servo or MACRO ICs
(e.g. CK3Es, IPCs).
While most users do not need to know the specific order of tasks within the servo interrupt,
advanced users, especially those writing custom algorithms, may find this information useful. The
order of tasks is:
1. EtherCAT cyclic input transfers (if enabled), loading input data including servo feedback
into ECAT[i].IO[k].Data memory holding elements.
2. Encoder conversion table pre-processing of feedback and master data, starting with the
entry whose index is specified by Sys.FirstEnc and continuing in numerical order until
the first entry with EncTable[n].type = 0.
3. Update raw actual positions (Motor[x].Pos, Pos2) for all active motors, from lowest to
highest numbered. For each:
a. Read encoder conversion table results and add into previous cycle’s position
b. Update buffers for filtered velocity calculations
4. Update cam table and compensation table outputs for all active tables
5. Update commanded position for all active motors, from lowest to highest numbered. For
each:
6. Servo loop update for each active motor, from lowest to highest numbered. For each:
7. Update time-base (%) value for each active coordinate system, from lowest to highest
8. EtherCAT cyclic output transfers (if enabled), transmitting output data including servo
commands from ECAT[i].IO[k].Data memory holding elements over the network.
*Can be delayed until after some motor loop closures with non-zero value for Sys.CompMotor
*Can specify the number of motors to execute these checks each RTI with Sys.MotorsPerRtInt.
The following diagram shows how key phase and servo clock hardware and software tasks are
coordinated:
Phase
Clock
[1] [1]
Phase [2] [2]
[2]
Tasks
Servo
Tasks
Servo
Clock
[1] Servo command for motors not
commutated by PMAC
Feedback devices that provide data to the Power PMAC serially, such as serial-protocol encoders,
serial ADCs, and the MACRO ring, must be strobed earlier than these interrupt-causing clock
edges to provide time for the full data transfer before the interrupt, at which time the data is
latched into processor-readable registers. Usually, these are strobed on the preceding rising edge
of the phase clock, meaning that there is an added one-half phase cycle delay in using this data.
Some of the serial encoder and serial ADC interfaces permit the strobing to be delayed somewhat
past this clock edge, permitting a reduction the time delay before use at the CPU interrupt. The
serial encoder interfaces permit the strobing to occur on the previous falling edge of the phase
clock, or on either edge of the servo clock, if there is not enough time to transmit the data in one-
half phase cycle.
When the phase tasks are completed in any cycle where the servo clock signal is low, the servo
software tasks immediately start. As each motor’s servo loop is executed, if the motor is not
commutated by PMAC, its command output is written directly to the specified register at this
time. (See arrows marked [1].) If the motor is commutated by PMAC, its command output is held
in memory for use by the commutation algorithm that starts in the next phase clock cycle. This
value may be used as input to the commutation algorithm in multiple phase cycles. (See arrows
marked [2].)
In virtually all applications, the phase tasks for all motors will complete before the rising edge of
the phase clock, so there is only a one-half phase cycle delay from the start of computation to the
start of transmission. If the phase tasks for any motor complete after this rising edge, the
command values will not be transmitted until the next rising edge, resulting in a one-and-one-half
cycle delay. (This is very rare.)
In many applications, the servo tasks for all motors will complete before the first rising edge of
the phase clock. In this case, for motors not commutated by PMAC, command transmission will
start at this first rising edge. If there are the default 4 phase cycles per servo cycle, there will be a
1/8-servo-cycle delay from the start of computation to the start of transmission. If the servo tasks
for any motor not commutated by PMAC complete after this rising edge, the command values
will not be transmitted until the next rising edge. With 4 phase cycles per servo cycle, this results
in a 3/8-servo-cycle delay.
For a motor commutated by PMAC, if the servo tasks for a motor are completed by the next
falling edge of the phase clock, the servo command output is used as an input to the commutation
algorithm in this next phase cycle. If the servo tasks for a motor are not completed by this edge,
the servo command output will not be used until the following phase cycle.
Background Tasks
For “single-core” versions of the CPU, in the time available between cycles of the above tasks,
the Power PMAC processor performs background tasks, both those controlled by Power PMAC’s
scheduler, and independent applications running under the general-purpose operating system
(GPOS).
For “multi-core” versions of the CPU, in the default configuration, the interrupt-driven tasks
listed above execute in one core, and the background tasks execute simultaneously in a separate
core.
In Power PMACs with “kernel mode” operation (UMAC, Clipper, Brick, CK3M), each
background cycle, Power PMAC repeats a loop of executing one scan of one active background
Script PLC program, then one scan of all active background C PLC programs until all of the
active background Script PLC programs have executed, followed by one pass of the background
housekeeping and status update tasks.
In Power PMACs with “Posix mode” operation (CK3E, Sysmac IPC, NJ/NX PLC), each
background cycle, Power PMAC repeats a loop of executing one scan of one active background
Script PLC program, followed by one pass of the background housekeeping and status update
tasks.
In either case, when a background cycle is complete, the Power PMAC background scheduler
“sleeps” for an interval to provide time for independent applications and GPOS tasks (including
the “gpascii” communications threads) to run. The “sleep” interval is set by saved setup
element Sys.BgSleepTime, and can range from 0.25 milliseconds to 10.0 milliseconds, with a
default of 1.0 millisecond.
This diagram shows the background process flow for “kernel mode” Power PMACs:
Independent
PMAC Scheduled Background Tasks OS Tasks
This diagram show the background process flow for “Posix mode” Power PMACs:
House-
Script Background C Apps,
keeping
PLC 2 Sleep Time GPOS
Independent
OS Tasks
Independent
PMAC Scheduled Background Tasks OS Tasks
Multi-Tasking Example
The following time-line drawing provides an example of how a single-core Power PMAC
processor allocates time for different tasks. The top line shows one phase cycle, with the phase
tasks highlighted in red at the beginning of the cycle, immediately following the interrupt. The
second line shows a servo cycle, with the servo tasks highlighted in blue occurring after the
higher-priority phase tasks have finished.
The third line shows a real-time interrupt cycle, with the RTI tasks highlighted in green occurring
after the higher-priority phase and servo tasks have finished. The last line shows a background
cycle (which is not a fixed-time cycle like the above cycles are), with the background tasks
highlighted in yellow occurring when all the interrupt tasks have finished.
Phase
Phase
Interrupt
Interrupt
Servo Servo
Interrupt Interrupt
RTI RTI
Background
Cycle (Interrupt Tasks) BGPLC BGCPLCs (Interrupt Tasks) Sleep for GPOS Apps
In a dual-core CPU, the core executing the interrupt tasks is idle during the periods where a
single-core CPU would be executing background tasks (yellow in the above example). The other
core will be executing background tasks concurrently.
Power PMACs with Quad Core ARM CPUs (LS1043A) permit the user to change the task
assignments from the default configuration through the IDE. Note, however, that the default
configuration is appropriate for the large majority of applications, so the assignments should be
changed only if the default is found to be not appropriate. See the section “Task Priority Duty
Cycles” below for information on analyzing these cases.
The IDE control for assigning tasks to cores is shown below. If the configuration is changed, a
full reboot or power cycling is required to implement the change.
In this window, you can enter your desired phase-clock frequency directly in kilohertz (kHz). For
the servo-clock frequency, which must be derived from the phase-clock frequency, you must
choose from the pick list of possible frequencies. The PWM frequencies of hardware that can
generate pulse-width-modulated signals can also be selected from a pick list by right-clicking on
the hardware name. Once you have entered the settings you want, click on the “Accept” button on
the right to load the appropriate settings into the Power PMAC.
The following sections explain how to make these settings manually and directly, both for
understanding and to permit other avenues for specifying these settings.
Gaten[i].PwmPeriod
Gaten[i].PhaseClockDiv
Gaten[i].ServoClockDiv
In this description, n is 1 for a DSPGATE1 Servo IC, or 2 for a DSPGATE2 MACRO IC.
The following figure shows the block diagram for the circuits that generate these clock signals, as
well as the “hardware clock” signals in a PMAC2-style IC.
PWM Max
Count
PWM Dead Time/
PFM Pulse Width 8
DT / PW
24 6 40 MHz
1
Data Address
3
Encoder Sample n = 0 - 7 1 SLCK
Clock Control 2n
PFM n=0-7 1 PFMCLK
Clock Control 2n
DAC n=0-7 1 DACCLK
Clock Control 2n
ADC n=0-7 1 ADCCLK
Clock Control 2n
Int/Ext Phase
Int/Ext Servo
Phase n = 0 - 15 1 PHASE
Clock Control 2n
Servo n = 0 - 15 1 SERVO
Clock Control 2n
External External
Phase Servo
To set Gaten[i].PwmPeriod for a desired “MaxPhase” clock frequency, the following formula
can be used:
117,964.8 (kHz)
Gaten [i].PwmPeriod 1
2 * MaxPhaseFr eq (kHz)
MaxPhaseFr eq (kHz)
Gaten [i].PhaseClock Div 1
PhaseFreq (kHz)
At the default value of 0 (divide by 1) and the default MaxPhase frequency of 9.04 kHz, this sets
a phase clock frequency of 9.04 kHz (110 μsec period).
PhaseFreq (kHz)
Gaten [i].ServoClock Div 1
ServoFreq (kHz)
At the default value of 3 (divide by 4) and the default phase clock frequency of 9.04 kHz, this sets
a servo clock frequency of 2.26 kHz (442 μsec period).
The following diagram shows the relationship between the PWM counter, whose
period/frequency is set by the Gaten[i].PwmPeriod parameter, the resulting MaxPhase clock
signal, and the phase and servo clock signals that are derived from MaxPhase.
PWM
Counter t
-Pwm
Period
Max
Phase
Phase
Servo
Gate3[i].PhaseFreq
Gate3[i].ServoClockDiv
The following figure shows the block diagram for the circuits that generate these clock signals, as
well as the “hardware clock” signals in a PMAC3-style IC.
PSD Bit 0 = 0
Gate3[i].Chan[1]. f PWM 1
Gate3[i]. PwmFreqMult
PhaseClockDiv PSD Bit 0 = 1
If the IC is generating its own phase clock, it is possible for it to output a phase clock signal to the
system that is 2, 4, or 8 times the frequency that it uses internally, as controlled by saved setup
element Gate3[i].PhaseClockMult. The internal frequency is multiplied by a value of
(2^Gate3[i].PhaseClockMult) to obtain the output frequency. At the default value of 0, the
output frequency is the same as the internal frequency, and this should only be changed for
specialized systems, generally those that require a very wide range of PWM frequencies from
different ICs.
If the IC is accepting an external phase clock, it is possible for it to divide down this frequency
for internal use by a factor of 2, 4, or 8, as controlled by saved setup element
Gate3[i].PhaseClockDiv. The external frequency is divided by a value of
(2^Gate3[i].PhaseClockDiv) to obtain the internal frequency. At the default value of 0, the
internal frequency is the same as the input frequency, and this should only be changed for
specialized systems, generally those that require a very wide range of PWM frequencies from
different ICs.
Note that in the DSPGATE3 IC, the channel PWM frequencies are derived from the phase clock
frequency, whereas in the older PMAC2-style ICs, the phase clock frequency is derived from the
(common) PWM frequency. In the DSPGATE3 IC, a channel’s PWM frequency is determined by
Gate3[i].Chan[j].PwmFreqMult, and can range from 0.5 to 3.5 times the phase clock frequency.
PhaseFreq (kHz)
Gate3[i].ServoClock Div 1
ServoFreq (kHz)
At the default value of 3 (divide by 4) and the default phase clock frequency of 9.04 kHz, this sets
a servo clock frequency of 2.26 kHz (442 μsec period).
If the Power PMAC is closing the current loop for direct PWM control over the MACRO ring, it
is desirable to have two hardware ring update cycles (which occur at the hardware phase clock
frequency) per software phase update. This eliminates one ring cycle of delay in the current loop,
which permits higher gains and performance. To do this, the phase clock frequency would be set
twice as high as the desired current-loop closure frequency (e.g. 18 kHz vs. 9 kHz), and
Sys.PhaseCycleExt would be set to 1.
parameter does not control the servo update period, it merely notifies the interpolation software
what this period is. The default value of Sys.ServoPeriod matches the default settings for the
servo update period in the Gaten[i] data structures.
In applications with very high RTI frequencies, typically for very high move block rates, this
frequency of checking is not needed and can consume a noticeable percentage of CPU time.
Setting Sys.MotorsPerRtInt (new in V1.6 firmware, released 1st quarter 2014) to a value greater
than 0 means that only the specified number of motors will be checked each RTI. This parameter
provides the user with additional flexibility in allocating CPU time in demanding applications.
This mode of operation is used when the Power PMAC is commanding servo drives over a
network such as EtherCAT and does not need any local ICs, or for software simulation purposes
when only a CPU is present. Note that the CPU cannot output physical phase and servo clock
signals in this mode, so it could not be kept synchronized with any of these local ICs.
If Power PMAC detects valid clock signals at power-up/reset, but loses them subsequently, the
watchdog timer will trip, shutting down operation of the system. If saved setup element
Sys.BgWDTReset is set well, a “soft” trip will occur, leaving the processor running, but forcing
all interface hardware into its reset state. If such a soft trip does not occur, the hardware watchdog
timer circuitry will force a “hard” trip, completely shutting down the processor as well as forcing
all interface hardware into its reset state. For more details on the watchdog timer, refer to the
User’s Manual chapter Making Your Power PMAC Application Safe.
A sample display for a dual-core CPU is shown in the next figure. It shows the time usage of each
core separately.
Note that the time status elements used for these displays, and detailed below, are only directly
accessible from the Script environment, as they actually implement function calls to calculate the
scaled values.
The user can set the Sys.MinPhaseTime and Sys.MaxPhaseTime elements to 0.0 to “reset”
them, and Power PMAC will restart its evaluation of the lowest and highest times, respectively,
from this point. This is useful when a change in configuration is made.
Any incrementing of the Sys.PhaseErrorCtr value should be considered a serious problem that
requires correction.
The user can set the Sys.MinServoTime and Sys.MaxServoTime elements to 0.0 to “reset”
them, and Power PMAC will restart its evaluation of the lowest and highest times, respectively,
from this point. This is useful when a change in configuration is made.
If the servo tasks are interrupted by the phase clock before they are finished, the time elapsed
measured for the servo tasks, which is simply the difference between the times when they started
and when they ended, includes any intervening higher-priority phase tasks. For details of how to
derive the actual servo task time, refer to the individual element descriptions in the Software
Reference Manual.
The user can set the Sys.MinRtIntTime and Sys.MaxRtIntTime elements to 0.0 to “reset” them,
and Power PMAC will restart its evaluation of the lowest and highest times, respectively, from
this point. This is useful when a change in configuration is made.
If the real-time interrupt tasks are interrupted by the phase or servo clock before they are finished,
the time elapsed measured for the real-time interrupt tasks, which is simply the difference
between the times when they started and when they ended, includes any intervening higher-
priority phase or servo tasks. For details of how to derive the actual RTI task time, refer to the
individual element descriptions in the Software Reference Manual.
The user can set the Sys.MinBgTime and Sys.MaxBgTime elements to 0.0 to “reset” them, and
Power PMAC will restart its evaluation of the lowest and highest times, respectively, from this
point. This is useful when a change in configuration is made.
In the standard single-core CPUs, if the scheduled background tasks are interrupted by the phase,
servo, or RTI clock before they are finished, the time elapsed measured for the background tasks,
which is simply the difference between the time when they started and when they ended, includes
any intervening higher-priority phase, servo, or RTI tasks.
In a multi-core CPU, the background tasks are running on a separate core, so are not interrupted
by foreground tasks. In this case, the time elapsed from start to finish is the time actually spent
computing these tasks.
The background cycle does not have a fixed period. After a background cycle’s tasks complete,
the background execution thread “sleeps” for the time set by Sys.BgSleepTime (1.0 millisecond
by default) before it will look to start the next cycle. This interval provides independent C
applications with time to execute. Of course, all interrupt-based tasks will pre-empt any
background tasks.
The time from the start of interrupt software tasks in one phase cycle to the start of these tasks in
the next phase cycle can be found in status element Sys.PhaseDeltaTime. The longest time found
is stored in Sys.MaxPhaseDeltaTime; the shortest time found is stored in
Sys.MinPhaseDeltaTime. (The user can set these max and min elements to 0.0 to “reset” them.)
If there is an unusually long latency in one cycle, Sys.PhaseDeltaTime for that cycle will be
large. If the following cycle has a typical delay, Sys.PhaseDeltaTime for this next cycle will be
small. A good estimate of worst case latency (WCL) can be made by calculating:
Sys.MaxPhaseDeltaTime Sys.MinPhaseDeltaTime
WCL 1
2
In this equation, the variation in latency is determined by subtracting the “min” value from the
“max” value and dividing by 2. This variation is then added to the typical latency of 1 μsec.
In a single-core CPU, the primary cause of intermittent high latency is heavy Ethernet
communications, as there are certain tasks in the communications that cannot be interrupted.
These can cause occasional latencies of 10 μsec or more. In a dual-core CPU, Ethernet
communications is handled on a different core from the interrupt tasks, so this is not an issue.
In a dual-core CPU, the primary cause of intermittent high latency is arbitration of shared
resources between cores, such as the external memory bus. These can cause occasional latencies
of 3 to 4 μsec.
If the worst case latency causes the command output value of a phase or servo task to be
computed after it should be sent to the output devices, this can cause a “glitch” in the control
effort, which may not be tolerable in the application.
If your Power PMAC application does not utilize the MACRO ring, this chapter can be skipped.
MACRO is a master/slave network. Power PMAC is most commonly used as a master on the
ring, sending commands to slave servo drives, I/O modules, and other peripherals on the ring, and
receiving feedback values from them. However, it is possible to configure Power PMAC as a
slave device on the ring, and for its motors to be set up to accept cyclic servo commands over the
ring. This permits a single Power PMAC (the master) to compute all of the coordinated tasks, but
to distribute the individual motor tasks such as servo-loop closure and motor commutation, and
the hardware, across the ring.
In addition, a MACRO ring can be configured as a “multi-master” network, with each master
device commanding its own slave devices over a common ring. In this setup, one of the master
devices must be configured as the “synchronizing master”, which provides the overall control of
the ring. Other masters on the same ring must be configured as “non-synchronizing” masters. In
the physical connection of the ring, the synchronizing master must be “upstream” of the other
masters. (In a single-master ring, the master device must be configured as a synchronizing
master.)
Note that a single device on a MACRO ring may have multiple MACRO ICs, and each IC must
be configured as to its function on the ring. Only a single IC on the ring may be configured as a
synchronizing master. Other ICs on master devices, even if on the same device as the IC
configured as a synchronizing master, must be set up as non-synchronizing masters.
The function of a MACRO IC on a ring is determined by a saved setup element for the IC. The
exact functionality of this setup element differs based on the IC used.
PMAC2-Style MACRO IC
In a PMAC2-style “DSPGATE2” MACRO IC, the IC’s function on the ring is determined by
saved setup element Gate2[i].MacroMode. (Remember that you can also use the accessory name
for the structure, so you could refer to it as Acc5E[i].MacroMode.) The important bits in this
element are bit 4, bit 5, and bit 7.
Bit 4 (value $10) should be set to 1 if the IC is used as a master on the ring, synchronizing or not.
It should be set to 0 if the IC is used as a slave on the ring.
Bit 5 (value $20) should be set to 1 if the IC is used as the synchronizing master on the ring (in
which case bit 4 must also be set to 1). It should be set to 0 if the IC is used as a non-
synchronizing master or as a slave.
Bit 7 (value $80) determines whether the IC’s phase clock counter is automatically reset on the
IC’s receipt of the “sync” data packet. This bit should be set to 0 if the IC is used as a
synchronizing master, because its own phase clock will control the entire ring (but setting it to 1
will not hurt operation). The bit should be set to 1 if the IC is used as a non-synchronizing master
or as a slave, in order to keep it in sync with the synchronizing master.
Synchronizing Master IC
The IC used as the ring’s synchronizing master (most commonly Gate2[0]) should have bits 4
and 5 set to 1, and bit 7 set to 0, so Gate2[i].MacroMode should be set to $30 for this IC.
Non-Synchronizing Master IC
An IC used as a non-synchronizing master should have bit 4 set to 1 and bit 5 set to 0. If the IC is
in the same Power PMAC system as the ring’s synchronizing master IC, it receives the ring-
controlling phase clock signal directly, and does not need to use the receipt of the sync packet to
stay synchronized. For such an IC (such as the 2nd MACRO IC on the same ACC-5E as the
synchronizing master, or a MACRO IC on another ACC-5E in the same UMAC rack), bit 7 can
be set to 0, so Gate2[i].MacroMode should be set to $10.
However, if the IC is in a different Power PMAC system from the ring’s synchronizing master
IC, it must use the receipt of the sync packet to stay properly synchronized on the ring. For such
an IC, bit 7 should be set to 1 to maintain this synchronization. In addition, the IC must be able to
accept “broadcast” communications from the synchronizing master, which has a different master
IC number. These broadcast messages are sent on Node 14, so bit 14 (value $4000) of this
element should also be set to 1 to disable the “master-number check” for the Node 14 packet.
This means that Gate2[i].MacroMode should be set to $4090 for this IC (Node 14 master-
number check disable, sync packet receipt lock, and master IC).
Slave IC
An IC used as a slave on the ring should have bits 4 and 5 both set to 0 to disable any master
functionality. Bit 7 should be set to 1 to lock in the IC’s phase clock on receipt of the sync packet.
Bit 14 should be set to 1 to disable the “master-number check” on the Node 14 packet. This
means that Gate2[i].MacroMode should be set to $4080 for this IC (Node 14 master-number
check disable, sync packet receipt lock). This is the default value for the IC.
PMAC3-Style MACRO IC
In a PMAC3-style “DSPGATE3” MACRO IC, the IC’s function on the ring is determined by
saved setup elements Gate3[i].MacroModeA and Gate3[i].MacroModeB. Note that the
DSPGATE3 IC acts as a “double IC” on the MACRO ring, with two separate master numbers,
one for bank “A” of MACRO nodes, and one for bank “B”.
(Remember that you can also use the accessory name for the structure, so you could refer to the
elements as Acc5E3[i].MacroModeA and Acc5E3[i]MacroModeB for Power UMAC systems,
or Acc5EP3[i].MacroModeA and Acc5EP3[i].MacroModeB for Power PMAC EtherLite
controllers.) The important bits in this element are bit 12, bit 13, and bit 15.
As key setup variables in the DSPGATE3 IC, these elements are write-protected to prevent
inadvertent changes by unauthorized personnel. In the Script environment, global variable
Sys.WpKey should be set to $AAAAAAAA to permit changes to the values of these elements. In
the C environment, IC variable Gate3[i].WpKey should be set to $AAAAAAAA before each
command that would change the value of these elements in the IC.
Bit 12 (value $1000) should be set to 1 if the IC is used as a master on the ring, synchronizing or
not. It should be set to 0 if the IC is used as a slave on the ring.
Bit 13 (value $2000) should be set to 1 if the IC is used as the synchronizing master on the ring
(in which case bit 12 must also be set to 1). It should be set to 0 if the IC is used as a non-
synchronizing master or as a slave.
Bit 15 (value $8000) determines whether the IC’s phase clock counter is automatically reset on
the IC’s receipt of the “sync” data packet. This bit should be set to 0 if the IC is used as a
synchronizing master, because its own phase clock will control the entire ring (but setting it to 1
will not hurt operation). The bit should be set to 1 if the IC is used as a non-synchronizing master
or as a slave, in order to keep it in sync with the synchronizing master.
Synchronizing Master IC
The IC used as the ring’s synchronizing master (most commonly Gate3[0]) should have bits 12
and 13 set to 1, and bit 15 set to 0, so Gate3[i].MacroModeA and Gate3[i].MacroModeB
should be set to $3000 for this IC.
Non-Synchronizing Master IC
An IC used as a non-synchronizing master should have bit 12 set to 1 and bit 13 set to 0. If the IC
is in the same Power PMAC system as the ring’s synchronizing master IC, it receives the ring-
controlling phase clock signal directly, and does not need to use the receipt of the sync packet to
stay synchronized. For such an IC (such as the 2nd MACRO IC on the same ACC-5E3 or ACC-
5EP3 as the synchronizing master, or a MACRO IC on another ACC-5E3 in the same UMAC
rack), bit 15 can be set to 0, so Gate3[i].MacroModeA and Gate3[i].MacroModeB should be
set to $1000.
However, if the IC is in a different Power PMAC system from the ring’s synchronizing master
IC, it must use the receipt of the sync packet to stay properly synchronized on the ring. For such
an IC, bit 15 should be set to 1 to maintain this synchronization. In addition, the IC must be able
to accept “broadcast” communications from the synchronizing master, which has a different
master IC number. These broadcast messages are sent on Node 14, so bit 22 (value $400000) of
this element should also be set to 1 to disable the “master-number check” for the Node 14 packet.
This means that Gate3[i].MacroModeA and Gate3[i].MacroModeB should be set to $409000
for this IC (Node 14 master-number check disable, sync packet receipt lock, and master IC).
Slave IC
An IC used as a slave on the ring, as in a Power Brick drive used as a slave device, should have
bits 12 and 13 both set to 0 to disable any master functionality. Bit 15 should be set to 1 to lock in
the IC’s phase clock on receipt of the sync packet. Bit 23 should be set to 1 to disable the
“master-number check” on the Node 23 packet. This means that Gate3[i].MacroMode should be
set to $808000 for this IC (Node 15 master-number check disable, sync packet receipt lock).
The synchronizing master IC for the ring should also be the source of the phase-clock signal for
the Power PMAC in which it resides. When a Power PMAC system is re-initialized, it
automatically selects the lowest numbered MACRO IC it finds (with a preference for PMAC3-
style ICs over PMAC2-style ICs if both are present) as its source for the phase (and servo) clock
signal it uses internally.
The general topic of setting the clock frequencies for a Power PMAC system is covered in the
Power PMAC System Configuration chapter of the User’s Manual. This section covers those
aspects particular to systems with a MACRO ring interface.
PMAC2-Style MACRO IC
In a PMAC2-style “DSPGATE2” MACRO IC, the phase-clock frequency is determined by the
settings of saved setup elements Gate2[i].PwmPeriod, which sets the internal “MaxPhase” clock
frequency, and Gate2[i].PhaseClockDiv, which controls how the phase-clock signal itself is
divided down from MaxPhase.
The required setting for Gate2[i].PwmPeriod to obtain a desired MaxPhase clock frequency is
given by the following equation:
117,964.8(kHz)
Gate2[i].PwmPeriod 1
2 * MaxPhaseFreq(kHz)
This is typically rounded down to the next integer if the equation produces a fractional
component.
The frequency of the phase clock signal is given by the following equation:
MaxPhaseFreq(kHz)
PhaseFreq(kHz)
Gate2[i].PhaseClockDiv 1
In almost all MACRO systems, it is acceptable to set the phase-clock frequency to the MaxPhase
frequency, so Gate2[i].PhaseClockDiv can be set to 0, and Gate2[i].PwmPeriod can be used
directly to set the phase-clock frequency. In this case, the frequency of any PWM signals
generated by this IC are one-half that of the phase clock. It is rare that the same IC is used to
generate PWM signals, so this is not a constraint in most systems.
For example, to set a phase-clock frequency of 8 kHz, with the internal MaxPhase frequency the
same, Gate2[i].PwmPeriod would be calculated as:
117,964.8
Gate2[i ].PwmPeriod 1 7371
2 *8
Gate2[i].PhaseClockDiv would be set to 0 so that the phase-clock frequency is the same as the
MaxPhase clock frequency.
PMAC3-Style MACRO IC
In a PMAC3-style “DSPGATE3” MACRO IC, the phase-clock frequency is determined by the
setting of saved setup element Gate3[i].PhaseFreq, which specifies the frequency directly in
Hertz. To set a phase-clock frequency of 8 kHz, Gate3[i].PhaseFreq would be set to 8000.
If Power PMAC is closing the current loops of motors in “direct PWM” mode, as with Delta
Tau’s Geo MACRO drives, the added ring delays can have a significant impact on the quality of
the resulting performance. In this mode, many users want to increase the hardware ring-cycle
frequency to lessen these delays.
Saved setup element Sys.PhaseCycleExt specifies the number of hardware phase-clock cycles
that are skipped between each phase-clock cycle that causes the software tasks such as
commutation and current-loop closure to execute. At the default value of 0 that is used in almost
all non-MACRO applications, these software tasks are executed every hardware phase-clock
cycle.
If Sys.PhaseCycleExt is set greater than 0, one or more hardware cycles are skipped between
consecutive phase software updates in the Power PMAC. Since the MACRO ring operates on the
hardware phase-clock cycle, it is possible to raise the ring-update frequency without increasing
the software load on the Power PMAC processor, but reduce the ring transport delays to improve
loop performance.
Many MACRO users will set Sys.PhaseCycleExt to 1 so that one hardware cycle is skipped
between consecutive phase software updates. For example, a 20 kHz ring-cycle update frequency
could be used with only a 10 kHz phase-software update rate. This reduces the ring transport
delays from two 100-microsecond periods to two 50-microsecond periods, which can permit
significantly higher performance.
The following timeline diagram shows how the overall data transmission and loop calculations
work with Sys.PhaseCycleExt set to 0 and 1, with the phase-clock frequency doubled when the
setting is 1. Note that the overall loop delays are cut in half in this case, but the frequency of loop
calculations in the master Power PMAC is unchanged.
Phase
Clock
Ring Feedback Master Loop Ring Command Slave Command Slave Output
Cycle n-1:
Transmission Calculation Transmission Processing Transmission
Slave Input Slave Feedback Ring Feedback Master Loop Ring Command Slave Command Slave Output
Cycle n:
Transmission Processing Transmission Calculation Transmission Processing Transmission
Slave Input Slave Feedback Ring Feedback Master Loop Ring Command
Cycle n+1:
Transmission Processing Transmission Calculation Transmission
* Total Loop *
Delay
Phase
Clock
* Total Loop *
Delay
If Power PMAC is commanding drives over the MACRO ring in torque or velocity mode, as with
most third-party MACRO drives, the fact that the ring is updated every phase-clock cycle, but
new data is only used every servo cycle typically provides sufficient “oversampling” of the ring
(assuming that the phase-clock frequency is higher than the servo-clock frequency) so that this
software extension is not useful.
Each node is identified by a 4-bit master number (0 to 15) and a 4-bit slave number (0 to 15).
This means that each master number supports 16 slave numbers. The net 8-bit node number must
match between master and slave devices for communication to take place between the devices.
Node Allocation
For each master IC number, there are 16 nodes, numbered 0 – 15, for which a data packet can be
transmitted each ring cycle. In most MACRO systems, these nodes are organized as follows:
I/O Nodes
Node 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Auxiliary
Nodes Servo Nodes
For example, with PMAC2-style ICs, the standard mapping for a 20-axis system would be:
With PMAC3-style ICs, the standard mapping for a 20-axis system would be:
In both cases, a motor will use the encoder conversion table entry of the same index number (e.g.
Motor[2] will use EncTable[2]).
In the second part, bits 16 – 19, which form the second hex digit, specify the node number of the
sync packet. In standard Power PMAC operation, this packet belongs to Node 15, so this hex
digit is set to $F.
In the third part, bits 20 – 23, which form the first hex digit, specify the master number for the IC,
whether the IC is used as a master or a slave device. If it is a slave device, this value specifies the
number of the master to which it responds. While it is possible for separate ICs to share the same
master number, particularly for slave devices, it is essential that no two master devices with the
same master number or no two slave devices with the same master number have any of the same
servo or I/O nodes enabled.
For example, to enable the first six servo nodes (0, 1, 4, 5, 8, and 9), the first three I/O nodes (2,
3, and 6), and the two auxiliary nodes (14 and 15) for master number 1 with sync node 15,
Gate2[i].MacroEnable would be set to $1FC37F.
Hex digit 1 F C 3 7 F
Script Bit # 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Bit Value 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1
In the second part, bits 24 – 27, which form the second hex digit, specify the node number of the
sync packet. In standard Power PMAC operation, this packet belongs to Node 15, so this hex
digit is set to $F.
In the third part, bits 28 – 31, which form the first hex digit, specify the master number for the IC,
whether the IC is used as a master or a slave device. If it is a slave device, this value specifies the
number of the master to which it responds. While it is possible for separate ICs to share the same
master number, particularly for slave devices, it is essential that no two master devices with the
same master number or no two slave devices with the same master number have any of the same
servo or I/O nodes enabled.
As key setup variables in the DSPGATE3 IC, these elements are write-protected to prevent
inadvertent changes by unauthorized personnel. In the Script environment, global variable
Sys.WpKey should be set to $AAAAAAAA to permit changes to the values of these elements. In
the C environment, IC variable Gate3[i].WpKey should be set to $AAAAAAAA before each
command that would change the value of these elements in the IC.
For example, to enable the first five servo nodes (0, 1, 4, 5, and 8), the first four I/O nodes (2, 3,
6, and 7), and the two auxiliary nodes (14 and 15) for master number 0 with sync node 15,
Gate3[i].MacroEnableA would be set to $0FC1FF00.
0 F C 1 F F 0 0
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 - - - - - - - -
Master IC Sync Packet # Node Enable Control Bits
Saved setup element Macro.TestMaxErrors specifies the maximum number of errors that can
be detected within a single evaluation period without causing a shutdown. A value of 2 is
suggested for performing the evaluation, which means that the ring would be shut down on a third
error in a given evaluation period.
Saved setup element Macro.TestReqdSynchs specifies the minimum number of the specified
synch packets that must be received within a single evaluation period to avoid a shutdown. A
value of (TestPeriod – 2) is suggested for performing the evaluation, which means the ring
would be shut down if only 2 or more expected sync packets were not received during the test
period.
For the 4 registers in each set, the register index values are 0, 1, 2, and 3. Register 0 has 24 bits (3
bytes) of real data that is transmitted across the ring each cycle. Registers 1, 2, and 3 each have 16
bits (2 bytes) of real data that is transmitted across the ring each cycle.
written to, the value is placed in the output register; when the element is read from, the value
returned is from the input register.
All of these data elements are 24-bit values (found in the high 24 bits of Power PMAC’s 32-bit
bus). For registers 1, 2, and 3 of a node, the real 16 bits of data are found in the high 16 bits of the
24-bit element. It is important to realize that many of the automatic functions will access the full
32-bit register, so care must be taken in comparing the 24-bit value in the element with the 32-bit
value used by the automatic function (which will be 256 times larger).
Similarly, in this IC, the MACRO data software elements for accessing the hardware input
registers of a node are Gate3[i].MacroInA[j][k] and Gate3[i].MacroInB[j][k] for banks A and
B, respectively, of the IC. Since the output and input hardware registers are accessed by separate
elements in this IC, it is possible to read back a value written to an output register, which can be
useful for debugging an application.
All of these data elements are 32-bit values. For register 0 of a node, the real 24 bits of data are
found in the high 24 bits of the 32-bit element. For registers 1, 2, and 3 of a node, the real 16 bits
of data are found in the high 16 bits of the 32-bit element.
In almost all cases, the ECT entry will be reading the single value in a MACRO node input
register 0, with real data in bits 8 – 31 of the 32-bit data bus, with the low 5 bits of this data
representing a fractional count value (so the integer count data starts in bit 13).
In most cases, the mapping of encoder table entry numbers to MACRO node numbers is the same
as the mapping of motor numbers to MACRO node numbers explained above (although this is
not required). In this scheme, the motor numbers will match the encoder table entry numbers
number (e.g. Motor[2] will use EncTable[2]).
For example, with PMAC2-style ICs, the standard mapping for a 20-axis system would be:
With PMAC3-style ICs, the standard mapping for a 20-axis system would be:
This type of entry does not use a secondary source, so the setting of EncTable[n].pEnc1 does not
matter. It is fine to leave it at its factory-default setting of Sys.pushm.
The most significant bit of position data in the 24-bit hardware register must end up in the highest
bit of the 32-bit intermediate result in order to support rollover of the source data properly. In the
most common case, there is true position data in all 24 bits of the hardware register. In this case,
EncTable[n].index1 should be set to 8 to cause a secondary “shift-left” of the data by 8 bits to
return the position data to its original position in the 32-bit register (but now with all zeros in the
low 8 bits).
Occasionally, there will not be a full 24 bits of position data in the source register, and this second
operation will need to be slightly different. For example, if the source register contains only 17
bits of position data starting in bit 8 of the 32-bit register (bit 0 of the 24-bit hardware register and
data structure element), after the initial shift-right of 8 bits, the most significant bit of position
data is in bit 16. In order to have this bit end up in bit 31 of the intermediate result, a subsequent
shift-left of 15 bits is required, so EncTable[n].index1 should be set to 15.
Note that in the common case of having 24 bits of true position data, leaving index1 and index2
at their default values of 0 will generally provide acceptable results, with the “noise” from
undetermined data in the low 8 bits not being noticeable in most applications. However, it is
recommended that these elements be set as explained above to minimize the chances of any
problems.
The ECT permits you to implement a “maximum change” filter in an encoder table entry to
mitigate the effects of such errors. If EncTable[n].MaxDelta is set to positive value, it represents
the maximum change (either velocity or acceleration) that will be regarded as real. Changes
larger than this will be considered due to data errors in the received data, and this data will not be
used.
Note that many users will not implement change limiting when they are establishing initial
functionality, leaving MaxDelta at 0 during this stage of development. However, it is strongly
recommended that some sort of change limiting be implemented before development is finished,
even if no problems have been noted during development.
Velocity Limiting
If EncTable[n].index3 is set to its default value of 0, MaxDelta acts as the maximum velocity
that will be considered real. It is expressed in least-significant-bits (LSBs) of the feedback per
servo cycle. It assumes that the LSB is found in the bit of the 32-bit register specified by the
index2 element for the entry. Note that in many cases using MACRO products, this LSB will be a
fraction (often 1/32) of a “count” of the feedback.
If the magnitude of change in the source data is greater than MaxDelta, the sample will be
assumed to be erroneous, and so the source data will not be used. Instead, the data will be
assumed to have changed the same amount it did in the previous cycle (i.e. to have maintained the
last velocity), using the value held in the status element EncTable[n].PrevDelta. If in the next
servo cycle, the change is still too large, a change in the source data is assumed to have occurred,
and the result will be changed by MaxDelta. This rate will be maintained until the result matches
the new source.
In this mode, it is recommended that MaxDelta be set to a value about 25% greater than the
maximum true velocity that is expected.
For example, quadrature encoder feedback with 1/T extension is received with units of 1/32 of a
count. The maximum expected speed is 200 quadrature counts per servo cycle, or 6400 LSBs per
servo cycle. To set a speed limit, index3 is set to 0, and MaxDelta is set to 8000, providing a
25% margin.
Acceleration Limiting
If EncTable[n].index3 is set to a value greater than 0, MaxDelta acts as the maximum
acceleration that will be considered real. It is expressed in LSBs per servo cycle per servo cycle,
assuming that the LSB is found in the bit of the 32-bit register specified by index2. If the
magnitude of change in the rate of change (i.e. the second derivative) in the source data is greater
than MaxDelta, the sample will be assumed to be erroneous, and so the source data will not be
used. Instead, the data will be assumed to have the same second derivative it did in the previous
cycle (i.e. to have maintained the last acceleration), using the value held in PrevDelta. If
subsequent readings are also considered erroneous, the acceleration used in PrevDelta will be
used for a total of index3 servo cycles. After this, it will use the value in MaxDelta to slew to the
new source value.
In this mode, it is recommended that MaxDelta be set to a value about 25% greater than the
maximum true acceleration that is expected.
For example, absolute encoder feedback is received in units of LSBs of the encoder. In any servo
cycle, the velocity is not expected to change more than 12 LSBs per servo cycle. We want to be
able to “ride through” three bad readings. To set the acceleration limit this way, index3 should be
set to 3, and MaxDelta should be set to 15 (providing a 25% margin).
Numerical Integration
As with other sources of feedback, Power PMAC can numerically integrate the source feedback
in the ECT entry. EncTable[n].index4 specifies the number of times the incoming data is
integrated, and it can be set to 0 (no integration), 1 (single integration – velocity to position), or 2
(double integration – acceleration to position). It is rare to integrate feedback received over the
MACRO ring, so usually index4 is left at its default value of 0.
After the data shifting, the unit of the sensor usually ends up in bit 8 (if no “sub-count” data was
provided) or bit 13 (if 5 bits of “sub-count” data was provided) of the 32-bit intermediate value.
In the first case, ScaleFactor should be set to 1/28, or 1/256 (= 0.00390625) so the result is in the
proper units. In the second case, ScaleFactor should be set to 1/213, or 1/8192 (=
0.0001220703125). In the case of the 17-bit encoder whose LSB was left in bit 15, ScaleFactor
should be set to 1/215, or 1/32,768. It is usually best to enter these values as expressions and let
Power PMAC compute the exact numerical values.
The MACRO IC node registers are expressed “generically” in this section, using IC index i, and
node index j. In most cases, these index values will be those in the table shown above in the
section Typical Mapping of MACRO Nodes to Motors.
When a PMAC2-style MACRO IC is used, the setting will be of the form Motor[x].pDac =
Gate2[i].Macro[j][0].a.
When a PMAC3-style MACRO IC is used, the setting will be of the form Motor[x].pDac =
Gate3[i].MacroOutA[j][0].a or Gate3[i].MacroOutB[j][0].a.
If Power PMAC is not performing commutation or current-loop closure for the motor, the single
command output from the servo loop will be written to this register.
If Power PMAC is performing commutation for the motor, but not the digital current-loop closure
(sinewave output mode), the first phase-current command (A) will be written to this register (0),
and the second phase-current command (B) will be written to the next register (1) for the node.
If Power PMAC is performing both commutation and current-loop closure (direct-PWM output
mode) for the motor, the first phase-voltage command (A) will be written to this register (0), the
second phase-voltage command (B) will be written to the next register (1) for the node, and the
third phase-voltage command (C) will be written to the subsequent register (2) for the node.
These position values must have been processed through the encoder conversion table, so these
elements must specify the address of a table entry. So Motor[x].pEnc and Motor[x].pEnc2 are
set to EncTable[n].a. In the most common case of a single sensor, both of these are set to the
address of the same entry. Usually the entry index n is the same as the motor index x.
Motor[x].AbsPosFormat should be set to $01103808 to specify the use of the high 24 bits of
this address and the high 16 bits of the next register, supporting a possible 40 bits of absolute
position value.
Motor[x].AbsPosSf should be set to 0.03125 (= 1/32) if the data is provided in the common
scaling of 1/32 of a count.
Interface Type
Motor[x].EncType should be set to 4 to denote that this motor uses a MACRO interface to a
slave device, or to 12 to denote that this motor uses a MACRO interface to a Turbo PMAC or
Power PMAC acting as a MACRO slave. While this saved setup element does not do much
directly, the act of setting it in the Script environment causes several key motor addressing
settings to be made automatically, as explained below.
When a PMAC2-style MACRO IC is used, the settings will be of the form Motor[x].p{flag} =
Gate2[i].Macro[j][3].a.
When a PMAC3-style MACRO IC is used, the settings will be of the form Motor[x].p{flag} =
Gate3[i].MacroInA[j][3].a or Gate3[i].MacroInB[j][3].a.
Motor[x].AmpFaultBit = 23
Motor[x].LimitBits = 25
Motor[x].CaptFlagBit = 19
The MACRO standard calls for a high-true amplifier fault bit, so Motor[x].AmpFaultLevel
should be set to the default value of 1.
When using quadrature encoder feedback with 5 bits of 1/T sub-count extension, the following
settings should be used to process whole-count captured data, as for homing:
Motor[x].CaptPosShiftLeft = 13
Motor[x].CaptPosShiftRight = 0
Motor[x].CaptPosRound = 1
When receiving flags over the MACRO ring for a motor, Motor[x].EncType should be set to 4
to tell Power PMAC of the expected format of the flags. With this setting, when
Motor[x].pEncStatus is set to an address address (Gate2[i].Macro[j][3].a for a PMAC2-style
IC, Gate3[i].MacroInA[j][3].a or Gate3[i].MacroInB[j][3].a for a PMAC3-style IC), Power
PMAC automatically sets the above bit values to the appropriate settings for the MACRO
protocol.
When a PMAC2-style MACRO IC is used, the setting will be of the form Motor[x].pEncCtrl =
Gate2[i].Macro[j][3].a.
When a PMAC3-style MACRO IC is used, the setting will be of the form Motor[x].pEncCtrl =
Gate3[i].MacroOutA[j][3].a or Gate3[i].MacroOutB[j][3].a.
Motor[x].pAmpEnable specifies the address of the register where the motor’s amplifier-enable
output flag is written.
Motor[x].AmpEnableBit = 22
When sending flags over the MACRO ring for a motor, Motor[x].EncType should be set to 4 to
tell Power PMAC of the expected format of the flags. With this setting, when Motor[x].EncCtrl
is set to an address (Gate2[i].Macro[j][3].a for a PMAC2-style IC, Gate3[i].MacroOutA[j][3].a
or Gate3[i].MacroOutB[j][3].a for a PMAC3-style IC), Power PMAC automatically sets the
above bit value to the appropriate setting for the MACRO protocol.
Commutation Addresses
If Power PMAC is performing the phase commutation tasks for a motor controlled over the
MACRO ring, several more address settings must be made properly to interface with the
MACRO ring.
For these motors, Motor[x].PhaseCtrl must be set to 4 to enable commutation using “unpacked”
data (the data to and from each motor phase in a separate register), because none of the MACRO
ICs support “packed” data.
Note that Power PMAC will read the entire 32-bit value at this address, even though there is only
real data in the upper 24 bits (i.e. starting at bit 8). In addition, with many MACRO devices, the
low 5 bits of the real data may contain fractional-count data for improved servo resolution, so a
single “count” of feedback may appear in bit 13 of the 32-bit register. This must be taken into
account when scaling the data into commutation cycles.
Power PMAC can perform “data shifting” operations on the value read from this register using
Motor[x].PhaseEncRightShift and Motor[x].PhaseEncLeftShift. While PhaseEncRightShift
can be used to shift out the low 8 bits of “garbage data” in the register, since Power PMAC only
uses 11 bits of position data in a commutation cycle, this is seldom needed.
If true position data is not present in the highest bit of the register read, PhaseEncLeftShift must
be used to shift the most significant bit of true position data to bit 31 of the resulting register.
Otherwise, the rollover of the value in the register will not be handled properly. For example, if
the register holds only 17 bits of single-turn position data in bits 8 – 24 of the 32-bit register,
PhaseEncLeftShift should be set to 7 to move the MSB to bit 31.
Motor[x].PhasePosSf multiplies this 32-bit value to convert the units of this (entire) register to
the commutation units of 1/2048 of a commutation cycle (motor pole pair). The formula for
computing this element is:
In the first example, a 1000-line quadrature encoder is used on a 4-pole motor. At the remote
MACRO device, “times-4” decode is performed on the encoder to obtain 4000 counts per
revolution, and “1/T” extension is performed to provide 5 bits of fractional count data before the
data is sent to Power PMAC over the MACRO ring. This setup yields 2000 full encoder counts
per commutation cycle, with a count appearing in bit 13 (8 + 5) of the 32-bit register. So there are
(2000 * 213), or 16,384,000 register LSBs per commutation cycle. Motor[x].PhasePosSf should
be set to 2048 / 16,384,000. It is usually best to enter this as an expression and let Power PMAC
compute the exact resulting value. (In this case, the expression could be reduced to 1 / 8000).
In the second example, an encoder provides 20 bits of single-turn data on an 8-pole motor. Each
phase cycle, 24 bits of position data (covering 16 motor revolutions) are provided over the
MACRO ring, with no fractional data. With 4 commutation cycles per motor revolution, there are
218, or 262,144 encoder LSBs per commutation cycle, with an encoder LSB appearing in bit 8 of
the 32-bit register. So there are (218 * 28) = 226, or 67,108,864 register LSBs per servo cycle.
Motor[x].PhasePosSf should be set to 2048 / 67108864. (This could be reduced to 1 / 32768.)
In the third example, an encoder provides 17 bits of single-turn data on a 4-pole motor. Each
phase cycle, these 17 bits of position data are provided over the MACRO ring, with no fractional
data. This data appears in bits 8 – 24 of the 32-bit register, with zeros above.
Motor[x].PhaseEncLeftShift should be set to 7 to move the encoder MSB to bit 31 of the
register. This leaves the encoder LSB in bit 15 of the register. With 2 commutation cycles per
motor revolution, there are 216, or 65,536 encoder LSBs per commutation cycle, with an encoder
LSB appearing in bit 15. So there are (216 * 215) = 231 register LSBs per servo cycle.
Motor[x].PhasePosSf should be set to (211 / 231) = 1 / 220, or 1 / 1048576.
Using the standard MACRO protocol, this should be set to Gate2[i].Macro[j][1].a for a PMAC2-
style protocol, or to Gate3[i].MacroInA[j][1].a or Gate3[i].MacroInB[j][1].a for a PMAC3-
style MACRO IC. This will cause Power PMAC to read the node’s input register 1 for the Phase
A current value, and input register 2 for the Phase B current value.
For n-bit ADCs, the true feedback data will appear in the high n bits of the 16-bit hardware
register (and of the full 32-bit value read). The high n bits of the 32-bit saved setup element
Motor[x].AdcMask should be set to 1 to tell Power PMAC which bits to use. For the most
common 12-bit ADCs, AdcMask should be set to $FFF00000.
This technique is particularly useful when individual Power PMAC systems are limited in the
number of physical hardware channels they can interface to. For example, Power PMAC Brick
systems are limited to 8 channels of local interface, so can only directly control 8 axes. However,
this same system can also command 32 additional axes across the MACRO ring (for example on
4 other Power PMAC Bricks), bringing the total to 40 axes. (Its software supports a total of 256
axes.) In an alternate configuration a Power PMAC Etherlite network controller can command
large number of axes on Power PMAC Bricks through this technique. If all of the coordinating
software tasks (e.g. motion programs) are executed on a single Power PMAC, it is much easier to
accomplish.
This technique can also reduce the computational load on the coordinating Power PMAC by
offloading some of the high-frequency cyclic tasks such as phase commutation and current-loop
closure to other Power PMACs. This can permit the coordinating Power PMAC to execute its key
tasks at higher frequencies than would be possible if it had to do all of these high-frequency tasks
as well.
One advantage of this technique is the ability for the network-slave Power PMAC to take full
control of its axes in the event of a problem such as a ring break. This can provide important fault
recovery capabilities, such as permitting the retraction of motors to safe positions. (Any fault
recovery algorithms must be written by the user for any particular application.)
Command Modes
Cyclic commands of any of the following types can be sent to the network-slave motor:
1. Commanded position
2. Commanded velocity
3. Commanded torque/force
4. Commanded phase currents (“sinewave” mode)
5. Commanded phase voltages (“direct PWM” mode)
The most common command format in this mode of operation is torque/force. This offloads the
high-frequency phase-commutation and current-loop closure tasks to the remote Power PMAC,
but the main position/velocity servo loop is in the coordinating Power PMAC, making setup and
tuning easier. Current-loop closure is done locally in the network slave, avoiding network
transport delays inside the high-bandwidth current loop. In this mode, operation is the same as for
commanding many third-party MACRO drives.
The second most common command format is phase voltages (PWM). While this does not
offload any computational load from the coordinating Power PMAC, all motor setup, including
commutation setup and current-loop tuning, is in the coordinating Power PMAC. In this mode,
operation is the same as for commanding Delta Tau Geo MACRO drives.
Note that, while cyclic commanded positions can be sent across the network, certain important
functionality, such as establishing position reference, is not fully supported at this time.
A motor in the coordinating Power PMAC commanding a network-slave motor over the MACRO
ring in another Power PMAC is set up just as if it were commanding a separate MACRO drive. A
quick guide to the setup of the coordinating Power PMAC motor is given here.
Motor[x].EncType should be set to 4 to specify the motor’s hardware interface will be of the
MACRO style. This automatically sets several parameters, including Motor[x].AmpEnableBit,
Motor[x].AmpFaultBit, Motor[x].CaptFlagBit, and Motor[x].LimitBits, to the values
matching the MACRO protocol.
Motor[x].pDac should be set to the address of output register 0 of this MACRO servo node so
the command output value(s) of whatever format will be sent over the ring through that node. For
a PMAC2-style “DSPGATE2” MACRO IC, the setting will be of the form
Gate2[i].Macro[j][0].a. For a PMAC3-style “DSPGATE3” IC, the setting will be of the form
Gate3[i].MacroOutα[j][0].a.
Motor[x].pEncCtrl should be set to the address of output register 3 of this MACRO servo node
so the trigger flag on the remote Power PMAC can be properly armed. For a PMAC2-style
“DSPGATE2” MACRO IC, the setting will be of the form Gate2[i].Macro[j][3].a. For a
PMAC3-style “DSPGATE3” IC, the setting will be of the form Gate3[i].MacroOutα[j][3].a.
Motor[x].pAmpEnable should be set to the address of output register 3 of this MACRO servo
node so the amplifier-enable flag value is sent over the ring through the command-flag register of
the node. For a PMAC2-style “DSPGATE2” MACRO IC, the setting will be of the form
Gate2[i].Macro[j][3].a. For a PMAC3-style “DSPGATE3” IC, the setting will be of the form
Gate3[i].MacroOutα[j][3].a.
Motor[x].pEncStatus should be set to the address of input register 3 of this MACRO servo node
so encoder flag functions sent over the ring are read. For a PMAC2-style “DSPGATE2” MACRO
IC, the setting will be of the form Gate2[i].Macro[j][3].a. For a PMAC3-style “DSPGATE3” IC,
the setting will be of the form Gate3[i].MacroInα[j][3].a.
EncTable[n].ScaleFactor should be set to 1/256 if it is desired that the LSB of the 24-bit register
be one unit of output from the entry. If the value from the network slave has 8 bits of fractional
data, as with 1/T incremental encoder interpolation from a DSPGATE3 IC, this should be set to
1/256/256, or 1/65,536, so an encoder count is one unit of output from the entry.
Motor[x].pEnc and Motor[x].pEnc2 should be set to the address of this encoder conversion
table entry (EncTable[n].a) so the processed feedback value is used for the outer-loop and inner-
loop, respectively, actual position. Note that if dual feedback is desired, the secondary encoder
would need to be transmitted back to the coordinating Power PMAC through a software
mechanism other than the automatic motor transfers.
In this mode of operation, setup terms for the position/velocity servo loop, phase commutation
algorithm, and digital current-loop are not used. The actual position feedback value from the
network slave is only used for monitoring purposes – actual position can be queried, and the
difference between commanded and actual position can be checked against the following error
limits. Motor[x].PhaseCtrl should be set to 0 to disable phase tasks in the coordinating Power
PMAC.
In this mode of operation, no “inner-loop” feedback gains should be used, as the tasks they
accomplish (e.g. damping) are done in the network-slave motor servo loop. In particular, velocity
feedback gains Motor[x].Servo.Kvfb and Kvifb should be set to 0.0. Motor[x].PhaseCtrl
should be set to 0 to disable phase tasks in the coordinating Power PMAC.
In this mode of operation, it is essential that the inner (velocity) servo loop be properly tuned on
the coordinating Power PMAC as well as the outer (position) servo loop. Motor[x].PhaseCtrl
should be set to 0 to disable phase tasks in the coordinating Power PMAC.
In this mode of operation, it is essential that the inner (velocity) servo loop be properly tuned on
the coordinating Power PMAC as well as the outer (position) servo loop. Motor[x].PhaseCtrl
should be set to 4 to enable phase tasks in the coordinating Power PMAC interfacing through a
MACRO IC. Motor[x].pAdc should be set to 0 to disable current-loop closure in the
coordinating Power PMAC, since that task will be performed in the network-slave Power PMAC.
In this mode of operation, it is essential that the inner (velocity) servo loop be properly tuned on
the coordinating Power PMAC as well as the outer (position) servo loop. Motor[x].PhaseCtrl
should be set to 4 to enable phase tasks in the coordinating Power PMAC interfacing through a
MACRO IC. Motor[x].pAdc should be set to the address of input register 1 of the MACRO
servo node to enable current-loop closure in the coordinating Power PMAC using the values read
in registers 1 and 2 of the node. For a PMAC2-style “DSPGATE2” MACRO IC, the setting will
be of the form Gate2[i].Macro[j][1].a. For a PMAC3-style “DSPGATE3” IC, the setting will be
of the form Gate3[i].MacroInα[j][1].a.
1. Commanded position
2. Commanded velocity
3. Commanded torque/force
4. Commanded phase currents (“sinewave” mode)
5. Commanded phase voltages (“direct PWM” mode)
Motor[x].pMotorNode should be set to the address of the MACRO ring register where the cyclic
command value (or the first cyclic command value in the case of multiple phase commands) is
expected. This is virtually always the input register 0 of a MACRO servo node.
When the MACRO IC is a PMAC2-style “DSPGATE2” IC, as in a UMAC ACC-5E this setting
will be of the form Gate2[i].Macro[j][0].a, where i is the IC index, j is the node number.
When the MACRO IC is a PMAC3-style “DSPGATE3” IC, as in a Power Brick or UMAC ACC-
5E3, the setting will be of the form Gate3[i].MacroInα[j][0].a, where i is the IC index, j is the
node number, and α is “A” or “B”.
When the MACRO IC is a PMAC2-style “DSPGATE2” IC, this will be set to 0, because in this
IC the input and output registers for a MACRO node have the same addresses.
When the MACRO IC is a PMAC3-style “DSPGATE3” IC, this will be set to 64, because in this
IC the output registers start at an address 64 higher than the input registers of the same MACRO
node.
up for independent operation first, then easily converted to network-mode. It also permits the
motor to be converted back to independent operation if necessary for fault recovery.
Motor[x].pDac: Gaten[i].Chan[j].Pwm[0].a
Motor[x].pEncCtrl: Gate1[i].Chan[j].Ctrl.a
Gate3[i].Chan[j].OutCtrl.a
Motor[x].pAmpEnable: Gate1[i].Chan[j].Ctrl.a
Gate3[i].Chan[j].OutCtrl.a
Motor[x].pEncStatus: Gaten[i].Chan[j].Status.a
Motor[x].pAmpFault: Gaten[i].Chan[j].Status.a
Motor[x].pCaptFlag: Gaten[i].Chan[j].Status.a
Motor[x].pLimits: Gaten[i].Chan[j].Status.a
Note that when this position value is received by the coordinating Power PMAC, it will be
processed through an encoder conversion table entry there. That entry will not do significant
processing. In many cases, it will simply pass the value through, although a “maximum change”
filter to catch spurious values is recommended.
In single-feedback systems, Motor[x].pEnc2 should be set to the address of this entry as well. In
dual-feedback (load and motor) systems, it will be set to the address of a different entry to get a
separate position value. Note that the position value obtained from the register pointed to by
pEnc2 is not automatically sent back to the coordinating Power PMAC through this mechanism.
However, if Motor[x].MotorMode is set to 1 or 2 (position or velocity commands), it will be
used on the network-slave Power PMAC to close the inner (velocity) loop.
If Motor[x].MotorMode is set to 5, the network-slave Power PMAC will simply take the phase-
voltage commands it receives and write them to the registers specified by Motor[x].pDac, then
read the actual phase-current values from the registers specified by Motor[x].pAdc and write
them to the MACRO feedback registers. The phase-position register for the motor will be the
same one as used for position-loop servo feedback (unless some other mechanism is used to send
a separate value back). In this mode, no other commutation or current-loop parameters need to be
set.
Note that the initial setup for feedback or master sensors is independent of any motor or
coordinate system. A motor or coordinate system may use the numerical value resulting from the
initial hardware and/or software processing of a position signal, but this is not required. It is also
possible for user programs or commands to access these position values directly, without a motor
or coordinate-system automatic function using them at all.
Signal Format
Quadrature encoders provide two digital signals that are a function of the position of the encoder,
each nominally with 50% duty cycle, and nominally one-quarter cycle apart. This format provides
four distinct states per cycle of the signal, or per line of the encoder. The phase difference of the
two signals permits the decoding electronics to discern the direction of travel, which would not be
possible with a single signal.
1 2 3 4 5 6 1 2 3 4 5 6
“Clockwise” “Counterclockwise”
Typically, these signals are at 5V TTL/CMOS levels, whether single-ended or differential. The
input circuits are powered by the main 5V supply for the controller, but the can accept up to +/-
12V between the signals of each differential pair, and +/-12V between a signal and the GND
voltage reference.
Differential encoder signals can enhance noise immunity by providing common-mode noise
rejection. Modern design standards virtually mandate their use for industrial systems, especially
in the presence of PWM power amplifiers, which generate a great deal of electromagnetic
interference.
Hardware Setup
This section describes the Power PMAC encoder hardware interface in general terms. Consult the
Hardware Reference Manual for your particular configuration for details.
Power PMAC’s encoder interface circuitry employs differential line receivers, but can accept
single-ended encoders as well as differential encoders. The following diagram shows the basic
interface circuitry for a phase of an encoder:
+5V
R aR
A+ + A
A- -
1
2
bR 3
A?
The differential inputs for the phase (A+ and A-) are at left. They are connected to the two inputs
of a differential line receiver whose digital output state is dependent on which signal has a higher
voltage. The “+” signal has a pull-up resistor (with R about 1 kΩ) to the internal 5V supply. The
“-” signal has a higher-valued pull-up resistor (with aR about 2 kΩ) to the internal 5V supply, and
a second resistor with value bR that is (at least by default) pulled down to the 0V signal GND
return.
PMAC2-Style Interfaces
On the PMAC2-style ACC-24E2, ACC-24E2A, and ACC-24E2S UMAC axis-interface boards,
this second resistor is implemented with a reversible socketed resistor pack for the encoder. The
resistors in this pack have the same value as the pull-up resistors (bR = aR) for this signal. In the
default configuration (pin 1 of the pack – marked with the dot – matching pin 1 of the socket), it
provides pull-down resistors that create a voltage divider that holds the “-” line at 2.5V if there is
no input on the line. The resistor pack must be in this configuration to accept single-ended
encoder signals on the “+” lines; nothing should be connected to the “-” lines.
Encoders with differential line-driver signal pairs (RS-422 signal type), the most common type of
industrial encoders, can be used with the resistor pack in either orientation. However, in the
default orientation, the encoder-loss detection circuit is not enabled. If the resistor pack is
reversed in the socket, making these pull-up resistors, the encoder-loss detection circuit,
explained below, is enabled.
PMAC3-Style Interfaces
On the PMAC3-style ACC-24E3 UMAC axis-interface board with the digital feedback
mezzanine and on the PMAC3-style Power Brick control board, the second resistor for the “-”
line is hardwired to ground, but it is of a higher-value than the pull-up resistor in a 3-to-2 ratio, so
it creates a voltage divider that holds the line at 3V if there is no input on the line. The encoder-
loss logic uses TTL-level inputs that consider 3V a high logic level. In this way, the circuitry can
be used for single-ended encoders and for differential encoders with encoder-loss detection
enabled.
Power PMAC encoder interface circuits provide this capability. Each signal pair is connected to
the two inputs of an “exclusive-or” (XOR) gate, as well as to the differential line receiver. With a
properly acting encoder with the two signals in different logic states, the output of the XOR gate
is high. If the signal is lost, as when the cable comes disconnected, and the resistors on the input
lines pull both signals to a high logic state, the output of the XOR gate goes low, indicating signal
loss.
Power PMAC software can provide automatic detection and shutdown of this encoder-loss
condition. For more details, refer to the section on encoder loss detection in the chapter Making
Your Power PMAC Application Safe of the User’s Manual.
It is also possible to use a separate supply for the encoders with non-isolated signals connected to
Power PMAC. In this case, the return of the supply should be connected to the digital common
GND on Power PMAC to give the signals a common reference. The +5V lines of separate
supplies should not be tied together, as they could fight each other to control the exact voltage
level.
If isolation of the simulated encoder signals is not feasible, Power PMAC’s digital circuitry and
the amplifier signal circuitry (including any Power PMAC’s analog circuitry) must be well tied
together to provide a common reference voltage. This is best done by putting jumpers on the
Power PMAC interface board (E-Points E85, E87, and E88 on many boards), tying the digital and
analog circuits on Power PMAC together, and therefore also the analog signal circuits. What must
be avoided is having the simulated encoder cable(s) providing the only connection between the
circuits. This can result in lost signals from bad referencing, or even component damage from
ground loops.
Wiring Techniques
There are several important techniques in the wiring of the encoders that are important for noise
mitigation. First, the encoder cable should be kept physically separate from the motor power
cable if at all possible. Second, both of these cables should be shielded, the motor cable to prevent
noise from getting out, and the encoder cable to prevent noise from getting in. The encoder
shields should be grounded at the “inward” end only, that is, to the device that is itself tied to a
ground.
A third important noise mitigation technique is to twist the leads of the complementary pairs
around each other. With these “twisted pairs”, what noise does get in tends to cancel itself out in
opposite halves of the twist.
Each encoder input channel has a digital delay filter consisting of three cascaded D-flip-flops on
each line, with a best two-of-three voting scheme on the outputs of the flip-flops. The flip-flops
are clocked by the SCLK signal. This filter does not pass through a state change that only lasts for
one SCLK cycle; any change this narrow should be a noise spike. In doing this, the filter delays
actual transitions by two SCLK cycles – a trivial delay in virtually all systems.
If both the A and B channels change state at the decode circuitry (post-filter) in the same SCLK
cycle, an unrecoverable error to the counter value will result. The ASIC hardware notes this
problem by setting and latching the “encoder count error” bit in the channel’s status word,
accessible with the Gaten[i].Chan[j].CountError status element. The problem can also be
detected by capturing the count value each revolution on the index pulse and seeing whether the
correct number of counts have elapsed.
The SCLK frequency must be at least 4 times higher than the maximum encoder cycle (line)
frequency input, regardless of the quadrature decoding method used (with the most common
“times-4” decode, the SCLK frequency must be at least as high as the count rate). In actual use,
due to imperfections in the input signals, a 20 – 25% safety margin should be used.
Few users will change the default SCLK frequency settings in the interface ICs. Some will
increase the frequency to permit very high count rates, and some will lower the frequency for
increased noise immunity.
The other three clock frequencies that this element controls are virtually never changed, so the
following table may be useful for setting the SCLK frequency with the others left at the default
frequency:
The default SCLK frequency of 9.83 MHz can reliably accept count frequencies up to 8 MHz,
corresponding to 2 MHz line cycle frequencies.
Note that while the ASIC itself could accept a 25 MHz signal frequency for a 100 MHz
quadrature count rate, the line receiver circuitry is only rated to a 10 MHz signal frequency.
This variable is almost always set for “times-4” decode, which derives 4 counts per signal cycle,
one for each signal edge. This requires a variable value of 3 or 7. The difference between these
two values is the direction sense – which direction of motion causes the counter to count up.
The following diagram shows a block diagram of the PMAC2-style “DSPGATE1” IC’s encoder
circuitry, including the memory-mapped registers available to the processor.
Servo
Clock
TimeBetweenCts
Timers
TimeSinceCts
A
B Decoder Counter ServoCapt
EncCtrl Phase
Clock
C PhaseCapt
HOME
PLIM Trigger Trigger
Flag Select
MLIM
Select
USER
CaptCtrl HomeCapt
CaptFlagSel
Address Data
The following diagram shows a block diagram of the PMAC3-style “DSPGATE3” IC’s encoder
circuitry, including the memory-mapped registers available to the processor.
Trigger
Count
Timer Home Capture Home
Extension Whole Count Fraction
Trigger
Servo
Clock
A
Servo Capture Servo
B Decoder Counter
Whole Count Fraction
Dir
Servo
Clock
AtanEna
Phase
Clock
SinData
ADC Shift Arctangent Phase Capture Phase
CosData
Registers Extension Whole Count Fraction
Phase
Clock Address Data
PMAC3-ASIC-Based Interface
With a PMAC3-style IC, the 1/T extension, if performed, has been done in the IC, and the ECT
entry will simply use Gate3[i].Chan[j].ServoCapt, which will have the extended count value, as
the only position source using the “Type 1” single-register-read conversion. The following saved
setup elements must be specified:
If the encoder is connected to the serial encoder lines of an interface channel that uses a PMAC3-
style IC, with the serial interface disabled, the ECT entry is the same as above except that
EncTable[n].pEnc is set to Gate3[i].Chan[j].SerialEncDataA.a.
These conversions are covered in detail in the chapter “Setting Up the Encoder Conversion
Table”.
Many optical encoders have “Hall tracks”. These commutation tracks provide signal outputs
equivalent to those of magnetic Hall commutation sensors, but use optical means to create the
signals.
Signal Format
Digital Hall sensors provide three digital signals that are a function of the position of the motor,
each nominally with 50% duty cycle, and nominally one-third cycle apart. This format is often
called “120° spacing”. Power PMAC can also support “60° spacing” for the purpose of power-on
commutation position, but its use is discouraged because of the increased difficulty in detecting
signal failure.
The 3-phase Hall format provides six distinct states per cycle of the signal. Typically, one cycle
of the signal set corresponds to one electrical cycle, or pole pair, of the motor. These sensors,
then, can provide absolute (but low-resolution) information about where the motor is in its
commutation cycle, and eliminate the need to do a power-on phasing search operation.
U/A
1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12
V/B
W/C
“Clockwise” “Counterclockwise”
This diagram shows the signal format for the 120° spacing for two full cycles. Note that the states
where all signals are “high” and all are “low” are not valid states in this format. Since the
common failure modes (such as a disconnected cable) would likely leave the signals in one of
these invalid states, it is quite easy to detect signal failure.
The 60° spacing format can be obtained by inverting any of the signals in the above diagram. In
this format, the states where all signals are “high” and all are “low” are valid states, so it is much
more difficult to detect the common failure modes.
Hardware Setup
If just used for power-up commutation position feedback, the hall sensors are typically wired into
the U, V, and W supplemental flag inputs on a PMAC2-style or PMAC3-style interface channel.
These are single-ended 5V digital inputs on all existing hardware implementations. They are not
optically isolated inputs; if isolation is desired from the sensor, this must be done externally.
If used for servo position and velocity feedback, the three hall sensors are connected to the A, B,
and C “encoder” inputs, so that the signal edges can be counted. As with quadrature encoders,
these inputs can be single-ended or differential. They are not optically isolated inputs; if isolation
is desired from the sensor, this must be done externally. There may be applications in which the
signals are connected both to U, V, and W inputs (for power-on commutation position) and to A,
B, and C inputs (for servo feedback).
To use this value for power-on phase position, the following settings are typically used:
Motor[x].pAbsPhasePos = Gaten[i].Chan[j].Status.a
Motor[x].AbsPhasePosFormat = $0400031C (for a PMAC2-style “Gate1” IC)
Motor[x].AbsPhasePosFormat = $0400030C (for a PMAC3-style “Gate3” IC)
Motor[x].AbsPhasePosSf = +/-2048/12
Motor[x].AbsPhasePosOffset = {application-dependent setting}
For details on setting up these variables, refer to the “Setting Up Commutation” chapter of the
User’s Manual.
Multiple serial encoder protocols can be supported by each interface type. In the FPGA-based
interface, the board must be ordered with a (single) particular protocol installed for all channels.
In the ASIC-based interface, all of the protocols are installed simultaneously, and the particular
protocol desired is selected in software for all channels.
Signal Format
The signal format for the encoder is dependent on the particular protocol, but in all protocols,
there is a “strobe” and/or “clock” output from the controller, and a data channel into the processor
from the encoder. The encoder is queried synchronously with the Power PMAC’s phase or servo
clock, and the incoming serial data is latched into a memory-mapped register for the processor to
read.
Hardware Setup
This section describes the Power PMAC serial encoder hardware interface in general terms.
Consult the Hardware Reference Manual for your particular configuration for details.
All of the supported serial encoder interfaces use differential signal pairs at 5V RS-422 levels. All
have clock and/or “strobing” outputs, and all have a data signal input. In some protocols, the data
line is bi-directional, supporting data output commands to the encoder.
Because of the serial data protocol, the transfer of data from the encoder to the Power PMAC
interface circuitry takes a significant amount of time. The data must be ready for the processor
immediately after the falling edge of the phase and/or servo clock signals, which are the interrupts
to the processor telling it to start those respective tasks.
The process of querying the encoder for data must start well before these signal edges, and this
timing must be carefully considered. If it starts too late, the data will not be ready in time. If it
starts too early, unnecessary delay is introduced into the feedback loop, possibly compromising
its performance. In both styles of interface, the multi-channel saved setup element permits the
user to optimize the timing by selecting the edge (rising or falling) of the clock signal (phase or
servo) that starts the triggering process, and the time delay from this edge until the actual
triggering occurs. The following diagram shows the time lines for the possible configurations:
Phase
Clock
Used1
t=1 TD1 Xmit1 TD2 Xmit2 Used2
Servo
Clock
This section describes the setup elements for the serial encoder interface in general terms.
Detailed information for each serial encoder protocol can be found in the Power PMAC software
reference manual, and the manual for the appropriate hardware device.
The different components of this 32-bit full-word element cannot be accessed as independent
elements, so it is necessary to assemble the full-word value from the values of the individual
components. It is easiest to treat the value as a hexadecimal value, so the individual components
can be seen independently.
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
The protocols presently supported in the ASIC, and their specifying codes in “pp”, are:
* The ACC-84x FPGA-based interface has a more comprehensive interface for these protocols.
The DSPGATE3 ASIC used here has the interface circuitry for
all of these protocols installed simultaneously (unlike the
FPGA-based designs). The user can simply select which
Note protocol – common to all 4 channels – is to be used by setting
the value of this component of the element.
The serial encoder signal lines can also be used for a simple auxiliary quadrature-encoder
interface, independent of the main incremental encoder interface for the channel. This can be
done when Gate3[i].SerialEncEna is set to its default value of 0. In this case, the clock and data
lines are used for the A and B channel inputs of the quadrature encoder (there is no index channel
input). The status register Gate3[i].Chan[j].SerialEncDataA contains the 32-bit clock-latched
count value of the encoder, with the low 8 bits containing the timer-based sub-count estimation.
The trigger select component “t” can presently take four values:
Refer to the figure “Serial Encoder Interface Timing”, above, for an illustration of these options.
It is best to choose the edge that minimizes the delay between the triggering of the encoder and its
use by the Power PMAC software. The software will use the received encoder value immediately
after the falling edge of the phase clock for commutation feedback, and immediately after the
falling edge of the servo clock for servo feedback.
If you are using the serial encoder data for commutation feedback, you must trigger using the
phase clock in order to get new data every phase cycle. If there is sufficient time to receive the
data in one half of a phase clock cycle, you should use the rising edge of the phase clock to
trigger. For example, at the default phase clock frequency of 9 kHz, a clock cycle is 110 µsec. If
the serial encoder data can be received within 55 µsec, the rising edge should be used. If not, the
falling edge must be used.
If you are only using the serial encoder data for servo, and not commutation, feedback, the servo
clock can be used for the trigger. However, it is still advisable to use the phase clock if possible to
minimize the delay. When using the servo clock, as with the phase clock, use the rising edge if
possible for the trigger, and the falling edge only if required.
Remember that the servo clock signal is low only for one half phase clock cycle. For example,
with the default 9 kHz phase clock and 2.25 kHz servo clock, the servo clock is low for only a
half of 110 µsec phase clock cycle, and the delay from the rising edge to the next falling edge is
385 µsec.
The triggering does not need to start exactly on the specified clock edge. The trigger delay
component “dd” specifies the number of serial encoder clock cycles after the specified clock edge
before the triggering of the encoder actually begins. It can take a value of $00 to $FF (0 to 255
clock cycles). Non-zero values can be used to minimize the delay between triggering of the
encoder and the use of its data in the next software cycle.
The linear clock-frequency division component “mm” controls how an intermediate clock
frequency is generated from the IC’s fixed 100 MHz clock frequency. The resulting serial-
encoder clock frequency is then generated from this intermediate clock frequency by the
exponential division component “nn”, described below.
f int MHz
100
M 1
where M is the numerical value of “mm”. This 8-bit component can take a value from 0 to 255, so
the resulting intermediate clock frequencies can range from 100 MHz down to 392 kHz.
The exponential clock-frequency division component “n” controls how the final serial-encoder
clock frequency is generated from the intermediate clock frequency set by “mm”. The equation
for this final frequency is:
f int MHz
f ser MHz
100
2 N
M 1 * 2 N
where N is the numerical value of “n”. This 4-bit component can take a value from 0 to 15, so the
resulting 2N divisor can take a value from 1 to 32,768.
For serial-encoder protocols with an explicit clock signal and fixed timing on reading the data, the
resulting frequency is the frequency of the clock signal that is output from the IC. For “self-
clocking” protocols without an explicit clock signal or for those with time-delay compensation
circuitry, this frequency is the input sampling frequency, and will be 20 to 25 times higher than
the input bit rate. Refer to the instructions for the particular protocol for details.
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
The 16-bit component SerialEncCmdWord is used to define a command value sent to the serial
encoder in a protocol-specific manner.
The 2-bit component SerialEncParity defines the parity type to be expected for the received data
packet (for those protocols that support parity checking). A value of 0 specifies no parity; a value
of 1 specifies odd parity; a value of 2 specifies even parity. (A value of 3 is reserved for future
use.)
The 1-bit component SerialEncTrigEna specifies whether the encoder is to be sampled or not. A
value of 0 specifies no sampling; a value of 1 enables sampling of the encoder. If sampling is
enabled with SerialEncTrigMode at 0, the encoder will be repeatedly sampled (every phase or
servo cycle as set by the multi-channel element Gate3[i].SerialEncCtrl) as long as
SerialEncTrigEna is left at a value of 1. However, if sampling is enabled with
SerialEncTrigMode at 1, the encoder will be sampled just once, and the IC will automatically set
SerialEncTrigEna back to 0 after the sampling.
The 1-bit component SerialEncGtoB specifies whether the data returned in SSI protocol
undergoes a conversion from Gray format to numerical-binary format or not. A value of 0
specifies that no conversion is done; a value of 1 specifies that the incoming data undergoes a
Gray-to-binary conversion.
The 1-bit component SerialEncDataReady is a read-only status bit indicating the status of the
serial data reception. It reports 0 during the data transmission indicating that valid new data is not
yet ready. It reports 1 when all of the data has been received and processed. This is particularly
important for slower interfaces that may take multiple servo cycles to complete a read; in these
cases, the bit should be polled to determine when data is ready.
The 4-bit component SerialEncStatusBits specifies the number of status bits the interface will
expect from the encoder in the SPI protocol. The valid range of settings is 0 to 12.
The 6-bit component SerialEncNumBits specifies the number of data bits the interface will expect
from the encoder in the SPI, SSI, or EnDat protocol. The valid range of settings is $0C to $3F (12
to 63 bits).
This section describes the setup elements for the serial encoder interface in general terms.
Detailed information for each serial encoder protocol can be found in the Power PMAC software
reference manual, and the manual for the appropriate hardware device.
The different components of this 24-bit full-word element cannot be accessed as independent
elements, so it is necessary to assemble the full-word value from the values of the individual
components. It is easiest to treat the value as a hexadecimal value, so the individual components
can be seen independently.
The full element can be viewed in the following format. In the Script environment, it is a 24-bit
element. In the C environment, it is a 32-bit element with the real data in the high 24 bits.
Hex Digit ($) - -
Script Bit # 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - -
C Bit # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7-4 3-0
Bit Value - - - -
Component: SerialClockMDiv SerialClockNDiv -- -- TC TE SerialTrigDelay SerialProtocol
The serial protocols presently supported in the FPGA, and their specifying codes in “p”, are:
$2: SSI
$3: EnDat2.1/2.2
$4: Hiperface
$6: Sigma II/III/V
$7: Tamagawa
$8: Panasonic
$09: Mitutoyo
$B: BiSS-B/C (Unidirectional)
$C: Matsushita
$D: Mitsubishi
$E: Omron 1S
The FPGA used here comes with the interface for only a single
serial protocol, which was pre-installed at the factory as
specified in the order. (This is unlike the DSPGATE3 ASIC,
which has all of the protocols installed.) This component of the
Note element is read-only, simply notifying the user which protocol
has been installed.
The trigger select component “t” can presently take four values:
Refer to the figure “Serial Encoder Interface Timing”, above, for an illustration of these options.
It is best to choose the edge that minimizes the delay between the triggering of the encoder and its
use by the Power PMAC software. The software will use the received encoder value immediately
after the falling edge of the phase clock for commutation feedback, and immediately after the
falling edge of the servo clock for servo feedback.
If you are using the serial encoder data for commutation feedback, you must trigger using the
phase clock in order to get new data every phase cycle. If there is sufficient time to receive the
data in one half of a phase clock cycle, you should use the rising edge of the phase clock to
trigger. For example, at the default phase clock frequency of 9 kHz, a clock cycle is 110 µsec. If
the serial encoder data can be received within 55 µsec, the rising edge should be used. If not, the
falling edge must be used.
If you are only using the serial encoder data for servo, and not commutation, feedback, the servo
clock can be used for the trigger. However, it is still advisable to use the phase clock if possible to
minimize the delay. When using the servo clock, as with the phase clock, use the rising edge if
possible for the trigger, and the falling edge only if required.
Remember that the servo clock signal is low only for one half phase clock cycle. For example,
with the default 9 kHz phase clock and 2.25 kHz servo clock, the servo clock is low for only a
half of 110 µsec phase clock cycle, and the delay from the rising edge to the next falling edge is
385 µsec.
The triggering does not need to start exactly on the specified clock edge. The trigger delay
component “d” specifies the number of 20-microsecond intervals after the specified clock edge
before the triggering of the encoder actually begins. It can take a value of $0 to $F (0 to 15, or 0
to 300 microseconds). Non-zero values can be used to minimize the delay between triggering of
the encoder and the use of its data in the next software cycle.
The linear clock-frequency division component “mm” controls how an intermediate clock
frequency is generated from the IC’s fixed 100 MHz clock frequency. The resulting serial-
encoder clock frequency is then generated from this intermediate clock frequency by the
exponential division component “nn”, described below.
f int MHz
100
M 1
where M is the numerical value of “mm”. This 8-bit component can take a value from 0 to 255, so
the resulting intermediate clock frequencies can range from 100 MHz down to 392 kHz.
The exponential clock-frequency division component “n” controls how the final serial-encoder
clock frequency is generated from the intermediate clock frequency set by “mm”. The equation
for this final frequency is:
f int MHz
f ser MHz
100
2 N
M 1 * 2 N
where N is the numerical value of “n”. This 4-bit component can take a value from 0 to 15, so the
resulting 2N divisor can take a value from 1 to 32,768.
For serial-encoder protocols with an explicit clock signal and fixed timing on reading the data, the
resulting frequency is the frequency of the clock signal that is output from the IC. For “self-
clocking” protocols without an explicit clock signal or for those with time-delay compensation
circuitry, this frequency is the input sampling frequency, and will be 20 to 25 times higher than
the input bit rate. Refer to the instructions for the particular protocol for details.
The full element can be viewed in the following format. In the Script environment, it is accessed
as a 24-bit element. In the C environment, it is accessed as a 32-bit element with the real data in
the high 24 bits.
Hex Digit ($) - -
Script Bit # 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - -
C Bit # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7-4 3-0
Bit Value - - -
Component: SerialEncCmdWord Parity TM TE GB Ena Status NumBits
The 8-bit component SerialEncCmdWord is used to define a command value sent to the serial
encoder in a protocol-specific manner. This value can be changed during an application for
different functionality, such as resetting an encoder. Not all protocols require a command value.
The 2-bit component SerialEncParity defines the parity type to be expected for the received data
packet (for those protocols that support parity checking). A value of 0 specifies no parity; a value
of 1 specifies odd parity; a value of 2 specifies even parity. (A value of 3 is reserved for future
use.)
The 1-bit component SerialEncTrigEna specifies whether the encoder is to be sampled or not. A
value of 0 specifies no sampling; a value of 1 enables sampling of the encoder. If sampling is
enabled with SerialEncTrigMode at 0, the encoder will be repeatedly sampled (every phase or
servo cycle as set by the multi-channel element Acc84E[i].SerialEncCtrl) as long as
SerialEncTrigEna is left at a value of 1. However, if sampling is enabled with
SerialEncTrigMode at 1, the encoder will be sampled just once, and the ACC-84E’s IC will
automatically set SerialEncTrigEna back to 0 after the sampling.
The 1-bit component SerialEncGtoB specifies whether the data returned in SSI protocol
undergoes a conversion from Gray format to numerical-binary format or not. A value of 0
specifies that no conversion is done; a value of 1 specifies that the incoming data undergoes a
Gray-to-binary conversion.
The 1-bit component SerialEncEna / SerialEncDataReady has separate functions for writing to
and reading from the register. When writing to the register, this bit represents SerialEncEna,
which enables the driver circuitry for the serial encoder. This bit must be set to 1 to use any
protocol of serial encoder on the channel. If there is an alternate use for the same signal pins, this
bit must be set to 0 so the encoder drivers do not conflict with the alternate use. Note that you
cannot read back the value you have written to this bit!
When reading from the register, you get the SerialEncDataReady status bit indicating the state of
the serial data reception. It reports 0 during the data transmission indicating that valid new data is
not yet ready. It reports 1 when all of the data has been received and processed. This is
particularly important for slower interfaces that may take multiple servo cycles to complete a
read; in these cases, the bit should be polled to determine when data is ready.
The 4-bit component SerialEncStatusBits specifies the number of status bits the interface will
expect from the encoder in the SPI protocol. The valid range of settings is 0 to 12.
The 6-bit component SerialEncNumBits specifies the number of data bits the interface will expect
from the encoder in the SSI, EnDat, or BiSS protocol. The valid range of settings for these
protocols is 12 – 63. In other protocols, the number of bits is not specified this way, and this value
does not matter, so this component is usually left at 0.
rollover of this data properly, the most significant bit (MSB) of this data must end up in bit 31 of
the 32-bit result, shifted if necessary. With most protocols, no shifting is necessary, but some will
require a net “left shift” to achieve this result.
Motor[x].pPhaseEnc = Gate3[i].Chan[j].SerialEncDataA.a
Motor[x].PhaseEncRightShift = 0 // If encoder LSB in Register 0
Motor[x].PhaseEncLeftShift = (32 - # of bits)
Motor[x].PhasePosSf = 2048 / (LSBs per commutation cycle)
In the 32-bit PMAC3 ASIC, the LSB of the encoder data is generally found in bit 0 on the 32-bit
data bus. If the encoder protocol does not provide a full 32 bits of data in the SerialEncDataA
register, the data will need to be “shifted left” so that the MSB ends up in bit 31 of the result. For
purposes of computing the scale factor, the LSB of the resulting (post-shift) 32-bit value should
be used as the “LSB”.
Motor[x].pPhaseEnc = Acc84E[i].Chan[j].SerialEncDataA.a
Motor[x].PhaseEncRightShift = 8 // If encoder LSB in Register 8
Motor[x].PhaseEncLeftShift = (32 - # of bits)
Motor[x].PhasePosSf = 2048 / (Register LSBs per commutation cycle)
In the 24-bit ACC-84E, the LSB of the encoder data is generally found in bit 8 on the 32-bit data
bus, with unpredictable values in the lowest 8 bits of the bus. While this low “phantom” data is
not known to affect actual commutation performance in real systems, some users will want to
remove this data with an 8-bit “shift right” operation. When this is done, a “shift left” operation
must also be done to leave the MSB of encoder data in bit 31 of the result. For purposes of
computing the scale factor, the LSB of the resulting (post-shift) 32-bit value should be used as the
“LSB”.
This section gives an overview of those settings; details can be found in the element descriptions
in the Software Reference Manual, the Setting Up Commutation chapter of the User’s Manual,
and the Hardware Reference Manual for the interface. In addition the motor setup routines in the
IDE software will walk you through this setup.
Motor[x].pAbsPhasePos = Gate3[i].Chan[j].SerialEncDataA.a
Motor[x].AbsPhasePosFormat = $aabbccdd // Protocol-specific settings
Motor[x].AbsPhasePosSf = 2048 / (LSBs per commutation cycle)
Motor[x].AbsPhasePosOffset = (Difference between sensor zero and commutation zero)
For the format variable, the LSB of the encoder data is typically found in bit 0 of the 32-bit
register, and only enough bits to cover a single commutation cycle need to be used. (However, it
does not hurt to specify more bits than are required.) It is almost never required to use data from
the next register.
Motor[x].pAbsPhasePos = Acc84E[i].Chan[j].SerialEncDataA.a
Motor[x].AbsPhasePosFormat = $aabbccdd // Protocol-specific settings
Motor[x].AbsPhasePosSf = 2048 / (LSBs per commutation cycle)
Motor[x].AbsPhasePosOffset = (Difference between sensor zero and commutation zero)
For the format variable, the LSB of the encoder data is typically found in bit 8 of the 32-bit
register, and only enough bits to cover a single commutation cycle need to be used. (However, it
does not hurt to specify more bits than are required.) It is seldom required to use data from the
next register.
EncTable[n].Type = 1
EncTable[n].pEnc = Gate3[i].Chan[j].SerialEncDataA.a
EncTable[n].index1 = (32 - # of bits) // Shift left # of bits
EncTable[n].index2 = 0 // Shift right # of bits
EncTable[n].ScaleFactor = 1/ (232 - # of bits) // For result in encoder LSBs
Motor[x].pEnc = EncTable[n].a // Use table result for position-loop feedback
Motor[x].pEnc2 = EncTable[n].a // Use table result for velocity-loop feedback
EncTable[n].Type = 1
EncTable[n].pEnc = Acc84E[i].Chan[j].SerialEncDataA.a
This section gives an overview of those settings; details can be found in the element descriptions
in the Software Reference Manual, the Basic Motor Setup chapter of the User’s Manual, and the
Hardware Reference Manual for the interface. In addition the motor setup routines in the IDE
software will walk you through this setup.
Motor[x].pAbsPos = Gate3[i].Chan[j].SerialEncDataA.a
Motor[x].AbsPosFormat = $aabbccdd // Protocol-specific settings
Motor[x].AbsPosSf = (Motor units per sensor LSB)
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
For the format variable, the LSB of the encoder data is typically found in bit 0 of the 32-bit
SerialEncDataA register. If the encoder provides more than 32 bits of absolute position data, the
format element permits data from SerialEncDataB to be used as well.
Motor[x].pAbsPos = Acc84E[i].Chan[j].SerialEncDataA.a
Motor[x].AbsPosFormat = $aabbccdd // Protocol-specific settings
Motor[x].AbsPosSf = (Motor units per sensor LSB)
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
For the format variable, the LSB of the encoder data is typically found in bit 8 of the 32-bit
SerialEncDataA register. If the encoder provides more than 24 bits of absolute position data, the
format element permits data from SerialEncDataB to be used as well. Note, however, that the
data in SerialEncDataA must go all the way to bit 31 for this to work. In protocols such as
Tamagawa and Panasonic, which provide only 17 bits of data in SerialEncDataA and more in
SerialEncDataB, the full absolute position must be assembled in a user algorithm.
Signal Format
The sinusoidal encoder interfaces for Power PMAC are designed to accept “sine” and “cosine”
signals (90° out of phase with each other), of 1-volt (peak-to-peak) magnitude. Most commonly,
these signals are differential pairs, wired into the SIN+, SIN-, COS+, and COS- inputs for the
channel. Single-ended inputs can also be used, wired into the SIN+ and COS+ inputs for the
channel, with the SIN- and COS- inputs connected directly to the 2.5V signal provided on the
connector.
The ideal signals are both centered around the reference voltage, exactly one-quarter cycle out of
phase with each other, and of the same magnitude. Deviations from this ideal will cause errors in
the resulting interpolated position values. The following diagram shows the common signal
errors:
CosMag
SinMag
CosOffset 90°
SinOffset
θ
φ
(φ = PhaseError)
Power PMAC hardware and software have the capability of correcting for some or all of these
errors. The accuracy requirements of a particular system can dictate which type of interface is
used.
The second style is based on the PMAC3-style “DSPGATE3” ASIC, as used in the standard
analog feedback option for the UMAC ACC-24E3 axis-interface board or for the Power Brick
family. This can compute the interpolated position in hardware, so the processor simply needs to
read the result. Alternately, the data from this IC can be interpolated in software with additional
correction terms.
The third style is based on a combination of a PMAC3-style “DSPGATE3” ASIC and a pre-
processing FPGA, as used in the “auto-correcting” analog feedback option for the UMAC ACC-
24E3 axis-interface board or for the Power Brick family. In this style, the FPGA automatically
detects and corrects for the common signal errors of voltage offsets, magnitude mismatch, and
phase error. It also uses oversampling and averaging to reduce the effect of electrical noise on the
resulting position.
o Encoder sampled half phase cycle before servo interrupt, ready at interrupt
o No automatic identification of signal errors
o Software compensation for voltage offsets in ECT
o Software compensation for phase error in ECT
o Software compensation for magnitude mismatch error in ECT
o Software filtering for noise in ECT at servo rate (in kHz)
o Resulting position value has 14 bits of interpolation (16,384 states per line)
o Interpolated hardware capture and compare based on uncorrected signals
Hardware Setup
This section describes the Power PMAC interpolator hardware interface in general terms. Consult
the Hardware Reference Manual for your particular configuration for details.
Interface Circuitry
The interpolator analog hardware interfaces operate on a single 5V supply relative to the GND
reference voltage. There is no isolation from the digital 5V circuitry. It is intended that the analog
input signals be centered on the intermediate 2.5V level. If the signals are differential, this
centering does not have to be precise, but the signal levels cannot go above 5V or below GND. If
the signals are single-ended, they must be directly compared to an intermediate voltage, most
likely the regulated 2.5V level generated in the interface and supplied on the connector.
The “+” and “-” input pairs are connected in the interface through termination resistors. These
resistors both serve to preserve the signal quality by preventing ringing and to facilitate signal-
loss detection by pulling the two inputs to the same voltage in the absence of a driving signal.
The sinusoidal input signals are fed into both differential receivers acting as comparators that
produce digital quadrature signals into the ASIC, and into analog-to-digital converters (ADCs)
that produce numbers proportional to the sine and cosine signal levels.
The following diagram shows the principle of the Power PMAC standard processing of the
sinusoidal encoder signals.
A
Sin+
+
Quad Counter
- B Decode
Sin-
SCLK (MHz)
Interpolated Position
Servo Clock (kHz)
Cos+
ADC
+
Arctangent Fraction
-
Cos- ADC
The following diagram shows the principle of the Power PMAC Auto-Correcting Interpolator’s
processing of the sinusoidal encoder signals.
Raw Corrected
Readings Readings
A PosData'
Sin+ Serial Encoder Position
+
- B A'
Sin- Quad
B' Decode
Counter
Signal Error
Auto-Detection
20 MHz
and
Correction
SinData Interpolated Position
Cos+ ADC
+
- CosData SinData'
Cos- ADC Arctangent Fraction
CosData'
Wiring Techniques
In order to get good position information from the sinusoidal encoder interface, it is vital that
proper wiring techniques be employed. The impact of a small amount of noise on these analog
signals is much greater than for digital signals.
The use of differential signal pairs is very important in reducing the amount of noise at the
receiver circuits. These signal pairs provide common-mode noise rejection, with the resulting
voltage difference being much smaller than the disturbance to the individual signals. The signal
pairs should be wired as twisted pairs, providing cancellation of received noise.
The encoder cable should be kept physically separate from the motor power cable if at all
possible. Running the two cables parallel and adjacent provides a strong coupling mechanism for
noise. Both motor cable and encoder cable should be shielded, the motor cable to prevent noise
from getting out, and the encoder cable to prevent noise from getting in.
If the motor is driven by a pulse-width-modulated (PWM) or similar switching drive, the rapid
switching of the power signals generates high levels of noise that are difficult to keep out of the
encoder signal. Often, chokes must be installed on the outputs from the drive to “soften” the
transitions and reduce the generated noise. Note that in the highest-resolution systems, linearly
modulated amplifiers are often employed to eliminate this switching noise altogether.
The encoder cable for sinusoidal encoders is often double-shielded, with the inner shield tied to
the signal ground (0V) at the controller end, and the outer shield tied directly to the chassis
ground at the controller end. Some users prefer to tie the encoder casing to the outer shield, but
the inner shielding should be left floating at the encoder end. This configuration provides the
optimal protection of the encoder signal.
The following diagram illustrates the optimal wiring and shielding for sinusoidal encoders. In the
diagram, each signal pair is individually shielded. Many users will put all of the signal pairs
inside a single shield, which provides protection almost as good for substantially reduced cost.
Encoder PMAC
SIN+ A+/SIN+
SIN- A-/SIN-
0V
COS+ B+/COS+
COS- B-/COS-
0V
IDX+ C+/IDX+
IDX- C-/IDX-
0V
Chassis
Ground
Instructions for setting the SCLK frequency are given in the section on digital quadrature
encoders, above. Note that with analog sinusoidal encoders, noise issues must be dealt with well
in the hardware interface, so that optimizing the ASIC’s digital delay filter is not important here.
For proper operation, the direction sense of this decode must also match the direction sense of the
“arctangent” processing of the sine and cosine ADC values so the whole-count and sub-count
polarities match; otherwise rough operation will occur. When the interpolation is done in software
in the encoder conversion table, as with the ACC-51E, the matchup only occurs on the
initialization of the table entry (which is automatically done at power-up/reset of the Power
PMAC). If the decode direction sense is changed between 3 and 7, the table entry must be re-
initialized by setting EncTable[n].index3 to 0.
table (which is slower but supports corrections for voltage offsets, phase error, and magnitude
mismatch.
Gate3[i].EncClockDiv specifies the frequency of the SCLK signal. The default value of 5
specifies a frequency of 3.125 MHz. This supports signal frequencies up to about 600 kHz,
suitable for the majority of cases. Reducing the value of this element supports higher frequencies.
Note that with analog sinusoidal encoders, noise issues must be dealt with well in the hardware
interface, so that optimizing the ASIC’s digital delay filter is not important here.
In this process, there is a delay of half of a phase-clock cycle between when the data is sampled
and when the data is used. In a high-performance servo system, this time delay might produce a
noticeable degradation of servo performance. In many cases, this half-cycle delay may be
significantly more than is required to acquire and process the data. In these cases, saved setup
parameter Gate3[i].EncLatchDelay permits this sampling to be started after the rising edge of
the phase clock, thus reducing the delay between sampling and use. Gate3[i].EncLatchDelay is
in units of 16 encoder ADC clock cycles (each default 320 nanoseconds, set by
Gate3[i].AdcEncClockDiv), specifying how many of these cycles elapse before the encoder data
is sampled. It can range from the default of 0 to 255, for 4080 ADC clock cycles.
Acquiring and processing the encoder data requires 25 cycles of the encoder ADC clock, which is
8 microseconds at the default ADC clock frequency. At the default phase clock frequency of 9
kHz, sampling fully a half phase cycle ahead yields a 55 microsecond delay, over 40
microseconds more than is needed. If Gate3[i].EncLatchDelay is set to 125, the sampling is
delayed for 40 microseconds from the rising edge, reducing the net delay from sampling until use
to 15 microseconds, but still providing enough time to acquire and process the data.
For proper operation, the direction sense of this decode must also match the direction sense of the
“arctangent” processing of the sine and cosine ADC values so the whole-count and sub-count
polarities match; otherwise rough operation will occur. If the interpolation calculations are done
in hardware in the interpolator, this matchup occurs automatically. However, if the interpolation
calculations are done in software in the encoder conversion table, the matchup only occurs on the
initialization of the table entry (which is automatically done at power-up/reset of the Power
PMAC). If the decode direction sense is changed between 3 and 7 (which often happens during
initial setup), the table entry must be re-initialized by setting EncTable[n].index3 to 0.
element Gate3[i].Chan[j].AdcOffset[0] is added to the value measured from the “sine” signal in
Gate3[i].Chan[j].AdcEnc[0], and the value in Gate3[i].Chan[j].AdcOffset[1] is added to the
value measured from the “cosine” signal in Gate3[i].Chan[j].AdcEnc[1].
If the sub-count interpolation is to be done in the encoder conversion table using a software-based
arctangent calculation there, these bias-compensation terms in the ASIC are not used. The
equivalent bias values should be placed in software elements EncTable[n].SinBias and
EncTable[n].CosBias, respectively. These terms are used along with magnitude-mismatch error
term EncTable[n].CoverSerror (cosine-over-sine error) and phase-error term
EncTable[n].TanHalfPhi for a more complete correction of encoder signal errors.
If the sub-count interpolation is to be done in the encoder conversion table using a software-based
arctangent calculation there, Gate3[i].Chan[j].AtanEna must be set to 0 to disable the
combination of the hardware-calculated value with the quadrature count. The software-based
interpolation has the capability to correct for phase-offset and magnitude-mismatch errors, but
does require more processor time. It should only be used if correction for phase-offset and/or
magnitude-mismatch errors is performed.
Gate3[i].EncClockDiv specifies the frequency of the SCLK signal. The default value of 5
specifies a frequency of 3.125 MHz. This supports signal frequencies up to about 600 kHz,
suitable for the majority of cases. Reducing the value of this element supports higher frequencies.
Each reduction of 1 supports twice the frequency.
In this process, there is a delay of half of a phase-clock cycle between when the data is sampled
and when the data is used. In a high-performance servo system, this time delay might produce a
noticeable degradation of servo performance. In many cases, this half-cycle delay may be
significantly more than is required to acquire and process the data. In these cases, saved setup
parameter Gate3[i].EncLatchDelay permits this sampling to be started after the rising edge of
the phase clock, thus reducing the delay between sampling and use. Gate3[i].EncLatchDelay is
in units of 16 encoder ADC clock cycles (each default 320 nanoseconds, set by
Gate3[i].AdcEncClockDiv), specifying how many of these cycles elapse before the encoder data
is sampled. It can range from the default of 0 to 255, for 4080 ADC clock cycles.
Acquiring and processing the encoder data requires 25 cycles of the encoder ADC clock, which is
8 microseconds at the default ADC clock frequency. At the default phase clock frequency of 9
kHz, sampling fully a half phase cycle ahead yields a 55 microsecond delay, over 40
microseconds more than is needed. If Gate3[i].EncLatchDelay is set to 125, the sampling is
delayed for 40 microseconds from the rising edge, reducing the net delay from sampling until use
to 15 microseconds, but still providing enough time to acquire and process the data.
For standard operation with continuous auto-identification and auto-correction of encoder signal
errors, Gate3[i].AdcEncStrobe should be set to $800000, which sets only the MSB to 1. In any
mode of operation, this bit must be set to 1 to start the conversions synchronized to the phase
clock cycle. The other bits of this element can be set to 1 for alternate modes of operation, as
discussed here. Most of these alternate modes are for diagnostic purposes.
The individual bit meanings of Gate3[i].AdcEncStrobe are shown in the following diagram:
Hex Digit ($)
Bit # 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Chan[0]
Chan[1]
Chan[2]
Chan[3]
Chan[0]
Chan[1]
Chan[2]
Chan[3]
Chan[0]
Chan[1]
Chan[2]
Chan[3]
Chan[0]
Chan[1]
Chan[2]
Chan[3]
Chan[0]
Chan[1]
Chan[2]
Chan[3]
none
none
All
All
Channel
Additional Data
Additional Data
Additional Data
Request Bit 0
Request Bit 1
Request Bit 2
Hold Present
Corrections
Corrections
Clear
Function
Start Convert: The most significant bit (MSB) of Gate3[i].AdcEncStrobe must be set to 1 for
the interpolator to operate properly. This is the first bit of the word output serially, and it starts the
transmission of data from the FPGA to the ASIC.
Clear Corrections: To use the uncorrected encoder signals in the interpolations, set the “Clear
Corrections” bit for the channel to 1. To do this without changing any other settings, the
following commands can be used:
To start using the corrected encoder signals in the interpolations again, reset the “Clear
Corrections” bit for the channel to 0. To do this without changing any other settings, the
following commands can be used:
Hold Corrections: To freeze the present corrections to use in the interpolations, set the “Hold
Corrections” bit for the channel to 1. To do this without changing any other settings, the
following commands can be used:
To start using new corrections in the interpolations again, reset the “Hold Corrections” bit for the
channel to 0. To do this without changing any other settings, the following commands can be
used:
Additional Data Requests: The auto-correcting interpolator permits the processor to access
additional information for a channel in that channel’s alternate A/D converter registers
Gate3[i].Chan[j].AdcEnc[2] and Gate3[i].Chan[j].AdcEnc[3]. The following types of
additional data are presently supported:
Unfiltered uncorrected (“raw”) A/D-Converter Data: If the additional data request value for a
channel is set to 0, the interpolator will place the unfiltered uncorrected A/D-converter values for
the sine and cosine signals into Gate3[i].Chan[j].AdcEnc[2] and Gate3[i].Chan[j].AdcEnc[3],
respectively, each phase cycle. These are the most recent direct readings from the ADCs.
To request the uncorrected A/D converter values for a channel, set bit 0 of the “additional data
request value” for the channel to 0. To do this without changing any other settings, the following
commands can be used:
Unfiltered corrected A/D-Converter Data: If the additional data request value for a channel is set
to 1, the interpolator will place the unfiltered, but corrected A/D-converter values for the sine and
cosine signals into Gate3[i].Chan[j].AdcEnc[2] and Gate3[i].Chan[j].AdcEnc[3], respectively,
each phase cycle. Note that while these values are not filtered, they are corrected using the most
recently determined correction factors.
To request the unfiltered corrected A/D converter values for a channel, set bit 0 of the “additional
data request value” for the channel to 1. To do this without changing any other settings, the
following commands can be used:
Present Sine and Cosine Bias Values: If the additional data request value for a channel is set to 2,
the interpolator will place the present bias values for the sine and cosine signals into
Gate3[i].Chan[j].AdcEnc[2] and Gate3[i].Chan[j].AdcEnc[3], respectively, each phase cycle.
To request the present sine and cosine bias values for a channel, set bit 1 of the “additional data
request value” for the channel to 1. To do this without changing any other settings, the following
commands can be used:
Present Magnitude-Mismatch and Phase-Error Values: If the additional data request value for a
channel is set to 3, the interpolator will place the present magnitude-mismatch value (ratio of sine
over cosine) into Gate3[i].Chan[j].AdcEnc[2] and the present phase-error value (signed 16-bit
value with full range representing ±180°) into Gate3[i].Chan[j].AdcEnc[3], each phase cycle.
To request the present magnitude-mismatch and phase-error values for a channel, set bits 0 and 1
of the “additional data request value” for the channel to 1. To do this without changing any other
settings, the following commands can be used:
Velocity and Acceleration Data: As part of the process of identifying and correcting encoder
errors, the FPGA in the Auto-Correcting Interpolator is continually calculating high-quality
velocity and acceleration values from the encoder signals. If the additional data request value for
a channel is set to 4, 5, 6, or 7, the interpolator will place these values into
Gate3[i].Chan[j].AdcEnc[2] and Gate3[i].Chan[j].AdcEnc[3], respectively. These are 32-bit
elements, with real data in the high 24 bits.
It is possible to use these values for servo feedback, which can provide superior performance
since these values have less time delay and time jitter than those values obtained by single and
double differentiation of position values.
The difference in operation from the possible additional data-request values 4, 5, 6, and 7 is just
one of the scaling of the reported velocity and acceleration quantities, with each setting differing
from the next by a value of 4. The scale factor SF for the velocity value can be computed as:
16
SF * n * ServoFreq( Hz )
75
where the reported velocity value (considered as a 32-bit value) multiplied by SF would equal the
value obtained by the difference between the position values in consecutive servo cycles (the
alternate method of computing velocity) when the position value is scaled in 1/65,536 of an
encoder line. The possible values of “n” are:
A smaller value of n and therefore a smaller scale factor SF means a larger reported velocity
number for the same physical velocity. This means a lower maximum velocity before saturation,
but more resolution in the reported velocity. The optimal setting is the lowest scale factor that
supports the maximum physical velocity without saturation, as this will provide the highest
resolution possible.
To request the velocity and acceleration values for a channel with n = 1 scaling, set bit 2 of the
“additional data request value” for the channel to 1. To do this without changing any other
settings, the following commands can be used:
To request the velocity and acceleration values for a channel with n = 4 scaling, set bits 2 and 0 of
the “additional data request value” for the channel to 1. To do this without changing any other
settings, the following commands can be used:
To request the velocity and acceleration values for a channel with n = 16 scaling, set bits 2 and 1
of the “additional data request value” for the channel to 1. To do this without changing any other
settings, the following commands can be used:
To request the velocity and acceleration values for a channel with n = 64 scaling, set bits 2, 1, and
0 of the “additional data request value” for the channel to 1. To do this without changing any
other settings, the following commands can be used:
Disable Additional Data Request: To disable the request for additional information for a channel,
reset all of the bits of the “additional data request value” for the channel to 0. To do this without
changing any other settings, the following commands can be used:
The DSPGATE3 ASIC should be set up to accept these signals. Even if the primary position
feedback is read from a simulated serial encoder signal (see next section), the quadrature and A/D
data should be used to support the possibility of full-resolution hardware capture and compare in
the ASIC, and to be able to read additional data values in the supplementary A/D converter
registers.
For proper operation, the direction sense of this decode must also match the direction sense of the
“arctangent” processing of the sine and cosine ADC values so the whole-count and sub-count
polarities match; otherwise rough operation will occur. If the interpolation calculations are done
in hardware in the interpolator, this matchup occurs automatically. (With the Auto-Correcting
Interpolator, there is no good reason to do the interpolation in software in the encoder conversion
table.)
First, as it is possible to request the data on the actual servo and phase interrupt and have it ready
in time for use, there is less time delay inside the feedback loop. Second, it is possible to obtain
this position with less time jitter due to the higher frequency of the serial encoder clock compared
to the A/D converter clock. Third, the processor can access the fully interpolated value by just
reading a single I/O register, rather than two, saving processor time each servo cycle. Most
applications would not notice these improvements, but the highest-precision applications could
see an advantage.
The E1 jumper on the Auto-Correcting Interpolator board must be configured to connect pins 2
and 3 to use this simulated serial-encoder value. If it is configured to connect pins 1 and 2, an
external serial encoder can be read through this interface instead.
It is possible to use this simulated serial position value for servo and commutation feedback, and
simultaneously use the counter values for hardware capture and compare functionality.
Motor[x].pPhaseEnc = Gate1[i].Chan[j].PhaseCapt.a
Motor[x].PhasePosSf = 2048 / (256 * 4 * lines per commutation cycle)
In the 24-bit ACC-51E, the LSB of the encoder counter is found in bit 8 on the 32-bit data bus,
and so is equal to 256 LSBs of the 32-bit register. Each LSB of the counter is ¼ of an encoder
line, because “times-4” decode is in force. Note that even this uninterpolated count value has
enough resolution for high-performance commutation in virtually all cases.
Motor[x].pPhaseEnc = Gate3[i].Chan[j].PhaseCapt.a
Motor[x].PhasePosSf = 2048 / (LSBs per commutation cycle)
With the arctangent interpolation active in the ASIC channel (Gate3[i].Chan[j].AtanEna = 1),
the LSB of the PhaseCapt register is 1/16,384 of an encoder line. The denominator of the
expression for PhasePosSf should therefore be 16,384 times the number of encoder lines (signal
cycles) per commutation cycle (or 4096 times the number of quadrature counts per commutation
cycle).
With the arctangent interpolation not active in the ASIC channel (Gate3[i].Chan[j].AtanEna =
0), the LSB of the PhaseCapt register is 1/1024 of an encoder line. The denominator of the
expression for PhasePosSf should therefore be 1024 times the number of encoder lines (signal
cycles) per commutation cycle (or 256 times the number of quadrature counts per commutation
cycle).
Motor[x].pPhaseEnc = Gate3[i].Chan[j].PhaseCapt.a
Motor[x].PhasePosSf = 2048 / (LSBs per commutation cycle)
With the arctangent interpolation active in the ASIC channel (Gate3[i].Chan[j].AtanEna = 1),
the LSB of the PhaseCapt register is 1/16,384 of an encoder line. The denominator of the
expression for PhasePosSf should therefore be 16,384 times the number of encoder lines (signal
cycles) per commutation cycle (or 4096 times the number of quadrature counts per commutation
cycle).
With the arctangent interpolation not active in the ASIC channel (Gate3[i].Chan[j].AtanEna =
0), the LSB of the PhaseCapt register is 1/1024 of an encoder line. The denominator of the
expression for PhasePosSf should therefore be 1024 times the number of encoder lines (signal
cycles) per commutation cycle (or 256 times the number of quadrature counts per commutation
cycle).
To use the encoder position in the ASIC obtained from the FPGA through the serial encoder
interface for ongoing phase position, the following saved setup elements must be specified:
Motor[x].pPhaseEnc = Gate3[i].Chan[j].SerialEncDataA.a
Motor[x].PhasePosSf = 2048 / (LSBs per commutation cycle)
The LSB of the SerialEncDataA register is 1/65,536 of an encoder line. The denominator of the
expression for PhasePosSf should therefore be 65,536 times the number of encoder lines (signal
cycles) per commutation cycle.
Here the conversion table entry performs the (12-bit) arctangent interpolation in software using
the A/D-converter values it reads. The choice of ScaleFactor depends on whether the units of the
result are LSBs of the interpolation (= 1.0), quadrature counts (= 1/1024, as shown), or lines of
the encoder (= 1/4096).
Software Corrections: The following saved setup elements in the table entry can be set to non-
zero values to correct for signal imperfections:
Software Filtering: The analog front end of the standard interpolator circuitry has very “light”
filtering, to permit the use of very high encoder signal frequencies (and therefore very high motor
speeds). If the noise level on the resulting position values is too high, software filtering can be
performed in the conversion table entry. This is enabled by setting EncTable[n].index2 to a
value of 32 or larger, with EncTable[n].index1 and EncTable[n].index2 acting as the gains of
the filter. Refer to the User’s Manual chapter Setting Up the Encoder Conversion Table for
details.
Here, the (14-bit) arctangent interpolation has been performed in the ASIC, and the conversion
table simply needs to read the combined whole-count/fractional count value in the channel’s
ServoCapt element. The choice of ScaleFactor depends on whether the units of the result are
LSBs of the interpolation (= 1.0), quadrature counts (= 1/4096, as shown), or lines of the encoder
(= 1/16384).
Here the conversion table entry performs the (16-bit) arctangent interpolation in software using
the A/D-converter values it reads. The choice of ScaleFactor depends on whether the units of the
result are LSBs of the interpolation (= 1.0), quadrature counts (= 1/16384, as shown), or lines of
the encoder (= 1/65536).
Software Corrections: The following saved setup elements in the table entry can be set to non-
zero values to correct for signal imperfections:
Software Filtering: The analog front end of the standard interpolator circuitry has very “light”
filtering, to permit the use of very high encoder signal frequencies (and therefore very high motor
speeds). If the noise level on the resulting position values is too high, software filtering can be
performed in the conversion table entry. This is enabled by setting EncTable[n].index2 to a
value of 32 or larger, with EncTable[n].index1 and EncTable[n].index2 acting as the gains of
the filter. Refer to the User’s Manual chapter Setting Up the Encoder Conversion Table for
details.
Here, the (16-bit) arctangent interpolation has been performed in the ASIC, and the conversion
table needs to read the combined whole-count/fractional count value in the channel’s ServoCapt
register and combine it with the extended interpolation in the channel’s AtanSumOfSqr register.
The choice of ScaleFactor depends on whether the units of the result are LSBs of the
interpolation (= 1.0), quadrature counts (= 1/16,384, as shown), or lines of the encoder (=
1/65,536).
Note that the auto-correcting interpolator oversamples the signal and performs filtering in digital
hardware, so further filtering in the encoder conversion table is not recommended in this case.
Simulated Serial Encoder Position: To use the encoder position in the ASIC obtained from the
FPGA through the serial encoder interface for ongoing servo position, the following saved setup
elements must be specified:
Note that the auto-correcting interpolator oversamples the signal and performs filtering in digital
hardware, so further filtering in the encoder conversion table is not recommended in this case.
Direct Velocity Value: If the additional data request value has been set to obtain a direct velocity
value from the FPGA, this value can be used to close the inner servo loop. (It should not be used
to close the outer servo loop.) Use of this value may provide superior servo performance
compared to using the differentiated position value.
To use this value for inner-loop position, which requires a single numerical integration, the
following saved setup elements must be specified:
Direct Acceleration Value: If the additional data request value has been set to obtain a direct
acceleration value from the FPGA, this value can be used to close the inner servo loop. (It should
not be used to close the outer servo loop.) Use of this value may provide superior servo
performance when acceleration feedback is used (typically for “electronic flywheel” effects)
compared to using the differentiated position value.
To use this value for inner-loop position, which requires double numerical integration, the
following saved setup elements must be specified:
Setting Up Resolvers
Resolvers are often used as position sensors when the environmental conditions – temperature,
shock, vibration, radiation, etc. – do not permit the use of optical or magnetic encoders. In
addition resolvers are absolute sensors, at least over one revolution of the motor. Power PMAC
provides two basic interfaces for resolvers. The first is based on the PMAC3-style “DSPGATE3”
IC, as used with the analog feedback option of the ACC-24E3 axis-interface board and of the
Power Brick. The second is based on the PMAC2-style “DSPGATE1” Servo IC, as used in the
UMAC ACC-58E resolver-to-digital (R/D) converter board.
Note that in many uses of resolver feedback, the resolver interface and conversion is performed in
the servo drive, and a simulated encoder signal, usually in digital quadrature format, is output
from the drive to the controller. This is the case if it is a brushless motor drive operating in
“torque mode”, “velocity mode”, or even “position mode”, because the drive needs the resolver
position information for commutation. In these cases, Power PMAC setup is for the simulated
signal type.
Generally, Power PMAC performs the resolver interface and conversion only if it is performing
commutation for the motor, usually with a “direct PWM” amplifier.
Signal Format
The Power PMAC resolver interfaces generate a sinusoidal “excitation” signal output for each
resolver, and accept differential “sine” and “cosine” feedback signals from the resolver. The
excitation signal has a programmable frequency, magnitude, and phase offset from the system
clocks. The feedback signals contain this same “carrier” frequency, and demodulated, their
magnitudes reflect the sine and cosine of the physical angle of the resolver.
The Power PMAC interfaces effectively demodulate the feedback signals by sampling them
synchronously into analog-to-digital converters (ADCs) at or near the peaks of the carrier signal;
the angle is then calculated as the arctangent of the sine and cosine numbers produced by the
ADCs.
The following diagram shows the principle of operation for this type of resolver interface.
Excitation
Output
sin(ωt+φ)
Exc+
Exc-
Sin+ Sine
Feedback
θ
sin(θ)sin(ωt)
Sin-
Cosine
Feedback
cos(θ)sin(ωt)
Cos- Cos+
Phase
Clock
Hardware Setup
The two leads for the resolver’s excitation signal are connected between the channel’s RESOUT
(R1) signal and the GND reference voltage. The four leads for the resolver’s differential sine and
cosine signals are connected in pairs to the channel’s SIN+ (S2) and SIN- (S4), COS+ (S3) and
COS- (S1) inputs.
The highest 8 bits of the element, which form component ResolverExciteShift, represented in the
first two hex digits of the element, specify the phase shift of the excitation sine wave relative to
the phase clock. It can take a value from $00 (0) to $FF (255), in units of 1/512 of an excitation
cycle. This component is usually set experimentally, to maximize the magnitude of the feedback
signals, which are sampled on the rising edge of the phase clock. Resolvers with different
electrical L/R time constants will require different phase shifts to provide maximum readings.
The IDE setup control for resolver feedback does this automatically; it is also possible to do this
manually, by monitoring the magnitude of status element Gate3[i].Chan[j].SumofSquares for
the ASIC channel. The ASIC automatically computes this value each phase cycle from the
readings of input elements Gate3[i].Chan[j].AdcEnc[0] and AdcEnc[1].
The next 2 bits of the element, which form component ResolverExciteGain, represented in the
high part of the third hex digit, specify the magnitude of the excitation output. Values of 0, 1, 2,
and 3 for this component specify magnitudes of 1/4, 1/2, 3/4, and 1 times, respectively, the
maximum magnitude. The highest magnitude that does not cause saturation of the feedback
ADCs (which can be detected by values in SumOfSquares greater than 32,767) should be used.
The next 2 bits of the element, which form component ResolverExciteFreq, represented in the
low part of the third hex digit, specify the frequency of the excitation output. Values of 0, 1, 2,
and 3 for this component specify frequencies of 1, 1/2, 1/4, and 1/6 times, respectively, the phase
clock frequency. The frequency that comes closest to that recommended by the resolver
manufacturer should be used.
For example, to set up an excitation signal with a ¼-cycle (128/512 of a cycle) lag, ½ of the
maximum magnitude, and at ¼ of the phase clock frequency, Gate3[i].ResolverCtrl would be set
to $80500000.
changed between its default value of 7 and 3, but for purposes of the resolver conversion, all that
matters is the value of bit 2.
The ECT entry only reads this bit from the IC when the value of EncTable[n].index3 is 0 for the
entry; it then copies the value of the IC channel’s EncCtrl element into its index3 element, which
it then uses each servo cycle to determine the direction sense of its conversion (this saves
significant computation time). Normally, this is done just at power-on reset. If you change the
value of Gate1[i].Chan[j].EncCtrl during setup to change the direction sense, also set the value
of EncTable[n].index3 to 0, so the ECT entry will use the new direction sense.
Note that with the PMAC2-style ACC-58E interface, the resolver position is computed in the
encoder conversion table (ECT), which executes under the servo interrupt. Therefore, if the phase
interrupt is at a higher frequency than the servo interrupt, it will not get new position data each
cycle. Because the required position resolution for the commutation algorithm is not that high, the
resulting errors usually do not matter. A simple compensation can be done using the
Motor[x].AdvGain “phase advance” term, so that errors at velocity average to zero. Alternately,
the servo clock frequency can be set equal to the phase clock frequency, and the servo-loop
closure rate slowed if necessary by setting Motor[x].Stime greater than zero to skip interrupts
between successive closures.
Power PMAC reads the entire 32-bit register each phase cycle and scales the result to the 2048-
part commutation cycle. (Note that this means that only the high 11 bits are really needed.) One
cycle of the resolver position in this register has a range of 4,294,967,298 (232) LSBs of the
register. This covers the travel over one north-south pole pair of the resolver. For the most
common 2-pole resolver, this is a full mechanical revolution of the resolver.
For an n-pole motor, one mechanical revolution covers n/2 commutation cycles of the motor.
With the typical 2-pole resolver, one resolver cycle covers these n/2 commutation cycles. In the
more general case of an nr-pole resolver on an nm-pole motor, one resolver cycle covers nm/nr
resolver cycles.
In either interface, the value of AbsPhasePosOffset is usually found by executing the “stepper-
motor” phasing search, which forces the motor to the zero point of the commutation cycle, and
reading the value of the resolver position there. The negative of this value (using the proper
number of bits) is multiplied by AbsPhasePosSf and written into AbsPhasePosOffset.
Motor[x].pAbsPhasePos = Gate3[i].Chan[j].AtanSumOfSqr.a
Motor[x].AbsPhasePosFormat = $00001010 // Use high 16 bits of 32-bit register
Motor[x].AbsPhasePosSf = = nm/nr * 2048/65536 // Scale to 2048-part cycle
Motor[x].AbsPhasePosOffset = (Difference between sensor zero and commutation zero)
Motor[x].pAbsPhasePos = EncTable[n].PrevEnc.a
Motor[x].AbsPhasePosFormat = $00001010 // Use high 16 bits of 32-bit register
Motor[x].AbsPhasePosSf = = nm/nr * 2048/65536 // Scale to 2048-part cycle
Motor[x].AbsPhasePosOffset = (Difference between sensor zero and commutation zero)
interface, where the interpolation has not been performed in the ASIC, and so must be performed
in the software conversion.
Here, the 16-bit arctangent conversion has been performed in the ASIC, and the conversion table
simply needs to read the value in the upper half of the channel’s AtanSumOfSqr element.
Here the conversion table entry performs the 16-bit arctangent calculation in software using the
A/D-converter values it reads.
Motor[x].pAbsPos = Gate3[i].Chan[j].AtanSumOfSqr.a
Motor[x].AbsPosFormat = $00001010 // Use high 16 bits of 32-bit register
Motor[x].AbsPosSf = 1.0 // Motor units of 65,536 per resolver cycle
Motor[x].AbsPosOffset = (Difference between sensor zero and motor zero)
Motor[x].pAbsPos = EncTable[n].PrevEnc.a
Motor[x].AbsPosFormat = $00001010 // Use high 16 bits of 32-bit register
Motor[x].AbsPosSf = 1.0 // Motor units of 65,536 per resolver cycle
Motor[x].AbsPosOffset = (Difference between sensor zero and motor zero)
Setting Up MLDTs
A Power PMAC can provide direct interface to magnetostrictive linear displacement transducers
(MLDTs), such as MTS’s Temposonics® brand, with either PMAC3-style ICs as used on the
UMAC ACC-24E3 boards or in the Power Brick products, or PMAC2-style ICs, as used on the
UMAC ACC-24E2x boards. MLDTs can provide absolute position information in rugged
environments; they are particularly well suited to hydraulic applications. In this interface Power
PMAC provides a periodic excitation pulse output to the MLDT, receives the echo pulse that
returns at the speed of sound in the transducer, and very accurately measures the time between
these pulses, which is directly proportional to the distance of the moving member from the
stationary base of the transducer. The timer therefore contains a position measurement.
Signal Format
MLDTs are available with several different interface formats; for this interface, a format with
“external excitation” is required, because Power PMAC provides the excitation pulse. Usually
this format has an “RS-422” interface, because the excitation and echo pulses are at RS-422
levels. The Power PMAC MLDT interface inputs and outputs are at RS-422 levels.
There are two common signal formats of the external excitation type; MTS calls them “RPM”
and “DPM”. In the RPM format there are two short pulses returned from the MLDT: an
immediate “start” pulse, and a delayed “stop” pulse.
Return
Start Stop
Since Power PMAC uses the first rising signal edge returned after the falling edge of the output
pulse to latch the timer, the key setup issue in this format is to make sure that the output pulse
width is large enough so that the falling edge of the output pulse occurs after the rising edge of
the return line’s start pulse (see “PFM Pulse Width”, below).
In the DPM format, there is only one long pulse returned from the MLDT.
Return
Start Stop
The rising edge of the return pulse in the DPM format is the equivalent of the rising edge of the
start pulse in the RPM format. The falling edge of the return pulse in the DPM format is the
equivalent to the rising edge of the stop pulse in the RPM format. Because Power PMAC is
expecting a rising signal edge to latch the timer, in this signal format the return signals should be
inverted so that the ‘+’ output of the MLDT is wired into Power PMAC’s ‘-’ input, and vice
versa.
Hardware Setup
The PULSEn output that is commonly used to command stepper drives is used as the excitation
signal for the MLDT; the CHAn input that is typically part of encoder feedback is used to accept
the response. The PULSEn output is an RS-422 style differential line-drive pair. The CHAn input
is an RS-422 style differential line receiver pair. The use of differential pairs for both inputs and
outputs is strongly encouraged for the common-mode noise rejection it provides.
On some interface boards (e.g. ACC-24E2A, ACC-24E2S), the PULSEn+/- signals are output on
lines that would otherwise be supplemental flag inputs, and jumper(s) must be installed to enable
the outputs on these lines. Consult the hardware reference manual for your board for details.
Remember that in the DPM signal format or equivalent (see above), the ‘+’ output of the MLDT
should be wired into the CHAn- input, and the ‘-’ output of the MLDT should be wired into the
CHAn+ input.
PMAC3-Style Interface
The PMAC3-style “DSPGATE3” Servo IC uses a channel’s pulse-frequency-modulation (PFM)
output circuits and encoder timer input circuits to interface to an MLDT. Several setup elements
must be configured for this interface.
PMAC2-Style Interface
The PMAC2-style “DSPGATE1” Servo IC uses a channel’s pulse-frequency-modulation (PFM)
output circuits and encoder timer input circuits to interface to an MLDT. Several setup elements
must be configured for this interface.
The frequency of the pulse output should produce a period just slightly longer than the longest
expected response time for the echo pulse. For MLDTs, the response time is approximately 0.35
sec/mm (9 sec/inch). On an MLDT 1500 mm (~60 in) long, the longest response time is
approximately 540 sec; a recommended period between pulse outputs for this device is 600
sec, for a frequency of 1667 Hz. Note that the frequency should always be at least as high as the
servo update frequency for the motor, so each servo cycle uses new data. This may require
lowering the servo update frequency for the motor.
The PFM clock frequency, which sets the finest interval to which the pulse output timing can be
controlled, is determined by the value of multi-channel saved setup element
Gate1[i].HardwareClockCtrl. The PFM clock frequency at the factory default value for this
element is 9.83 MHz, and this should not need to be changed for any MLDT application.
The value in the non-saved 24-bit channel command register Gate1[i].Chan[j].Pfm determines
the pulse output frequency given the clock frequency. Note that as a non-saved element, it must
be set in the user’s project or program after each power-on or reset.
To produce the desired pulse output frequency from a channel, the following formula can be
used:
Gate1[i].Chan [ j ].Pfm
OutputFreq (kHz) PFMCLK _ Freq (kHz)
16,777,216
or:
OutputFreq (kHz)
Gate1[i].Chan [ j ].Pfm 16,777,216 *
PFMCLK _ Freq (kHz)
To produce a pulse output frequency of 1.667 kHz with the default PFMCLK frequency of 9.83
MHz (9,830 kHz), we calculate:
1.667
Gate1[i ].Chan [ j ].Pfm 16,777,216 * 2,982
9,830
element must be set to 12. With this setting, the pulse timer is cleared to zero at the falling edge
of the output pulse. It then counts up at 117.96 MHz until a rising edge on the return pulse is
received, at which time the timer’s value is latched into status element Gate1[i].Chan[j].TimerA.
The timer register contains the time elapsed between the excitation pulse output and the echo
pulse feedback. It is in the units of cycles of the high-frequency clock for the IC: 8.477
nanoseconds for the PMAC2 IC’s 117.96 MHz clock, and 1.667 nanoseconds for the PMAC3
IC’s 600 MHz clock.
At the nominal speed of sound in these devices, 2.81 mm/µsec (0.110 in/µsec), each timer
interval represents 0.0238 mm (0.000937 in) for a PMAC2 IC, or 0.00468 mm (0.000184 in) for a
PMAC3 IC. Check with the manufacturer for the actual transmission speed for the particular
sensor.
PMAC3-Style Interface
To use the MLDT position value from the timer registers in a PMAC3-style IC for ongoing servo
position, the following saved setup elements must be specified:
PMAC2-Style Interface
To use the MLDT position value from the timer registers in a PMAC2-style IC for ongoing servo
position, the following saved setup elements must be specified:
PMAC3-Style Interface
To use the MLDT position value from the timer register in a PMAC3-style IC for absolute power-
on servo position, the following saved setup elements must be specified:
Motor[x].pAbsPos = Gate3[i].Chan[j].TimerA.a
Motor[x].AbsPosFormat = $00001808 // Use high 24 bits of 32-bit register
Motor[x].AbsPosSf = (Motor units per 600 MHz period)
Motor[x].AbsPosOffset = (Difference between sensor zero and motor zero)
PMAC2-Style Interface
To use the MLDT position value from the timer register in a PMAC2-style IC for absolute power-
on servo position, the following saved setup elements must be specified:
Motor[x].pAbsPos = Gate1[i].Chan[j].TimeBetweenCts.a
Motor[x].AbsPosFormat = $00001808 // Use high 24 bits of 32-bit register
Motor[x].AbsPosSf = (Motor units per 117.96 MHz period)
Motor[x].AbsPosOffset = (Application specific value)
Signal Format
The ACC-14E card can accept up to 48 digital inputs at 5V TTL/CMOS levels. These levels are
suitable for most parallel-format position data.
Hardware Setup
The multiple bits of the parallel position data word are connected to consecutively numbered I/O
lines on the ACC-14E, with the LSB connected to the lowest numbered I/O pin of the set.
Typically one 24-bit port of the ACC-14E is used for one set of data. Port A provides pins I/O00
to I/O23, with I/O00 typically used for the LSB of the position data. Port B provides pins I/O24
to I/O47, with I/O24 typically used for the LSB of the position data.
Note that if the position data is not absolute, as with an interferometer, it may not be necessary to
connect all of the bits provided. Only enough bits need to be connected so that the resulting
numerical value cannot cover more than half of its cycle between consecutive servo cycles. If this
is the case, Power PMAC can handle the rollover properly and extend the position data
indefinitely.
For example, many interferometers provide 32 bits of incremental position data, but it is rarely
necessary to connect more than the low 24 bits. This permits a velocity of over 8 million (223)
LSBs per servo cycle. At a 5 kHz servo update and a 1.25 nanometer LSB, this permits a top
speed of over 50 meters per second.
The ACC-14E provides several possibilities for handshaking and latching the data using the
phase or servo clock signals and/or some other high-frequency clocks. Refer to the ACC-14E
manual to select the appropriate method and implement it properly.
Each ACC-14E has a saved initialization sub-structure GateIo[i].Init (or Acc14E[i].Init). The
following are the suggested settings for latched feedback inputs on all 48 pins (6 byte-wide data
registers).
GateIo[i].Init.CtrlReg should be set to $3F so that outputs on all 6 registers are disabled, and
cannot interfere with the connected input values.
The values of GateIo[i].Init.DataReg0[j], which set initial output values, do not matter, and can
be left at 0.
The values of GateIo[i].Init.DataReg64[j], which set the inversion control for the specified data
register (j = 0 to 5), are typically set to $FF to specify all inputs non-inverting (high = 1).
The values of GateIo[i].Init.DataReg128[j], which control the numeric form expected for the
specified data register (j = 0 to 5), should be set to $00 for the typical numeric binary, or to $FF
for Gray code.
The values of GateIo[i].Init.DataReg192[j], which control which value is read for the specified
data register (j = 0 to 5), should be set to $FF to read the value latched on the most recent clock
(rather than the “transparent” value).
In all the sections below, if the LSB of the position word is connected to pin I/O00 on Port A,
DataReg[0] is addressed. If the LSB of the position word is connected to pin I/O24 on Port B,
DataReg[3] is addressed.
Motor[x].pAbsPos = GateIo[i].DataReg[j].a
Motor[x].AbsPosFormat = $aa20cc08 // $cc is number of bits, $aa is format
Motor[x].AbsPosSf = (Motor units per LSB) // Must match ongoing pos resolution
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
noticeable effect on commutation performance. If necessary, this time delay can be compensated
for with Motor[x].AdvGain.
To use this processed data for ongoing commutation feedback, set Motor[x].pPhaseEnc to
EncTable[n].PrevEnc.a, where n is the index of the ECT entry that is processing the feedback.
The ECT processing needs to have performed any shifting necessary for the data to roll over
properly, so Motor[x].PhaseEncRightShift and Motor[x].PhaseEncLeftShift should be left at
their default values of 0.
To scale the 32-bit value in the PrevEnc register into the commutation units of 1/2048 of a
commutation cycle (pole-pair), you will need to know how many LSBs of the input data there are
per commutation cycle, and in what bit n of the PrevEnc register the data LSB resides (which
should be equal to the value of EncTable[n].index1 for the entry. The scaling element
Motor[x].PhasePosSf can then be set according to the following equation:
2048
Motor[ x].PhasePosSf
2 * LSBs / comm _ cycle
n
Motor[x].pAbsPhasePos = GateIo[i].DataReg[j].a
Motor[x].AbsPhasePosFormat = $aa20cc08 // $cc is number of bits, $aa is format
Motor[x].AbsPhasePosSf = (Motor units per LSB) // Must match ongoing pos res
Motor[x].AbsPhasePosOffset = (Difference between sensor zero and commutation zero)
These accessories can be used to interface to analog sensors such as LVDTs and RVDTs (already
demodulated), potentiometers, capacitive distance sensors, tachometers, accelerometers, strain
gauges, and others, to be used as servo loop feedback or master data.
Signal Format
The analog-input accessories for the Power PMAC accept a voltage input that is intended to be
proportional to the quantity being measured. (The ACC-59E3 can also be configured to accept 4 –
20 mA current inputs, but that is seldom used for feedback data.) All of these accessories have
differential analog inputs, measuring the voltage difference between ADCn+ and ADCn- input
lines.
While differential inputs are strongly recommended due to the common-mode noise rejection
they provide, it is easy to use single-ended analog inputs simply by tying the ADCn- input to the
AGND reference voltage provided on the same connector.
ACC-28E
On the ACC-28E, if jumper En (n = 1 to 4) for hardware channel ADCn connects pins 1 and 2 to
select unipolar conversion, then the range of input voltage difference (V[ADCn+] – V[ADCn-])
is 0 to +10V, corresponding to converted values of 0 to 65,535.
If jumper En connects pins 2 and 3 to select bipolar conversion, then the range of input voltage
difference (V[ADCn+] – V[ADCn-]) is -10V to +10V, corresponding to converted values of 0 to
65,535.
ACC-36E, ACC-59E
On the ACC-36E and ACC-59E, if the software convert code specifies unipolar conversion, then
the range of input voltage difference (V[ADCn+] – V[ADCn-]) is 0 to +20V, corresponding to
converted values of 0 to 4,095.
If the software convert code specifies bipolar conversion, then the range of input voltage
difference (V[ADCn+] – V[ADCn-]) is -10V to +10V, corresponding to converted values of -
2048 to +2,047.
ACC-59E3
On the ACC-59E3, the range of input voltage difference (V[ADCn+] – V[ADCn-]) is -10V to
+10V, corresponding to converted values of -32,768 to +32,767.
Hardware Setup
The ADCs on all of these accessories are sampled based on the system phase clock. Also, the
highest frequency at which the converted values can be read by the processor is that of the phase
clock. In almost all cases, the source of the phase clock signal is not the ADC accessory itself. (It
is possible, but rare, for the ACC-59E3 to be the source of the system phase clock.)
ACC-28E
On the ACC-28E, all 4 ADCs are sampled simultaneously on the rising edge of the phase clock.
The data is available to be read by the processor on the next falling edge of the phase clock,
which is the phase interrupt to the processor. Every “N” phase-clock interrupts to the processor is
also the servo clock interrupt, which causes servo tasks to be performed.
ACC-36E, ACC-59E
The ACC-36E and ACC-59E use multiplexed 8-channel ADCs. In the de-multiplexing scheme
explained in the next section, on each falling edge of the phase clock, one of these 8 channels can
be read by the processor, and the next channel selected and sampled for reading in the next phase
clock cycle.
ACC-59E3
On the ACC-59E3, all 16 ADCs are sampled every phase clock cycle. The lower two numbered
hardware channels on each connector (1, 2, 5, 6, 9, 10, 13, and 14) are sampled on the rising edge
of the phase clock ,with the data available to be read by the processor on the next falling edge of
the phase clock (one-half cycle later), which is the phase interrupt to the processor. The higher
two numbered hardware channels on each connector (3, 4, 7, 8, 11, 12, 15, and 16) are sampled
on the falling edge of the phase clock with the data available to be read by the processor on the
following falling edge (one full cycle later). Every “N” phase-clock interrupts to the processor is
also the-servo clock interrupt, which causes servo tasks to be performed.
processor on the next falling edge (one half phase cycle later). The last two channels on each
board (ADC3 and ADC4) are sampled on the falling edge of the phase clock with the data
available to be read by the processor on the following falling edge (on full phase cycle later).
Every “N” phase-clock interrupts to the processor is also the-servo clock interrupt, which causes
servo tasks to be performed.
ACC-28E
On the ACC-28E, no setup parameters are necessary to prepare the ADC data for access by the
processor, for either servo or non-servo tasks.
Power PMAC’s automatic de-multiplexing algorithms select one register to read each phase cycle
(which selects two ADCs on the ACC-36E). To create a “ring” cycle of reading all 8 channels of
a multiplexed ADC takes 8 phase cycles. When ADC readings are used for servo purposes, there
should be a new value every servo update. To ensure this happens, the user has several options.
First, the hardware phase update frequency relative to the servo update frequency can be raised to
be 8 times higher (the default is 4 times). If necessary, the bulk of the software tasks executed in
the phase cycle – mainly the motor commutation algorithms – can be performed at a lower
frequency than by setting Sys.PhaseCycleExt above its default value of 0. (The de-multiplexing
still takes place at the phase clock frequency.)
Second, the servo update frequency of a motor using this data can be set lower than the servo
clock frequency by setting Motor[x].Stime above its default value of 0. (Since this is done on a
motor-by-motor basis, other motors can be updated at the servo clock frequency.)
Third, the de-multiplexing ring cycle can be made smaller than the full cycle of 8 ADC channels.
However, any ADC channels that are not part of this ring cycle cannot be used at all, even for
lower-priority non-servo tasks.
To configure the ring cycle, the saved setup elements AdcDemux.Address[i] must be set to the
address offset of the card in Power PMAC’s I/O space (e.g. to $A00000 for Acc36E[0] or
Acc59E[0]). If every entry in the ring cycle is for the same card, each of these elements will be
set to the same value. For example, to configure an 8-way ring cycle for the ADCs of Acc36E[1],
the elements AdcDemux.Address[0] through AdcDemux.Address[7] should all be set to
$B00000.
Next, the ADC or pair of ADCs at the specified address for each ring slot, and the conversion
format(s), must be selected with AdcDemux.ConvertCode[i]. These elements take a value of
$m00n00, although for the ACC-59E, only the last 3 hex digits ($n00) are needed. The value of
the variable hex digit n specifies the software index of the selected channel in the “low” 8-
channel ADC, which is 1 less than the hardware channel number (e.g. 3 for ADC4). The value of
the variable hex digit m is 9 less than the hardware channel number of the “high” 8-channel ADC
on the ACC-36E (e.g. 5 for ADC14). If the ADC is to be sampled as a bipolar voltage, returning a
signed value (rather than as a unipolar voltage, returning an unsigned value), a value of 8 should
be added to the digit.
For example, to sample all eight ADC channels of an ACC-59E as unipolar values in an 8-slot
ring, the following settings would be made:
AdcDemux.ConvertCode[0] = $000
AdcDemux.ConvertCode[1] = $100
AdcDemux.ConvertCode[2] = $200
AdcDemux.ConvertCode[3] = $300
AdcDemux.ConvertCode[4] = $400
AdcDemux.ConvertCode[5] = $500
AdcDemux.ConvertCode[6] = $600
AdcDemux.ConvertCode[7] = $700
In another example, to sample all sixteen ADC channels of an ACC-36E as bipolar values in an
8-slot ring, the following settings would be made:
AdcDemux.ConvertCode[0] = $800800
AdcDemux.ConvertCode[1] = $900900
AdcDemux.ConvertCode[2] = $A00A00
AdcDemux.ConvertCode[3] = $B00B00
AdcDemux.ConvertCode[4] = $C00C00
AdcDemux.ConvertCode[5] = $D00D00
AdcDemux.ConvertCode[6] = $E00E00
AdcDemux.ConvertCode[7] = $F00F00
Finally, AdcDemux.Enable must be set to specify the number of slots in the ring cycle. Setting it
to a value of 8 will cause Power PMAC to use the values of AdcDemux.Address[i] and
AdcDemux.ConvertCode[i] for i = 0 to 7.
ACC-59E3
On the ACC-59E3, several setup parameters in the Acc59E3[i] data structure (documented under
the generic Gate3[i] structure name) are necessary to prepare the ADC data for access by the
processor, either for servo or non-servo tasks. Most of the saved setup elements can use their
factory default values. When setting the values of these elements, Sys.WpKey must be set to
$AAAAAAAA to enable changes in their values.
The cutoff frequency of the analog low-pass filtering on the card is configurable in software for
each input. Two control bits per ADC channel permit the -3dB cutoff frequency to be selected
from the choices of 3.2 kHz, 4.3 kHz, 12.2 kHz, and 24.5 kHz.
To enable the use of these control bits, saved direction-control element Acc59E3[i].GpioDir[0]
must be set to $FFFFFFFF – not the default – so that all 32 of the IC’s 32 digital I/O lines are
configured as outputs, and the saved polarity-control element Acc59E3[i].GpioPol[0] should be
left at its default value of $00000000.)
The value of the 32-bit non-saved element Acc59E3[i].GpioData[0] determines the value of
these two control bits for each of the 16 inputs. To set all 16 analog inputs to the same cutoff
frequency, the following settings can be used:
Since Acc59E3[i].GpioData[0] is not a saved element, it must be explicitly set after each power-
on/reset. This can be done in pp_startup.txt or in a power-on PLC program. If no explicit
action is taken, all inputs are configured for a 24.5 kHz cutoff frequency. If you wish to set
different cutoff frequencies for different inputs, refer to the ACC-59E3 manual for details.
Further filtering can be done digitally in the encoder conversion table entry that processes the
input.
The examples shown in this section use the entry parameters EncTable[n].index1 and index2 to
create a type of low-pass filter called a digital tracking filter. This can be used to reduce the effect
of high-frequency noise in the signal. It is also possible to use these parameters to eliminate any
“garbage data” from the low bits of the 32-bit source register, but since generally there is noise on
at least the LSB of “real data”, any sub-LSB noise from the “garbage data” will not have any real
effect on the resulting performance.
If both EncTable[n].index1 and index2 are set to their default values of 0, no filtering or shifting
is performed. This may be suitable for many applications.
Note that unlike many other forms of feedback data, the numerical value from these analog
signals will not roll over, so it is not required to shift the data so that the MSB of the real data
ends up in the MSB of the 32-bit register. (It is acceptable, but not necessary.)
If it is desired to perform numerical integration on source data in the ECT entry, as to convert
velocity or acceleration data into position, it is not possible to perform explicit low-pass filtering
as well. (The numerical integration automatically has the effect of low-pass filtering.)
ACC-28E
For an ACC-28E, the channel hardware register is read directly over the 32-bit bus. The data is in
the high 16 bits of the 32-bit bus. (If you are reading the source element directly from a Script
program, it is a 16-bit element from the high 16 bits of the bus.)
For the ADC1 – ADC4 inputs on an ACC-28E, the values can be found in the status elements
Acc28E[i].AdcSdata[j] or Acc28E[i].AdcUdata[j], where the index j (= 0 to 3) is one less than
the hardware channel number. These two elements for each index j access the same data, just
interpreting it differently, as signed or unsigned data, respectively. When specifying the address
of the entire 32-bit register for the encoder conversion table entry, it does not matter which
element name you use.
The key elements for the ECT entry to process this value and for the motor to use the processed
result are:
If scale factors Motor[x].PosSf and Motor[x].Pos2Sf are set to the default values of 1.0, the
motor units will be LSBs of the ADC.
This example shows the most common setup, with a low-pass “tracking filter” to reduce noise,
but no numerical integration. It is also possible to perform one or two integrations (e.g. velocity
or acceleration into position) instead of filtering.
ACC-36E, ACC-59E
For an ACC-36E or ACC-59E, the de-multiplexed value is read from its holding register in
memory over the 32-bit data bus. The actual data is in the low 12 bits of the 32-bit bus.
For the ADC1 – ADC8 inputs on either the ACC-36E or ACC-59E, the de-multiplexed value can
be found in status element AdcDemux.ResultLow[i], where the index i matches that of saved
setup elements AdcDemux.Address[i] and AdcDemux.ConvertCode[i].
The key elements for the ECT entry to process this value and for the motor to use the processed
result are:
If scale factors Motor[x].PosSf and Motor[x].Pos2Sf are set to the default values of 1.0, the
motor units will be LSBs of the ADC.
For the ADC9 – ADC16 inputs on the ACC-36E, the de-multiplexed value can be found in status
element AdcDemux.ResultHigh[i], where the index i matches that of saved setup elements
AdcDemux.Address[i] and AdcDemux.ConvertCode[i].
ACC-59E3
For an ACC-59E3, the channel hardware register is read directly over the 32-bit bus. The actual
data is in the high 16 bits of the 32-bit register. (If you are reading the source element from a user
Script program or command, it is also a 32-bit value with real data in the high 16 bits.)
The status element for each input can be accessed as Acc59E3[i].Chan[j].AdcAmp[k], where the
channel and register indices for each input can be found in the following table:
The key elements for the ECT entry to process this value and for the motor to use the processed
result are:
If scale factors Motor[x].PosSf and Motor[x].Pos2Sf are set to the default values of 1.0, the
motor units will be LSBs of the ADC.
This example shows the most common setup, with a low-pass “tracking filter” to reduce noise,
but no numerical integration. It is also possible to perform one or two integrations (e.g. velocity
or acceleration into position) instead of filtering.
For the ADC1 – ADC4 values on the Power Brick, the data can be found in
PowerBrick[0].Chan[j].AdcAmp[2], where j (= 0 to 3) is one less than the hardware channel
number. For the ADC5 – ADC8 values, the data can be found in
PowerBrick[1].Chan[j].AdcAmp[2], where j (= 0 to 3) is five less than the hardware channel
number. In both cases, the structure name Gate3[i] can be used instead of PowerBrick[i]. The
indices for each input are shown in the following table:
The key elements for the ECT entry to process this value and for the motor to use the processed
result are:
If scale factors Motor[x].PosSf and Motor[x].Pos2Sf are set to the default values of 1.0, the
motor units will be LSBs of the ADC.
For the ADC1 – ADC4 values on the Power Clipper board, the data can be found in
Clipper[0].Chan[0].AdcEnc[k], where k (= 0 to 3) is one less than the hardware channel
number. For the ADC1 – ADC4 values on the optional ACC-24S3 axis expansion stack board,
the data can be found in Clipper[1].Chan[0].AdcEnc[k], where k (= 0 to 3) is one less than the
hardware channel number. In both cases, the structure name Gate3[i] can be used instead of
Clipper[i]. The indices for each input are shown in the following table:
The key elements for the ECT entry to process this value and for the motor to use the processed
result are:
If scale factors Motor[x].PosSf and Motor[x].Pos2Sf are set to the default values of 1.0, the
motor units will be LSBs of the ADC.
The addresses given in this section are the same as for ongoing servo position, and are specified
in more detail in that section, above.
ACC-28E
To use analog position data from an ACC-28E for absolute power-on servo position, the
following saved setup elements must be specified:
Motor[x].pAbsPos = Acc28E[i].AdcSdata[j].a
Motor[x].AbsPosFormat = $aa001010 // $aa is 00 for unsigned, 01 for signed
Motor[x].AbsPosSf = (Motor units per LSB) // Must match ongoing pos resolution
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
ACC-36E, ACC-59E
To use analog position data from ADC1 – ADC8 on an ACC-36E or ACC-59E for absolute
power-on servo position, the following saved setup elements must be specified:
Motor[x].pAbsPos = AdcDemux.ResultLow[i].a
Motor[x].AbsPosFormat = $aa000C14 // $aa is 00 for unsigned, 01 for signed
Motor[x].AbsPosSf = (Motor units per LSB) // Must match ongoing pos resolution
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
To use analog position data from ADC9 – ADC16 on an ACC-36E for absolute power-on servo
position, the following saved setup elements must be specified:
Motor[x].pAbsPos = AdcDemux.ResultHigh[i].a
Motor[x].AbsPosFormat = $aa000C14 // $aa is 00 for unsigned, 01 for signed
Motor[x].AbsPosSf = (Motor units per LSB) // Must match ongoing pos resolution
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
ACC-59E3
To use analog position data from an ACC-59E3 for absolute power-on servo position, the
following saved setup elements must be specified:
Motor[x].pAbsPos = Acc59E3[i].Chan[j]AdcAmp[k].a
Motor[x].AbsPosFormat = $00001010 // Unsigned 16 bits from high 16 bits
Motor[x].AbsPosSf = (Motor units per LSB) // Must match ongoing pos resolution
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
Motor[x].pAbsPos = PowerBrick[i].Chan[j]AdcAmp[2].a
Motor[x].AbsPosFormat = $00001010 // Unsigned 16 bits from high 16 bits
Motor[x].AbsPosSf = (Motor units per LSB) // Must match ongoing pos resolution
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
Motor[x].pAbsPos = Clipper[i].Chan[0]AdcAmp[k].a
Motor[x].AbsPosFormat = $00000C14 // Unsigned 12 bits from high 12 bits
Motor[x].AbsPosSf = (Motor units per LSB) // Must match ongoing pos resolution
Motor[x].HomeOffset = (Difference between sensor zero and motor zero)
The first stage in the position processing uses the hardware registers such as encoder counters
with associated timers, A/D registers, or accessory cards for parallel input. These work
continually without direct software intervention (although they can be configured through
software), with data typically latched on the servo interrupt. This stage is covered in the
Hardware Reference manual for the particular device, and the Setting Up Feedback chapter of the
User’s Manual. Beyond this point, the process is software-controlled.
All raw feedback data is “fixed-point” (integer) data. The servo algorithms require
floating-point data. The ECT converts the data from fixed-point to floating-point data.
There are several pieces of raw data that need to be combined into one resulting position
number, as with the counter and timers for “1/T” encoder interpolation.
There is some checking for special conditions, such as rollover or sudden changes
indicative of noise, which needs to be done to ensure robust data.
While the primary purpose of the table is to produce processed (“converted”) values for feedback
and master position data for the servo algorithms to use, other uses are possible. The table’s
guaranteed execution at the beginning of each servo cycle, and its many tools for processing data,
permit other uses as well.
The table is executed in order from top (normally Entry 0, but if Sys.FirstEnc is set to a non-zero
value, at the entry specified by its value) to bottom (last active entry before the first “end of table”
entry found) each cycle. If a value from one entry is used as the source for another entry, it is
usually desirable to have the second entry further down in the table, so a servo cycle’s delay is
not introduced.
The 32-bit MaxDelta element and the two 16-bit elements SinBias and CosBias share a single
32-bit register. The register is used for one or the other purpose depending on the conversion
method. The EncBias element shares a register with the PrevDelta status element.
Not all of these setup elements are used in every conversion type. Each is discussed where
appropriate below, and also in the Software Reference Manual chapter on Saved Data Structure
Elements.
This configuration window can be found under the “Delta Tau” menu bar item, then selecting
“Configure” from the pull-down menu, followed by “Encoder Conversion Table”.
Most users prefer to have the results in natural units of the sensors. For example, “counts” for
quadrature encoders, “LSBs” (least significant bits) for ADCs and serial or parallel numeric
feedback. There are subsequent motor scale factors for each motor term that uses an ECT result
that can convert these raw units to engineering units, and also axis scale factors that can perform a
further conversion.
If you change the scale factor in the conversion table entry, you are changing the units of any
subsequent motor and axis functions that use the result. Changing to larger engineering units can
effectively disable many safety limits for motors, such as following-error and overtravel limits,
that are scaled in the resulting motor units. For feedback terms, you are also changing the overall
feedback-loop gain, which could result in dangerous instability in some cases.
It is also possible to change the sign of the entry scale factor to invert the direction sense of the
result. However, doing so for data that is presently being used successfully to close a feedback
loop will result in unstable positive feedback and a potentially dangerous runaway condition.
In addition, if you are using hardware position capture for triggered moves such as homing-search
moves, the motor must properly match the scaling of the servo data from the table result with the
scaling of the captured position in hardware.
Motor[1].pEnc = EncTable[1].a
Motor[1].pEnc2 = EncTable[1].a
Motor[1].pMasterEnc = EncTable[0].a
Note that these motor addressing parameters must be set to the address of an ECT entry. This
means that any feedback or master position information for a motor must be processed through an
ECT entry.
The final result for each ECT entry every servo cycle is actually stored in the data structure
element EncTable[n].DeltaPos. However, the motor addressing elements just described should
not be given the address of this register directly, as Power PMAC automatically adds in the offset
from the starting address of the entry to the DeltaPos element.
Note that the DeltaPos element contains the change in position for the most recent servo cycle as
a scaled floating point value. Power PMAC automatically adds in this change to the previous
cycle’s value for the outer-loop feedback position and the master position, so this is a hidden
detail for most users.
Another common use of the result of a conversion table entry is for “external time base” for a
coordinate system. Here the coordinate system’s time-base addressing parameter
Coord[x].pDesTimeBase should contain the address of the DeltaPos element itself, not the base
address of the entry, as there is no automatic address offset. For example:
Coord[1].pDesTimeBase = EncTable[0].DeltaPos.a
The most recent cycle’s position value is stored in the data structure element
EncTable[n].PrevEnc. Power PMAC stores this value for the next servo cycle to compute the
change in position for that cycle. The value in PrevEnc incorporates the initial processing, but
does not include the final output scaling. It is a 32-bit integer value.
For each PMAC2-style Servo IC it finds on a board designed for quadrature feedback, as on an
ACC-24E2x board, it will set up a Type 3 “software 1/T encoder extension” entry for all four
channels on the IC.
For each PMAC2-style Servo IC it finds on a board designed for sinusoidal feedback, as on an
ACC-51E board, it will set up a Type 4 “sinusoidal encoder arctangent extension” entry for all
four channels on the IC.
For each PMAC2-style MACRO IC it finds on a board designed for MACRO interface, as on an
ACC-5E board, it will set up a Type 1 single-register read of the Register 0 for each of the 8
MACRO servo nodes present on every IC found.
For each PMAC3-style IC it finds on a servo card, as on an ACC-24E3 board, it will set up a
Type 1 single-register read of the ServoCapt register for all four channels of the IC. This IC can
automatically perform 1/T or arctangent extensions in hardware and provide the extended
position in a single register, so all the ECT needs to access is this single register.
For each PMAC3-style IC it finds on a board designed for MACRO interface, as on an ACC-5E3
board, it will set up a Type 1 single-register read of the Register 0 for each of the 16 MACRO
servo nodes present on every IC found.
It starts assigning these entries with EncTable[1]. After all of the real entries it creates, all
higher-numbered entries are set to the Type 0 “end of table” method so the Power PMAC does
not waste time performing unneeded conversions. For example, if two 4-channel ICs are found,
EncTable[1] through EncTable[8] are set up to use these. EncTable[9] and up are set to Type 0.
As part of the re-initialization default parameter setup, motors starting with Motor 0 point to the
results of the ECT entries of the same number for outer-loop (position) feedback and inner-loop
(velocity) feedback. All motors point the result of Entry 0 for their master position (but following
is disabled by default).
properly. The first entry encountered with Type 0 does nothing except indicate end of table; the
values of other setup elements in the entry do not matter.
31 0
It is commonly used to access registers in the PMAC3-style “DSPGATE3” IC, as in the ACC-
24E3 axis-interface accessory. Common types of settings are:
EncTable[n].pEnc = Gate3[i].Chan[j].ServoCapt.a
EncTable[n].pEnc = Gate3[i].Chan[j].TimerA.a
EncTable[n].pEnc = Gate3[i].Chan[j].SerialEncDataA.a
EncTable[n].pEnc = Gate3[i].Chan[j].Atan.a
EncTable[n].pEnc = Gate3[i].Chan[j].AdcAmp[k].a
The ServoCapt register has an encoder count value that is extended by either timers or
arctangent calculations in hardware (so software extension calculations are not required).
The TimerA register can hold the time elapsed before the echo pulse of an MLDT sensor
is received (and therefore the position of the sensor). It can also hold the pulse count of
the pulse-frequency modulation (PFM) output for stepper-type motors (or simulated
motors).
The SerialEncDataA register holds the low 32 bits of position data from a serial encoder
attached to the channel. (If there are more bits, only the low 32 bits are used every servo
cycle.)
The Atan register holds the arctangent of the “sine” and “cosine” ADC registers, and so
the position of a resolver whose winding voltages are read by these ADCs.
The AdcAmp[k] register holds the converted value of the analog input for that register,
as for the analog-to-digital converters of the ACC-59E3 board.
EncTable[n].pEnc can also be set to the address of registers in the PMAC2-style “DSPGATE1”
Servo IC. Common types of settings are:
EncTable[n].pEnc = Gate1[i].Chan[j].PhaseCapt.a
EncTable[n].pEnc = Gate1[i].Chan[j].TimeBetweenCts.a
The PhaseCapt register has an encoder count value without any extension, useful to read
when the pulse count of the PFM output drives the counter circuit.
The TimeBetweenCts register can hold the time elapsed before the echo pulse of an
MLDT sensor is received (and therefore the position of the sensor).
EncTable[n].pEnc can be set to the address of the low 24 bits of position data from a serial
encoder attached to a channel of an ACC-84E or related serial encoder board:
EncTable[n].pEnc = Acc84E[i].Chan[j].SerialDataA.a
EncTable[n].pEnc can be set to the address of the position data from a MACRO input node on
an ACC-5E (Gate2) or ACC-5E3 (Gate3):
EncTable[n].pEnc = Gate2[i].Macro[j][0].a
EncTable[n].pEnc = Gate3[i].MacroInα[j][0].a
EncTable[n].pEnc = ECAT[i].IO[k].Data.a
Next, this result is shifted left by the number of bits specified in index1. Generally, index1 is set
to the quantity 32 minus the number of bits of real data in the source register. This will cause the
MSB of actual data in the source register to end up in the highest bit of the intermediate result
register. This must occur if Power PMAC is to handle rollover of the source data value properly.
For example, if the source register has 20 bits of real data starting at bit 8 (so in bits 8 – 27 of the
32-bit register), index2 should be set to 8 to eliminate the original bits 0 – 7, and index1 should
be set to (32 – 20), or 12, so that the MSB of real data in the source register (bit 27) ends up in bit
31 of the intermediate result. The process is shown in the following diagram.
31 28 27 8 7 0
If the source data cannot roll over and comes from the most significant bits of the 32-bit register,
as is the case with some types of feedback processed through an analog-to-digital converter, it is
not necessary to perform the shift-left operation, so index1 can be set to 0. Eliminating this
second shift has two advantages in this case. First, it eliminates the slight possibility that a jump
of more than half the range of the source in a single servo cycle could lead to an inadvertent
rollover extension of the result. Second, if the LSB of the source data ends up in bit 0 of the 32-
bit intermediate register, the output scale factor for the entry can be 1.0.
Note, however, that if index2 is set to a value of 32 or greater (an impossible shift!), then index1
and index2 are used as gains in a tracking filter, and no shifting is performed. The operation of
the tracking filter is described in a later section.
In the tracking filter, index2 serves as the “proportional” gain term, index1 serves as the
“mantissa” of the “integral” gain term, and index4 serves as the “exponent” of the “integral” gain
term. All are 8-bit unsigned integer values, with a range of 0 to 255.
Filter Execution
The following equations are executed by a tracking filter in a Power PMAC encoder conversion
table (ECT) entry each servo cycle k:
where the digital gain terms Kid (digital integral gain) and Kpd (digital proportional gain),
expressed in terms of entry parameters, are:
index1
K id
256 * 2 index 4
256 index2
K pd
256
Re-arranging these equations and converting to digital (z) transform form, we get:
k
out k out k 1 K pd errk K id errj
j 0
Out z 1 z 1 K pd Errz
K id
1 z 1
Errz
1 z 1
Converting to an equivalent analog (s) transform using s , where Ts is the servo sample
Ts
time, we get:
K id
sTs Out s K pd Errs Errs
sTs
K pd K id
s Out s 2 Errs
Ts sTs
K
s Out s K p i Errs
s
K id index1
Ki
Ts2
256 2 index 4 Ts2
K pd 256 index2
Kp
Ts 256 Ts
This can be viewed in block diagram form like a traditional tracking loop:
From this, we can compute the overall transfer function of the filter:
1 K
Kp i
Out s s s s2 K s Ki
2 p
Ins 1 K i s 2 s K p s Ki
1 K p
s s
Out s 2n s n2
Ins s 2 2n s n2
From this, we can derive the analog gain terms from standard filter specifications:
K i n2
K p 2 n
Next, we can compute the digital gain terms and the tracking filter parameters:
If the integral gain term specified by index1 is set to 0, then the filter reduces to a 1st-order low-
pass filter with a time constant in servo cycles of (256 /[256- index2]) – 1. It is not recommended
to use a 1st-order filter for servo feedback terms, because there will be steady-state error at
velocity.
1. Select a cutoff frequency f c in Hertz. This is the frequency beyond which the filter will
start attenuating the signal. Generally values from 100 – 200 Hz are used for resolvers,
and values of about 1000 Hz are used for sinusoidal encoders.
4. Compute the filter’s sample time Ts in seconds. This is the servo update period, and can
be calculated as Sys.ServoPeriod / 1000.
5. Compute the proportional gain term index2 = 256 - 512 * ς * ωn * Ts and round to the
nearest integer.
6. Compute the (tentative) integral gain term index1' = 256 * ωn2 * Ts2
7. If index1' is less than 64, rounding it to the nearest integer could change the filter
characteristics too much, so double it enough times to make it greater than 64, set the
element index1 to this value, and set the element index4 to the number of doublings.
Example
As an example, we will design a tracking filter for resolver feedback at the default servo update
period:
4. We compute the filter sample time in seconds as 0.442 / 1000 = 4.42 x 10-4
If EncTable[n].MaxDelta is set greater than 0, this change-limiting is active for the entry. With
this limiting active, if index3 is set to 0, then the first derivative (velocity) of the source data is
limited to MaxDelta, expressed in LSBs of real source data per servo cycle (this assumes that this
LSB is in bit (32 – index1) of the 32-bit source register).
If the magnitude of the source data changes by more than this amount in a single servo cycle, the
source data is rejected, and instead the resulting position is changed by the same amount it was in
the previous servo cycle (i.e., the velocity is maintained), using the value stored in the status
element EncTable[n].PrevDelta for the entry. If the anomaly persists for one or more additional
servo cycles, the source data is still rejected, but the resulting position is now slewed at the
MaxDelta rate toward the new source value. (This case usually occurs during configuration,
when some aspect of the setup or source is changed, yielding a step change in the input value.)
With EncTable[n].MaxDelta greater than 0, if index3 also set greater than 0, then the second
derivative (acceleration) of the source data is limited to MaxDelta, expressed in LSBs of real
source data per servo cycle per servo cycle (again assuming that this LSB is in bit (32 – index1)
of the 32-bit source register). In this case, the value of index3 is the number of servo cycles the
last valid acceleration is maintained in the case of an anomaly. After this number of servo cycles,
if the anomaly persists, the resulting position jumps immediately to the new source value.
Generally, a velocity limit is easier to implement, and is satisfactory for most applications.
However, an acceleration limit can be more sensitive to corrupted data, and provide a more
accurate substitute in case bad data is detected.
In our example of 20 bits of real data, after the two shifting operations, the LSB of real source
data will be in bit 12 of the intermediate register. To get a result value where this LSB amounts to
one unit, this must be multiplied by 1 / 2(32 – 20) = 1 / 212 = 1/4096. It is usually best to enter the
value for ScaleFactor as an expression and let Power PMAC compute the exact resulting value.
EncTable[n].pEnc = Gate2[i].LowIoData.a
EncTable[n].pEnc = Acc84E[i].SerialEncDataA.a
EncTable[n].pEnc1 is set to the address of the second source register. It takes data from bits 8 –
15 of this register and uses this data to form the high 8 bits of the initially assembled 32-bit value.
It can be used to access the high 8 bits of the parallel I/O on the DSPGATE2 IC, or the high 8 bits
from a serial encoder through an ACC84E board. In these cases, the setting is like:
EncTable[n].pEnc1 = Gate2[i].HighIoData.a
EncTable[n].pEnc1 = Acc84E[i].SerialEncDataB.a
The following diagram shows how the data from the two sources is combined in this first step:
31 8 7 0
Combined
Result
32-bit data field
31 24 23 0
With 28 bits of real data, after the two shifting operations, the LSB of real source data will be in
bit 4 of the intermediate register. To get a result value where this LSB amounts to one unit, this
must be multiplied by 1 / 2(32 – 28) = 1 / 24 = 1/16. It is usually best to enter the value for
ScaleFactor as an expression and let Power PMAC compute the exact resulting value.
The following diagram shows the principle of 1/T sub-count extension, with the timer values
being used to estimate the fractional count value between the whole-count information from the
hardware counter.
T1 T2 T1 T2
Extended
Position Counter
Position
Time
The DSPGATE1 Servo IC is commonly used to process up to four quadrature encoders, as on the
ACC-24E2, ACC-24E2A, and ACC-24E2S axis-interface modules for the UMAC rack. It
employs the Gate1[i] data structure. The DSPGATE2 MACRO IC can also be used to process
one or two quadrature encoders, as on the ACC-5E MACRO & I/O module for the UMAC rack.
It employs the Gate2[i] data structure.
EncTable[n].pEnc = Gate1[i].Chan[j].ServoCapt.a
EncTable[n].pEnc = Gate2[i].Chan[j].ServoCapt.a
EncTable[n].pEnc1 is set to the address of the first timer register for the channel. Common
setting types are:
EncTable[n].pEnc1 = Gate1[i].Chan[j].TimeBetweenCts.a
EncTable[n].pEnc1 = Gate2[i].Chan[j].TimeBetweenCts.a
If a PMAC3-style IC (which uses the Gate3[i] data structure) is used, as from an ACC-24E3
UMAC board with a standard analog feedback mezzanine board, or a Power Clipper or Power
Brick with a standard analog feedback board, it is possible to use the hardware extension
performed in the IC and simply employ a Type 1 single-register read of the IC channel’s
ServoCapt register with the sub-count position data. This requires substantially less processor
time.
However, the only correction factors the IC’s hardware extension has are those for voltage
offsets. When this Type 4 software extension is employed, magnitude mismatch and phase offset
correction factors can be used as well. Note that when this software extension technique is used,
Gate3[i].Chan[j].AtanEna for the source IC channel must be set to 0 to disable the hardware
extension in the IC.
With an “auto-correcting interpolator” board on the ACC-24E3 UMAC board or in the Power
Brick, all of these errors are detected and corrected for in hardware, resulting in a very accurate
interpolated position value in the ServoCapt or SerialEncDataA register for the channel, so
there is no reason to use this Type 4 software extension in that case..
The following diagram shows the common signal errors found in feedback from a sinusoidal
encoder. Correction terms for these errors are detailed below.
CosMag
SinMag
CosOffset 90°
SinOffset
θ
φ
(φ = PhaseError)
When the data comes from a PMAC2-style IC, 10 bits of sub-count fractional data are calculated,
for a resulting resolution of 1/1024 of a quadrature count, or 1/4096 of an encoder line. When the
data comes from a PMAC3-style IC, 14 bits of sub-count fractional data are calculated, for a
resulting resolution of 1/16,384 of a quadrature count, or 1/65,536 of an encoder line.
Note that the hardware extension provides 12 bits of sub-count fractional data in a single register,
for a resulting resolution of 1/4096 of a quadrature count, or 1/16,384 of an encoder line, directly
accessible with the type = 1 single-register read method. The type = 7 extended hardware
arctangent interpolation adds 2 more bits, providing 14 bits of sub-count fractional data, for a
resulting resolution of 1/16,384 of a quadrature count, or 1/65,536 of an encoder line
EncTable[n].pEnc = Gate1[i].Chan[j].Status.a
EncTable[n].pEnc = Gate3[i].Chan[j].Status.a
EncTable[n].pEnc1 is set to the address of the first ADC register used for the channel. The
setting will be of the form:
EncTable[n].pEnc1 = Gate1[i].Chan[j].Adc[0].a
EncTable[n].pEnc1 = Gate3[i].Chan[j].AdcEnc[0].a
However, on the initial setup of the entry, and on any change to the decode value, it is important
to set this either to 0 or to the (new) value of the EncCtrl element. The EncCtrl element for the
IC channel must be set to 3 (“times-4” decode clockwise) or to 7 (“times-4” decode counter-
clockwise) in order for this entry to process the data correctly. If the direction sense of
EncTable[n].index does not match that of the present value of Gaten[i].Chan[j].EncCtrl, the
direction sense of the resulting sub-count data will not match that of the whole-count data,
resulting in a “sawtooth” pattern in the resulting combined position.
arctangent function. The SinBias and CosBias terms allow the user to compensate for this type of
offset. The value of SinBias is added to the reading in Adc[0] or AdcEnc[0], and the value of
CosBias is added to the reading in Adc[1] or AdcEnc[1], before the arctangent is calculated.
SinBias and CosBias are signed 16-bit values, so for the purpose of calculating the needed
offsets, the ADCs should be treated as having 16-bit resolution (even though they are probably 14
bits). For example, if a 14-bit ADC has a reading of -5 LSBs when it should read 0, this is
equivalent to a reading of -20 of a 16-bit ADC, and the bias term should be set to +20 to
compensate. The hardware ADC registers in the ICs – Gate1[i].Chan[j].Adc[k] in a PMAC2-
style IC, Gate3[i].Chan[j].AdcEnc[0] in a PMAC3-style IC – are treated as 24-bit elements in
the Script environment and 32-bit elements in the C environment, with the real data from the n-bit
ADC in the high n bits of the element.
EncTable[n].CoverSerror represents the fractional component of the correction factor, not the
entire correction factor. It is a signed 16-bit integer value, and its range of -32,768 to +32,767
represents a fractional value of -1.0 to +0.9999 that is added to 1.0 and the resulting sum is
multiplied by the measured cosine signal value. In this way, the default value of 0 for
CoverSerror represents a correction factor of 1.0, which provides no adjustment. CoverSerror
should be greater than 0 if the measured cosine signal (Adc[1] or AdcEnc[1]) has a lower
numerical magnitude that the measured sine signal, and less than 0 if the measured cosine signal
has a higher numerical magnitude that the measured sign signal.
For example, if the magnitude of the measured sine signal (Adc[0] or AdcEnc[0]) is 7.5% larger
than that of the measured cosine signal (Adc[1] or AdcEnc[1]), the cosine signal values should
be multiplied by a factor of 1.075, and CoverSerror, which represents the fractional component
of 0.075, should be set to 2458 (= 0.075 * 32,768).
EncTable[n].TanHalfPhi represents the tangent of half of the phase error angle (“phi”). A
positive value of phase error phi (and therefore a positive value of TanHalfPhi) means that the
two signals are separated by more than 90°; a negative value of Phi means that the two signals are
separated by less than 90°. TanHalfPhi is a signed 16-bit integer value, and its range of -32,768
to +32,767 represents a range for the tangent of -0.5 to +0.49999, covering a range of “half
angles” of +/-26.5°, or a range of phase error angles of +/-53°.
For example, if the two signals were found to be separated by 80° instead of the ideal 90°, the
phase error phi would be -10°, so the half angle would be -5°, and the tangent of the half angle
would be -0.087488, and TanHalfPhi should be set to -5734 (= -0.087488 * 32,768 * 2).
When a PMAC2-style IC is used, for users who wish the result to be scaled in units of LSBs of
the interpolator (1/1024 of a quadrature count, or 1/4096 of an encoder line), this should be set to
1.0. For users who wish the result to be scaled in units of quadrature counts (1/4 of an encoder
line), as if it were a digital quadrature encoder, this should be set to 1/1024. For those who wish
the result to be scaled in units of encoder lines, this should be set to 1/4096. It is usually best to
enter the value for ScaleFactor as an expression and let Power PMAC compute the exact
resulting value.
When a PMAC3-style IC is used, for users who wish the result to be scaled in units of LSBs of
the interpolator (1/16,384 of a quadrature count, or 1/65,536 of an encoder line), this should be
set to 1.0. For users who wish the result to be scaled in units of quadrature counts (1/4 of an
encoder line), as if it were a digital quadrature encoder, this should be set to 1/16,384. For those
who wish the result to be scaled in units of encoder lines, this should be set to 1/65,536. It is
usually best to enter the value for ScaleFactor as an expression and let Power PMAC compute
the exact resulting value.
EncTable[n].pEnc1 is set to the address of the second source register. It takes data from bits 8 –
15 of this register and uses this data to form the next 8 bits of the initially assembled 32-bit value.
It is most commonly used to access the middle byte of a 24-bit port (A or B) on an ACC-14E. In
this case, the setting is like:
The third byte automatically comes from the next register after the one specified by pEnc1 (an
address 4 higher). This will typically be the high byte of a 24-bit port (A or B) on an ACC-14E.
The fourth byte (seldom used) automatically comes from the third-next register after the one
specified by pEnc (an address 12 higher). In the cases where there is real data in this byte, this
will typically be the low byte of Port B of an ACC-14E, where the other three bytes come from
Port A.
The following diagram shows how the data from the 4 registers is combined in this first step:
31 16 15 8 7 0
Combined
Result
32-bit data field
31 24 23 16 15 8 7 0
With 24 bits of real data, after the two shifting operations, the LSB of real source data will be in
bit 8 of the intermediate register. To get a result value where this LSB amounts to one unit, this
must be multiplied by 1 / 2(32 – 24) = 1 / 28 = 1/256. It is usually best to enter the value for
ScaleFactor as an expression and let Power PMAC compute the exact resulting value.
Note that the PMAC3-style DSPGATE3 IC performs this arctangent conversion in hardware, so
this software-based arctangent conversion should not be used with the PMAC3-style IC. Instead,
a Type 1 single-register read of the Atan register should be used.
EncTable[n].pEnc1 is set to the address of the first ADC register for the channel. The setting
will be of the form:
EncTable[n].pEnc1 = Gate1[i].Chan[j].Adc[0].a
SinBias and CosBias are signed 16-bit values, so for the purpose of calculating the needed
offsets, the ADCs should be treated as having 16-bit resolution (even if they have other
resolution).
The tracking-filter operations for the software arctangent direct resolver conversion method are
identical to those for the single-register read. Refer to the section under Single-Register Read for
details.
For users who wish the result to be scaled in units LSBs of the 16-bit conversion (1/65536 of a
resolver cycle), this should be set to 1.0. For users who wish the result to be scaled as if a lower-
resolution conversion were performed, this should be set to 1/216-n for an n-bit conversion. For
example, to scale the result as if a 14-bit conversion had been performed, ScaleFactor should be
set to 1/216-14 = 1/4. This is the most common setting.
With the “auto-correcting” interpolator (released 4th quarter 2013 for the ACC-24E3), it is
possible to obtain a higher degree of interpolation that can be obtained in this register alone. The
Type 7 extended hardware arctangent interpolation method allows the user to obtain 16 bits of
fraction per line (14 bits of fraction per quadrature count) for “x65536” interpolation.
To use this method, Gate3[i].Chan[j].AtanEna for the source IC channel must be set to 1 to
enable the hardware extension in the IC.
EncTable[n].pEnc = Gate3[i].Chan[j].ServoCapt.a
EncTable[n].pEnc1 = Gate3[i].Chan[j].AtanSumOfSqr.a
It is also possible to specify this simply as the address of the partial-word Atan element, but it
will report back as the address of the full-word AtanSumOfSqr element.
For users who wish the result to be scaled in units of LSBs of the interpolator (1/16,384 of a
quadrature count, or 1/65,536 of an encoder line), this should be set to 1.0. For users who wish
the result to be scaled in units of quadrature counts (1/4 of an encoder line), as if it were a digital
quadrature encoder, this should be set to 1/16,384. For those who wish the result to be scaled in
units of encoder lines, this should be set to 1/65,536. It is usually best to enter the value for
ScaleFactor as an expression and let Power PMAC compute the exact resulting value.
EncTable[n].pEnc = EncTable[m].PrevEnc.a
EncTable[n].pEnc1 is set to the address of the second source register. It reads the entire 32-bit
value at this register, treating it as a signed integer. In most cases, this register will be the
PrevEnc element of an earlier (lower-numbered) entry in the conversion table. In this case the
setting is like:
EncTable[n].pEnc1 = EncTable[l].PrevEnc.a
In Type 8, the value in the second source register is added to the value in the first source register.
In Type 9, the value in the second source register is subtracted from the value in the first source
register. Once this addition or subtraction has been performed, subsequent processing can be done
just as for one of the parallel-read methods. Note, however, that this processing could also have
been done in the ECT entries of the source registers.
If this master encoder is also used as a feedback encoder, there will likely be two ECT entries
reading the encoder position value. The first will keep the type = 1 or type = 3 setting all the time
so it can be used for servo feedback. The second, used for the triggered time base master, with the
value of type changed between the frozen/armed state and the running state.
To ensure proper referencing to the master position at the trigger, the arming operation must
occur after the initial move that is to start at the trigger has been fully calculated and ready to
execute. It is best accomplished in a PLC program, where a single program line can arm the entry
if it sees that it is frozen – for example:
If the running state of the entry is type = 3, ScaleFactor for a time base master entry should be
set to 1 / (512 * RTIF), with RTIF expressed in counts per millisecond.
If the running state of the entry is type = 1, ScaleFactor for a time base master entry should be
set to 1 / (256 * RTIF), with RTIF expressed in counts per millisecond.
Because this method is focused on serial encoders, this element is typically used to access the
first serial encoder data register in either the PMAC3-style “DSPGATE3” IC, as in the ACC-
24E3, the Power Brick, or the Power Clipper, or in the ACC-84x FPGA IC:
EncTable[n].pEnc = Gate3[i].Chan[j].SerialEncDataA.a
EncTable[n].pEnc = Acc84E[i].Chan[j].SerialEncDataA.a
For the usual serial encoder interface, this element is used to access the second serial encoder data
register in the PMAC3-style “DSPGATE3” IC, or the second or third serial encoder data register
(depending on the protocol) in the ACC-84x FPGA IC.
EncTable[n].pEnc1 = Gate3[i].Chan[j].SerialEncDataB.a
EncTable[n].pEnc1 = Acc84E[i].Chan[j].SerialEncDataB.a
EncTable[n].pEnc1 = Acc84E[i].Chan[j].SerialEncDataC.a
If EncTable[n].pEnc1 is set to the default value of Sys.pushm (the start of the user shared
memory buffer), no read of an error register will be performed, so no errors of this type can be
automatically detected and acted upon.
The following tables show the settings to be used if all of the error bits, and optionally alarm bits
and status bits, are to be treated as real errors by the entry, for both the DSPGATE3 IC and ACC-
84x interfaces. Of course, the user may choose not to monitor all of these bits.
DSPGATE3-Based Interfaces
Protocol Gate3[i] Element Bits Mask Word
index6 value
SPI SerialEncDataB Status bits 31:20* $FFF00000*
SSI SerialEncDataB Error bit 31 $80000000
EnDat 2.1 SerialEncDataB Error bits 31:29 $E0000000
Hiperface (not for cyclic read)
Yaskawa I (not for cyclic read)
Yaskawa II/III/V SerialEncDataB Error bits 31:29 $E0000000
+Alarm bits 27:20 $EFF00000
Tamagawa SerialEncDataB Error bits 31:30 $C0000000
+Alarm bits 23:16 $C0FF0000
Panasonic SerialEncDataB Error bits 31:30 $C0000000
+Alarm bits 15:08 $C000FF00
Mitutoyo SerialEncDataB Error bits 31:30 $C0000000
+Alarm bits 23:16 $C0FF0000
+Status bits 27:24 $CFFF0000
Kawasaki SerialEncDataB Error bits 31:30 $C0000000
+Alarm bits 26:24 $C7000000
* Implementation-specific; most encoders will not use all of these bits.
ACC-84x Interfaces
Protocol Acc84x[i] Element Bits Mask Word
index6 value
BiSS-B/C SerialEncDataB Error bits 31:30 $C0000000
+Status bits 29:24 $FF000000
EnDat 2.1/2.2 SerialEncDataB Error bits 31:30,27:26 $CC000000
Mitutoyo SerialEncDataC Error bits 31:30 $C0000000
+Alarm bits 23:16 $C0FF0000
Panasonic SerialEncDataC Error bits 31:30 $C0000000
+Alarm bits 23:16 $C0FF0000
SSI SerialEncDataB Error bit 31 $80000000
Tamagawa SerialEncDataC Error bits 31:30 $C0000000
+Alarm bits 23:16 $C0FF0000
Yaskawa II/III/V SerialEncDataB or Error bits 31:29 or $E0000000 or
SerialEncDataC Alarm bits 23:16 $00FF0000
If any of the bits in the error register specified by index6 is found to be true in a given servo
cycle, the data in the position register will be considered invalid. In this case, a replacement
position value would be calculated just as if the read position value caused the “maximum
change” limit, as set by the index3 and MaxDelta elements for the entry, to be exceeded (see
below).
In addition, if any of these errors is found in a given servo cycle, bit 0 of EncTable[n].Status is
set to 1. (If no errors are found in a given servo cycle, this bit is set to 0.) Some users may want to
have the motor’s automatic encoder-loss detection function use this bit, which can effectively
combine multiple error bits. This is done by setting Motor[x].pEncLoss to
EncTable[n].Status.a, Motor[x].EncLossBit to 0, and Motor[x].EncLossLevel to 1.
Motor[x].EncLossLimit, which sets the accumulated number of errors that must be exceeded
before shutdown, should generally be set large enough to permit continued operation on
intermittent errors.
Next, this result is shifted left by the number of bits specified in index1. Generally, index1 is set
to the quantity 32 minus the number of bits of real data in the source register. This will cause the
MSB of actual data in the source register to end up in the highest bit of the intermediate result
register. This must occur if Power PMAC is to handle rollover of the source data value properly.
For more information and examples for these elements, refer to the description of Type 1, above.
If EncTable[n].MaxDelta is set greater than 0, this change-limiting is active for the entry. While
this change can be specified as a first derivative (velocity) by setting EncTable[n].index3 to 0, it
is much better in this method to specify it as a second derivative (acceleration) by setting index3
greater than 0, with the value of index3 specifying the number of consecutive servo cycles the
last valid acceleration is maintained in the replacement position value. After this number of servo
cycles, if the anomaly persists, the resulting position jumps immediately to the new source value.
When the change limit is expressed as an acceleration, MaxDelta is expressed in LSBs of the
source data per servo cycle per servo cycle.
The following diagram shows the tasks that are performed in motor control and the different
places they can be split between the controller and the drive.
Desired Position
Desired Velocity
Desired Torque
Desired Phase Currents
Desired Phase Voltages
+
Trajectory + +
Position Velocity Phase Current Power
Generation + -
Filter Filter Commutation Filters Modulation
Interpolation - -
-
d
dt Phase Currents
Position
E Motor
Position-
Mode Drive
Velocity-
Mode Drive
Torque-
Mode Drive
Sinewave-
Mode Drive
Direct PWM-
Mode Drive
Any of these modes can be employed directly in a Power PMAC system, or over the MACRO
ring. When using the MACRO ring, the command and feedback values are passed across the ring
as binary numerical values; the actual generation of command signals and processing of feedback
signals is done at the remote MACRO node. The motor algorithms in the Power PMAC are the
same regardless of whether the MACRO ring is used or not. The choice of mode of operation is
independent for each motor.
The IDE motor setup control can be invoked by clicking on “Tools” in the top bar, then on
“System Setup” in the pull-down menu. On the left window of the control, click on “Power
PMAC”, then on a motor number, or on “Add Motor”.
Most of the software configuration of a motor involves setting proper values for these variables,
as explained in the following sections. This section has a quick survey of the key variables, and
the variables that are common to all modes. Depending on how you are setting up the motor, you
may branch to other sections of the manual. The following flow chart summarizes the motor setup
possibilities:
Beginning
Motor
Setup
Single Output
Setup Use PMAC to close
current loop?
No Yes
Analog
Sine-Wave Direct PWM
Output?
Output Output
Yes Setup Setup
No
Synchronous
Motor?
No Yes
Slip and
Phase
Magnetization
Referencing
Current Setup
Position/Velocity
Servo Loop
Setup
Presently, two non-zero values are supported. A value of 1 activates this motor in normal mode,
in which it generates its own command trajectory. A value of 8 activates this motor in a special
“gantry follower” mode, in which it uses the commanded trajectory generated by the motor
specified by this motor’s saved setup element Motor[x].CmdMotor. This mode guarantees that
this motor will track the specified “gantry leader” motor during jogging, homing, and
programmed moves. This gantry leader motor is set up identically to an independent motor, with
a value of 1 for this element.
If bit 2 is set to 1 (typically Motor[x].PhaseCtrl = 4), Power PMAC will perform commutation
tasks for the motor with any phase input and output values accessed in separate registers for each
phase. This is known as “unpacked mode”, and must be used with PMAC2-style Servo ICs, as on
the ACC-24E2x UMAC axis-interface boards, or with a MACRO ring interface using either
PMAC2 or PMAC3 ASICs. It can be used with PMAC3-style ICs, as on the ACC-24E3 UMAC
axis interface boards, provided that the setup elements Gate3[i].Chan[j].PackInMode and
Gate3[i].PackOutMode are changed from their default values of 1 and set to 0.
If bit 0 is set to 1 (typically Motor[x].PhaseCtrl = 1), Power PMAC will perform commutation
tasks for the motor with any phase input and output values accessed in pairs, two values per 32-
bit register – Phases A and B together, Phases C and D (if present) together. This is known as
“packed mode”, and can be used with PMAC3-style ICs, as on the ACC-24E3 UMAC axis
interface boards, provided that the setup elements Gate3[i].Chan[j].PackInMode and
Gate3[i].PackOutMode are set to their default values of 1. Packed mode saves significant time
for input/output operations, which can be important in high-frequency and/or high-axis-count
applications.
If commutation tasks are enabled in either packed or unpacked mode, the commutation setup
elements must be set to specify how commutation is performed. The instructions for setting these
variables are given in the Setting Up Power PMAC Commutation chapter of the User’s Manual.
The names of these address parameters start with a lower-case “p”, which indicates “pointer to”.
It is not necessary for the user to know the numerical value of the address specified for one of
these functions. Instead, the name of the data structure element for the register is specified, along
with the “.a” (denoting “address of”) suffix.
The default values of Motor[x].pDac use the output registers for the machine interface channel
usually assigned to the motor, or command registers (starting with Register 0) for the MACRO
node usually assigned to the motor. The exact setting is dependent on the mode used, and is
covered in the section for each mode of control. Typical types of settings used are:
Motor[x].pDac = Gaten[i].Chan[j].Dac[0]
Motor[x].pDac = Gaten[i].Chan[j].Pwm[0]
Motor[x].pDac = Gaten[i].Chan[j].Pfm
Motor[x].pDac = Gate2[i].Macro[j][0]
Motor[x].pDac = Gate3[i].MacroOutα[j][0]
Using a feedback sensor on the motor alone is usually the most cost-effective solution, especially
for a rotary motor. If the motor rotation is “geared down” to the load, the sensor provides a higher
resolution when measuring load movement. It is typically easier to protect the sensor from
environmental damage when it is on the motor.
However, a motor-mounted sensor provides a very indirect measurement of the load position,
with many factors capable of introducing errors, including coupling compliance, gear backlash,
and screw tolerances. If only a motor sensor is used, these errors must either be tolerated, or
characterized and compensated.
A feedback sensor mounted directly on the load provides a much more direct, and therefore
accurate, measurement of the load position. However, a load sensor, particularly if linear, tends to
be much more exposed to physical and environmental damage, and is often more expensive. Of
course, effective resolution multiplication through gearing is not possible for a directly mounted
load sensor. If only a load sensor is used, coupling and connection imperfections, such as
compliance and backlash, are “inside” the servo loops closed with its feedback, making it more
difficult to achieve stable control.
Power PMAC makes it easy to utilize dual motor/load feedback to get the advantages of both
sensor placements. It closes an outer position loop with its choice of feedback sensor, and an
inner velocity loop with a separate choice of feedback sensor. While a large majority of users will
select the same sensor for both loops, it is very simple to select separate sensors, closing the
position loop using the load sensor for high accuracy, and the velocity loop using the motor
sensor for good stability and high bandwidth (from the effective high resolution).
The following diagram shows the basic principle of selecting single or dual feedback with Power
PMAC. The details of this selection are covered in the next sections.
DesPos pDac
P Amp
+ +
- -
ActPos
D
E Motor Load
ActPos2 pEnc2
Encoder
pEnc
This address must be the address of an entry in the “encoder conversion table” (ECT) to access
processed data from the table, so the specification will always take the form of EncTable[n].a.
This means that any data to be used for servo feedback must be processed through the ECT.
Despite the name of this element, it is not required that the feedback ultimately come from an
encoder sensor.
By default, Motor n accesses the result of ECT entry n for its outer-loop feedback. Refer to the
User’s Manual section on the encoder conversion table for more information on that setup.
The data read at this address is multiplied by the value of the scale factor element
Motor[x].PosSf before it is used for motor position. The floating-point data read from the ECT
will almost always have units of “counts” or “LSBs”, even if there is fractional resolution. Most
users will leave Motor[x].PosSf at its default value of 1.0 so that motor units are also in “counts”
or “LSBs”.
However, it is possible to use a different, and usually smaller, value than 1.0 to make the motor
units engineering units such as millimeters and degrees, which virtually always consist of many
feedback “counts”. Note, however, that Motor[x].PosSf acts as a gain term in the servo loop, and
decreases to its value will require corresponding increases to servo-loop gain terms that use the
resulting position values.
The data read at this address is multiplied by the value of the scale factor element
Motor[x].Pos2Sf before it is used for the motor’s inner-loop position. The floating-point data
read from the ECT will almost always have units of “counts” or “LSBs”, even if there is
fractional resolution. Most users will leave Motor[x].Pos2Sf at its default value of 1.0 so that the
motor’s inner-loop units are also in “counts” or “LSBs”.
However, it is possible to use a different, and usually smaller, value than 1.0 to make the inner-
loop units engineering units such as millimeters and degrees, which virtually always consist of
many feedback “counts”. Note, however, that Motor[x].Pos2Sf acts as a gain term in the servo
loop, and decreases to its value will require corresponding increases to inner-loop servo-loop
gains that use the resulting position values.
When the new feedback source is selected, the motor will immediately start using the change in
position from the new source instead of the old source. Because it reads the change in position
each cycle, and not the position itself, there is no position jump when the new source is selected.
(And there is no need, as in older PMACs, to read and store a “previous position” to compute this
change properly.)
It is strongly recommended that all sources of feedback position have the same resolution as they
appear to the motor. With differing resolutions, handling issues of servo gains and position
referencing become extremely difficult. If the sensors have different physical resolution, the use
of compensating scale factors in their encoder conversion table entries can provide them with
matching effective resolutions to the motor.
Setting the value of Motor[x].EncType in the Power PMAC script environment (but not in C)
automatically sets the value of several other setup elements for the “flags” for the motor to values
that match the feedback type and interface. These elements include:
Motor[x].pCaptFlag
Motor[x].pCaptPos
Motor[x].CaptFlagBit
Motor[x].CaptPosRightShift
Motor[x].CaptPosLeftShift
Motor[x].CaptPosRound
Motor[x].AmpEnableBit
Motor[x].AmpFaultBit
Motor[x].LimitBits
This automatic assignment sets up for the most common configuration for the interface, but
permits subsequent changes for unusual configurations. Each of these elements is discussed
separately, below, and in the section on triggered moves in the Motor Moves chapter. In addition,
each is described in detail in the Software Reference Manual.
In order to use the very accurate hardware position capture function of the ASIC, this must use
the status register from the same ASIC and channel as is used for ongoing outer (position) loop
feedback as specified by Motor[x].pEnc and EncTable[i].pEnc from the table entry thus
specified.
Motor[x].CaptFlagBit specifies the bit number within this specified register to be used as the
capture trigger bit. It should be set to 19 for a PMAC2-style Servo IC, or for a MACRO interface;
it should be set to 20 for a servo interface in a PMAC3-style IC. It will be assigned the
appropriate value automatically when a script command sets the value of Motor[x].EncType.
PMAC3-style IC. If no hardware overtravel limit flags are used for the motor, this element should
be set to 0, disabling the function for the motor.
Saved setup element Motor[x].LimitBits specifies which bit(s) of the 32-bit register are read for
the status of the limit inputs. In the standard range of 0 to 30, its value specifies the bit number of
the positive limit input, with the negative limit input mapped into the next higher bit. This range
should be appropriate for all standard Delta Tau hardware interfaces.
If Motor[x].LimitBits is in the range of 32 to 63, (LimitBits – 32) specifies the bit number of the
single input that is triggered by either the positive or negative limit switch. This configuration is
not recommended, but occasionally must be used, particularly on retrofit systems. Note that with
this setting, it is not possible to command a move out of either limit without first disabling the
limit functionality by setting Motor[x].pLimits to 0.
If Motor[x].LimitBits is in the range of 64 to 94, (LimitBits – 64) specifies the bit number of the
negative limit input, with the positive limit input mapped into the next higher bit. This setting can
be useful for some networked drives with the limit switches wired into the drives.
If Motor[x].LimitBits is in the range of 96 to 127, (LimitBits – 96) specifies the bit number of
the positive limit in the register specified by Motor[x].pLimits. In this case,
Motor[x].pAuxFault specifies the register for the negative limit input, with
Motor[x].AuxFaultBit setting the bit number for that input in the register. This range permits the
use of separate registers, or non-adjacent bits in the same register, for the two limit input bits,
particularly valuable when the limits are wired into general-purpose I/O points on a fieldbus or
network.
If bit 7 (value 128) of Motor[x].LimitBits is also set, a value of “0” in a specified limit input bit
signifies that the motor is into that limit, rather than a “1” if this control bit is not set. The use of
normally closed limit switches is strongly recommended, and usually these report a “1” when
open (on the limit), so this control bit is rarely set. However, some devices, particularly when
using a fieldbus or network, will have the opposite polarity, requiring the use of the control bit to
configure the system.
Motor[x].AmpFaultBit specifies the bit number within this specified register to be used as the
amplifier fault bit. It should be set to 23 for a PMAC2-style Servo IC, or for a MACRO interface;
it should be set to 7 for a servo interface in a PMAC3-style IC. It will be assigned the appropriate
value automatically when a script command sets the value of Motor[x].EncType.
Because there is no standard on amplifier-fault interfaces, the value of the saved setup element
Motor[x].AmpFaultLevel (0 or 1) determines which value in the fault status bit of the specified
register will be interpreted as a fault.
Motor[x].AmpEnableBit specifies the bit number within this specified register to be used as the
amplifier-enable bit. It should be set to 22 for a PMAC2-style Servo IC, or for a MACRO
interface; it should be set to 8 for a servo interface in a PMAC3-style IC. It will be assigned the
appropriate value automatically when a script command sets the value of Motor[x].EncType.
Power PMAC always considers a “0” in the enable control bit to mean a disabled state for the
amplifier, and a “1” to mean an enabled state. Because Power PMAC must be able to force the
disable state in hardware (due to a watchdog timer trip or hardware reset), it is not possible to
change this polarity in software.
Note that many systems will have a sensor that is absolute over a single motor revolution or
commutation cycle, but not over the entire range of motion for the motor, as with a single-turn
resolver or absolute encoder, or with Hall-style commutation sensors. In these cases, if the motor
position is required to be known over multiple revolutions, a homing-search move will still be
required, and Motor[x].pAbsPos should be set to 0. (If Power PMAC is performing the phase
commutation for such a motor, the similar element Motor[x].pAbsPhasePos can be set to read
this sensor for absolute position within one commutation cycle.)
Motor[x].pAbsPos can be set to the address of the hardware register for the absolute position
sensor (e.g. Gate3[i].Chan[j].SerialEncData.a or GateIo.DataReg[j].a) or to already-processed
data in the encoder conversion table (e.g. EncTable[i].PrevEnc.a). It can also be set to a memory
register (e.g. Sys.udata[i].a) if custom processing by the user is required.
The data read here does not have to be from the same sensor as is used for ongoing outer
(position) loop feedback. It does not have to have the same scaling, offset, or even direction sense
as the ongoing position.
Power PMAC interprets the data at the specified address according to the rules specified by
Motor[x].AbsPosFormat. Note that while this provides great flexibility, the data read must be in
The formatted value is next multiplied by the scale factor Motor[x].AbsPosSf (which can be
negative to change the direction sense), and then offset by subtraction of the value of
Motor[x].HomeOffset to get the resulting absolute motor position value. Note that
Motor[x].AbsPosSf can be different from the scale factor for “ongoing” position
Motor[x].PosSf, permitting the use of different sensors with different resolution for power-on
and ongoing position.
If the saved value of bit 2 (value 4) of Motor[x].PowerOnMode is set to 1, this absolute position
read function will automatically be performed at power-on/reset. With this setting, it is very
important that the sensor is reliably powered up and ready to respond before Power PMAC
attempts this read. This absolute position read can be commanded at any time (regardless of the
setting of this bit) using the on-line hmz command or the buffered program command homez.
Virtually all modern servomotor control employs current-loop closure for high response,
tolerance of parameter variation, and protection against overcurrent conditions. While this has
traditionally performed in the servo drive, Power PMAC is capable of closing the current loop
digitally for motors using “power-block” amplifiers in “direct PWM” mode.
If Power PMAC is either performing the phase commutation, closing the current loop, or both, for
the motor, jump to the next chapter, “Setting Up Power PMAC-Based Commutation and/or
Current Loop” for further instructions. If Power PMAC is doing neither task for this motor,
continue below in this chapter.
There are three subsequent sections in this chapter. The first deals with using the traditional
analog velocity-mode or torque-mode interface, still the most common servo-amplifier interface.
The second deals with the pulse-and-direction interface, the traditional and still most common
stepper-amplifier interface, also used with “stepper-replacement” servo amplifiers. The last
covers position-mode amplifiers, with which Power PMAC just provides the trajectory generation
algorithm and does not close any feedback loops.
The Power PMAC setup for both types of control is the same with the exception of the servo loop
tuning. With a velocity-command output, the velocity loop is closed in the drive, and the velocity-
feedback gains in the Power PMAC can be set to 0.0 (provided the drive’s velocity loop is well
tuned). With a torque-command output, Power PMAC is closing the velocity loop, and at least
one of the velocity feedback gains in the Power PMAC servo algorithm must be set greater than
zero to close a velocity loop.
When driving a hydraulic cylinder through either a proportional valve or a servo valve, the
dynamics appear to the Power PMAC to be those of a velocity command to a motor.
Hardware Setup
Several Power PMAC products and accessories have analog outputs suitable for use as voltage or
torque commands to appropriate servo amplifiers. The most common of these are the UMAC
ACC-24E2A analog servo interface board using PMAC2-style ICs, and ACC-24E3 servo
interface boards using PMAC3-style ICs with “analog amplifier interface” mezzanine boards.
This diagram shows the output circuitry for a channel of the PMAC2-style DSPGATE1 IC.
Output Mode
Control Bits PwmAtop
Pulse Width
PwmAbot
Modulator
Phase A
Command Value DacClk
DAC Shift
DacAdata
Register
DAC Clock &
Strobe Control PwmBtop
Pulse Width
PwmBbot
Modulator
Phase B
Command Value DacStb
DAC Shift
Data DacBdata
Register
PWM Frequency
& Deadtime Ctrl PwmCtop
Adr
Pulse Width
PwmCbot
Modulator
Phase C
Command Value Dir
Pulse Frequency
Modulator Pulse
The following diagram shows the output circuitry for a channel of the PMAC3-style DSPGATE3
IC. It has four phases (A, B, C, and D), rather than the three of the DSPGATE1 IC.
Output Mode
Control Bits PwmAtop
Pulse Width
PwmAbot
Modulator
Phase A
Command Value DacClk
DAC Shift
DacAdata
Register
DAC Clock &
Strobe Control PwmBtop
Pulse Width
PwmBbot
Modulator
Phase B
Command Value DacStb
DAC Shift
Data DacBdata
Register
PWM Frequency
& Deadtime Ctrl PwmCtop
Adr
Pulse Width
PwmCbot
Modulator
Phase C
Command Value DacClk
DAC Shift
DacCdata
Register
PFM Clock, Mode
Width Control PwmDtop
Pulse Width
PwmDbot
Modulator
Phase D
Command Value Dir/A
Pulse Frequency
Pulse/B
Modulator
Output Packing
Control To encoder mux
or timer
The products may have more than one phase of analog output per servo channel. For velocity or
torque-mode control, only one phase is used, typically the “A” phase. The output for a phase may
be used in single-ended format, using just the DAC+ output for the phase with respect to the
reference voltage AGND. Alternately it may be used in differential mode, using the DAC+ and
the DAC- outputs together. Note that the voltage between DAC+ and DAC- is always twice the
voltage between DAC+ and AGND.
Consult the appropriate hardware reference or accessory manual for the details of the hardware
setup and connection.
Note that because the 18-bit DACs used on the ACC-24E3 in this configuration accept a 24-bit
word, the data must first be shifted. The motor element Motor[x].DacShift must be set to 6 in
this case to orient the data properly before it is written to the hardware.
Please consult the product-specific reference manuals for those configurations for detailed
instructions on setting up the filtered-PWM analog outputs.
Note that these registers share an address with the Pwm[0] registers for the same channel, so
when the value of Motor[x].pDac is queried or backed up, the address will report as that of the
Pwm[0] register.
This same technique is useful for creating “virtual” motors with no physical motion hardware
attached. These are often used to follow real motors that do not have incremental encoders, so
counter-associated functions such as position-compare outputs can be used on the virtual motor as
if they were on the actual motor.
ASIC
(Rollover)
Pulse
Accumulator Dir
Stepper
DesPos Drive
Servo
Adder
+ Filter
-
PFM Circuit
Simulated Servo
ActPos Loop
Decoder/
Counter
Hardware Setup
PMAC2-style and PMAC3-style ICs have pulse-and-direction outputs for each channel on the IC.
In most configurations of interface and breakout hardware, these signals are accessible as RS-
422-level differential line-driver output pairs. These signals are driven by the value in a register
for the channel, with the pulse frequency proportional to the value in this register. For this reason,
these outputs are technically known as pulse-frequency-modulated (PFM) outputs.
The signals from the PFM output register can alternately be used as pulse-width-modulated
(PWM) outputs, and commonly form the last-phase command signals for “direct-PWM” output
of brushless motors.
The pulse-and-direction signals are available on the encoder connectors of the UMAC ACC-
24E2S, ACC-24E2A, and ACC-24E2 axis-interface boards. On the ACC-24E2S and ACC-
24E2A, the outputs use the same pins as the T, U, V, and W flag inputs for the channel; a jumper
must be installed to enable the outputs on these pins.
On the ACC-24E3, these outputs are also shared with the T, U, V, and W input pins on the
encoder connector, but the outputs are enabled under software control by setting the (unsaved)
OutFlagD control bit for the channel to 1 (Gate3[i].Chan[j].OutFlagD = 1). If the digital
amplifier-interface mezzanine board is used, they are directly available as the “D” phase outputs.
Signal Timing
The PULSEn and DIRn signals are driven from the internal PFM clock signal, whose frequency
is controlled by Gate1[i].HardwareClockCtrl or Gate3[i].PfmClockDiv (see below). The width
of the pulse is controlled by the PFM clock frequency and Gate1[i].PwmDeadTime or
Gate3[i].Chan[j].PfmWidth (see below). The output on PULSEn can be high-true (high during
pulse, low otherwise) or low-true, as controlled by Gate1[i].Chan[j].OutputPol or
Gate3[i].Chan[j].OutputPol; the default is high-true. The polarity of the DIRn signal is
controlled by Gate1[i].Chan[j].PfmDirPol or Gate3[i].Chan[j].PfmDirPol.
The DIRn signal is latched in this state at least until the front end of the next pulse. The PULSEn
signal stays true for the number of PFMCLK cycles set by the dual-use multi-channel element
Gate1[i].PwmDeadTime for PMAC2-style ICs, or by the channel-specific element
Gate3[i].Chan[j].PfmWidth for PMAC3-style ICs.
In the PMAC2-style IC, it then goes false and stays false for a minimum of this same time. This
guarantees that the pulse duty cycle never exceeds 50%; the pulse signal can be inverted with
Gate1[i].Chan[j].OutputPol without violating minimum pulse width specifications. If another
pulse is generated internally during this minimum false time, the pulse will be skipped entirely
(not delayed) on the output signal.
In the PMAC3-style IC, there is no minimum time in the false state, so the duty cycle can go to
100%. If the pulse width is less than the cycle length for the commanded frequency, the signal
will go false until the start of the next cycle. If the pulse width is greater than or equal to the cycle
length for the commanded frequency, the signal will simply stay true.
In either case, undesired signal properties will be present at frequencies high enough that the
cycle length becomes almost as short as the pulse width. The user should be careful to ensure that
this cannot occur in the actual application.
This PFM clock frequency puts an upper limit on the pulse frequency that can be generated –
with an absolute limit of 1/4 of the PFM clock frequency. Depending on the worst-case frequency
distortion that can be tolerated at high speeds, most people will limit their maximum pulse
frequency to 1/10 of the PFMCLK/addition frequency, therefore selecting a PFMCLK/addition
frequency 10 to 20 times greater than their maximum desired pulse frequency.
The PFMCLK/addition frequency sets a lower limit on the pulse frequency as well – an absolute
limit of one eight-millionth of the addition frequency. The default frequency of approximately 10
MHz can provide a useful range of about 1 Hz to 1 million Hz, and is suitable for a wide variety
of applications, especially with microstepping drives. For full or half step drives, the
PFMCLK/addition frequency will probably be set considerably lower – to the approximately 1.2
MHz or 600 kHz settings.
Gate1[i].HardwareClockCtrl controls the PFM clock frequency for all of the axis-interface
channels on the specified PMAC2-style IC, as well as other hardware clock signals. The input to
the clock control circuitry is a 39.3216 MHz signal; this can be divided by 1, 2, 4, 8, 16, 32, 64,
or 128 to create the PFMCLK signal. Therefore, the possible PFMCLK frequencies and the I-
variable values that set them are:
These variables also independently control the frequencies of the encoder sample clock SCLK,
plus the clocks for the serial D/A and A/D converters, DACCLK and ADCCLK, which are also
divided down in the same way from the same 39.3216 MHz signal. The SCLK frequency should
be the same as the PFMCLK frequency if the pulse train is fed into the encoder counters. The
above table shows the value of the I-variable for each possible frequency of the PFMCLCK,
assuming the SCLK frequency is set equal to the PFMCLK frequency, and the DACCLK and
ADCCLK frequencies are left at their default settings.
The minimum gap between pulses is equal to the pulse width, so the minimum pulse cycle period
is twice the pulse width set here. This sets a maximum frequency of the PFM output. If the
algorithm asks for a higher frequency, the IC will not produce the requested frequency, and
pulses will be skipped.
A value of 8 selects the internally generated PFM signal, and automatically selects the pulse-and-
direction decode for the signal. Note that no external cable is required to feed back the PFM
signal.
For an external feedback signal, the correct setting of Gate1[i].Chan[j].EncCtrl should cause the
encoder counter to count up in the direction you desire. It also must match the direction sense of
the output; a positive command value (for instance, with the out10 command) must cause the
counter to count up, and a negative command value (e.g. out-10) must cause the counter to
count down. You can invert the direction sense of the output with Gate1[i].Chan[j].PfmDirPol,
or by changing the wiring.
This PFM clock frequency puts an upper limit on the pulse frequency that can be generated –
with an absolute limit of 1/4 of the PFM clock frequency. Depending on the worst-case frequency
distortion that can be tolerated at high speeds, most people will limit their maximum pulse
frequency to 1/10 of the PFMCLK/addition frequency, therefore selecting a PFMCLK/addition
frequency 10 to 20 times greater than their maximum desired pulse frequency.
The PFMCLK/addition frequency sets a lower limit on the pulse frequency as well – an absolute
limit of one eight-millionth of the addition frequency. The default frequency of approximately 12
MHz can provide a useful range of about 1.5 Hz to 1 million Hz, and is suitable for a wide variety
of applications, especially with microstepping drives. For full or half step drives, the
PFMCLK/addition frequency will probably be set considerably lower – to the approximately 1.6
MHz or 800 kHz settings.
Gate3[i].PfmClockDiv specifies how many times an internal 100 MHz clock signal is divided by
2 to create the PFM clock signal. It has a range of 0 to 15, permitting a range of PFM clock
frequencies from 100 MHz down to 3 kHz.
The encoder input circuitry for the channel must be able to accept pulses at least as fast as they
are generated, so the encoder sample clock frequency must be at least as great as the PFM clock
frequency. This means that the element Gate3[i].EncClockDiv must be set to a value less than or
equal to that of Gate3[i].PfmClockDiv.
Unlike the PMAC2-style ICs, there is no minimum gap between pulses, as long as there is a gap.
If pulses are generated internally faster than the previous pulses end, the pulse output will be
continuously in the “on” state.
The second option is to feed back the pulse train for simulated feedback, but also to use an
encoder for confirmation periodically. In the PMAC3-style IC, this can all be done in a single
channel (it requires two channels on a PMAC2-style IC).
The third option is to use an actual encoder to close the servo loop. Because of the difficulty in
properly matching encoder counts to pulse outputs, this option is generally not recommended.
There are two possibilities to implement the first option. If Gate3[i].Chan[j].EncCtrl is set to 8,
the encoder decoding circuitry accepts and processes the internally generated PFM signal, and
automatically selects the pulse-and-direction decode mode. With Gate3[i].Chan[j].TimerMode
at the default value of 0, the pulse count, with 8 bits of timer-based fractional-count estimation, is
latched each servo cycle into the Gate3[i].Chan[j].ServoCapt register, where it can be used by
the encoder conversion table to pre-process the simulated motor feedback.
The second possibility is to set Gate3[i].Chan[j].TimerMode to 3. This feeds back the internally
generated PFM signal to the timer circuitry, using it as a counter. In this mode, the pulse count is
latched each servo cycle into the Gate3[i].Chan[j].TimerA register, in units of whole counts,
with no fractional-count estimation. Since the fractional-count estimation can cause unwanted
dithering, this mode is usually preferred for the first option.
To implement the second option, the pulse train must be fed back into the channel’s timer
circuitry with Gate3[i].Chan[j].TimerMode set to 3. The Gate3[i].Chan[j].TimerA register will
be used to close the simulated servo loop. The confirming encoder is fed into the channel’s
encoder inputs, and Gate3[i].Chan[j].EncCtrl is set to a value from 0 to 7 (probably 3 or 7) to
decode this signal.
Gate3[i].Chan[j].EncCtrl controls the source of the position feedback signal and how it is
decoded. Values of 0 to 7 set up for an external signal wired into PMAC, with the different values
in this range determining how the signal is decoded. One of these values should be used if you
have a real feedback sensor; typically 3 or 7 for “times-4” decode of a quadrature encoder signal.
The pulse count, without fractional-count estimation, is latched each servo cycle into the
Gate3[i].Chan[j].ServoCapt register, where it can be compared to the internal pulse count as
desired.
For the third option of an external feedback signal, the correct setting of
Gate3[i].Chan[j].EncCtrl should cause the encoder counter to count up in the direction you
desire. It also must match the direction sense of the output; a positive command value (for
instance, with the out10 command) must cause the counter to count up, and a negative
command value (e.g. out-10) must cause the counter to count down. You can invert the
direction sense of the output with Gate3[i].Chan[j].PfmDirPol, or by changing the wiring.
Note that these registers share an address with the Pwm[2] register (PMAC2-style IC) or the
Pwm[3] register (PMAC3-style IC) for the same channel, so when the value of Motor[x].pDac is
queried or backed up, the address will report as that of the Pwm[k] register.
When using a PMAC2-style IC, to get the count value with 1/T sub-count extension, you would
select “Type 3” conversion (software 1/T extension). This method has the advantage of being
automatically present in the table already, but it might lead to dithering at rest. In the IDE menu,
you just need to select the IC and channel numbers, and the IDE will make all of the settings to
provide an output scaled in counts (with fractional resolution).
If setting up the entry manually, the following settings should be made (with the appropriate
numerical indices):
EncTable[n].Type = 3
EncTable[n].pEnc = Gate1[i].Chan[j].ServoCapt.a
EncTable[n].pEnc1 = Gate1[i].Chan[j].TimeBetweenCts.a
EncTable[n].index3 = 0
EncTable[n].MaxDelta = 0
EncTable[n].ScaleFactor = 1/512
When using a PMAC2-style IC, to get the count value without 1/T sub-count extension, you
would select “Type 1” conversion (single-register read). This method has the advantage of not
being susceptible to dithering due to sub-count feedback values. In the IDE menu, you just need
to specify that the source register is the PhaseCapt register for the channel, to use 24 bits starting
at bit 8, with one output unit per count.
If setting up the entry manually, the following settings should be made (with the appropriate
numerical indices):
EncTable[n].Type = 1
EncTable[n].pEnc = Gate1[i].Chan[j].PhaseCapt.a
EncTable[n].index1 = 8
EncTable[n].index2 = 8
EncTable[n].index3 = 0
EncTable[n].MaxDelta = 0
EncTable[n].ScaleFactor = 1/256
When using a PMAC3-style IC, to get the value with 1/T sub-count extension (already done by
the IC), you would select “Type 1” conversion (single-register read). This method has the
advantage of being automatically present in the table already, but it might lead to dithering. In the
IDE menu, you just need to specify that the source register is the ServoCapt register for the
channel, with one output unit per 256 LSBs.
If setting up the entry manually, the following settings should be made (with the appropriate
numerical indices):
EncTable[n].Type = 1
EncTable[n].pEnc = Gate3[i].Chan[j].ServoCapt.a
EncTable[n].index1 = 0
EncTable[n].index2 = 0
EncTable[n].index3 = 0
EncTable[n].MaxDelta = 0
EncTable[n].ScaleFactor = 1/256
When using a PMAC3-style register, to get the pulse-count value from the “timer” register, which
does not have sub-count extension, you would select “Type 1” conversion (single-register read).
This method has the advantage of not being susceptible to dithering due to sub-count feedback
values. In the IDE menu, you just need to specify that the source register is the TimerA register
for the channel, to use 24 bits starting at bit 0, with one output unit per count.
If setting up the entry manually, the following settings should be made (with the appropriate
numerical indices):
EncTable[n].Type = 1
EncTable[n].pEnc = Gate3[i].Chan[j].TimerA.a
EncTable[n].index1 = 0
EncTable[n].index2 = 0
EncTable[n].index3 = 0
EncTable[n].MaxDelta = 0
EncTable[n].ScaleFactor = 1/256
Feedback Addresses: Motor[x].pEnc, Motor[x].pEnc2
Motor[x].pEnc specifies what register the motor reads for its outer (position) loop feedback. This
must be the result from an encoder conversion table entry, and will always take the form of
EncTable[n].a.
Motor[x].pEnc2 specifies what register the motor reads for its inner (velocity) loop feedback.
This also must be the result from an encoder conversion table entry, and will always take the form
of EncTable[n].a. In this mode, it will virtually always be the same register as is used for outer-
loop feedback.
Motor[x].Servo.Kp = 40
Motor[x].Servo.Kvfb = 0
Motor[x].Servo.Kvff = 40
Motor[x].Servo.Ki = 0.001
Deadband
Because it is easy to command end positions with fractional-count components and the system
can only resolve full count (pulse) values at rest, it is strongly advised to implement a count of
true deadband in the simulated servo loop to prevent dithering at rest. To do this, the following
settings should be made:
This deadband functionality is not present in the basic PID algorithm (Sys.PidCtrl). However, it
is present in the default Sys.ServoCtrl algorithm and all of the other built-in algorithms.
Note that these registers share an address with the Pwm[0] registers for the same channel, so
when the value of Motor[x].pDac is queried or backed up, the address will report as that of the
Pwm[0] register.
To use a network output register, Motor[x].pDac must specify the address of the appropriate
register for that network. Refer to instructions for the particular network for details.
In the case of a fast actuator with an analog feedback loop, a position feedback value is often not
available (and would require an ADC input on the Power PMAC in any case). However, with a
networked positioning drive, the actual position value is almost always reported back to the
central controller. In this case, it is strongly recommended to process this position value through
the encoder conversion table and read it for the motor through Motor[x].pEnc for both position
reporting and error checking purposes.
In a networked drive, the actual position is often reported back to the Power PMAC one or two
network cycles after the comparable command position is sent. At high velocities, especially with
high feedback resolution, this can lead to Power PMAC computing large numerical following-
error values (which do not exist in the drive). The value of Motor[x].FatalFeLimit may have to
be adjusted to avoid unnecessary failures.
For example, with a 1-millisecond network update period and a 2-cycle delay in reporting actual
position, a motor with a 17-bit encoder (131,072 “counts” per revolution) running at 3000 rpm
(50 rev/sec), Power PMAC would report a following error of:
This error would be present even if there were no actual following error in the network drive’s
own servo loop. In this case, Motor[x].FatalFeLimit would need to be increased substantially
from its default value of 2000. Of course, the drive should have its own error limit, and the user
should set this as tight as possible without causing nuisance trips.
Very few users will do these steps manually; almost all will use the automated procedures of the
IDE’s “motor setup” control, even for the setup of the first unit. The instructions in this section
are for the user who wants a full understanding of the Power PMAC algorithms and how they are
set up for a particular application.
The selection of an optimal phase clock frequency depends on several factors. The phase clock
frequency must be an integer multiple of the servo clock frequency. While it is possible to set the
phase clock frequency equal to the servo clock frequency, this typically delays the servo
command value from taking effect on the machine for too great a time, because the output does
not occur until the next phase update after the servo loop is closed. For this reason, in most
applications, the phase clock frequency is set to 2 to 4 times the servo clock frequency.
If a motor is being commutated by Power PMAC, but the current loop is being closed in the
amplifier, the key performance factor is ensuring that there are sufficient updates to complete a
cycle. There should be a minimum of 6 software phase updates per commutation cycle of the
motor. Note that this will only become a factor for very high-speed motors. The default phase
update frequency of 9 kHz can support a commutation frequency of 1.5 kHz, which corresponds
to 45,000 rpm on a 4-pole motor.
If the current loop is being closed by Power PMAC, proper selection of the phase update
frequency becomes important in more applications, as the bandwidth of the current loop can be
dependent on the update rate. While the default update rate of 9 kHz is sufficient for many
applications, a significant number of applications can benefit in performance from a higher
update frequency. Remember that the phase update frequency cannot be more than twice the
PWM output frequency for a motor (because only two decisions can be made in a PWM cycle:
the turn-on time, and the turn-off time).
The first steps in setting up the commutation are common whether or not Power PMAC is
performing the current loop closure (direct-PWM output mode) or not (sine-wave output mode).
These steps are described in this section. The next steps differ based on which mode is used;
these are described in the next two sections, only one of which is used for any given motor.
Finally, the last steps in the setup of commutation are again common to the two modes of
operation; these are described in the following section.
This unpacked software format can be used with the DSPGATE3 PMAC3-style ASIC (as in the
ACC-24E3 UMAC accessory) if the ASIC channel hardware is also set up in “unpacked” format.
The channel hardware will be in unpacked format if Gate3[i].Chan[j].PackOutData (bit 23 of
the channel’s output control register Gate3[i].Chan[j].OutCtrl) is set to 0, and
Gate3[i].Chan[j].PackInData (bit 22 of the channel’s input control register
Gate3[i].Chan[j].InCtrl) is set to 0. However, this mode is less efficient than “packed” format
(see below), and should generally only be used when more than 16 bits of command output
resolution are required, as with the optional 18-bit DAC outputs of the ACC-24E3.
The “packed” I/O format cannot be used with the PMAC2-style DSPGATE1 or DSPGATE2
ASICs, or when the control is done over the MACRO ring with any ASIC.
Only one of bit 0 and bit 2 of Motor[x].PhaseCtrl should be set to 1 at any given time. Bits 1
and 3 control other features related to use of the phase interrupt, and their settings are
independent of these two bits.
The element is usually set to the address of the desired register by using the “.a” suffix with the
register’s element name. For an incremental encoder phase capture register, the setting will take
the form of:
Motor[x].pPhaseEnc = Gaten[i].Chan[j].PhaseCapt.a
where n specifies the ASIC type (1, 2, or 3), i specifies the ASIC number in the system, and j
specifies the channel index (0 to 3).
For a serial encoder position register in a PMAC3-style DSPGATE3 IC, the setting will take the
form of:
Motor[x].pPhaseEnc = Gate3[i].Chan[j].SerialEncDataA.a
For a MACRO-node position-feedback register, the setting will take the form of:
Motor[x].pPhaseEnc = Gate2[i].Macro[k][0].a
for a PMAC2-style DSPGATE2 MACRO ASIC, where i specifies the ASIC number in the
system, and k specifies the node number in the ASIC (0 to 15); or:
Motor[x].pPhaseEnc = Gate3[i].MacroInA[k][0].a
Motor[x].pPhaseEnc = Gate3[i].MacroInB[k][0].a
for a PMAC3-style DSPGATE3 ASIC as in the ACC-5E3 MACRO card for UMAC racks. Note
that in this ASIC, there are separate input and output registers, so you must specify a “MacroIn”
register to read the value, and there are two banks of registers, A and B, so you must specify
which one is to be used. As with the PMAC2-style ASIC, i specifies the ASIC number in the
system, and k specifies the node number in the bank (0 to 15).
Power PMAC reads the specified 32-bit register without masking out any bits. If the position data
in the register can roll over, the most significant bit of the data must be in the highest bit (bit 31)
of the register. If there are a few undetermined low bits in the register, as with 8 low bits when
reading a 24-bit register from a PMAC2-style ASIC or MACRO register, their value will not have
any significance to the resulting calculations.
Some serial encoder data protocols separate single-turn and multi-turn data into separate registers.
If the MSB of the single-turn data does not appear on the data bus in bit 31, the data must be
processed before it can be used. In addition, there is the possibility that less significant bits in the
register do not reflect position data, and need to be eliminated. (However, remember that Power
PMAC only uses 11 bits of position data for its 2048-part commutation cycle.)
Each phase cycle, Power PMAC takes the 32-bit data from the register specified by
Motor[x].pPhaseEnc and shifts it right by the number of bits specified in saved setup element
Motor[x].PhaseEncRightShift. A n-bit right shift eliminates the low n bits of the starting value.
Then it takes this new value and shifts it left by the number of bits specified in saved setup
element Motor[x].PhaseEncLeftShift. An m-bit left shift eliminates the high m bits of the
starting value and fills in the low m bits of the result with zeros.
The following diagram shows how the shifting process would work for 20-bit commutation
position feedback that is found in bits 8 through 27 of the 32-bit bus. There is first a right of 8
bits, then a left-shift of 32 – 20 = 12 bits.
31 28 27 8 7 0
31 20 19 0
With both elements at their default value of 0, no net processing is done; the resulting value is the
same as the value read from the source register. If all that is desired is to eliminate some low bits,
the two shift lengths should be the same. If all that is desired is to move the data MSB to bit 31 of
the result, the right shift value should be 0, and the left shift value should be set to 31 minus the
bit number of the MSB in the source data.
Motor[x].PhasePosSf converts the data from the raw units of the 32-bit source register (after any
shifting operations) to units of 1/2048 of a commutation cycle. Note that the units of the full
source register will be different from those of the hardware circuit if the hardware does not use
the full range of the 32-bit register. For example, the 24-bit “phase capture” registers of PMAC2-
style ASICs used in ACC-24E2x UMAC boards occupy bits 8 to 31 of the 32-bit register, with bit
8 representing 1 count of the encoder. Bit 0 of the 32-bit register therefore represents 1/256 of a
count, so the source register should be considered to have units of 1/256 of a count.
In the PMAC3-style ASIC, the encoder “phase capture” registers are 32 bits wide, but for
quadrature encoders a single count is in bit 8 (the low 8 bits being fractional-count estimate), so
here also the source register should be considered to have units of 1/256 of a count. For sinusoidal
encoders, the “phase capture” registers have 12 bits of fractional resolution per quadrature count
(14 bits per line of the encoder), so the source register should be considered to have units of
1/4096 of a count (1/16,384 of a line).
For example, if there are 5000 quadrature-encoder counts per commutation cycle (as with 10,000
counts per revolution for a 4-pole motor) read through a PMAC2-style Servo IC, this scale factor
should be computed as:
It is often easier to let Power PMAC do the math for you, so the following command could be
used to set this element for Motor 1:
Motor[1].PhasePosSf = 2048/5000/256
Motor[x].pAdc controls which mode of operation is used. If it is set to 0, Power PMAC will not
close the current loops for the motor. Further setup for this mode is covered in the next section,
“Setting Up for Sine-Wave Output Control”.
If Motor[x].pAdc is set to a non-zero address value, Power PMAC will close the current loops
for the motor, with this value specifying the address of the first register for current feedback.
Setup for this mode is covered in the following section, “Setting Up for Direct PWM Control”.
Sine-wave output mode is typically used to control linearly modulated brushless motor amplifiers
in the highest-precision systems, often with sub-nanometer resolution. There are several reasons
for its use in this class of applications. First, it has the highest-resolution command outputs, with
16-bit or 18-bit DACs directly commanding motor phase currents. Second, the ability to use
linearly modulated amplifiers dramatically reduces electromagnetic interference (EMI) from the
amplifier compared to switching (PWM) amplifiers, reducing noise on the position feedback and
other measurements. Finally, the analog nature of the current-loop closure in the drives eliminates
sampling delays that can reduce control performance.
DC AC
IaVolts
Magnetization
IdCmd
+ Va Modu- Va
DAC PI
Current Direct Current
Ia lation
Command -
dq
to Phase A Current Loop
Balance Loop
r
1/s
+ +
PMAC Amplifier
Hardware Setup
For Power PMAC to operate a motor in the sine-wave commutation analog output mode, two
analog outputs are required for the motor. Typically, these are the Phase A and B DACs on the
same channel of a Servo IC.
PMAC2-Style IC Interface
PMAC2-style “DSPGATE1” Servo ICs are used on ACC-24E2A analog axis interface boards for
the UMAC rack-mounted control systems. These provide two DACs per servo channel.
Only the DACCLK signal is directly used with the sine-wave output, to control the frequency of
the serial data stream to the DACs. The default DAC clock frequency of 4.9152 MHz is suitable
for the DACs on all Delta Tau PMAC2-style hardware. Refer to the
Gate1[i].HardwareClockCtrl description for detailed information on setting these variables.
The sign of the Motor[x].PhaseOffset commutation phase angle parameter must match that of
Gate1[i].Chan[j].EncCtrl for your particular wiring; if it is wrong, you will lock into a position
rather than generate continuous torque. A test for determining this polarity match is given below.
Remember that if you change Gate1[i].Chan[j].EncCtrl on a working motor, you will have to
change Motor[x].PhaseOffset as well.
PMAC3-Style IC Interface
PMAC3-style “DSPGATE3” ICs are used on ACC-24E3 axis interface boards for the UMAC
rack-mounted control systems and in the Power PMAC Brick Controller. These can be ordered
with analog-amplifier interface boards with one or two DACs per servo channel. The
configuration with two DACs per servo channel must be ordered to perform sine-wave output
commutation.
If a PMAC2-style DSPGATE1 Servo IC is used for the direct interface, as in the ACC-24E2A,
the setting will be of the type:
Motor[x].pDac = Gate1[i].Chan[j].Dac[0].a
where i is the IC number (4 to 19), and j is the channel index number (0 to 3) in the IC. Note that
when the value of this element is queried, it will report back showing the “Pwm” register at the
same address instead of the “Dac” register.
If a PMAC2-style DSPGATE2 MACRO IC is used for the interface over the ring, as in the ACC-
5E, the setting will be of the type:
Motor[x].pDac = Gate2[i].Macro[k][0].a
where i is the IC number (0 to 15), and k is the MACRO node number (0 to 13) in the IC.
Register 0 of the node must be specified to conform to the MACRO standard for this mode.
If a PMAC3-style DSPGATE3 IC is used for the direct interface, as in the ACC-24E3, the setting
will be of the type:
Motor[x].pDac = Gate3[i].Chan[j].Dac[0].a
where i is the IC number (0 to 15), and j is the channel index number (0 to 3) in the IC. Note that
when the value of this element is queried, it will report back as the “Pwm” register at the same
address instead of the “Dac” register.
If a PMAC3-style DSPGATE3 IC is used for the interface over the MACRO ring, as in the ACC-
5E3, the setting will be of the type:
Motor[x].pDac = Gate3[i].MacroOutA[k][0].a
or
Motor[x].pDac = Gate3[i].MacroOutB[k][0].a
where i is the IC number (0 to 15), and k is the MACRO node number (0 to 13) in the IC.
Register 0 of the node must be specified to conform to the MACRO standard for this mode.
The test uses the offset variables Motor[x].IaBias and Motor[x].IbBias to force current direction
into the particular phases and drive the motor like a stepper motor. Based on the direction of
motion between the two “steps”, the proper sign for Motor[x].PhaseOffset can be determined.
The following example uses Motor 1, commanded from the terminal window:
If the phase position changed in the negative direction between these two steps,
Motor[x].PhaseOffset should be a positive value (683 for a 3-phase motor, 512 for a 2-phase
motor). If the phase position changed in the positive direction between these two steps,
Motor[x].PhaseOffset should be a negative value (-683 for a 3-phase motor, -512 for a 2-phase
motor).
If the servo loop computes an output value with a higher magnitude than Motor[x].MaxDac, the
magnitude of the output will be limited to that of Motor[x].MaxDac before it is used by the
commutation algorithm. Note that this is a clamping limit, not a multiplying gain term.
For details on how to calculate the appropriate value for MaxDac, refer to the Current Limits
section of the User’s Manual chapter Making Your Power PMAC Application Safe.
With sinewave-output commutation, Power PMAC is not measuring the actual current in the
motor and amplifier, so it uses the commanded current values in its calculations
Almost always it is the continuous current rating of the motor that is used for this limit.
Motor[x].I2tSet is calculated in a manner similar to Motor[x].MaxDac:
ContCurrentLimit
I 2tSet * 32,768
FullRangeCurrent
For details on how to calculate the appropriate value for I2tSet, refer to the Current Limits
section of the User’s Manual chapter Making Your Power PMAC Application Safe.
I 2tTrip MaxDac2 IdCmd 2 I 2tSet 2 * PermittedTime(sec)
The following diagram illustrates how I2T protection works using a sample time history.
2
I2 I norm
32768 2 1 .0 2
2 Saturation
MaxDac
MaxDac 2
32768 I2t Fault
Integrator
Charge-Up
2
I 2tSet
I 2tSet2
32768
Integrator
Discharge
time (sec)
For details on how to calculate the appropriate value for I2tTrip, refer to the Current Limits
section of the User’s Manual chapter Making Your Power PMAC Application Safe.
Introduction
In this mode, the current control loop is closed by using digital computation operating on
numerical values in registers rather than by using analog processing operating on voltage levels
with op-amps. The digital techniques bring many advantages: there is no need for pot tweaking or
personality modules; there is no drift over temperature or time; computer analysis and auto-tuning
are possible; gain values are easily stored for backup and copying onto other systems; and
adaptive techniques are possible.
When performing digital current loop closure on the Power PMAC, several hardware and
software features must be set up properly to utilize the digital current loop and direct PWM
outputs correctly. The following section details how to perform this setup manually. However,
typically, these steps are automated through the use of the motor setup screens of the IDE
program running on a PC and communicating with the Power PMAC.
Power PMAC permits digital closure of the motor current loops, mathematically creating phase
voltage commands from numerical registers representing commanded and actual current values.
These numerical phase voltage commands are converted to PWM format through digital
comparison to an up/down counter that creates a digital “saw tooth” waveform. The analog
current measurements must be converted to digital form with ADCs before the loop can be
closed.
The following diagram shows the principle of the PWM signal generation using PMAC2-style
Servo ICs, using the comparison of the PWM command value to the running up/down PWM
counter value. The principle in the PMAC3-style IC is similar.
New
Command
Loaded
Motor[x].PwmSf
Gate1[i]. PWM
PwmPeriod Command
or Value
16384 (Gate3)
-Gate1[i].
PWM
PwmPeriod
Up/Down
or
Counter
-16384 (Gate3)
-Motor[x].PwmSf
PWM
Top Signal
PwmDeadTime
PWM
Bottom Signal
By directly commanding the on-off states of the power transistors in this manner, Power PMAC
minimizes the calculation and transport delays in the feedback loops. This permits the use of
higher gains, which in turn permit greater stiffness, acceleration, and disturbance rejection. Also,
digital techniques permit the use of mathematical transformations of the current-loop data,
turning measured AC quantities into DC quantities for loop closure. This technique, explained in
the next section, significantly improves high-speed performance by minimizing high-frequency
problems.
Frames of Reference
A very important advantage of the digital current loop is its ability to close the current loops in
the “field frame”. To understand this advantage, some basic theoretical background is required.
In a motor, there are three frames of reference that are important. The first is the “stator frame”,
which is fixed on the non-moving part of the motor, called the stator. In a brushless motor, the
motor armature windings are on the stator, so they are fixed in the stator frame.
The second frame is the “rotor frame”, which is referenced to the mechanics of the moving part of
the motor, called the rotor. This frame, of course, rotates with respect to the stator. For linear
brushless motors, this is actually a translation, but because it is cyclic, we can easily think of it as
a rotation.
The third frame is the “field frame”, which is referenced to the magnetic field orientation of the
rotor. In a synchronous motor such as a permanent-magnet brushless motor, the field is fixed on
the rotor, so the field frame is the same as the rotor frame. In an asynchronous motor such as an
induction motor, the field “slips” with respect to the rotor, so the field frame and rotor frame are
separate.
A current vector in the stator that is parallel to the rotor field induces current in the rotor that
changes the magnetic field strength of the rotor (when the stator and rotor field are rotating
relative to each other). This component of the stator current is known as “direct” current. For an
induction motor, this is required to create a rotor magnetic field. For a permanent-magnet
brushless motor, the rotor magnets always produce a field, so direct current is not required,
although it can be used to modify the magnetic field strength. On Power PMAC, saved setup
element Motor[x].IdCmd determines the magnitude of the direct current.
As the motor is rotating, and/or the field is slipping, these current values, command and actual,
are AC quantities. Overall loop gain, and therefore system performance, is reduced at high
frequencies (high speeds). The back EMF phase voltage, which acts as a disturbance to the
current loop, is also an AC quantity. The current loop integral gain or lag filter, which is supposed
to overcome disturbances, falls well behind at high frequencies.
The direct and quadrature current values are DC quantities when the motor is moving in one
direction, even as the motor is rotating and the field is slipping. Therefore, the high-frequency
limitations of the servo loop are irrelevant. This provides significantly improved high-speed
performance from identical motors and power electronics.
Power PMAC has a PI (proportional-integral) digital current loop. There is only one set of gains,
which serves for both the direct current loop and the quadrature current loop. Tuning is best done
on the direct current loop, because this will generate no torque, and therefore no movement. The
current-loop auto-tuner in the PMAC Executive program uses the direct current loop to tune. This
is valid even for permanent-magnet brushless motors where no direct current will be used in the
actual application. It is important to remember that current loop performance is not load-
dependent, so the motor does not need to be attached to the load during the tuning process (for
position/velocity loop tuning, the load does need to be attached).
The following diagram shows the principle of the digital current loop closure in the field frame. It
should be compared to the comparable diagram for sinewave-output mode in the previous section.
DC AC
Hardware Setup
For Power PMAC to operate a motor in the direct PWM output mode, three PWM top-and-
bottom signal pairs, and two current measurements through ADCs, are required for the motor.
Using either the PMAC2-style or PMAC3-style Servo ICs, this requires PWM outputs on the A,
B, and C phases and ADC inputs on the A and B phases for the channel.
PMAC2-Style IC Interface
PMAC2-style “DSPGATE1” Servo ICs are used on ACC-24E2 PWM axis interface boards for
the UMAC rack-mounted control systems. These provide three PWM phase outputs and two
ADC inputs per servo channel.
117,964.8kHz
Gate1[i].PwmPeriod int 1
4 * PWMFreq (kHz)
(If the axes are being driven from a MACRO Station, MI900 on the Station controls the PWM
frequency of the first four channels on the Station according to the same equation; MI906 does
the same for the second four channels on the Station.)
The frequency should be set within the specified range for the drives. Too high a frequency can
lead to excessive drive heating due to switching losses; too low a frequency can lead to lack of
responsiveness, excess acoustic noise, possible physical vibration, and excessive motor heating
due to high current ripple.
The PWM frequency for any set of channels must have a definite relationship to the phase clock
frequency. If the channels are driven by the same Servo IC that is generating the phase and servo
clock, this relationship is set automatically. If the PWM frequency for channels on another Servo
IC is the same, this relationship also will automatically hold.
The PWM frequency on other channels does not have to be the same as the frequency of those
channels on the Servo IC generating the phase clock, but they do have to have a synchronous
relationship with the phase clock. The following relationship must hold for proper direct-PWM
operation of other channels:
PWMFreq
2* {Positive _ Integer}
PhaseFreq
If a Servo IC is used to generate the Phase and Servo clocks, Gate1[i].PwmPeriod for that IC
also sets the frequency of the “MaxPhase” clock to twice the PWM frequency for the channels on
that IC. The MaxPhase clock is the highest frequency at which Power PMAC’s phase update
tasks, which include phase commutation and digital current loop closure, can operate. Note that
any change to this IC’s Gate1[i].PwmPeriod automatically changes the Phase and Servo clock
frequencies for the controller. Gate1[i].PhaseServoDir for the IC generating the system Phase
and Servo clock signals must be set to 0 to tell it to use its internally generated signals and output
them; it must be set to 3 on other ICs to tell them to use externally generated signals for these
clocks.
(If the axes are being driven from a MACRO Station, MI903 on the Station controls the hardware
clock frequencies of the first four channels on the Station according to the same equations; MI907
does the same for the second four channels on the Station.)
Only the ADCCLK signal is directly used with the digital current loop, to control the frequency
of the serial data stream from the current-loop ADCs. The ADC clock frequency must be at least
100 times higher than the PWM frequency, but it must be within the capability of the serial
While most direct-PWM drives enforce a minimum deadtime, it is recommended to specify the
required deadtime here both for redundant protection of the drive, and to maintain the highest
possible resolution, as most drives use a lower-frequency clock signal in their deadtime circuitry.
Relying on the drive’s deadtime setting thus effectively reduces the resolution of the PWM
command signal.
(If the axes are being driven from a MACRO Station, MI904 on the Station controls the hardware
clock frequencies of the first four channels on the Station according to the same equations; MI908
does the same for the second four channels on the Station.)
The least-significant bit (LSB) of this element is a mode-control bit for formatting the serial data
from the ADCs. If this bit is 0, all bits in the returned serial data stream are considered part of the
numerical current value, with the first bit received ending up in the MSB of the current register in
the IC. No “header bits” can be accepted in this mode. Older direct-PWM amplifiers, such as
Delta Tau’s “Quad Amp”, operate in this mode. Gate1[i].AdcStrobe is usually set to $FFFFFE
for this mode of operation.
If the LSB is set to 1, the IC can accept up to 4 bits of “header” data on the data stream and “roll
it over” to the lowest bits of the ADC register where numerical data is not expected. For an ADC
with n header bits, the first (4 – n) bits of the strobe word should be set to 0 to delay the start of
the strobe (if there are no delays in the data response). The ADCs in Delta Tau’s “Geo” family of
direct-PWM drives have one bit of header data, and so require this last bit to be set.
Gate1[i].AdcStrobe is set to $1FFFFF for ADCs with one header bit, or to $3FFFFF if there is a
clock cycle delay in getting the data back.
(If the axes are being driven from a MACRO Station, MI940 on the Station controls the ADC
strobe word for the first four channels on the Station in this same way; MI941 does the same for
the second four channels on the Station.)
PMAC3-Style IC Interface
PMAC3-style “DSPGATE3” ICs are used on ACC-24E3 axis interface boards for the UMAC
rack-mounted control systems. These can be ordered with digital-amplifier “mezzanine” boards
with three or four PWM phases per servo channel. They are also used in the Power PMAC
“Brick” integrated controller/amplifier.
The frequency of the internally generated phase clock signal in a DSPGATE3 IC is determined
by the value of saved setup element Gate3[i].PhaseFreq. This is a floating-point value, in units
of Hertz (Hz). The default value is 9035.69, about 9 kHz. Even if an external phase clock signal is
used by the IC, the IC’s own internally generated frequency set by this element should be set as
close as possible to the frequency resulting from the external signal (as divided by
Gate3[i].PhaseClockDiv + 1), to keep the internal circuitry optimally locked to the external
signal.
If an external phase-clock signal is used, its frequency can be divided down by a factor of up to 4
before it is used internally, as determined by the setting of Gate3[i].PhaseClockDiv. This
element can take a value of 0 to 3, and the resulting division factor is one greater than this value.
It is rare that the value of this element is changed from its default value of 0 (divide by 1), but it
can be used to provide a wider range of PWM frequencies (which are derived from the internal
phase clock frequencies) across different ICs.
PwmFreqMult 1
f PWM f IntPhase
2
the variable value. The deadtime should not be set smaller than the recommended minimum for
the drive, or excessive drive heating could occur. Too large a deadtime value can cause
unresponsive performance. The default value of 15, which produces a deadtime of 0.8 µsec, is
suitable for lower-power drives, but may be too small for many higher-power drives, which may
require deadtimes of 1 to 3 µsec. For example, a 2 µsec deadtime requires a
Gate1[i].Chan[j].PwmDeadTime setting of about 38.
While most direct-PWM drives enforce a minimum deadtime, it is recommended to specify the
required deadtime here both for redundant protection of the drive, and to maintain the highest
possible resolution, as most drives use a lower-frequency clock signal in their deadtime circuitry.
Relying on the drive’s deadtime setting thus effectively reduces the resolution of the PWM
command signal.
100MHz
f AdcAmpClk AdcAmpClockDiv
2
The default value of 5 produces a 3.125 MHz frequency, suitable for most direct-PWM
amplifiers. In general, this should be set to the lowest value (producing the highest frequency)
that does not exceed the maximum frequency of the ADCs. The ADC clock frequency must be at
least 100 times as high as the PWM frequency in order to receive the complete ADC data in time
for the software interrupt. At the default 3.125 MHz ADC clock frequency, this limits the PWM
frequency to 31 kHz.
output information over the ring. In most configurations, these are the default settings for this
setup element.
If a PMAC2-style DSPGATE1 Servo IC is used for the direct interface, as in the ACC-24E2, the
setting will be of the type:
Motor[x].pDac=Gate1[i].Chan[j].Pwm[0].a
where i is the IC number (4 to 19), and j is the channel index number (0 to 3) in the IC.
If a PMAC2-style DSPGATE2 MACRO IC is used for the interface over the ring, as in the ACC-
5E, the setting will be of the type:
Motor[x].pDac=Gate2[i].Macro[k][0].a
where i is the IC number (0 to 15), and k is the MACRO node number (0 to 13) in the IC.
Register 0 for the specified node must be used to conform to the MACRO standard for this node.
If a PMAC3-style DSPGATE3 IC is used for the direct interface, as in the ACC-24E3, the setting
will be of the type:
Motor[x].pDac=Gate3[i].Chan[j].Pwm[0].a
where i is the IC number (0 to 15), and j is the channel index number (0 to 3) in the IC.
If a PMAC3-style DSPGATE3 IC is used for the interface over the MACRO ring, as in the ACC-
5E3, the setting will be of the type:
Motor[x].pDac=Gate3[i].MacroOutA[k][0].a
or
Motor[x].pDac=Gate3[i].MacroOutB[k][0].a
where i is the IC number (0 to 15) and k is the MACRO node number (0 to 13) in the bank.
Register 0 for the specified node must be used to conform to the MACRO standard for this node.
The address specified is that of the first register (Phase A); the next register is automatically read
for Phase B current information. (If Motor[x].PhaseCtrl bit 0 is set to 1 to specify the use of
“packed” format, only a single 32-bit read is performed with Phase A and B feedback expected in
the high and low 16 bits. This format is only supported in direct interface with the PMAC3-style
DSPGATE3 ASIC. It is not supported in PMAC2-style ASICs, or in the MACRO interface in a
PMAC3-style ASIC.)
If a PMAC2-style DSPGATE1 Servo IC is used for the direct interface, as in the ACC-24E2, the
setting will be of the type:
Motor[x].pAdc=Gate1[i].Chan[j].Adc[0].a
where i is the IC number (4 to 19), and j is the channel index number (0 to 3) in the IC.
If a PMAC2-style DSPGATE2 MACRO IC is used for the interface over the ring, as in the ACC-
5E, the setting will be of the type:
Motor[x].pAdc=Gate2[i].Macro[k][1].a
where i is the IC number (0 to 15), and k is the MACRO node number (0 to 13) in the IC.
Register 1 for the specified node must be used to conform to the MACRO standard for this node.
If a PMAC3-style DSPGATE3 IC is used for the direct interface, as in the ACC-24E3, the setting
will be of the type:
Motor[x].pAdc=Gate3[i].Chan[j].AdcAmp[0].a
where i is the IC number (0 to 15), and j is the channel index number (0 to 3) in the IC.
If a PMAC3-style DSPGATE3 IC is used for the interface over the MACRO ring, as in the ACC-
5E3, the setting will be of the type:
Motor[x].pAdc=Gate3[i].MacroInA[k][1].a
or
Motor[x].pAdc=Gate3[i].MacroInB[k][1].a
where i is the IC number (0 to 15) and k is the MACRO node number (0 to 13) in the bank.
Register 1 for the specified node must be used to conform to the MACRO standard for this node.
If a PMAC2-style DSPGATE1 ASIC is being used for the output, the counter moves between
Gate1[i].PwmPeriod + 1 and -Gate1[i].PwmPeriod - 2. To utilize the full dynamic range of the
PWM circuitry well, Motor[x].PwmSf should be set slightly greater than Gate1[i].PwmPeriod.
Typically a value 10% greater is used, permitting full-on conditions at maximum command
values over about 1/6 of the commutation cycle. However, some amplifiers require that the PWM
signals never reach the full-on or full-off condition in order to keep a charge-pump circuit active.
For these amplifiers, Motor[x].PwmSf is typically set to 95% of Gate1[i]. PwmPeriod. Consult
the amplifier manual for details.
If a PMAC3-style DSPGATE3 ASIC is being used for the output, the counter moves between +/-
16,384, regardless of the PWM frequency. To utilize the full dynamic range of the PWM circuitry
well, Motor[x].PwmSf should be set slightly greater than 16,384. Typically a value 10% greater
is used, permitting full-on conditions at maximum command values over about 1/6 of the
commutation cycle. However, some amplifiers require that the PWM signals never reach the full-
on or full-off condition in order to keep a charge-pump circuit active. For these amplifiers,
Motor[x].PwmSf is typically set to 95% of 16,384. Consult the amplifier manual for details.
Motor[x].PwmSf effectively acts as a voltage limit for the motor. If the amplifier is oversized for
the motor, exceeding the maximum permitted voltage for the motor, Motor[x].PwmSf should be
set proportionately less than the full useful range to limit the maximum possible voltage for the
motor. Since Motor[x].PwmSf is a gain, if it is changed, the current loop must be tuned or
retuned afterwards.
In most other modes, a value of 32,767 (215-1) for Motor[x].MaxDac for this parameter is full
range. In 3-phase direct-PWM mode, however, the value of 32,767 corresponds to the full-range
readings of the Phase A and Phase B A/D converters. The mathematics involved in the
transformation from the phase currents to the direct and quadrature currents effectively multiplies
the phase values by cos(30°), or 0.866. This means that the Motor[x].MaxDac value
corresponding to the full-range ADC reading is 32,767 * 0.866 = 28,377. Therefore,
Motor[x].MaxDac should never be set to a value greater than 28,377 in 3-phase direct-PWM
mode.
The amplifier manual should specify the level of current that provides full-range feedback from
the ADCs. The user should then take the instantaneous current limit for the drive or for the motor,
whichever is less, and set Motor[x].MaxDac according to the following relationship:
InstCurrentLimit
MaxDac min 28,377, * 28,377
FullRangeCurrent
If the drive outputs analog current readings and the ADCs are on the interface board, the full-
range current value must be calculated from the volts-per-amp gain of the current sensing in the
drive and the full-range voltage into the interface board.
If a non-zero value of Motor[x].IdCmd magnetization current will be used, for induction motor
control or for field weakening of a permanent-magnet brushless motor, then Motor[x].MaxDac
should be replaced in the above equation by MaxDac 2 IdCmd 2 .
For details on how to calculate the appropriate value for MaxDac, refer to the Current Limits
section of the User’s Manual chapter Making Your Power PMAC Application Safe.
Almost always it is the continuous current rating of the motor that is used for this limit.
Motor[x].I2tSet is calculated in a manner similar to Motor[x].MaxDac:
ContCurrentLimit
I 2tSet * 28,377
FullRangeC urrent
Note that in direct-PWM mode, the current values for the I2T calculations are the measured
(actual) current values, instead of commanded current as in other operational modes. With 3-
phase direct PWM control, as with most brushless servo motors and induction motors, the full-
range current values are 32,767 * cos(30°), or 28,377, as used in the above equation. For 2-phase
control, as with stepper motors, the value of 32,767 can be used instead.
For details on how to calculate the appropriate value for I2tSet, refer to the Current Limits
section of the User’s Manual chapter Making Your Power PMAC Application Safe.
I 2tTrip MaxDac2 IdCmd 2 I 2tSet 2 * PermittedTime(sec)
The following diagram illustrates how I2T protection works in 3-phase direct-PWM mode using a
sample time history.
2
I2 I norm
28377 2 0.866 2
2 Saturation
MaxDac
MaxDac 2
32768 I2t Fault
Integrator
Charge-Up
2
I 2tSet
I 2tSet 2
32768
Integrator
Discharge
time (sec)
For details on how to calculate the appropriate value for I2tTrip, refer to the Current Limits
section of the User’s Manual chapter Making Your Power PMAC Application Safe.
! properly for your system; otherwise the current loop will have
unstable positive feedback and want to saturate. This could
cause damage to the motor, the drive, or both, if overcurrent
Caution shutdown features do not work properly.
If the phase current sensors and ADCs in the amplifier are set up so that a positive PWM voltage
command for a phase yields a negative current measurement value, Motor[x].PhaseOffset must
be set to a value greater than 0: 683 for a 3-phase motor, or 512 for a 2-phase or DC brush motor.
If these are set up so that a positive PWM voltage command yields a positive current
measurement value, Motor[x].PhaseOffset must be set to a value less than 0: -683 for a 3-phase
motor, or -512 for a 2-phase or DC brush motor.
Note that for commutation with digital current loops, the proper setting of Motor[x].PhaseOffset
is unrelated to the polarity of the encoder counter. This is different from commutation without
digital current loops in the Power PMAC (“sine-wave” control), in which the polarity of
Motor[x].PhaseOffset (less than or greater than 0) must match the encoder counter polarity.
With the digital current loop, the polarity of the encoder counter must be set for proper servo
operation; with the analog current loop, once the Motor[x].PhaseOffset polarity match has been
made for commutation, the servo loop polarity match is guaranteed.
IiGain
1-z-1
Back Path
Integral Ipbgain Proportional
Measured
Gain
Gain Current
(Id or Iq)
However, with some basic knowledge of motor and amplifier parameters, it is possible to
calculate the current-loop gains directly. It is strongly advised that these computed gains be
checked against the values determined through the auto-tuning or interactive tuning of the IDE.
Isat Maximum (saturated) current reading from phase-current A/D converter (Amps).
This is a DC value, not an RMS AC value.
This value can be derived from the current-sensor gain Kc (volts/amp) and the maximum
voltage in volts that the A/D-converter can read Vcmax: Isat= Vcmax/Kc.
Next, the following performance specifications for the current loop are required:
Now we can compute the proportional current-loop gain Kcp and the integral current-loop gain Kci
according to the formulas:
2 L R
K cp I sat
n d /q d /q
V DC
TP n2 Ld / q
K ci I sat
VDC
Finally, to compute the setup elements to represent these gains, we use the following formulas for
PMAC2-style ICs:
K cp Gate1[i].PwmPeriod
IpfGain IpbGain
Motor[ x].PwmSf
K ci Gate1[i ].PwmPeriod
IiGain
Motor[ x].PwmSf
K cp 16384
IpfGain IpbGain
Motor [ x].PwmSf
K ci 16384
IiGain
Motor [ x].PwmSf
Note that the proportional gain term is expressed as the sum of two I-variables. IpfGain is the
“forward-path” proportional gain term, directly responding to changes in the command values;
IpbGain is the “back-path” proportional gain term, directly responding only to the actual current
values. When high position feedback resolution is used in the position/velocity loop, the
quantization noise in the current command is low, and it is better to use IpfGain. When low
position-feedback resolution is used, it is better to use IpbGain. Tradeoffs between
responsiveness and smoothness can be obtained by varying the amount of the proportional gain
term allocated to each of these two variables.
Example
The motor has a phase-to-phase resistance of 3.0 ohms, and a phase-to-phase-inductance of 39
millihenries. The amplifier phase-current sensors provide their maximum 5-volt output for 17.5
amps of current, and the ADCs provide their full-range value for an input of 5 volts. The
amplifier operates from an AC supply voltage of 120Vrms. The Power PMAC is operating at the
default phase update frequency of 9.03 kHz using a PMAC2-style IC. A current-loop natural
frequency of 200 Hz with a damping ratio of 0.7 is desired. The Gate1[i].PwmPeriod variable is
at the default value of 6527, and Motor[x].PwmSf is at the recommended value of 7181 (10%
greater).
Kcp = Isat [(2 n Ld/q) – Rd/q] / VDC = 17.5 [(2 * 0.7 * 1256 * 0.0225)- 1.732] / 170 = 3.89
Kci = Isat Tp n2 Ld/q / VDC = 17.5 * 0.000110 * 12562 *0.0225 / 170 = 0.401
In general, these bias terms should be set to the negative of the average raw measured value for
the phase when no current should be flowing in the phase. To determine the values for these, a set
of measurements of the actual phase current numerical values when the motor phase currents are
zero should be taken. Multiple measurements are strongly recommended as there is inevitably
noise in the measurements, and the averaging process will remove the noise.
The raw measured phase current values can be read in the ASIC ADC registers:
If the motor’s IaBias and IbBias terms are 0, these values are copied directly into
Motor[x].IaMeas and Motor[x].IbMeas, but if these bias terms are non-zero, the bias values are
added into these motor registers.
This auto-nulling is performed on motor enabling commands such as J/ (jog stop) and $ (phase
finding – can also be started by setting Motor[x].PhaseFindingStep to 1), and on coordinate
system enabling commands such as enable. If Motor[x].PhaseFindingStep is set to 8, the
auto-nulling is performed without enabling the motor afterwards.
In the first case, the bias measured is in the feedback circuits only (usually the dominant error
source). In the second case, the bias measured is a combination of the feedback circuits and the
voltage-command circuits. Typically, the bias in the feedback circuits is much larger than that in
the voltage-command circuits.
The motor should fundamentally be still during this process, so there is no back-EMF to create
current values. If Power PMAC detects any significant velocity during the auto-nulling
(Motor[x].FltrVel > 0.1% of Motor[x].MaxSpeed), the auto-nulling process will fail.
Motor[x].PwmDbComp specifies the size of the compensation added to the PWM phase voltage
command values when it is applied, in units of the PWM command values (which have a full
range of +/-Gate1[i].PwmPeriod for a PMAC2-style ASIC, and of +/-16,384 for a PMAC3-style
ASIC). When the magnitude of commanded current for a phase is greater than
Motor[x].PwmDbI, twice the value of PwmDbComp is added to the phase voltage command in
the same direction sense as the sign of the current value, and the value of PwmDbComp is added
to the other two phases in the opposite direction sense. These calculations are done for all three
phases each cycle, with the effect of increasing the voltage difference across the phases to
overcome the deadband effect.
Typically, these parameters are set interactively with the goal of producing AC phase current
waveforms with minimal zero-crossing distortion. This can be done on the analog signals with an
oscilloscope with current probes, or using the IDE’s “scope” plotting feature from the digitized
current values Motor[x].IaMeas and Motor[x].IbMeas.
To disable the current-loop closure, set bit 3 (value 8) of Motor[x].PhaseMode to 1. With this
control bit set, actual current measurements are still made, and these measurements can be used
for I2T integrated current protection, but these measured values are not compared to desired
values in the “forward path” to drive closed current loops.
In this voltage mode, the desired current values Motor[x].IqCmd (from the position/velocity
loop) and Motor[x].IdCmd are simply multiplied by the gain term Motor[x].IpfGain, acting
simply as a scaling factor, to get the quadrature and direct voltage values. (Motor[x].IiGain is
not used. Motor[x].IpbGain can be used in the “back path”, but seldom is in this mode, so
usually it will be set to 0.0.) These field-coordinate voltage values are then converted to phase
voltage values in the same way as when current loops are closed.
The following diagram shows the topology of the current loops with and without the forward loop
enabled.
Generally, Motor[x].IpfGain will be set to 1.0 to make this section a “pass-through”. Lower
values for IpfGain will limit the maximum output command voltage and therefore maximum
motor velocity. Higher values can lead to output saturation.
In this mode of operation, servo loop proportional gain Motor[x].Servo.Kp, current-loop forward
proportional gain Motor[x].IpfGain, and output scale factor Motor[x].PwmSf are all loop gain
terms in series. However, there can be saturation on the output of the servo loop, as set by
Motor[x].MaxDac, and on the output from the commutation algorithm.
When no forward-path current loop is closed, the current waveforms can significantly lag behind
the voltage waveforms at high frequencies, significantly reducing the torque capabilities at high
speeds unless compensated. Motor[x].AdvGain can be used to compensate for this lag, restoring
high-speed capabilities.
This voltage-mode direct-PWM control mode is new in V2.1 firmware, released 1st quarter 2016.
In older firmware versions, this type of control could be created by setting Motor[x].AdcMask to
$0, forcing the measured current values to 0, but this disabled I2T integrated current monitoring
for the motor.
The following block diagram shows how the standard direct PWM commutation and current loop
action is modified for control of DC brush motors:
This section summarizes how the saved setup elements must be set for this particular control
mode; many of these elements are discussed in more detail elsewhere. These instructions assume:
The brush motor’s stator magnetic field comes from permanent magnets or a wound field
excited by a separate means; the field is not controlled by one of the phases of this
channel.
The two leads of the brush motor’s armature are connected to amplifier phases (half-
bridges) that are driven by the A and C-phase PWM commands from the Power PMAC
servo channel. (Often these amplifier phases are labeled U and W.) The amplifier may
have an unused half-bridge (often labeled V) driven by the channel’s B-phase, but this
does not need to be present.
Motor[x].IdCmd should be set to the default value of 0.0 to command zero direct (field)
current.
Motor[x].DtOverRotorTc should be set to the default value of 0.0 for zero “slip” in the
commutation angle calculations.
It can also be set to 1, which causes the position loop to be closed automatically when the
phase referencing is done, but does not do this referencing immediately on power-
up/reset, instead waiting for a command (the on-line $ command or buffered
Motor[x].PhaseFindingStep=1 command).
the IDE’s automatic and interactive tuning routines inject “direct” current to monitor the
response. To use these tools with brush motors, manually set Motor[x].PhaseTableBias
to 512 (90°e) so that direct current corresponds to A-phase current. Remember to set
Motor[x].PhaseTableBias back to 0 before actual operation.
Phase current offset term Motor[x].IaBias and can be set just as for brushless motors to
compensate for offsets in the current value. Motor[x].IbBias is not used in this mode of
control.
Motor[x].PhasePosSf must be set to 0.0 so no matter what value is read as the ongoing
commutation position feedback, the commutation angle will not change.
Motor[x].PhaseOffset must be set to 512 (+90°e) if voltage and current polarities are
opposite (a positive voltage command in a phase produces negative current reading), or to
-512 (-90°e) if voltage and current polarities are the same. This puts the A and C phases
180° apart, so they will get “opposite” phase commands. This setting is the same as for 2-
phase brushless motors, but different from 3-phase motors.
Motor[x].PhaseMode should be set to 3. This setting disables the integrator for the
direct current loop, so offset and noise on the unused B-phase current sensor cannot
integrate into a substantial value. It also disables the algorithms for “third-harmonic
injection”, which are not needed for brush motors. Note that for the IDE’s current-loop
tuning, which uses the direct-current loop, PhaseMode should be set to 1 so that the
integrator is enabled and the integral gain term can be set correctly. PhaseMode must be
returned to a value of 3 after the tuning tests are completed.
The following settings do not matter for direct-PWM control of brushless motors:
Motor[x].pPhaseEnc does not matter, because whatever register is read for ongoing
commutation feedback, the change in angle is always forced to zero. It is fine to leave
this at the default of Gaten[i].Chan[j].PhaseCapt.a.
To use the IDE’s current-loop tuning controls, whether automatic or interactive tuning, the
motor’s “phase angle”, fixed at 0° for normal operation, must be set to 90° for the tuning. This is
done by manually setting non-saved setup element Motor[x].PhaseTableBias to 512 (one-
quarter of a commutation cycle) before starting the tuning. With this bias, the direct current
command is mapped to the Phase A current value.
In addition, bit 1 (value 2) of saved setup element Motor[x].PhaseMode must be set to 0 for the
test to enable the integrator for the direct current loop. This changes the value of PhaseMode
from 3 to 1. Note that a direct current command will generate torque and possible movement
during the test.
Direct microstepping with direct PWM control is commonly used on the Power Brick LV
controller, which has built-in amplifiers capable of driving both 2-phase and 3-phase motors.
Product-specific instructions for direct microstepping with the Power Brick LV are included in its
User’s Manual.
When performing direct microstepping commutation with current-loop closure, Power PMAC
calculates the voltage output commands for each phase, represented by PWM signals.
This technique is most widely used to control motors that are marketed as “stepper motors”, but
the principle of control for these motors – open-loop or closed-loop – is the same as for motors
that are marketed as “brushless servo motors”, so the technique can be used for either type of
motor.
Also note that “stepper motors” overwhelmingly (but not universally) are 2-phase motors with
electrically independent phases, whereas “brushless servo motors” are overwhelmingly (but not
universally) 3-phase motors with electrically connected (Y or delta) phases. This direct-
microstepping/direct-PWM technique can be used with either 2-phase or 3-phase motors,
although a couple of setup elements must be made differently, and there must be different power-
stage topologies for the two types of motors.
The intent of this algorithm is to be able to provide position control of stepper motors without the
use of any position sensor such as a shaft encoder. If there is a shaft encoder on the motor,
superior control can be established by treating the motor as a (high pole-count) brushless servo
motor with closed-loop commutation and servo algorithms.
Principle of Operation
This direct microstepping technique works by numerically integrating the servo loop’s command
output value both for its own feedback and to advance the phase angle for the commutation
algorithm. This permits both algorithms to operate without an actual position sensor on the motor,
so open-loop control can be achieved. Both values are driven very directly from the commanded
trajectory.
The following diagram shows the principle of operation for this technique, showing the typical 2-
phase motor configuration.
IaVolts
IdCmd IdVolts U
PI
+ dq W A
- to Amp
IdMeas IqVolts ab V
Current Loops X
IbVolts
DesPos IqCmd IaMeas
PID PI
+ + ab
- - to B
ActPos Simulated Servo IqMeas dq IbMeas
Loop
PhasePos
“Slip”
(0)
Integration + +
Open-Loop Commutation
ECT
Processing
Unlike in closed-loop servo control, the motor torque comes mostly from the “direct” current
command value IdCmd, which is generally held constant in magnitude. In direct microstepping,
the servo-loop output “quadrature” current command value IqCmd serves as a velocity, not a
torque command; its main purpose is to rotate the commanded rotor angle, and it provides only a
minimal contribution to the motor torque.
This section summarizes how the saved setup elements must be set for this particular control
mode; these elements are discussed in more detail elsewhere.
Speed Limitations
The direct microstepping technique has a maximum speed of 1024 microsteps per servo cycle.
For a standard 100-pole (1.8°) stepper motor with a 5 kHz update rate, this yields a 3000-rpm
maximum speed. There is also a limit of 512 microsteps (1 full step) per phase cycle. For the
same motor with a 10 kHz phase update rate, there is also a 3000-rpm maximum speed. Few
users will operate stepper motors at these speeds, but these limits should be calculated and update
rates set high enough that desired speeds can be reached.
Hardware Setup
The hardware setup of the Servo ICs for direct microstepping with direct PWM is the same as for
closed-loop servo control with direct PWM. Instructions for setting the IC configuration elements
for direct PWM control are given earlier in this chapter. Tuning of the digital current loops for
direct microstepping is also the same as for closed-loop servo control.
EncTable[n].index1 should be set to 5 to shift the intermediate data left 5 bits so it rolls
over properly.
Motor[x].PosSf for the outer servo loop, and Motor[x].Pos2Sf for the inner loop should
be set to 1.0 to scale the motor units as “microsteps”. (Other settings are possible, but
these require rescaling many other servo and commutation elements as well.) With this
scaling, there are 2048 motor units per commutation cycle (pole pair). For a common
100-pole (1.8° full-step) stepper motor, this provides 102,400 motor units per revolution.
The servo-loop proportional gain term Motor[x].Servo.Kp should be set to a value of 1.0
to create a high-performance simulated loop.
The servo-loop velocity feedback gain terms Motor[x].Servo.Kvfb and Kvifb should be
set to 0.0 because no damping action is required in this simulated loop.
The servo-loop integral gain term Motor[x].Servo.Ki should be set to 0.0 because there
are no steady-state errors to overcome in this simulated loop.
The servo-loop velocity feedforward gain term Motor[x].Servo.Kvff should be set to 1.0
to eliminate velocity-dependent tracking errors. Motor[x].Servo.Kviff should be set to
0.0.
Other servo-loop gain terms should be set to 0.0, as their action is not needed in this
simple simulated loop.
For a 2-phase motor (which most stepper motors are), Motor[x].PhaseOffset should be
set to 512 if voltage and current senses are opposite for the phases (true for Delta Tau
drives), or to -512 if voltage and current senses are the same for the phases. For a 3-phase
motor (which most brushless servo motors are), Motor[x].PhaseOffset should be set to
683 if voltage and current senses are opposite for the phases, or to -683 if voltage and
current senses are the same for the phases. Note that Delta Tau’s “LV” amplifiers are
software-configurable to drive 2-phase or 3-phase motors; refer to those manuals for the
required settings for your configuration.
Motor[x].DtOverRotorTc should be set to its default value of 0.0 so that slip is not a
function of the rotor time constant.
Phase current offset terms Motor[x].IaBias and Motor[x].IbBias can be set just as for
closed-loop control of brushless motors to compensate for offsets in the current values.
Motor[x].CurrentNullPeriod can be used to set these bias terms automatically each
time the motor is enabled.
The following settings are special to direct-microstepping/direct-PWM control, and will likely be
different from closed-loop control of brushless motors:
The setting of Motor[x].AbsPhasePosFormat does not matter, because the value read,
however, formatted, will always be scaled and offset to a zero result. It is fine to leave it
at its default value of $0.
Motor[x].PhasePosSf must be set to 0.0 so no matter what value is read as the ongoing
commutation position feedback, the resulting feedback phase position will not change.
This will permit the entire phase angle to come from the simulated slip due to the
integrated command velocity.
The setting of Motor[x].pPhaseEnc does not matter, because whatever register is read
for ongoing commutation feedback, the resulting change in angle is always forced to
zero. It is fine to leave this at the default of Gaten[i].Chan[j].PhaseCapt.a.
Motor[x].SlipGain must be set to 1 / (Phase cycles per servo cycle). If saved setup
element Sys.PhaseOverServoPeriod has been set correctly, Motor[x].SlipGain can just
be set to the value of Sys.PhaseOverServoPeriod. Each phase cycle, this value is
multiplied by the IqCmd output value from the simulated servo loop and the
commutation angle is advanced by the resulting product. This value properly matches the
servo loop scaling so that one microstep advances the commutation angle one entry in the
commutation table. At the default setting of 4 phase cycles per servo cycle, SlipGain
should be set to 0.25.
Motor[x].IdCmd must be set to specify the desired current magnitude in the motor. It is
scaled such that 32,768 represents the maximum current that can be read by the A/D
converters in the drive. Remember that this amount of current is used constantly, so any
value used more than momentarily must be within the steady-state current limit of both
the drive and the motor. It is possible to change the value of IdCmd at any time; many
users will lower the value at rest to reduce heating when higher currents are not needed.
After power-on/reset, the motor is initialized with a phase referencing process. This can be done
using the on-line motor-specific $ command, by setting Motor[x].PhaseFindingStep to 1 in a
PLC program, or automatically if bit 1 (value 2) of saved setup element
Motor[x].PowerOnMode is set to 1. If bit 0 (value 1) of PowerOnMode is set to 1, the motor is
automatically enabled with the simulated loop closed at the end of the phase referencing. When
the loop is closed, the motor will be commanded to the zero point in the commutation cycle.
Limiting Parameters
Many users will want to set a velocity limit that provides a safe and predictable shutdown if a
higher commanded velocity is requested. The easiest way of doing this is to set the value of
Motor[x].MaxDac, which acts as the velocity limit into the direct microstepping algorithm.
With servo gains of 1.0 as suggested above, the units of Motor[x].MaxDac are effectively motor
units per servo cycle. To calculate the parameter given a maximum RPM value, the following
equation can be used:
MaxRPM PolesPerRev
Motor [ x].MaxDac * * 2048 * Sys.ServoPeriod
60,000 2
For example, to set a maximum speed of 1500 rpm on a 100-pole motor at a 5 kHz servo update:
1500 100
Motor [ x].MaxDac * * 2048 * 0.2 512
60,000 2
If the magnitude of the commanded velocity exceeds this amount, the following error in the
simulated servo loop will quickly grow, and will trip when it exceeds Motor[x].FatalFeLimit.
Because the current magnitude in direct microstepping is essentially constant for long periods,
Power PMAC’s “I2T” integrated current limiting is not nearly as important in direct
microstepping as it is in closed-loop applications. Of course, the value of Motor[x].IdCmd used
must be lower than the continuous current rating of the motor and amplifier. It can still be
valuable to set the I2T parameters so that later changes to the value of Motor[x].IdCmd cannot
damage the motor or amplifier.
Fundamentally, there are two methods for establishing the phase reference. The first is a “phasing
search”, in which some kind of excitation signal is applied to the motor, and the physical response
of the motor is sensed in order to determine the phase angle. This does not require a sensor that is
absolute over a full commutation cycle.
The second method is an “absolute phasing read”, in which a sensor that is absolute (non-
repeating) over a full commutation cycle is read and the position value is used to set the
commutation phase angle. Of course, this cannot be done with an incremental sensor such as a
digital quadrature encoder or an analog sinusoidal encoder (although some of these devices have
additional “tracks” that support these absolute phasing reads).
However, even if there is a sensor that is absolute over at least a full commutation cycle and so
can be used for an absolute phasing read, a phasing search move must be done initially to
determine how the sensor is aligned relative to the motor’s commutation cycle. The section
immediately below on phasing search moves, particularly the “stepper motor” phasing search, is
therefore relevant for these applications as well.
Power PMAC will not permit closing the loop on a synchronous (zero-slip) motor commutated by
the controller until a successful phasing reference has been performed. The read-only status bit
Motor[x].PhaseFound is automatically set to 0 at power-on/reset and at the beginning of any
phasing-search move or absolute phase position read. It is only set to 1 if the Power PMAC
judges the move or read to be successful. The servo loop cannot be closed on the motor unless
this bit is 1.
Power PMAC presently supports two built-in types of phasing search moves. These moves are
specified and controlled by the settings of saved setup elements Motor[x].PhaseFindingTime
and Motor[x].PhaseFindingDac. A value for Motor[x].PhaseFindingTime that is greater than 0
specifies that a phasing search move is to be used for the phasing reference instead of an absolute
position read.
Bit 0 (value 1) of Motor[x].PowerOnMode specifies the state of the motor after a successful
phasing reference. If it is set to 0, the motor is “killed” (open-loop, zero output, amplifier
disabled). If it is set to 1, the motor is enabled in a closed-loop zero-velocity state. In an actual
application, a value of 1 is almost always desired. After an unsuccessful phasing reference, the
motor is always killed, and the Power PMAC will not permit subsequent closed-loop enabling of
the motor.
At the start of a stepper-motor phasing search, Power PMAC ramps up the current to half of the
amount specified in PhaseFindingDac over the time interval specified by PhaseFindingTime to
force the motor to +90° of the commutation cycle (+512 commutation units). Note that there is a
slight possibility the motor will be stuck in its “unstable equilibrium” position of -90°.
Next, the current is ramped up to the full amount specified by PhaseFindingDac over another
time interval of PhaseFindingTime to force the motor to 0° (0 commutation units) of the
commutation cycle. At the end of this period, a value of 0 is forced into the commutation phase
position register.
For the phasing search to be successful, the motion between the ends of the first and second steps,
expressed in commutation units (1/2048 of a commutation cycle) must be greater than the value
in Motor[x].AbsPhasePosOffset. In an ideal phasing search, this distance would be 512 units.
The distance that occurred in the most recent search can be found in Motor[x].New[0].Pos.
Generally, a value of about 400 for AbsPhasePosOffset will catch true failures without rejecting
slightly non-ideal searches.
are not too high, this acceleration is a good proxy for torque. An arctangent calculation from the
accelerations of the “sine” and “cosine” guesses can then determine the phase angle.
This method is quicker than the stepper-motor search method and requires less movement. It is
more sensitive to significant external loads.
With very low external loads, two guesses 90° apart are sufficient to determine the phase angle,
and earlier generations of PMAC used such a “two guess” method. With four guesses spaced
around the commutation cycle, the ability to remove the effect of external loads is greatly
improved, making the method significantly more robust.
For the phasing search to be successful, the sum of the squares of the (load-adjusted)
accelerations of the two pairs of guesses must be greater than the value in
Motor[x].AbsPhasePosOffset. The value in the most recent search for the “sine” guesses can be
found in Motor[x].New[0].Vel. The value in the most recent search for the “cosine” guesses can
be found in Motor[x].New[0].Acc. Generally a value of about 80% of the typical sum of square
for a search will catch true failure without rejecting slightly non-ideal searches.
Motor[x].pAbsPhasePos
Motor[x]AbsPhasePosFormat
Motor[x].AbsPhasePosSf
Motor[x].AbsPhasePosOffset
Power PMAC reads the data at the address specified by pAbsPhasePos, interprets it according to
the rules specified by AbsPhasePosFormat, multiplies it by AbsPhasePosSf to convert it into
commutation units, then adds AbsPhasePosOffset to incorporate the difference between the
sensor zero position and the commutation zero angle.
Note that the sensor used for absolute power-on phase position can be the same as that used for
ongoing phase position, or it can be different – including having different resolution.
This diagram shows the 3-phase Hall signals in the most common configuration, with the signals
spaced by 120° of the commutation cycle. An alternate configuration has the signals spaced by
60°; with the “V” signal inverted from what is shown in the diagram. The 120° spacing is
generally recommended, as the common failure states of all 0’s or all 1’s are not legal states, and
therefore easily detected.
UVW 1 3 2 6 4 5
1
U
0
1
V
0
1
W
0
The $aa byte specifies the data format to be used. It should be set to $04 for Hall signals with
120° spacing, or to $05 for Hall signals with 60° spacing.
There are four common settings of Motor[x].AbsPhasePosFormat for Hall sensors. They are:
The proper sign of Motor[x].AbsPhasePosSf is determined by the direction sense of the Hall
signals with respect to the commutation cycle. For 120° spacing, if W leads V and V leads U in
the counting-up sense of the commutation cycle (as determined by the ongoing commutation
sensor), the direction sense agrees, and Motor[x].AbsPhasePosSf should be positive: +170.667.
However, if U leads V and V leads W in the counting-up sense, the direction sense does not
agree, and Motor[x].AbsPhasePosSf should be negative: -170.667.
Note that this is only an approximate phase referencing; the computed phase angle here could be
up to +/-30° of the commutation cycle off from the true angle, yielding a significant reduction in
torque capability. See the section Correcting an Approximate Phase Reference, below, for
directions on how to follow this step with a more precise referencing.
Absolute Encoders
Absolute encoders are increasingly being used as the position sensors for both servo and
commutation feedback. They can serve as the sensors for both power-on and ongoing
commutation position. Note that a “single-turn” absolute encoder can be used for power-on
commutation position, as it only needs to be absolute over one commutation cycle of the motor.
The most common absolute encoder interface used with the Power PMAC is the serial-encoder
interface of the PMAC3-style ASIC, found on the ACC-24E3 UMAC servo interface board and
on the Power Brick control board, with dedicated circuitry and registers for the interface. In this
case, Motor[x].pAbsPhasePos should be set to Gate3[i].Chan[j].SerialEncDataA.a for the IC
and channel used. This register contains the low 32 bits of data from the serial encoder.
Parallel-format data can be brought in through the ACC-14E I/O board, which uses the IOGATE
I/O interface IC. In this case, Motor[x].pAbsPhasePos should be set to GateIo[i].DataReg[j].a,
where i specifies the index of the IC used, and j specifies which of the 6 byte-wide data registers
(0 – 5) on the IC contains the least significant byte of the encoder position data.
Other older serial-encoder interface boards exist for UMAC systems that do not have pre-defined
data structures for the memory-mapped registers. For these boards, Motor[x].pAbsPhasePos
should be set to the address directly, in the form of Sys.piom + {offset}, where Sys.piom is the
base address of the memory-mapped I/O space for the Power PMAC (the user does not need to
know the numerical value of this address), and {offset} is the numerical value of the address offset
of the specified register in this I/O space.
The user will calculate this offset in two parts. First is the offset of the base address of the board
from the base address of the I/O space. This is determined by the DIP-switch setting of the board.
For boards using the “general-purpose I/O” address space (all of the standard older serial-
interface boards), these offsets can be found in the following table:
Index # 0 1 2 3 4 5 6 7
IC Base $A00000 $B00000 $C00000 $D00000 $A08000 $B08000 $C08000 $D08000
Offset
Index # 8 9 10 11 12 13 14 15
IC Base $A10000 $B10000 $C10000 $D10000 $A18000 $B18000 $C18000 $D18000
Offset
To this must be added the (small) offset of the register used in the IC from the base address of the
IC. Remember that each consecutive register in the IC has an offset of 4 numerical addresses
from the previous register.
For example, to use the second register of an IC mapped to index 1 in the general-purpose I/O
space of the Power PMAC, Motor[x].pAbsPhasePos would be set to Sys.piom + $B00004.
The $dd byte specifies the starting bit number to be used in the register. It should generally be set
to $00 when reading data from Gate3[i].Chan[j].SerialEncDataA.a, as the LSB of the encoder
data should be found in bit 0 of the 32-bit register. When reading data from
GateIo[i].DataReg[j].a, it should generally be set to $08, as the LSB of the IOGATE IC registers
is mapped into bit 8 of the 32-bit bus. Most of the older serial-encoder interface boards also map
their LSBs into bit 8, so the $dd byte should be set to $08 for these as well.
The $cc byte specifies the number of bits to be used; it should be set to the number of bits of
encoder data that cover a single commutation cycle, even if the encoder provides more bits of
data. For example, if the encoder provides a total of 27 bits of data with 65,536 LSBs per
revolution of the motor, and the motor has 4 poles (2 commutation cycles per revolution), $cc
should be set to $0F (15 decimal) because there are 215 (32,768) LSBs of the encoder per
commutation cycle, so the low 15 bits of the encoder data should be used.
If the size of the commutation cycle cannot be expressed as a power of 2 of the LSBs of the
encoder, which will generally be the case for linear encoders, then a number of bits at least as big
as that necessary to cover the entire travel of the motor must be used, not just enough to cover a
single commutation cycle. If this requires more than 32 bits starting at the encoder LSB, then
enough of the least significant bits of the encoder should not be used (done by increasing the
value in byte dd) to reduce the total bits used to 32 or less.
The $bb byte specifies how data in any subsequent registers is to be used. Most absolute encoder
interfaces only use a single register, so this byte field is not used (it is recommended to set this to
$00 for these cases). When reading byte-wide data from GateIo[i].DataReg[j].a, it should be set
to $20 to specify that subsequent registers should be read starting at the same bit as the LSB of
the data.
The $aa byte specifies the data format to be used. It should be set to $00 if the data is provided in
numerical binary format, so no conversion is required, or to $02 if the data is provided in Gray
code, specifying that Power PMAC will automatically convert the data to numerical binary form
before use.
For example, if the encoder provides 18 bits of resolution per motor revolution, and the motor has
4 poles (2 commutation cycles) per revolution, there are 131,072 (217) LSBs of the encoder per
commutation cycle, so Motor[x].AbsPhasePosSf should be set to 2048 / 131,072 = 0.015625. It
is advisable to enter this value as an expression, and let Power PMAC compute the result
precisely.
It is desirable for clarity (but not strictly necessary) to use only the number of bits of this
information that cover a single commutation cycle – that is, the low n bits of data.
Motor[x].AbsPhasePosOffset should be set to the negative of this value, multiplied by the value
of Motor[x].AbsPhasePosSf.
Resolvers
Power PMAC provides two fundamental methods of processing absolute resolver feedback where
the Power PMAC hardware provides a direct analog interface to the resolver. The first, using the
ACC-58E UMAC Resolver-to-Digital (R/D) Converter board, relies on software processing of
the converted analog feedback in the encoder conversion table (ECT). The second uses the
hardware processing of the PMAC3-style “DSPGATE3” IC used on the ACC-24E3 with the
analog feedback module and the Power PMAC Brick control board with the analog feedback
module. The setup for using the resolver position for power-on absolute phase position is
substantially different for these two cases.
Resolver Address
Motor[x].pAbsPhasePos tells Power PMAC the address of the register to read for power-on
absolute phase position. If the resolver is processed through the ACC-58E and the ECT, the
resulting position data is found in the “previous encoder position” register of the table, so
Motor[x].pAbsPhasePos should be set to EncTable[n].PrevEnc.a for the entry n used to
process the data.
If the resolver is processed through the hardware of the PMAC3-style IC, the resulting data is
found in the “arctangent” register of the IC channel, so Motor[x].pAbsPhasePos should be set to
Gate3[i].Chan[j].Atan.a for the IC and channel used.
The $dd byte specifies the starting bit number to be used in the register. It should generally be set
to $00 when reading data from EncTable[n].PrevEnc.a, as with resolvers interfaced to the ACC-
58E, because the LSB of the data used is found in bit 0 of the register. When reading the data
from Gate3[i].Chan[j].Atan.a, as with resolvers processed by the PMAC3-style IC, it is usually
set to $10 (16 decimal) because the Atan element is found in the high 16 bits of the 32-bit
register. It is also possible to set it to a higher value if the lowest of the 16 bits are considered
spurious data due to noise in the analog circuitry. For example, if you only want to use the high
14 bits of data, this byte should be set to $12 (18 decimal).
The $cc byte specifies the number of bits to be used; it should be set to the number of bits of
resolver data that cover a single commutation cycle. The value depends on the number of bits of
resolver data used in a resolver cycle, and the number of commutation cycles per resolver cycle.
Most resolvers have a single cycle per motor revolution, and most motors have multiple
commutation cycles per motor revolution.
For example, if you are using 14 bits of feedback from a resolver that has one cycle per motor
revolution, and the motor has 2 commutation cycles (4 poles) per revolution, there are 13 bits per
commutation cycle, and the $cc should be set to $0D (13 decimal).
The $bb byte specifies how data in any subsequent registers is to be used. Since resolver data is
always found in a single register, this byte should always be set to $00.
The $aa byte specifies the data format to be used. It should always be set to $00 for resolver data
to specify that the data is expected in numerical binary format.
Resolver Scaling
Motor[x].AbsPhasePosSf is used to convert the resolver reading into commutation units. It
multiplies the formatted value so far derived, with the result having 2048 units per commutation
cycle. It therefore should be set to 2048 divided by the number of LSBs used from the resolver
conversion per commutation cycle.
For example, if the resolver conversion provides 14 bits of resolution per motor revolution, and
the motor has 4 poles (2 commutation cycles) per revolution, there are 8192 (213) LSBs of the
resolver per commutation cycle, so Motor[x].AbsPhasePosSf should be set to 2048 / 8192 =
0.25. The value can be entered as an expression.
Resolver Offset
Motor[x].AbsPhasePosOffset is used to compensate for the difference between the sensor’s zero
position and the commutation cycle zero position. The value can be unique to the application. To
set the value of Motor[x].AbsPhasePosOffset “manually”, execute a “stepper-motor” phasing
search to drive the motor to the zero point in the commutation cycle. Read the value of the
resolver position at this point from the register specified by Motor[x].pAbsPhasePos.
It is desirable for clarity (but not strictly necessary) to use only the number of bits of this
information that cover a single commutation cycle – that is, the low n bits of data.
Motor[x].AbsPhasePosOffset should be set to the negative of this value, multiplied by the value
of Motor[x].AbsPhasePosSf.
The motor’s generated torque per unit current is proportional to the cosine of the angle error (in
terms of the commutation cycle) of the phase referencing. Significant errors both reduce the peak
torque capability of the motor, and add significantly to motor heating.
A phase correction is essential when the initial phase referencing is done using Hall Sensors.
With 60° between edges of the signals, the best accuracy that can be achieved is +30°, which can
lead to a 14% reduction in peak torque, and a 20% increase in motor heating.
A phase correction is recommended when the initial phase referencing is done with a phasing-
search move. Even if initial testing shows the search to perform very reliably, errors can creep in
during the life of the machine, and a phase correction is good insurance.
The most common method of phase correction is to perform a homing-search move, settle at the
home position, and then write a pre-determined value into the Motor[x].PhasePos register. Saved
setup element Motor[x].AbsPhasePosForce is a holding register for the value to be copied into
the active Motor[x].PhasePos element.
Generally, the best technique for determining the value of Motor[x].AbsPhasePosForce for this
method is to perform a stepper-motor phasing search on the (unloaded) motor, then perform a
homing-search move to the index pulse of the encoder. With the motor settled at this home
position, the value of Motor[x].PhasePos is the value we want for
Motor[x].AbsPhasePosForce.
Then, in operation, after the initial rough phase referencing, a homing-search move is performed
that includes the encoder index pulse as part of the trigger. After the motor has settled at the home
position, Motor[x].PhasePos is set to Motor[x].AbsPhasePosForce. Sample PLC program code
to accomplish this is:
Typically, the Motor Setup program associated with the IDE can be used to set Motor[x].IdCmd
and Motor[x].DtOverRotorTc automatically. The program stimulates the induction motor to
infer its parameters, and sets these terms appropriately for the results it gets. This section explains
analytical and experimental methods for setting these parameters. Note that these settings are
independent of any mechanical load, so any tests can and should be done with an unloaded motor.
The key parameter needed is the ratio between the update time of the control algorithm (“Dt”),
which is Power PMAC’s phase update period, and the electrical time constant of the motor’s
rotort (“RotorTc”). For this reason, the saved setup element in Power PMAC is called
Motor[x].DtOverRotorTc. There are several ways to calculate this parameter, as explained
below.
The rated speed for the motor, usually given in revolutions per minute (rpm).
The electrical line frequency given for this rated speed, usually given in Hertz (Hz), or
cycles/sec. This is almost always 50 or 60 Hz.
The Power PMAC’s phase update period, usually given in microseconds (μsec).
The rated speed can be subtracted from the line frequency (after conversion to consistent units) to
get the slip frequency. This can then be multiplied by the phase update period (again after
conversion to consistent units) to get the Motor[x].DtOverRotorTc slip constant. The formula
is:
I mag _ std
DtOverRoto rTc e m * T p *
32,768
where:
ωe is the electrical frequency given, in radians/sec. To calculate from frequency in Hertz, multiply
by 2π (6.283). For 50 Hz, this is 314.3 radians/sec; for 60 Hz, this is 377.0 radians/sec.
ωm is the rated mechanical pole frequency, in radians/sec. To calculate from motor rated speed in
rpm and the number of poles, divide the speed in rpm by 60, multiply by 2π (6.283), then
multiply by the number of poles and divide by 2.
Tp is the Power PMAC’s phase update time in seconds. To convert from microseconds, divide by
one million.
If the phase update time is set by a PMAC2-style “DSPGATE1” IC, as on an ACC-24E2, the
phase update time can be calculated as:
Tp
2 * Gate1[i].PwmPeriod 3 * Gate1[i].PhaseClockDiv 1
117,964,800
If the phase update time is set by a PMAC3-style “DSPGATE3” IC, as on an ACC-24E3, the
phase update time can be calculated as:
1
Tp
Gate 3[i].PhaseFreq
Imag_std is the value of the magnetization current parameter Motor[x].IdCmd that would produce
the same rated speed/torque point as the direct operation off the AC lines. For a first calculation,
you can use a value of 3500 here. It will almost always get you close enough. If you set your
Motor[x].IdCmd value as explained in the next section for this type of operation, you can come
back and adjust this calculation.
Example
A 4-pole induction motor has a rated speed of 1740 rpm at a 60 Hz electrical frequency. It is
being controlled from a Power PMAC with default clock source and frequency from a PMAC2-
style IC. The electrical frequency is:
The default value of Gate1[i].PwmPeriod is 6257, which produces a 4.517 kHz PWM frequency
(222 µsec period) and a 9.035 kHz “MaxPhase” clock frequency (111 µsec period). The default
value of Gate1[i].PhaseClockDiv is 0, for a “divide by 1” from “MaxPhase” to “Phase” clock, so
the phase clock frequency is also 9.035 kHz (111 µsec period). Formally this can be calculated
as:
Tp
2 * 6527 3 * 0 1 0.000111sec
117,964,800
Tp
DtOverRotorTc
Tr
where Tp is Power PMAC’s phase update time, and Tr is the rotor’s electrical time constant.
Remember to use the same units for both times.
Example
You are running with a phase update frequency of 8 kHz, and you have a rotor time constant of
0.75 seconds. You can calculate:
Tp 0.000125
DtOverRotorTc 0.000167
Tr 0.75
The higher the value of Motor[x].IdCmd (before saturation), the more torque is produced per
unit of “quadrature” current commanded from the servo loop, but the higher the back-EMF
“generator” voltage produced per unit of motor velocity, so the lower the maximum velocity can
be achieved from a given supply voltage. The lower the value of Motor[x].IdCmd, the less
torque is produced per unit of commanded “quadrature” current, but the lower the back-EMF
voltage produced per unit of velocity, so the higher the velocity that can be achieved.
In most applications, a single value of Motor[x].IdCmd will be set and left constant for the
application. However, it is possible to change Motor[x].IdCmd dynamically as a function of
speed, lowering it at high speeds so as to keep the back-EMF under the supply voltage, extending
the motor’s speed range. This technique is generally known as “field weakening” and can be
implemented in a PLC program.
If you do not use the Motor Setup program to set the value of the Motor[x].IdCmd
magnetization-current parameter, it is best to do so experimentally. With a good value of
Motor[x].DtOverRotorTc set, simply issue a low-valued open-loop output command (e.g.
out10) at each of several settings of Motor[x].IdCmd and observe the end velocity the
unloaded motor achieves. This can be done simply by watching the real-time velocity read-out in
the IDE’s “position” window. If you use the data gathering feature, you can also note the rate of
acceleration to that speed.
This velocity is known as the “base speed” for the motor for that setting. Typically, a value of
3200 to 3500 for Motor[x].IdCmd will achieve the approximately a base speed equivalent to the
rated speed of the motor when run directly from a 50 Hz or 60 Hz line.
If your test values of Motor[x].IdCmd are low enough that none of them magnetically saturate
the rotor, the base speeds in the test will be approximately inversely proportional to the value of
Motor[x].IdCmd (and the accelerations to that speed will be approximately proportional to
Motor[x].IdCmd). If you start increasing Motor[x].IdCmd into the range that causes magnetic
saturation of the rotor, increases in Motor[x].IdCmd will not cause further lowering of base
speed and further increase in rate of acceleration to that speed.
Many users will want a value of Motor[x].IdCmd as high as possible without causing rotor
saturation. These users will want to find values of Motor[x].IdCmd that do cause saturation, then
reduce Motor[x].IdCmd just enough to bring it out of saturation.
There are some systems that get better performance with a slower servo update rate. Generally
these are systems with relatively low encoder resolution, usually an encoder only on the load,
where the derivative gain can not be raised enough to give adequate damping without causing an
unstable “buzz” due to amplified quantization errors. In this case, slowing down the update rate
(increasing the update time) can help to give adequate damping without excessive quantization
noise.
Changing the servo update rate changes the percentage of processor time devoted to the servo
tasks, which can have important implications for lower-priority tasks, such as motion-program
and PLC-program calculations. Refer to the Computational Features chapter for details on how to
evaluate these changes.
Usually the period is extended because of very slow dynamics of the plant controlled by this
motor, which make a long update period desirable. This is very common when the “motor” is not
an actual physical motor but a process variable such as temperature or pressure.
Closing the Servo Loop Under the Phase Interrupt for a Motor
It is possible to close the servo loop for a motor under the phase interrupt, which can have a
higher frequency than the servo interrupt. Generally, this is done for one or two very fast
actuators (“fast-tool servos”) in a system that require high update rates to achieve the bandwidth
that they are physically capable of. Typical actuators used in this manner are voice-coil motors,
galvanometers, magnetostrictive actuators, and piezoelectric actuators. Closing these motors
under a high-frequency phase interrupt and other motors under the lower frequency servo
interrupt helps optimize the computational resources of the Power PMAC.
Setting bit 3 (value 8) of saved setup element Motor[x].PhaseCtrl to 1 enables this mode of
operation for the motor. While it is also possible to set other bits to 1 to enable the commutation
algorithm for the motor, it is rare to require commutation for these fast actuators, so typically
Motor[x].PhaseCtrl is simply set to 8. Motor[x].ServoCtrl must also be set to a non-zero value
(usually 1), because many tasks for this motor will still be done under the servo interrupt.
If Power PMAC is not closing the current loop for this motor, it is best to set Motor[x].pAdc to 0
for the motor. Otherwise, Power PMAC will spend time reading the specified current feedback
registers every phase cycle, even though the results are not used.
Another use of this feature is for high-performance brushless motor control. In the standard
control mode, the command output of the servo loop is held in memory until the next phase
interrupt, when it is used as an input to the commutation/current-loop algorithm, and the
command values from these phase algorithms are output to hardware half a phase cycle later. In
very high performance systems, the added delay can hurt performance.
However, if the servo loop is closed under the phase interrupt and phase algorithms are also
active (Motor[x].PhaseCtrl = 9 or 12), the servo-loop command is immediately used by the
phase algorithm in the same cycle, eliminating a full phase-cycle net delay.
For an incremental encoder, it will be set to Gaten[i].PhaseCapt.a, which contains the encoder
counter value latched on the phase interrupt. Note that with a PMAC3-style “DSPGATE3” IC,
this register can include “1/T” timer-based sub-count extension for digital quadrature encoders, or
arctangent-based sub-count extension for analog sinusoidal encoders. However, with the older
PMAC2-style “DSPGATE1” IC, this register can only hold full quadrature counts.
Because these actuators typically have a very short travel, it is often possible to use an analog
feedback device as the position feedback through an A/D converter. It is important to choose an
A/D converter that updates every phase cycle, as on the ACC-28E, the ACC-59E3 or the Power
Brick control board. Multiplexed A/D converters, as on the ACC-36E, do not update individual
readings often enough to be of use here.
If serial encoders are used for feedback, as with the ACC-84E, the ACC-24E3, or the Power
Brick control board, it is important to set them up to be read every phase cycle, not just every
servo cycle. If parallel data is used for feedback, as with the ACC-14E, the data should be latched
on the phase clock signal, not the servo clock signal.
Types of Amplifiers
Power PMAC can interface to a variety of different types of amplifiers (drives). The type of
amplifier used for a particular motor or hydraulic valve has important ramifications for the tuning
of the servo loop. Each of the common types is explained below. The following block diagram
shows where the split between controller and amplifier tasks can be made:
Desired Position
Desired Velocity
Desired Torque
Desired Phase Currents
Desired Phase Voltages
+
Trajectory + +
Position Velocity Phase Current Power
Generation + -
Filter Filter Commutation Filters Modulation
Interpolation - -
-
d
dt Phase Currents
Position
E Motor
Position-
Mode Drive
Velocity-
Mode Drive
Torque-
Mode Drive
Sinewave-
Mode Drive
Direct PWM-
Mode Drive
The most common case for this mode involves the use of a smart networked drive (as on the
EtherCAT network) that is run in “position mode”, accepting commanded position values over
the network, and closing all feedback loops itself.
If the command value out of the Power PMAC servo loop, regardless of signal type, is a velocity
command, no velocity loop needs to be closed in the Power PMAC. In general, this means that
the velocity feedback (derivative) gain terms Motor[x].Servo.Kvfb and Motor[x].Servo.Kvifb
can be set to 0.
Before tuning Power PMAC’s position loop, it is important that the velocity loop of a velocity-
mode amplifier be well tuned with the load that it will drive. Because the velocity-loop tuning is
load dependent, the amplifier manufacturer cannot do the final tuning; the machine builder must
tune the loop. The velocity step response must not have any significant overshoot or ringing; if it
does, it will not be possible to close a good position loop around it with Power PMAC. The
Power PMAC IDE’s tuning section has a function called “Open-Loop Tuning” that can be used to
give velocity command steps to the amplifier and to observe the response plotted on the screen.
This makes it easy to tune the amplifier, or simply to confirm that it has been well tuned.
Pulse-and-Direction-Input Amplifiers
Pulse-and-direction-input amplifiers interpret each pulse as a commanded position increment. To
generate pulse-and-direction commands, the Power PMAC servo loop computes a pulse
frequency value that is sent to “pulse-frequency modulation” circuitry. This frequency value is
effectively a velocity command. The integrated pulse count received by the amplifier is a position
command, but because the numerical command value calculated by the Power PMAC servo loop
is a velocity command, this is considered to be a velocity-mode servo loop.
Amplifiers with this style of interface are of two types. First there is the stepper drive, for which
there is no position feedback to the drive. Usually, there is no encoder at all for these motors, so
the Power PMAC must use the output pulse train as simulated feedback (this does require use of a
separate encoder channel on a PMAC2-style Servo IC Power PMAC, even though no encoder is
physically connected).
If there is an encoder on the stepper motor, it can be used in either of two ways. It can be used as
regular feedback to the Power PMAC, just as on a servo motor. In this method, the key issue is
the resolution and phasing of the encoder edges relative to the steps or microsteps produced by
the drive – some deadband may have to be created in the Power PMAC servo loop to prevent
hunting at rest. Alternately, the encoder can just be used for position confirmation at the end of
moves. However, this technique requires the use of two encoder channels on the Power PMAC if
a PMAC2-style Servo IC is used: one for the simulated feedback of the pulse train, and one for
the confirmation encoder.
Next, there are the “stepper-replacement” servo amplifiers. These take position feedback from the
servo motor and close all the loops inside the drive. While it is possible in this case to use the
encoder signal from the drive for feedback into Power PMAC’s servo loop, this should not be
done, because the position loops in the drive and the controller will end up fighting each other.
With these drives, the commanded pulse train out of the Power PMAC should be used as
simulated feedback.
When using simulated feedback, it is possible to set up the Power PMAC servo gains solely with
analytic methods. See the section Setting Up Power PMAC for Pulse-and-Direction Control in
the chapter Basic Motor Setup on Power PMAC for details. When using real encoder feedback,
the servo loop should be tuned just as for an analog velocity-mode drive.
Hydraulic-Valve Amplifiers
Hydraulic-valve amplifiers, whether for servo valves or proportional valves, control a fluid-
volume flow proportional to their command input. Since fluid flow into or out of a hydraulic
cylinder is proportional to the velocity of the moving member of the cylinder, the command into
the valve’s amplifier is effectively a velocity command. With the less expensive proportional
valves, there is usually some physical deadband when crossing through zero velocity; the effect
of this can be reduced with the Power PMAC servo loop’s deadband compensation feature.
If the command value out of the Power PMAC servo loop, regardless of signal type, is a torque or
force command, the Power PMAC servo must close the velocity loop for the motor. With the
standard servo algorithms, this means that one or both of the velocity feedback (derivative) gain
terms Motor[x].Servo.Kvfb and Motor[x].Servo.Kvifb must be set greater than zero. This
derivative action is required to get the damping action needed for stability. Because motors
produce a torque or force proportional to motor current, the torque/force command out of the
servo can also be considered a current command.
Because no velocity-loop closure is done in these types of amplifiers, there is no need to tune
anything in the amplifier with the load attached to the motor. Any tuning that may be required is
dependent only on motor properties, and can potentially even be done by the amplifier
manufacturer.
Sinusoidal-Input Amplifiers
A sinusoidal-input amplifier accepts two phase-current commands that are sinusoidal functions of
time in the steady state. This type of amplifier expects the controller to calculate the
commutation, using the torque/force command out of the position/velocity-loop servo as the
current-magnitude command into the commutation. The amplifier performs the current-loop
closure in this style.
The resulting value is written to the register specified by saved setup element Motor[x].pDac as a
signed 32-bit integer, in the motor position units as defined by the user. This value can roll over if
necessary.
It is not necessary for the Power PMAC to receive any actual position feedback data for the
motor, but Power PMAC will still be computing following error as the difference between the
commanded and actual position registers, and disabling the motor if this difference exceeds the
value in saved setup element Motor[x].FatalFeLimit. If Power PMAC is not receiving actual
position feedback data, Motor[x].FatalFeLimit should be set to 0 to disable this error checking.
There are several reasons why reading an actual position value each servo cycle can be important.
Monitoring of the physical response of the motor: This can be very useful both in
development and the actual application. Reading the measured position and processing it
into motor actual position permits it to be queried and gathered just as for a motor where
Power PMAC is actually closing the servo loop.
Ability to use Power PMAC’s warning and fatal following error limit parameters: While
digital networked position-mode drives should have this capability internally, many
analog fast-tool amplifiers that accept position command values do not. Even when the
drive has this functionality, PMAC’s limits can be an important backup. Remember that
with networked drives, delay in receiving the actual position from the drives can result in
apparent large following errors at high speeds just due to the time delay between sending
out a cycle’s commanded position and receiving the actual position for that cycle.
Elimination of a possible position jump on enabling: Whether enabling for the first time
after power-on/reset, or after a fault, avoiding a position jump, particularly a large jump,
can be very important. When the servo loop is disabled, Power PMAC internally sets the
desired position value equal to the actual position value each servo cycle. When the drive
is (re-) enabled, it will actively command the motor to the position having this numerical
value. If this value corresponds to the actual physical position, there will be not jump on
enabling.
Reading the measured position and processing it for motor actual position is done in exactly the
same way as for a motor where Power PMAC is actually closing the servo loop. An encoder
conversion table (ECT) entry reads the input register and processes it. The motor’s outer-loop
position-feedback pointer Motor[x].pEnc is set to the address of the ECT entry.
If you are using Power PMAC’s fatal following-error safety function, the error limit
(Motor[x].FatalFeLimit) cannot be set as tightly as would be desirable. For example, if there is a
net 3-cycle delay, and the motor is moving at 100 units per servo cycle, there would be a 300-unit
following error from the reporting delay alone.
Also, if you are using the auxiliary outputs for feedforward, it can be difficult to optimize the
tuning of the feedforward terms because of the time offset between desired and actual position
values.
To compensate for the mismatch from this delay in reporting actual position, it is possible to
buffer and delay the reporting of desired position to match the physical network delay. If
Motor[x].Servo.SwPoly7 is set to a value greater than 0, it specifies the artificial delay in
reporting desired position, in units of 1/32 of a servo cycle.
For example, if the delay is 4.25 servo cycles, Motor[x].Servo.SwPoly7 should be set to 4.25 *
32 = 136. Up to 7 cycles of delay can be specified.
Usually, this value is set by jogging the (unloaded) motor with some integral gain active in the
drive so the steady-state error in the drive is zero. Divide by the following error that PMAC
reports due to the delay by the jogging speed to get the time delay. For example, jogging at 20
units per servo cycle and seeing a 75-unit error in PMAC shows a 75 / 20 = 3.75-cycle delay, so
the SwPoly7 term should be set to 3.75 * 32 = 120.
In general, any trajectory filtering algorithms in the drive should be disabled, as they can
introduce very large delays, and with Power PMAC’s own sophisticated trajectory generation,
such filtering is not required.
Note that the delay in reporting desired position does not delay the desired position that is output
to the drive. The purpose of the delay is to permit the user to properly match the desired and
actual position values in time for error calculations and feedforward optimization.
The option for auxiliary feedforward command outputs from the Sys.PosCtrl algorithm is new in
V2.0 firmware, released 1st quarter 2015.
These auxiliary command outputs are enabled by setting saved setup elements
Motor[x].Servo.pVelOut and Motor[x].Servo.pAccOut to the addresses of the registers that
will receive these commands. For EtherCAT drives, the setting will usually be of the form
Motor[x].Servo.pVelOut = ECAT[i].IO[j].Data.a
If these variables are set to their default values of 0, there will be no auxiliary command outputs
from the algorithm. However, if they are set to addresses, Power PMAC will compute
feedforward terms the same as in the default Sys.ServoCtrl algorithm, but instead of including
the resulting feedforward values in the single command output, it will write them separately to the
specified address(es).
The following block diagram shows the terms that are used in each output of the Sys.PosCtrl
servo algorithm:
CompDac
+
+ ->pAccOut
Kfff SwFffInt
+
+
DesVel 1 + ->pVelOut
Kviff
F(z)
+
1-z-1
->pDac
DesPos
Sign of desired velocity multiplied by Kfff friction feedforward gain (if SwFffInt is set
to 1)
Sign of desired velocity multiplied by Kfff friction feedforward gain (if SwFffInt is set
to 0)
The value in the Motor[x].CompDac register, usually from a torque compensation table
(new in V2.1 firmware, released 1st quarter 2016).
The desired velocity value can be filtered through the F(z) polynomial filter, which is useful as a
low-pass filter when there is high-frequency noise in the desired trajectory, as when it is tracking
a physical encoder signal (position following or external time base). This filtering smooths the
desired acceleration value as well. (This capability is new in V2.1 firmware, released 1st quarter
2016.)
It is possible to delay in time the output of these command values from the Power PMAC to
compensate for the drive’s delay in using the Power PMAC’s position command output so that
the resulting action in the drive is re-synchronized.
If the specified delay time includes a fractional component in the number of servo cycles, the
value output in a cycle is computed is a weighted average of the values computed in the whole
cycles on each side of this delay. For example, if SwZvInt is set to 88 to specify a 2.75-cycle
delay, the output in a given cycle is 0.75 times the value calculated 3 cycles ago plus 0.25 times
the value calculated 2 cycles ago.
This capability to use Motor[x].Servo.SwZvInt to delay the auxiliary outputs in the Sys.PosCtrl
algorithm is new in V2.6.1 firmware, released 2nd quarter 2021. At the default value of 0,
operation is compatible with older firmware versions. Its use in other servo algorithms is
unaffected.
1-z-1 Kaff
Sys.PidCtrl
Servo Algorithm
1-z-1 DesVel
Kvff
Kviff
+ + +
+ + +
DesPos
Kp ServoOut
- + -
- MaxPosErr MaxDac
Ki
1-z-1
Kvifb MaxInt
Kvfb
ActVel
1-z-1 ActPos2
ActPos
The basic PID algorithm uses the following gain terms, all saved setup elements:
Feedback Terms
The PID feedback filter consists of proportional (“P”), integral (“I”), and derivative (“D”) terms,
each with its own contribution to the control effort. They operate on position (following) error
and actual velocity values. The magnitude of the position error, computed as the difference
between the net desired position and net actual position values, is limited to the value of
Motor[x].Servo.MaxPosErr.
Some form of derivative action – effectively a velocity loop – is required for a stable position
loop. If a velocity loop is closed in the amplifier, and tuned well, the derivative gain terms in
Power PMAC can be set to 0. However, if there is no velocity loop closed externally, a positive
value of one of these gain terms will be required for stable operation.
Note that in the Power PMAC, this gain acts on the derivative of the actual position, not on the
derivative of the position error, as in some other controllers. This permits the simple use of dual
motor-and-load feedback with a separate sensor on the motor for derivative action (specified by
Motor[x].pEnc2) from the sensor on the load for proportional and integral action (specified by
Motor[x].pEnc).
In most cases, only one of these gain terms will be set to a non-zero value. Which is to be chosen?
Using Motor[x].Servo.Kvfb, which puts the integrator in the position loop, is generally better for
tracking commanded trajectories with minimum following error. Using Motor[x].Servo.Kvifb,
which puts the integrator inside the velocity loop, is generally better for good disturbance
rejection. It is possible to use both of these terms.
If the velocity feedback term Motor[x].Servo.Kvifb and the velocity feedforward term
Motor[x].Servo.Kviff are both zero, the integrator acts purely on the position (following) error
value. If either or both of these terms are non-zero, their results are added to the position error
term at the input to the integrator.
Each servo cycle, the input to the integrator is multiplied by Motor[x].Servo.Ki and the product
is added into Motor[x].Servo.Integrator (unless the output has saturated at the
Motor[x].Servo.MaxDac limit). If the magnitude of the value in the Integrator element exceeds
that of Motor[x].Servo.MaxInt, it will be clamped at that limit.
Note that in the basic filter of the PidCtrl algorithm, it is not possible to automatically turn off
the error input to the integrator during commanded motion and just have it on during while
stopped. This feature is implemented in the more extended filter of the ServoCtrl algorithm
explained in the next section, by setting Motor[x].Servo.SwZvInt to 1.
Feedforward Filter
Because a feedback filter is error driven, it is necessary that there be an error between the
commanded and actual positions before it takes any action. The actions of feedforward, on the
other hand, are dependent only on the commanded trajectory, and therefore do not require errors
to cause action. The basic idea of feedforward is to directly apply your best estimate of the
control effort needed to execute the commanded trajectory, without waiting for position errors to
build up. The feedback terms then only need to respond to the errors in this estimate, which are
typically quite small.
In a well-tuned system with low external loads, over 95% of the control effort can come from the
feedforward terms, with the feedback terms just providing small corrections for disturbances and
imperfections in the estimate. Power PMAC’s basic PID algorithm has velocity and acceleration
feedforward terms.
Properly set velocity feedforward will essentially eliminate following error components that are
proportional to velocity. If the Power PMAC is closing the velocity loop for the motor, the
optimal Motor[x].Servo.Kvff and Motor[x].Servo.Kviff will typically be equal to, or slightly
greater than the corresponding Motor[x].Servo.Kvfb and Motor[x].Servo.Kvifb.
In most cases, only one of these gain terms will be set to a non-zero value. Which is to be chosen?
Using Motor[x].Servo.Kvff, which puts the integrator in the position loop, is generally better for
tracking commanded trajectories with minimum following error. Using Motor[x].Servo.Kviff,
which puts the integrator inside the velocity loop, is generally better for good disturbance
rejection. It is possible to use both of these terms.
Properly set acceleration feedforward will essentially eliminate following error components that
are proportional to acceleration. The Motor[x].Servo.Kaff acceleration feedforward term is
essentially an estimate of the inertia of the system, directly providing a force or torque
proportional to it and the commanded acceleration.
If Motor[x].Servo.pAccOut is set to the address of a valid register (and not to 0), these
feedforward components will be written to that register. Otherwise, these components will be
added into the main servo command value, as shown in the diagram below.
Kviff
+ +
+ + +
DesPos
Kp ServoOut
- + -
- MaxPosErr MaxDac
Ki
1-z-1
Kvifb MaxInt
Kvfb
ActVel
1-z-1 ActPos2
ActPos
Kfff SwFffInt
1-z-1 Kviff
+
+ + + +
+ C(z) +
A(z) Kp
DesPos D(z) + Servo
- - + Out
MaxPos Kbreak - - OutDb MaxDac
Err Ki
1-z-1
Kafb
MaxInt
Kvifb
Kvfb
1-z-1
1
B(z) 1-z-1
ActVel E(z) ActPos2
ActPos
Polynomial Filters
The standard servo algorithm has six “polynomial filters” that can operate on values at various
points in the servo algorithm. These filters are:
With the factory default settings for the terms in these filters, they act as “pass-throughs”, where
the output of the filter is always equivalent to the input.
These filters can be used to implement functionality such as notch (band-reject) and low-pass
filters. Setting up these filters manually requires some reasonable knowledge of digital filter and
control theory. The auto-tuning functionality of the Integrated Development Environment (IDE)
software can provide good settings for these filters without the need for such knowledge by the
user.
“Numerator” polynomial filters are so-called because their transfer functions have terms in the
numerator, not the denominator. These polynomials act on the present and past inputs to the filter.
These filters have the general transfer function:
Tn z K 0 K 1 z 1 K 2 z 2 ... K n z n
That is, the filter output for sample cycle “k” is the sum of products of gain terms Ki and
corresponding input values from sample cycles “k-i”, where i ranges from 0 to n for an nth-order
polynomial.
“Denominator” polynomial filters are so-called because their transfer functions have terms in the
denominator, not the numerator. These polynomials act on past outputs from the filter. These
filters have the general transfer function:
Td z
1
1 K1 z K 2 z 2 ... K n z n
1
That is, the filter output for sample cycle “k” is the sum of products of gain terms Ki and
corresponding output values from sample cycles “k-i”, where i ranges from 0 to n for an nth-order
polynomial.
A z Ka 0 Ka1 z 1 Ka 2 z 2 Ka 3 z 3 Ka 4 z 4 Ka 5 z 5 Ka 6 z 6 Ka 7 z 7
Each Kai term in this transfer function corresponds to saved setup element Motor[x].Servo.Kai.
Each Kbi term in this transfer function corresponds to saved setup element Motor[x].Servo.Kbi.
C z 1 Kc1 z 1 Kc 2 z 2 Kc 3 z 3 Kc 4 z 4 Kc 5 z 5 Kc 6 z 6 Kc 7 z 7
Each Kci term in this transfer function corresponds to saved setup element Motor[x].Servo.Kci.
D z
1
1 2 3
1 Kd1 z Kd 2 z Kd 3 z Kd 4 z 4 Kd 5 z 5 Kd 6 z 6 Kd 7 z 7
Each Kdi term in this transfer function corresponds to saved setup element Motor[x].Servo.Kdi.
E z
1
1 Ke1 z Ke2 z 2
1
Each Kei term in this transfer function corresponds to saved setup element Motor[x].Servo.Kei.
F z
1
1
1 Kf1 z Kf 2 z 2
Each Kfi term in this transfer function corresponds to saved setup element Motor[x].Servo.Kfi.
Integration Modes
The standard servo algorithm has two control bits that affect how the integral gain term
Motor[x].Servo.Ki operates. These permit the user to optimize performance for the particular
application.
Having the integrator active only when the desired velocity is zero is the traditional choice, made
because of concern that the integrator would “charge up” during the move as actual position fell
behind command position, and then need to “discharge” at the end, causing overshoot at the
destination of the move. However, if feedforward terms are used well to minimize tracking errors
during moves, this effect is minimal, and it can be beneficial to have the integrator active during
moves.
Note that it is desirable to have the integrator off during moves when tuning the feedforward
gains, so that the effect of the feedforward gains during commanded moves can be seen clearly.
Even if it is then desired to have the integrator active at all times, bit 0 of
Motor[x].Servo.SwZvInt should be set to 1 when doing the feedforward tuning.
In the default integration mode, overshoot is necessary to “discharge” the integrator with the
instantaneous following error having the opposite sign from the integrated error causing the
integrator value to reduce in magnitude.
value in the integrator will immediately be cleared. This action minimizes the overshoot, as the
integral action is no longer trying to drive the motor in the same direction.
This clearing mode can be useful in move-and-settle applications that do not have significant net
biases such as gravity loads or analog offsets. If the application does have large biases, this mode
may not be appropriate, as a significant non-zero integrator value may be required to minimize
error at the endpoint.
Friction Feedforward
Motor[x].Servo.Kfff is a non-linear “friction feedforward” gain term. It is multiplied by the sign
(-1, 0, or 1) of the net desired velocity. If control bit Motor[x].Servo.SwFffInt is set to its default
value of 0, the resulting product is added directly to the servo command output. If
Motor[x].Servo.SwFffInt is set to 1, the resulting product is added to the input of the position-
error integrator instead.
This term is meant to compensate for the effects of dry (Coulomb) friction, which creates a force
opposing the direction of motion, but whose magnitude is independent of the magnitude of the
velocity.
For the first several servo cycles in which the net desired velocity for the motor has a new non-
zero sign – positive or negative – the value of Motor[x].Servo.Ksff is added to the value of the
(running) friction feedforward term Motor[x].Servo.Kfff. The sum is included in the feedforward
component, added to the command output if Motor[x].Servo.SwFffInt is set to the default of 0
or to the input of the integrator if SwFffInt is set to 1.
The number of servo cycles this added component from Ksff is used is determined by the
magnitude of Motor[x].Servo.SffCycles. The cycle count starts when the sign of the net desired
velocity changes from zero to either non-zero value, or when it changes directly from one non-
zero value to the opposite.
If SffCycles is a positive value, this component is always added for the specified number of servo
cycles. If SffCycles is a negative value, it specifies the maximum number of servo cycles this
component will be added, but if the sign of the actual velocity becomes the same as the sign of
desired velocity before this, this component will no longer be added.
For the first several servo cycles in which the net desired velocity for the motor has a new non-
zero sign – positive or negative – the value of Motor[x].Servo.Ksff is added to the value of the
(running) friction feedforward term Motor[x].Servo.Kfff. The sum is included in the feedforward
component, added to the command output if Motor[x].Servo.SwFffInt is set to the default of 0
or to the input of the integrator if SwFffInt is set to 1.
The number of servo cycles this added component from Ksff is used is determined by the
magnitude of Motor[x].Servo.SffCycles. The cycle count starts when the sign of the net desired
velocity changes from zero to either non-zero value, or when it changes directly from one non-
zero value to the opposite.
If SffCycles is a positive value, this component is always added for the specified number of servo
cycles. If SffCycles is a negative value, it specifies the maximum number of servo cycles this
component will be added, but if the sign of the actual velocity becomes the same as the sign of
desired velocity before this, this component will no longer be added.
Acceleration Feedback
Motor[x].Servo.Kafb is an acceleration feedback term that subtracts an amount from the servo
effort proportional to the actual acceleration detected. This can provide an “electronic flywheel”
effect. However, because the derivation of acceleration values from position feedback can be
noisy, it is strongly recommended to use the “E” polynomial that acts on the inner-loop feedback
as a low-pass filter to reduce this noise if you want to use acceleration feedback.
FEout
Kbreak
=2
=1
=0 FEin
BreakPosErr
Gain Kbreak
=2
Kp
=1
=0 FEin
This filter has two terms represented by saved setup elements. Motor[x].Servo.BreakPosErr
specifies the size of the zone (“one-sided”), in motor units, of the proportionally modified
following error. A setting of 0.0 disables this feature. Motor[x].Servo.Kbreak specifies the
proportional modification factor inside this zone. It can be thought of as a relative gain
(referenced to the Motor[x].Servo.Kp proportional gain term). Inside this zone, the net gain is
the product of the Kp and Kbreak terms. Outside this zone, the net gain asymptotically
approaches the value of Kp.
If Motor[x].Servo.Kbreak is set to 0.0, a full control deadband is created within the defined
zone, with no dynamic servo effort created from the Kp or Ki terms based on the position error.
Such a deadband can be desirable if the user wants to be still with a small error rather than “hunt”
trying to eliminate the error. Many users will want to create ½ or 1 “count” of control deadband if
it is possible that the desired end position of a move can have a fractional count component. Note
that this input deadband has no effect on the operation of the inner velocity loop, so there can still
be servo output as a result of non-zero actual velocity within the deadband.
Values of Motor[x].Servo.Kbreak between 0.0 and 1.0 provide a lower (but non-zero) control
gain within the defined zone. Settings in this range are not commonly used. A value of 1.0
provides a gain inside the zone equal to that outside of it, effectively disabling the feature.
Values of Motor[x].Servo.Kbreak greater than 1.0 provide a higher control gain within the
defined zone. This is commonly used if the physical system has a deadband or reduced gain near
zero command values. For example, proportional hydraulic valves have a low gain near their zero
crossing, so increased gain from the controller can compensate for this. Other users prefer a
higher gain in a small zone for high stiffness – but keeping the high gain outside the small zone
would result in instability. Very high gains in a very small (<< 1 feedback count) error band can
provide very tight control in the presence of friction.
Servo
Out
OutDbSeed
Kp
FE
OutDbOn
OutDbOff
When the desired velocity is zero and the magnitude of the following error is less than
Motor[x].OutDbOn, the servo command output value is forced to zero. In this state, status bit
Motor[x].Servo.Status is set to 1. The servo output will stay at zero as long as the following
error is less than Motor[x].Servo.OutDbOff, which should be greater than or equal to
OutDbOn.
When the motor exits the deadband, the value in the position-error integrator element
Motor[x].Servo.Integrator is “seeded” with the value in saved setup element
Motor[x].Servo.OutDbSeed. This value is added to the existing integrator value, giving the
servo a “kick” to push the motor back towards zero error. As this happens, status bit
Motor[x].Servo.Status is set to 0. The proportional gain effect here is just as if there were no
deadband.
The algorithm can be initialized in one of three ways at the end of a commanded move. When
Motor[x].DesVelZero changes from 0 to 1 at the end of the commanded move, if the magnitude
of the following error is greater than Motor[x].Servo.OutDbOff, the value of
Motor[x].Servo.OutDbSeed is added to the integrator with all other servo terms remaining
active. If the magnitude of the following error at this time is less than
Motor[x].Servo.OutDbOff, but greater than Motor[x].Servo.OutDbOn, then the servo terms
remain active, but there is no seeding offset to the integrator. If the magnitude of the following
error is less than Motor[x].Servo.OutDbOn, the servo output is forced to zero.
The initial seeding of the integrator is very useful for improving the settling time at the
destination position when there is substantial mechanical friction, particularly when the static
friction is higher than the running friction.
The legacy servo control algorithm is designed to make the conversion of Turbo PMAC servo-
loop settings to Power PMAC as simple as possible by duplicating the topology of the Turbo
PMAC servo algorithm. This algorithm is new in V2.0 firmware, released 1st quarter 2015.
Algorithm Structure
The following block diagram shows the structure of the LegacyCtrl algorithm:
Kfff SwFffInt
Sys.LegacyCtrl
1-z-1 Kaff Servo Algorithm
DesVel 1
Kvff
F(z)
1-z-1 Kviff
+ +
+ + +
+ + C(z)
A(z) Kp
DesPos + D(z) Servo
- MaxPos - + Out
Kbreak - - OutDb MaxDac
Err Ki
1-z-1
Kafb
MaxInt
Kvifb Kvfb
1-z-1
1
B(z) 1-z-1
ActVel E(z) ActPos2
ActPos
The key difference in this algorithm from the default ServoCtrl algorithm is the location of the
“C” and “D” polynomial filters. In the ServoCtrl algorithm, they are further to the left, right after
the Kp proportional gain term and before the velocity-loop summing node. In that algorithm,
these filters act on the (scaled) position error term.
Polynomial Filters
In the LegacyCtrl algorithm, the “C” and “D” polynomial filters are located after the torque-
command summing node, just as the Turbo PMAC “notch” filter is. The first two gain terms of
the “C” polynomial (Kc1 and Kc2) match the Ixx36 and Ixx37 numerator terms of the Turbo
PMAC notch filter; the first two gain terms of the “D” polynomial (Kd1 and Kd2) match the
Ixx38 and Ixx39 denominator terms. The same numerical values for these terms used in Turbo
PMAC can be used in the Power PMAC for the same servo update rate.
The “A”, “B”, “E”, and “F” polynomial filters in the LegacyCtrl algorithm are identical in
function and location to the standard ServoCtrl algorithm. The SwPoly7 control bit determining
whether the “A”, “B”, “C”, and “D” polynomials are limited to 2nd order or expanded to 7th order
is identical in function to the ServoCtrl algorithm. Refer to the above section Standard Servo
Algorithm for details.
(Remember that if any of the “A”, “B”, “E”, or “F” polynomial filters is used, or if more than the
first two terms of the “C” and “D” polynomial filters are used, it is no longer a direct port from
the Turbo PMAC servo algorithm. In this case, it is recommended that the default ServoCtrl
algorithm be used instead, with optimized tuning performed for that algorithm.)
Conversion Details
The selection of several feedback and feedforward terms to use in the LegacyCtrl algorithm for
maximum compatibility of operation depends on the setting of Turbo PMAC’s Ixx96 bit 1 (value
2). That control bit determines whether several feedback and feedforward terms are used after the
integrator or before.
If this bit is set to the default of 0 in Turbo PMAC, which is the most common case, the Kvfb
velocity feedback gain term and the Kvff velocity feedforward gain term should be used to mimic
the effects of Ixx31 and Ixx32 in the Turbo PMAC. The SwFffInt switch control bit should be set
to the default value of 0 so that the friction feedforward gain term Kfff mimics the effect of Ixx68
in the Turbo PMAC. In this case, the outputs from these gain terms are added into the torque
summing node, after the integrator.
However, if Ixx96 bit 1 is set to 1 (so Ixx96 = 2 or 3) in the Turbo PMAC, the Kvifb velocity
feedback gain term and the Kviff velocity feedforward gain term should be used to mimic the
effects of Ixx31 and Ixx32 in the Turbo PMAC. The SwFffInt switch control bit should be set to
1 so that the friction feedforward gain term Kfff mimics the effect of Ixx68 in the Turbo PMAC.
In this case, the outputs from these gain terms are added into the velocity summing node, before
the integrator.
If SwFffInt is set to 0, the output friction feedforward gain term is added to the input of the “C”
and “D” polynomial filters, whereas in Turbo PMAC it is added to the output of the “notch”
filter. This means that in Power PMAC, it is effectively multiplied by the DC gain of this pair of
polynomial filters. To get the identical effect in Power PMAC, the value of Kfff should be
divided by the DC gain of these filters:
1 Ixx38 Ixx39
Motor[ x].Servo.Kfff Ixx68 *
1 Ixx36 Ixx37
To compute the specific numerical values of Power PMAC gain terms to match Turbo PMAC
gain terms, refer to the Software Reference Manual chapter Power PMAC Turbo I-Variable
Equivalents for the appropriate formulas.
The adaptive control algorithm continually computes the “plant gain” of the system that is driven
by the Power PMAC in a recursive algorithm, compares this to a preset “reference gain” for the
plant, and adjusts the servo loop gain for the motor so that the overall loop gain stays constant,
maintaining the overall performance of the motor.
Kfff SwFffInt
1-z-1 Kviff
+
+ + + +
+ C(z) +
A(z) Kp SGF
DesPos D(z) + Servo
- - + Out
MaxPos Kbreak - - OutDb MaxDac
Err Ki
1-z-1 1
Kafb J Inertia
MaxInt Estimator
Kvifb
Kvfb MinGainFactor
1-z-1 MaxGainFactor
1
B(z) 1-z-1
ActVel E(z) ActPos2
ActPos
The output of the servo loop must be a torque command, which means that the Power PMAC
must be closing the velocity loop as well as the position loop for the motor. It does not matter
whether the motor phase commutation is performed by the Power PMAC, by the amplifier, or in
the motor itself.
In this case, the “plant gain” includes everything between the numerical command output of the
servo loop and the resulting physical acceleration as derived from the feedback position sensor.
This includes any output-signal gain, amplifier gain, motor torque constant, combined motor and
(reflected) load inertia gain, sensor resolution gain, and motor unit scaling gain.
In a typical system, the only gain component with significant variation will be the inertia gain
term (and the “inertia gain” is inversely proportional to the inertia). Note that this section uses the
term “inertia” to represent either the inertial mass of a linear system, or the mass moment of
inertia in a rotary system. The overall plant gain will vary in direct proportion to the inertia gain.
all of the same terms as the standard servo algorithm that is selected by setting Motor[x].Ctrl to
the default value of Sys.ServoCtrl, but adds several estimation and adaptation terms that are
discussed below.
In this (fixed) configuration, tune the servo loop as you would for a non-adaptive system. Either
the interactive tuning or the automatic tuning tools of the IDE program can be used, or both. Even
if you choose not to use the automatic tuning to set your servo loop gains, execute the excitation
pattern of the automatic tuning. The IDE will report the overall plant gain value that it measures
as a result of the excitation as the “Estimated Gain”. Set saved setup parameter
Motor[x].Servo.NominalGain to the reported value.
These conditions are intended to ensure that the plant is being excited vigorously enough that a
reasonable estimation of the inertial response of the plant can be made.
Motor[x].Servo.EstMinDac is usually set to a value equal to a few percent of the maximum
servo output magnitude that is set by Motor[x].MaxDac.
Once enough consecutive servo cycles with valid measurements have been made, the estimated
plant gain value in Motor[x].Servo.EstGain is used to calculate the servo-loop gain adjustment
term Motor[x].Servo.GainFactor, which is inversely proportional to the estimated plant gain.
The amount of variation of Motor[x].Servo.GainFactor, which is set to 1.0 when the estimated
plant gain is equal to the nominal plant gain, can be limited by the settings of
Motor[x].MinGainFactor and Motor[x].MaxGainFactor. These should be set to cover the
greatest expected variations in plant inertia, so as not to permit further compensation outside of
this range.
It is possible to specify how the closed-loop natural frequency and damping ratio should vary
across the range of system inertias. Generally, it will be desired to permit natural frequency to
decline somewhat as inertia increases. Sometimes, the same is true of damping ratio. Four new
saved setup elements are used to specify this variation.
Without any adaptation, the closed-loop natural frequency varies inversely with the square root of
the system inertia, so if the system inertia increased by a factor of 4, the natural frequency would
be reduced by a factor of 2. Standard adaptation attempts to keep natural frequency constant over
the range of inertias. MinW and MaxW are usually chosen to obtain a variation in natural
frequency in between these two cases.
Motor[x].Servo.MaxDR specifies the desired closed-loop damping ratio at the minimum system
inertia (maximum plant gain) of the adaptive range. Often, values at the higher end of the
common 0.7 to 1.0 range are used at this extreme.
Motor[x].Servo.MinW and Motor[x].Servo.MinDR must both be set greater than their default
values of 0.0 to enable the gain scheduling feature of the adaptive servo algorithm. When
enabled, it is essential that Motor[x].Servo.MaxW and Motor[x].Servo.MaxDR not be left at
their default values of 0.0, as these settings could lead to unsafe control conditions.
The following plots show the action of the adaptive filter. The first plot shows the response of the
system to a parabolic-profile commanded move with low inertia (“unloaded”). Position errors are
mostly within +/-10 counts of the encoder.
The next plot shows the response to the same commanded move when the system has much
higher inertia (“loaded”), with the same gains as for the unloaded system (no adaptation). Position
errors grow to over +/-500 counts.
The next plot shows the response of the same “loaded” system whose saved gains produced the
“unloaded” response shown in the first plot, but with the adaptation turned on. After an initial
perturbation from the sudden change in load, it quickly settles down to a position error range of
about +/-5 counts.
This block diagram shows how the cross-coupled control operates. The blocks ServoCtrlα and
ServoCtrlβ are the feedback/feedforward algorithms for the individual motors, operating on their
own command trajectories (which are generally identical, but are not required to be so) and
measured feedback positions (which can and do differ). The blocks Xctrlα and Xctrlβ are the
cross-coupled terms, which operate on the difference between the errors of the two motors.
-
+ + Gantry
AdaptiveCtrlα
Motor α
DesPosα ActPosα
+
PosErrorα
Xctrlα
+
-
Xctrlβ
PosErrorβ
-
DesPosβ ActPosβ
Gantry
AdaptiveCtrlβ
+ + Motor β
-
The output of the servo loops should be torque commands, which means that the Power PMAC
must be closing the velocity loop as well as the position loop for the motors. It does not matter
whether the motor phase commutation is performed by the Power PMAC, by the amplifier, or in
the motor itself.
The cross-coupled algorithm uses all of the same terms for each motor as the standard servo
algorithm that would be selected by setting Motor[x].Ctrl to the default value of Sys.ServoCtrl,
but adds several cross-coupling terms that are discussed below. Each motor can use all of the
terms of the adaptive control algorithm, which would be selected by setting Motor[x].Ctrl to
Sys.AdaptiveCtrl, and is a superset of the standard servo algorithm. This permits each motor’s
own gains to change as the cross axis moves, transferring inertia from the motor on one side to
the motor on the other.
This tuning is best done with the lower-numbered motor as the leader motor (standard setting of
Motor[x].ServoCtrl = 1), and the higher-numbered motor as the follower motor
(Motor[x].ServoCtrl = 8). The tuning control of the IDE software will automatically recognize
this configuration as a leader/follower pair when you specify either interactive or automatic
tuning for the leader motor. Any tuning move or excitation that can be done for a single motor
can now be done for the motor pair.
Whatever combination of automatic and interactive tuning steps is desired can be used to
optimize the performance with the non-coupled terms. The performance of profiled moves similar
to what will be used in the application should be evaluated.
The tuning control window in the IDE should recognize this configuration and show an option for
cross-coupled tuning. If it does not, change the selected motor up and back, or right-click and
select Refresh. In auto-tuning, there will be a check box marked “Use Cross-Coupled Gantry
Control”. In interactive tuning, there will be a button marked “Set Cross-Coupling Gains”.
Usually, the auto-tuning will be attempted first, as it should produce gain settings that are at least
close to optimum. Some users will attempt to improve on the auto-tuned settings through
subsequent interactive tuning procedures.
There are three cross-coupled terms for each motor in the gantry pair. All three operate on the
difference in the position errors of the two motors each servo cycle. The gains for a given motor
contribute to the servo command output for that motor in the direction sense to attempt to drive
the difference in errors between the two motors toward zero.
The three terms are the proportional, integral, and derivative (P, I, and D) gains.
Motor[x].Servo.Kxpg is the proportional gain term operating directly on the difference in errors.
Motor[x].Servo.Kxig is the integral gain term operating on the accumulated difference in errors.
Motor[x].Servo.Kxvg is the derivative gain term operating on the rate of change in the difference
in errors. Generally, these terms will be identical, or very similar, for both motors.
The transfer function for each cross-coupling control block, from the difference-of-errors input to
the output contribution to the servo command, is:
K xig
K x z K xpg 1
K xvg 1 z 1
1
1 z
To use the IDE’s tuning features, click on “Tools” in the top menu bar, then select “Tune” from
the pull-down menu. You will see a screen that looks something like this:
The buttons on the left allow you to select from the possible tuning options, both interactive and
automatic. If the button is “grayed out”, your setup for the motor does not support that
functionality. (The motor in this example does not have the adaptive control algorithm or digital
current loop enabled, so the buttons selecting tuning options for those features are disabled.)
Issues of tuning the digital current loop are only relevant if commutation and current-loop closure
are enabled for the motor. These issues are covered in the Setting Up Power PMAC-Based
Commutation and/or Current Loop chapter of the User’s Manual.
Note the motor-select control in the lower left corner, and the “Kill” button below that can be
used to disable the motor immediately if something goes wrong.
Automatic Tuning
Most users will start the tuning process for a motor with automatic tuning by the IDE. This
procedure is selected by clicking on the “Position Loop Auto Tune” button on the left side of the
screen. You will then see a screen that looks like this:
This is the “Basic Auto Tune” screen, which permits a very simple interface for obtaining
reasonable servo tuning functionality.
In Step 1, select the command output mode of the servo loop. Choose “Velocity Mode” for
analog velocity-mode servo drives, “pulse and direction” drives, and hydraulic valve controls.
Choose “Torque Mode” for analog torque (current) mode servo drives, “sinewave-input” servo
amplifiers, and “power-block” amplifiers.
In Step 2, select a location for the slider with the pointing device. The further to the right the
slider is moved, the stiffer the servo loop the IDE will create for the motor, resulting in more
responsive action, but increasing the possibility of vibration and instability due to overtuning. The
user should either select or de-select the “Feedforward” check box. Most users will want this box
selected, so that the IDE’s auto-tuning calculations implement the feedforward gains to optimize
trajectory tracking.
Clicking on “Auto Tune Motor” will cause Power PMAC to command an excitation sequence on
the motor, measure the response, and recommend gain settings. You will see a screen with
recommended settings such as the following:
In the “Basic Auto Tune” screen, you can click on the “Advanced Auto Tune” check box to get a
screen that gives you some more control over the excitation and auto-tuning process. You will see
a screen like this:
In Step 2, you can specify your desired results more directly. In Step 3, you can specify the
parameters for the excitation move.
In this screen, you must select one of the radio buttons under “Trajectory Selection”. Typically,
the first trajectory selected in the interactive tuning process is “Position Step”. This creates an
instantaneous step in the commanded position of the motor, holds it for a time, and then steps
back to the original position. The user can select the size of the step and the duration of the hold
from the right side of the screen. Clicking on “Do a Step Move” causes Power PMAC to execute
the step.
You will then see a plot of the step response in a screen like the following:
You can change gains and repeat the step move until you get the response you desire:
Next, many users will select the “Parabolic Velocity” trajectory to optimize trajectory tracking
with feedforward gains. This should be an aggressive move, especially to see the acceleration
effects. There should be no integral action during the move, so these should be done either with
the Ki gain set to 0, or preferably with SwZvInt set to 1 so the integrator is automatically turned
back on between moves so there is no significant error at the start of a move.
Note that the following error curve has the same shape as the commanded velocity curve.
Mathematically speaking, the two curves are highly correlated. The screen reports that the
correlation is virtually perfect, with a value of 1.000. Note also that the peak magnitude of the
following error is about 200 motor units.
First, eliminate the following error component that is proportional to the commanded velocity
using the velocity feedforward term:
Here, we see a very different error profile, and one with a maximum magnitude of about 10
counts. One aspect of the profile is V-shaped, related to the V-shaped acceleration profile. We
will tackle this now by eliminating the error proportional to acceleration with the acceleration
feedforward term.
The remaining error is of roughly constant magnitude during each half of the move, with the
same sign as the velocity. This is due to Coulomb (dry) friction. We can eliminate this with the
friction feedforward term:
Finally, enable the integrator during the move by setting the SwZvInt integration mode parameter
to 0:
This technique has many possible uses; the most common is to be able to close an auxiliary loop
around a standard position loop. The auxiliary loop controls some quantity affected by the
position loop’s motion, such as torque or force applied, or distance from a surface. The coupling
of the loops can be turned on and off, permitting easy switching between control modes.
Web tensioning
Torque-limited screwdriving
Metal bending
Controlled-force part insertion
Height control over uneven surface (e.g. for auto-focus)
The inner loop in these applications is typically a standard position loop driving a real actuator
with a standard position feedback device such as an encoder or resolver. The first step in setting
up such an application is to get this loop working in standard positioning mode (running at
continuous velocity if appropriate).
The outer loop in these applications uses a feedback sensor measuring whatever quantity the outer
loop is to be controlled. Often these force or torque transducers such as strain gages or tensioning
dancer arms, or distance (“gap”) transducers employing capacitive or ultrasonic mechanisms.
By engaging and disengaging the outer loop, the user can switch between standard position
control using just the inner loop, as when not meeting the resistance of a surface, and control of
the auxiliary function, as when pushing with controlled force against a surface. The transition is
simple to perform, and smooth in operation.
In some cases, the outer-loop “motor” is also a position loop, with its feedback being a position
sensor on the load. In this scenario, the inner-loop “motor” closes its position and velocity loops
using the sensor on the back of the motor. The outer-loop motor is used to issue corrections to the
inner-loop motor based on the load feedback. This technique is typically used when there is a
huge amount of backlash due to multiple-stage gearing, as when driving multi-ton loads. In these
cases, it is more effective than simply using the motor sensor for the velocity-loop feedback, and
the load sensor for the position-loop feedback, of a single Power PMAC “motor”.
the outer-loop closure and the inner-loop closure. This has the potential to limit performance of
the outer loop in very high-bandwidth applications.
The second strategy uses a special “zero-dimensional” (0D) compensation table to transfer the
outer loop’s command output to the inner loop. This 0D table has a single data point that takes the
command value from the outer loop each servo cycle and transfers it to a position offset register
for the inner loop. It is possible to do this without a servo-cycle delay, but the outer-loop motor
must be of a lower number than the inner-loop motor.
In addition, the compensation tables must be set to execute in between the servo-loop closure of
the outer-loop motor and that of the inner-loop motor by setting saved setup element
Sys.CompMotor to a value greater than the number of the inner-loop motor, but not greater than
that of the outer-loop motor. If you are also using compensation tables for other purposes, all
motors using these tables should be numbered greater than or equal to the value of
Sys.CompMotor.
The third strategy is a direct coupling of the loops using Motor[x].pCascadeCmd of the outer-
loop motor. This can be used to write the output command of the outer-loop motor directly to one
of the offset registers for the inner loop, without any intermediate steps. This method is new in
V2.1 firmware, released 1st quarter 2016.
In general, if the maximum total position offset required by the inner loop to keep the outer-loop
error at or near zero is within the range of the output value of the outer control loop, this value
does not need to be integrated before it is used by the inner loop. This is typically the case in
applications where the outer loop is only applying small corrections to the inner-loop, as in laser
auto-focus corrections or flying height gauge corrections. In these cases, the “steady-state”
condition is usually at zero velocity.
However, if the maximum total position offset required by the inner loop can get very large, and
potentially be unbounded, then the output value of the outer control loop must be integrated
before it is used as a position offset into the inner loop. This act of integration makes the output of
the outer loop effectively a velocity correction to the inner loop. Tensioning control of a
constantly moving web is a typical application of this type. In these cases, the “steady-state”
condition is usually at a non-zero velocity.
The method used to determine whether this command is integrated or not is different for each of
the strategies for coupling the loops together. The particular method for each strategy is explained
in the section for that strategy.
Note that when the output command from the outer loop is integrated, the gains of the outer servo
loop should be extremely small. Generally, the proportional gain term of the outer-loop motor,
Motor[β].Servo.Kp, will be much less than 1.0.
Typically, the feedback from the ECT entry will be scaled in units of least-significant bits (LSBs)
of the sensor. With the default motor feedback scale factor values of 1.0 for Motor[β].PosSf and
Motor[β].Pos2Sf, the motor will use these same units. It is possible to scale the motor into
engineering units (e.g. Newtons for force) with different values of PosSf and Pos2Sf; it is also
possible to perform the scaling into engineering units for the axis assigned to this motor with the
scaling coefficient of the axis definition statement.
You will not be able to tune the outer loop until you have linked it with the inner loop. The next
two sections describe the steps in the two methods of linking the loops.
Commanded
Auxiliary
Trajectory
EncTable[ζ].
+ pEnc
Auxiliary ECT Entry
Servo for Aux
Filter Command
- Motor[α].
pMasterEnc Power PMAC
Motor for
Virtual Motor[α]. Physical Actuator
Power PMAC MasterCtrl
Master
Motor Position + Motor[α].
+ Position pDac
Output
Servo Amp
Commanded Device
Filter
Position -
Trajectory
Auxiliary Position/Velocity
Servo Loop Motor M
Servo Loop
Actual
Actual Position Motor[α]. EncTable[δ].
Auxiliary pEnc ECT Entry pEnc
Position
Value for Position E Sensor
Sensor
Motor[β]. EncTable[ε].
pEnc ECT Entry pEnc
Auxiliary
for Aux S Sensor
Sensor
Note that using this internal memory register means that it does not matter where the outer-loop
motor writes its servo command with Motor[β].pDac. It also does not matter if the register
specified by pDac is overwritten by another motor (as would be the case if multiple motors wrote
to the register at the address of Sys.pushm).
In most cases, EncTable[ζ].index1, index2, index3, and index5 will be left at their default
values of 0. Non-zero values for these elements can be used for scaling and change-limiting
functions, but these will rarely be used in this type of application.
If the outer-loop command will not be integrated before use in the inner loop (i.e. it represents a
position offset), then EncTable[ζ].index4 should be set to its default value of 0. If the outer-loop
command will be integrated once before use in the inner loop (i.e. it represents a velocity offset),
then EncTable[ζ].index4 should be set to 1. While it is possible to integrate twice, this has not
been found to be useful in cascading servo loops.
EncTable[ζ].ScaleFactor allows you to scale the intermediate value for output. If you set it to
1/256 (with no pre-scaling or shifting), the result will be in the same units as the source register,
with a range of ±32,768. Of course, other scale factors can be used, but it is very important to
remember that this element acts as a gain term in the outer servo loop, so changing it changes the
outer loop’s overall gain.
Note that it is also possible to use the value in the output register specified for the outer-loop
motor with Motor[β].pDac. (In firmware versions older than V1.5, released 3rd quarter 2012, this
is required, because the ECT method for using floating-point values did not exist yet.) In this
case, pDac must contain the address of a valid register that can hold this value, and nothing can
overwrite this value before it is used in the next servo cycle. In this case, EncTable[ζ].type = 1
(single-register read), EncTable[ζ].pEnc contains the address of the same register as
Motor[β].pDac, EncTable[ζ].index4 is set to 0 for no integration, or 1 for single integration, and
EncTable[ζ].ScaleFactor is set to 1/65,536 to provide an output range of ±32,768, with other
setup elements typically left at their default values of 0.
Motor[α].MasterCtrl for the inner-loop motor also controls how the outer loop’s corrections
interact with trajectory commanded positions for the inner loop. When bit 1 of MasterCtrl is set
to 0, the inner-loop motor’s trajectory commanded positions are relative to a fixed origin, and
these commanded moves effectively cancel out whatever corrections have come in through the
master position port. When bit 1 (value 2) is set to 1, the following is in “offset mode”, the
corrections that come in through the master position port effectively offset the origin for
programmed commanded moves, permitting commanded moves and master corrections to be
superimposed. This distinction in mode is true even when following is disabled.
Note that when the following is in offset mode, when the position for the motor is reported, the
following component of this position is subtracted out, so the reported value is what the position
would be without the following offset. To see the following component, you must query the value
of the element containing it directly: Motor[α].ActiveMasterPos.
When the outer loop is engaged (bit 0 =1), the following almost always must be in offset mode
(bit 1 = 1), making the required value of Motor[α].MasterCtrl be 3 for this operation. Even if
there are not explicit commands in the motion program for the axis assigned to the inner loop’s
motor at this time, any motion command for the coordinate system containing this motor
implicitly commands that motor to its previous commanded position. If the following is not in
offset mode, this will take out the corrections that have come in since the last programmed move
or move segment.
When the following is disabled (bit 0 = 0), if you wish to command the inner loop’s motor to a
definite physical position, you must put the following in “normal mode” (bit 1 = 0), making the
required value of Motor[α].MasterCtrl be 0 for this operation.
Note that whenever the mode bit (bit 1) of Motor[α].MasterCtrl is changed, whether or not
following is enabled, the programming origin for the motor is changed, which changes the
relationship between motor and axis positions. This means that the “pmatch” position matching
function must be executed before the next programmed axis move. This function is automatically
implemented at the start of motion program execution, but if the mode change is made in the
middle of execution of a motion program, or the next programmed axis move is executed in a
PLC program, the function must be implemented through an explicit pmatch command (on-line
or buffered program).
Commanded
Auxiliary
Trajectory
CompTable[ζ].
+ Source[0]
Auxiliary “0-D”
Servo Comp
Filter Table
- CompTable[ζ].
Target[q] Power PMAC
Motor for
Virtual Sys. Physical Actuator
Power PMAC CompEnable
Compensation
Motor Desired Position + Motor[α].
+ Position pDac
Output
Servo Amp
Commanded Device
Filter
Position -
Trajectory
Auxiliary Position/Velocity
Servo Loop Motor M
Servo Loop
Actual
Actual Position Motor[α]. EncTable[δ].
Auxiliary pEnc ECT Entry pEnc
Position
Value for Position E Sensor
Sensor
Motor[β]. EncTable[ε].
pEnc ECT Entry pEnc
Auxiliary
for Aux S Sensor
Sensor
All compensation tables are updated immediately before the servo-loop closure of the motor
whose number is specified by Sys.CompMotor. When compensation tables are used for
measurement corrections, it is best to have them updated before the servo-loop closure of the
motor. Therefore, all motors using compensation tables for measurement corrections should have
numbers equal to or higher than the value of Sys.CompMotor.
If the application only uses a single cascaded servo loop, it is often easiest to utilize Motor 0 as
the virtual motor for the outer loop. On re-initialization, Motor 0 is left as a “dummy motor”, with
auto-identified hardware channels assigned to motors starting with Motor 1. Because the setup of
the outer loop will not be able to rely on the auto-assignments in almost all cases, it will make
sense to set up Motor 0 manually to implement the outer loop, set Sys.CompMotor to 1, and
utilize the automatic setup as much as possible for the physical motors starting at Motor 1.
CompTable[ζ].Source[0] for this table must be set to the number of the Power PMAC motor that
is executing the outer servo loop.
CompTable[ζ].Ctrl for this table must be set to 3 to instruct the table to automatically pick up
the servo command from this motor every servo cycle from its IqCmd register.
CompTable[ζ].Nx[0], Nx[1], and Nx[2] must all be set to 0 to specify zero data zones in each of
the three potential dimensions for the table, making this a “0D” table.
CompTable[ζ].Sf[0] is typically set to 1.0 so that no rescaling of the command is done before it
is used in the inner loop. Rescaling is possible, but it is important to remember that this scale
factor acts as a gain term in the outer servo loop, and changing its value changes the loop gain.
Sys.CompEnable must be to a value at least one greater than the index value ζ of the table in
order for the table to be active. Note that this activates all compensation tables with index values
from 0 to one less than the value of Sys.CompEnable.
If you want to be able to effectively disable this table alone, you can set the value of
CompTable[ζ].Sf[0] to 0, which forces the correction to 0.0. Alternately, you can redirect the
output of the table to an unused register by setting CompTable[ζ].Target[0] to something like
Motor[255].CompDesPos.a, which leaves the last correction in place for the inner-loop motor.
(This correction could then be overwritten manually.)
When the position for the target motor is reported, the compensation component of this position is
subtracted out, so the reported value is what the position would be without the compensation
offset. To see the compensation component, you must query the value of the element containing it
directly: Motor[α].CompDesPos.
As long as the outer loop is executed in a motor with a lower number than the motor for the inner
loop, there is no delay in the linkage. If the outer loop is executed in a motor with a higher
number than the motor for the inner loop, there will be a one servo-cycle delay, which possibly
could limit performance of the overall process.
In this method, the linkage is accomplished through the use of Motor[x].pCascadeCmd for the
outer-loop motor, which allows the servo command value for the motor to be written to one of
several offset registers for the inner-loop motor. (The standard Motor[x].pDac, which is typically
used for actual output of the servo command value, cannot be used for this purpose, because it
must point to an integer register, and these offset registers are double-precision floating-point.)
This block diagram shows the principle of cascaded servo loops with direct linkage.
Commanded
Auxiliary
Trajectory Motor[β].
pCascadeCmd
+
Auxiliary
Servo
Filter
-
Power PMAC
Master Position Motor for
Virtual or Physical Actuator
Power PMAC Compensation
Motor Desired Position
+ Motor[α].
+ Position pDac
Output
Servo Amp
Commanded Device
Filter
Position -
Trajectory
Auxiliary Position/Velocity
Servo Loop Motor M
Servo Loop
Actual
Actual Position Motor[α]. EncTable[δ].
Auxiliary pEnc ECT Entry pEnc
Position
Value for Position E Sensor
Sensor
Motor[β]. EncTable[ε].
pEnc ECT Entry pEnc
Auxiliary
for Aux S Sensor
Sensor
If you want to integrate the outer-loop command before writing it to the inner-loop offset register,
set Motor[x].CascadeMode for the outer-loop motor to 1. If you do not want to integrate the
command, set CascadeMode to its default value of 0.
If you are integrating the outer loop’s command value before using it in the inner loop, your
proportional gain term will be extremely low. Start with values for Motor[β].Servo.Kp of 0.01 or
so.
It is possible to use the IDE’s standard tuning tools to tune the outer loop just as you would for a
standard position loop.
Most commonly, the outer-loop motor will be assigned to an axis in the same coordinate system
as the inner-loop motor, and commanded in the same motion program for the coordinate system.
Axis-naming conventions and standards (e.g. RS/EIA-267) consider these as “secondary axes”
and suggest the name of U when matched with an X axis, V when matched with Y, and W when
matched with Z.
Setup Examples
In these examples, Motors 1, 2, and 3 are the X, Y, and Z-axes, respectively, in Coordinate
System 1 of a Cartesian stage. Each uses quadrature feedback with 0.1-micron resolution, and is
programmed in millimeters. These are set up as for a standard positioning application.
Motor 0 (which is not used in most applications) is used as a virtual motor to control the gap
height of the vertical tool over the surface. It uses a capacitive gap sensor through an ACC-28E
16-bit A/D converter, with the LSB of the ADC measuring 0.25 microns. It is assigned to the W-
axis in the same coordinate system, also programmed in millimeters (of gap). If we use the
position-following technique to couple the loops, we could use Motor 4 instead for this, but if we
use the compensation-table technique to couple the loops to eliminate the servo-cycle delay, we
must use a lower-numbered motor for this outer-loop motor than for the inner-loop motor (#3).
It does not matter where the servo output is written, for either method of coupling.
Motor[0].pDac can be left at its default value of Sys.pushm, so the output is written to the first
register of the user shared memory buffer.
To be able to use the processed result of this entry as the master for the Z-axis motor (#3), the
following setting should be made:
Motor[0].pCascadeCmd = Motor[3].ActiveMasterPos.a
By writing directly to this register, the position-following function for Motor 3 does not need to
be enabled, so bit 0 (value 1) of Motor[3].MasterCtrl should be left at its default value of 0.
However, to be able to superimpose this outer-loop command and an inner-loop trajectory value,
bit 1 (value 2) of Motor[3].MasterCtrl should be set, so the resulting value of
Motor[3].MasterCtrl in this mode should be 2.
To integrate the outer-loop command value before writing it to the inner-loop offset register, as
for the tensioning of a continuously moving web, Motor[0].CascadeMode should be set to 1. To
write without integrating, CascadeMode should be set to 0.
Enabling or disabling the following offset mode (whether the following function is enabled or
not) changes the relationship between the motor position and its related axis position. When this
relationship is changed, the “pmatch” position-matching function must be executed before the
next programmed axis move. While this function is automatically executed when a “run” or
“step” command is given to start a motion program, if the mode is changed in the middle of a
motion program, it must be explicitly commanded with the pmatch command.
The following motion program segment shows how the transition to engaging the outer loop can
be accomplished in our example system.
The following motion program segment shows how the transition to disengaging the outer loop
can be accomplished in our example system.
operation. It is set to 0.0 (table output always equal to 0) when the inner-loop motor is to be
controlled by itself, relative to a fixed origin. It is set to 1.0 (table output equal to outer-loop servo
command) when it is to be controlled by the outer-loop motor.
It is not advised to change this scale factor instantly between 0.0 and 1.0, as this could cause a
sudden jump in the position of the inner-loop motor. It is easy to change it gradually in a loop.
The following motion program segment shows how the transition to engaging the outer loop can
be accomplished in our example system.
The following motion program segment shows how the transition to disengaging the outer loop
can be accomplished in our example system.
When the value of Motor[x].pCascadeCmd is changed from the address of the target register to
0, unlinking the loops, the last value written to the target register remains there, keeping its
offsetting effect on the inner loop.
If it is desired to be able to command the inner loop directly to an absolute position, the motor
should be taken out of “offset following” mode by setting Motor[y].MasterCtrl to 0. This does
not cause motion of the motor, but allows the next programmed move for the axis assigned to the
motor to remove the offset.
When the value of Motor[x].pCascadeCmd is changed from 0 to the address of the target
register, linking the loops, the outer loop will write its command value to the target register on the
very next servo cycle. Care should be taken so that this will not create a significant jump in the
position of the inner loop.
Switching between offset and normal mode using Motor[y].MasterCtrl, even if the following
function itself is not enabled, changes the relationship between motor position and related axis
position. When this relationship is changed, the “pmatch” position-matching function must be
executed before the next programmed axis move. While this function is automatically executed
when a “run” or “step” command is given to start a motion program, if the mode is changed in the
middle of a motion program, it must be explicitly commanded with the pmatch command.
The following motion program segment shows how the transition to engaging the outer loop can
be accomplished in our example system.
The following motion program segment shows how the transition to disengaging the outer loop
can be accomplished in our example system.
Trajectory Pre-Filter
The motor’s trajectory pre-filter, while technically not part of the servo loop, is often treated as
such. It acts on the motor’s net desired position, including the mathematically computed
trajectory from programmed axis moves or independent motor moves such as jog moves, master
following positions. and compensation positions. The resulting output of the filter is sent to the
servo loop as a potentially modified net desired position.
5. Implementing a pure “time delay” filter. In some applications, particularly those in which
there is a time delay in transferring commanded positions to externally controlled axes
for some PMAC motors, it is desirable to add a pure time delay to internally controlled
axes. This can be done with the trajectory pre-filter. (For an added delay of x cycles of
the filter, set Pn0 to 1.0, Pnx to -1.0, Pd1 to -1.0, and all others to 0.0. Remember that
just setting Pn0 to 1.0, and all others to 0.0 creates a single-cycle delay.)
Overview
The trajectory pre-filter is a sampled digital filter with 4th-order polynomials in the numerator and
denominator. The sampling occurs every n servo cycles, where n is a positive integer. The input
to the filter is the difference between the present sample’s trajectory command position and the
previous sample’s trajectory command position. (It operates on the difference so that no
numerical resolution of the floating-point values is lost when the magnitude of the command
position values gets very large.)
The block diagram format of the filter is shown in the following diagram:
Ts Ts
Ppos + DesPos
Spliner
Trajectory To
Before Servo
Filter -
1 z 1
The overall transfer function of the pre-filter can be expressed by the equation:
Pz 1 1 z 1 Pz
The actual difference equation implemented each cycle k inside the P'(z) block itself is:
rk Pn0 rk Pn1rk 1 Pn2 rk 2 Pn3 rk 3 Pn4 rk 4 Pd1rk1 Pd 2 rk2 Pd3 rk3 Pd 4 rk4
where the r values are the inputs to the filter block and the r' values are the outputs from the filter
block.
If the motor servo loop is opened, either in the enabled or disabled (killed) state, Power PMAC
will automatically set Motor[x].PreFilterEna to the negative of the closed-loop value (e.g. to -5
when it is 5 when closed-loop). This permits the filter to be properly re-initialized when the loop
is next closed. These transitions require no user intervention.
Filter Coefficients
Motor[x].Pn0, Pn1, Pn2, Pn3, and Pn4 are the “numerator” coefficients of the core filter box,
with Pni multiplying the input value from i sample cycles previous. These coefficients are
double-precision (64-bit) floating-point values.
Motor[x].Pd1, Pd2, Pd3, and Pd4 are the “denominator” coefficients of the core filter box, with
Pdi multiplying the output value from i sample cycles previous. These coefficients are double-
precision (64-bit) floating-point values.
In most standard uses of the trajectory pre-filter, it is very important that the filter not add any
scaling to the trajectory – that its “DC gain” be exactly equal to 1.0. For this to be the case, the
sum of all Pni terms minus the sum of all Pdi terms must equal exactly 1.0. Usually, the Pn1 to
Pn4 terms, and the Pd1 to Pd4 terms are set to get the desired filter dynamics. Then Pd0 is set to
1.0 minus the sum of the higher-order Pni terms plus the sum of the Pdi terms so there is no net
scaling due to the filter. Usually it is best to let Power PMAC or the IDE calculate Pn0 from an
expression of the other terms for the most exact possible representation of this number.
Filter DC Gain
In almost all standard uses of the trajectory pre-filter, the filter should not add any scaling to the
trajectory – that is, its “DC gain” should be exactly equal to 1.0, so that when the input is constant
(DC), the value of the output equals the value of the input. The DC gain of a digital filter can be
evaluated by calculating the value of the transfer function with the operator z value set to 1.
Because of the topology of Power PMAC’s trajectory pre-filter, with the key filter block
operating on the difference of the input, it is virtually guaranteed that the DC gain of the overall
filter P(z) will be exactly equal to 1.0. This is due to the (1 – z-1) differencing term in front of the
key filter block, which evaluates as exactly 0.0 when z is 1. So the DC gain of the total filter
evaluates as:
P z z 1 1 1 1P z 1 0 1
(The exception to this rule occurs when the denominator of the P'(z) filter block has a factor of (1
– z-1) in it, which cancels out this differencing term. This is the case for the “machine lock” filter,
which has an overall DC gain of 0, preventing movement.)
Spliner Reconstruction
If Motor[x].PreFilterEna is set to a value n greater than 1, the filter itself is only sampling the
trajectory every n servo interrupts, and producing a new output every n servo interrupts. In this
case, the filtered output must be interpolated to provide a new set point for the servo loop every
servo interrupt.
This interpolation is done by the “spliner”, which interpolates between consecutive filter outputs
using a cubic B-spline technique that guarantees that velocity and acceleration of the
reconstructed trajectory are always continuous, even as the filter output points are passed. Not
that this reconstruction delays the output by 2 periods of the filter.
The IDE software allows you to directly specify the performance attributes you want from the
filter. From your specification, it will calculate the required coefficients for you. You do not need
to understand digital filtering theory in order to use this feature.
If the overall filter transfer function is P(z) and the Power PMAC difference-path filter transfer
function is P’(z), the two can be related by the following equations. With the overall transfer
function expressed as a function of the difference-path filter by:
Pz 1 1 z 1 Pz
The difference-path filter can then be expressed as a function of the overall filter as:
1 P z
P z
1 z 1
This equation permits you to compute the Power PMAC filter block required to implement a filter
designed in the standard analytic format.
For example, consider a second-order in-line filter with the following transfer function:
N 0 N1 z 1 N 2 z 2
P z
1 D1 z 1 D2 z 2
1 Pz 1 D1 z 1 D2 z 2 N 0 N1 z 1 N 2 z 2
P z
1 z 1 1 z 1 1 D1 z 1 D2 z 2
1 N 0 D1 N1 z 1 D2 N 2 z 2
Lz
1 D1 1z 1 D2 D1 z 2 D2 z 3
Note that the equivalent difference-path filter has an additional term in the denominator. This
means that for an in-line filter to have a direct equivalent in the difference path, it is limited to
third-order in the denominator.
Motor[x].Pn0 = 1 – N0
Motor[x].Pn1 = D1 – N1
Motor[x].Pn2 = D2 – N2
Motor[x].Pn3 = 0
Motor[x].Pn4 = 0
Motor[x].Pd1 = D1 – 1
Motor[x].Pd2 = D2 – D1
Motor[x].Pd3 = -D2
Motor[x].Pd4 = 0
n2
Ls
s 2 2n s n2
where n is the natural frequency (in radians per second), and is the damping ratio (unitless).
To implement this as a trajectory pre-filter, we must first convert it to digital form, then from the
in-line path to the difference path. We will examine both the “backward-difference” and “bi-
linear” (Tustin) conversions to digital format.
n2 n2Ts2
L z
2
1 z 1 1 z 1 1 2 z 1 z 2 2nTs 1 z 1 n2Ts2
2n n2
T s T s
n2Ts2
L z 2 2
n Ts 2nTs 1 2nTs 2z 1 z 2
n2Ts2
n2Ts2 2nTs 1
L z
2 T 2 1 1
1 2 2 n s z 2 2
z 2
n Ts 2nTs 1 n Ts 2nTs 1
n2
L z 2
2 1 z 1 2 1 z 1
1
2 n2
1
Ts 1 z Ts 1 z
n
n2Ts2
1 2 z 1
z 2
L z 4
nTs
1 2 z 1 z 4T 1 2 z
2 2
1
z 2 2 n s 1
z 2
2
Power PMAC can hold up to 256 compensation tables. Each table is individually controllable as
to its source(s), target(s), dimensionality, size, spans, and activation control. Once entered, the
tables operate transparently to the user.
Ability to define the start point and span of the table arbitrarily in each dimension
Ability to repeat the span of the table indefinitely in “rollover” or “mirror” mode
Source[n]: The number(s) of the (up to) 3 source motors, whose desired position is read
each servo cycle to determine the location in the table, where n is the “dimension index”
SourceCtrl: a 3-bit control value for the table, with each bit n specifying whether the
desired position or the actual position of the source motor of dimension index n is used to
calculate the compensation value.
Nx[n]: The number of data zones in each of the (up to) 3 dimensions
X0[n]: The starting location of the (up to) 3 sources; that is, the value of the source
motor’s desired position that coincides with the first table entry in each dimension
Dx[n]: The span of the (up to) 3 sources; that is, the difference between the starting
location and the ending values of the source register in each dimension
Ctrl: A control byte for the table specifying the interpolation order and boundary mode in
each dimension
Target[q]: The address(es) of the (up to) 8 target registers, where the table correction is
written each servo cycle
Sf[q]: The output scale factor for the (up to) 8 target registers, by which the table’s
correction is multiplied before being written to that target register.
OutCtrl: An 8-bit control value for the table, with each bit q specifying whether the
result replaces the existing value in the Target[q] register, or is added to the existing
value in the register.
Data[i]: The correction entries in a table with one active dimension, where i is the
“location index” in this dimension
Data[j][i]: The correction entries in a table with two active dimensions, where i is the
“location index” for the 1st dimension (“dimension index” n = 0) and j is the “location
index” for the 2nd dimension (“dimension index” n = 1).
Data[k][j][i]: The correction entries in a table with three active dimensions, where i is the
“location index” for the 1st dimension (“dimension index” n = 0), j is the “location index”
for the 2nd dimension (“dimension index” n = 1), and k is the “location index” for the 3rd
dimension (“dimension index” n = 2).
There must be sufficient memory reserved in this buffer for all of the tables used. Each data point
in a compensation table is a single-precision floating-point value, using 4 bytes of memory. The
memory required for the data entries of a table can be calculated as:
where Nx[i] is the table header element (CompTable[m].Nx[i]) specifying the number of zones
of the table in that dimension.
The best way of changing this memory allocation is through the “Project Properties” control in
the Integrated Development Environment (IDE) PC software, which allows you to set the “Table
Buffer” size in megabytes. In the Power PMAC, the buffer memory allocation is set only at
power-on/reset, so to change the allocation, you must change the setting the IDE project control,
download the project to the Power PMAC, issue the save command to store this value to flash
memory, then reset the Power PMAC.
The memory for the entire table is allocated when the first data entry value is set in a Script
command (e.g. CompTable[5].Data[0][0] = 3.5). The starting location is the first word past the
last table already defined, and a memory space is allocated to the table according to the above
equation. This means that the size of the table must be defined before any data points are entered.
If all of the tables are defined just one time after power-on/reset, whether from flash memory or
from project download, memory space is allocated to tables in the order they are defined, from
the start of the buffer toward the end. As long as there is sufficient buffer space for all tables, this
goes smoothly, with the details hidden from the user.
However, if the user wishes to redefine the size of an already loaded table, the ramifications for
memory allocation must be understood. Any time Power PMAC executes a Script command that
changes the value of an existing table dimension CompTable[m].Nx[i], the pointer to the table
data entries in the buffer is cleared.
The pointer to the start of table data entries is not set again until the first Script command that sets
a data entry value. At that time, the pointer is set to the address of the register in the buffer
immediately following the last existing table. This means that if the table whose dimensions were
changed was not the last table in the buffer, the memory that was allocated for the table data is
lost until the next power-on/reset.
Note that it is possible to set table dimension and table data values in C, but doing so does not
trigger any of the memory management functions that the Script commands do. If defining or
redefining tables in C, the commands to set the dimension values and the first data value should
still be done with Script commands. This can be done from a C routine using the command""
function to execute the Script command within the quotes. Then the subsequent entry of data
points, including possibly overwriting the first data point, can be done with much faster C
commands.
Dimension Indices
Each Power PMAC compensation table has the potential for using three dimensions. For the table
definition elements Source[n], Nx[n], X0[n], and Dx[n], the dimension index n can take a value
of 0, 1, or 2 for the 1st, 2nd, and 3rd dimensions, respectively.
For the table data points, the index values for each point specify the location of the point along a
dimension. For a 1D table, the value of the location index i for the point Data[i] indicates the
location of the point along the 1st dimension (corresponding to dimension index n = 0).
For a 2D table, the value of the location index i for the point Data[j][i] indicates the location of
the point along the 1st dimension (corresponding to dimension index n = 0), and the value of the
location index j indicates the location of the point along the 2nd dimension (corresponding to
dimension index n = 1).
For a 3D table, the value of the location index i for the point Data[k][j][i] indicates the location
of the point along the 1st dimension (corresponding to dimension index n = 0), the value of the
location index j indicates the location of the point along the 2nd dimension (corresponding to
dimension index n = 1), and the value of the location index k indicates the location of the point
along the 3rd dimension (corresponding to dimension index n = 2).
One-Dimensional Tables
To specify one active dimension (a “1D” table), CompTable[m].Nx[0] should be set greater than
0, but CompTable[m].Nx[1] and CompTable[m].Nx[2] should be set to 0 to keep the 2nd and 3rd
dimensions inactive.
The most common type of 1D table corrects a motor’s position as a function of that same motor’s
position (i.e. the “source” and “target” motors are the same). This type of table is commonly
known as a “leadscrew compensation table”, as it is often used to correct for mechanical errors in
the screw that converts rotary motor motion to linear travel. The concept of this type of table is
shown in the following figure:
If the source and target motors are different, a “cross-axis” table can be created. This type of table
can be used to correct for “straightness errors”, as shown conceptually in the following figure:
y y y y y y
M
E
While the spatial effect of such a table can be multi-dimensional, the mathematical structure of
the table is still “1D”.
Two-Dimensional Tables
To specify two active dimensions (a “2D”, or “planar”, table), CompTable[m].Nx[0] and
CompTable[m].Nx[1] should be set greater than 0, but CompTable[m].Nx[2] should be set to 0
to keep the 3rd dimension inactive.
The entries of a 2D table form a rectangular grid in a Cartesian space, as shown in the following
figure:
The figure shows the target motor as being a separate motor from either of the two sources, but it
is common for the target motor to be the same as one of the source motors.
Three-Dimensional Tables
To specify three active dimensions (a “3D”, or “volumetric”, table), CompTable[m].Nx[0],
CompTable[m].Nx[1], and CompTable[m].Nx[2] should all be set greater than 0 to activate all
3 dimensions.
“Zero-Dimensional” Tables
If Nx[0], Nx[1], and Nx[2] are all set to 0, the table still has a single entry (Data[0]), and the
value of this entry can be written to target registers. This “0D” table can have some interesting
uses, as explained below.
If a dimension is inactive (Nx[n] =0), it does not matter what the setting of Source[n] in that
dimension is. Even if the specified source motor for an inactive dimension moves, it will not
affect the calculations of the table. Typically, Source[n] is set to 0 for an inactive axis.
The key advantage of using desired position, particularly when the target motor is the same as the
source motor, is that there is not interaction of the compensations with the servo loop dynamics.
In addition, there is much less quantization noise, and no measurement noise, in the desired
position value, minimizing the numeric noise introduced into the target motor servo loop.
However, the use of desired position means that if there is following error, the calculated
compensation is not correct for the present physical position; the compensation in general
converges toward the correct value over multiple servo cycles. Use of actual position can yield
superior results when quantization noise is low (i.e. measurement resolution is high),
measurement noise is low, and correction values are small.
The first zone is the space between the data point with a location index of 0 in that dimension and
the data point with a location index of 1 in that dimension. The second zone is the space between
the data points with location indices of 1 and 2 in that dimension, and so on.
The operation of the last zone in this dimension is dependent on the “boundary mode” for the
dimension. The boundary mode, explained in detail below, determines what happens when the
position of the source motor goes past the declared boundaries. If the boundary mode for the
dimension is “maintain last position” or “mirror”, then this last zone “p” (Nx[n] = p) is defined as
the space between the data points with location indices of p-1 and p in that dimension.
However, if the boundary mode for the dimension is “rollover”, then this last zone “p” is defined
as the space between the data points with location indices of p-1 and 0. A data point with a
location index of and p in that dimension may be entered, but it will not be used.
So if the dimension has “rollover” boundary mode and Nx[n] = p, then p data points should be
entered for each “line” in that dimension, with indices of 0 to p-1 for the dimension. If the
dimension has “maintain-last-position” or “mirror” boundary mode and Nx[n] = p, then p+1 data
points should be entered for each “line” in that dimension, with indices of 0 to p for the
dimension.
The following diagram illustrates how the zones relate to the data points both with rollover and
without:
Nx[n] = 5, no rollover
Corr No rollover
Rollover
Source Pos
X0-Dx/Nx X0 X0+Dx/Nx X0+2Dx/Nx X0+3Dx/Nx X0+4Dx/Nx X0+Dx
The spacing between table points in that dimension can be calculated as Dx[n] / Nx[n].
Example
For a dimension n, if X0[n] = -20000, Dx[n] = 180000, and Nx[n] = 36, then this dimension of
the table starts at -20,000 units of the source motor specified by Source[n], and ends at -20,000
+180,000 = +160,000 units of the this motor. The spacing between points is 180,000 / 36 = 5,000
units of the source motor.
The data point with location index 0 in this dimension is at -20,000 units of the source motor; the
point with index 1 is at -15,000 units; the point with index 2 is at -10,000 units, and so on. The
point with location index 34 in this dimension is at +150,000 units of the source motor, and the
point with index 35 is at +155,000 units. If the boundary mode for this dimension is “maintain
last correction”, a point with location index 36 in this dimension should be entered to specify the
correction at +160,000 units of the source motor.
Interpolation Order
The table can use either 1st-order (linear) or 3rd-order (cubic) interpolation between data points,
with somewhat independent specification by dimension. Of course, the interpolation order
specified for an inactive dimension is not used.
In 1st-order interpolation, Power PMAC computes a linear fit for the correction between adjacent
data points in the dimension, using just one point on each side of the present location in the
dimension. The correction is continuous as it passes a data point, but its derivative, in general, is
not. The correction computed at a data point is exactly equal to the table entry at that point.
In 3rd-order interpolation, Power PMAC computes a cubic fit for the correction between adjacent
data points in the dimension, using two points on each side of the present location in that
dimension. Both the correction and its derivative are continuous as it passes a data point. The
correction computed at a data point is exactly equal to the table entry at that point.
3rd-order interpolation therefore produces a smoother correction, but at the cost of increased
calculation time. For most applications, the increased calculation time is not significant, so users
are encouraged to select 3rd-order interpolation unless the application risks overloading the
processor.
Boundary Mode
The “boundary mode” controls how corrections are calculated when the position of the source
motor passes the defined ends of the table. The boundary mode is individually selectable by
dimension. Three different boundary modes have been implemented: “maintain last correction”,
“rollover”, and “mirror”.
Maintain-Last-Correction Mode
In “maintain-last-correction” mode, if the position of the source motor for the dimension passes a
defined end for the table, the correction calculated is simply the value of the last table point
passed. That is, for a dimension n of the table with Nx[n] = p, if the source motor position is less
than X0[n], the correction will simply be the value of the data point with location index 0 for that
dimension, and if the source motor position is greater than (X0[n] + Dx[n]), the correction will
simply be the value of the data point with location index p for that dimension.
Rollover Mode
In “rollover” mode, the table can be considered to repeat indefinitely in that dimension on both
sides of the defined span for the table. If the source motor position goes outside the defined span
of the table, its position is “rolled over” to within the defined span of the table before the
correction is calculated. This mode is very useful for corrections that repeat periodically, such as
sensor imperfections on a rotary motor which repeat every revolution of the motor, or even those
that repeat for each line of a sinusoidal encoder.
For example, if the span of the table is defined as being from -10,000 to +90,000 units of the
source motor (a span of 100,000 units), the correction at +120,000 units will be the same as the
correction at +20,000 units; the correction at -75,000 units will be the same as the correction at
+25,000 units; the correction at +517,432 units will be the same as the correction at +17,432
units, and so on.
Mirror Mode
In “mirror” mode, the table can be considered to repeat indefinitely in that dimension on both
sides of the defined span for the table, but it is “flipped” each time it repeats. This mode can be
useful for mirror-symmetrical corrections, so the size of the table can be kept small. An example
of this type of application involves the use of two rotating mirrors to direct a laser beam around a
target plane. Due to the geometry, the location of the beam on the axes of the plane is not quite
proportional to the angles of the mirrors, and the difference is often corrected for with
compensation tables. The corrections are mirror-symmetrical about both the X=0 and Y=0 lines.
The mirror boundary mode permits the tables to be defined for only half (for a 1D table) or a
quarter (for a 2D table) of the work area, saving considerable memory.
For example, if the span of the table is defined as being from 0 to +100,000 units of the source
motor, the correct at -15,000 units will be the same as the correction at +15,000 units; the
correction at +125,000 units will be the same as the correction at +75,000 units, and so on.
Of course, settings for inactive dimensions do not matter. Most users should set this component to
3 to select 3rd-order interpolation.
Bits 2 and 3 of Ctrl determine the boundary mode for the dimension with index n = 0 (which uses
the motor specified by Source[0]). This 2-bit component has four possible values:
Bits 4 and 5 of Ctrl determine the boundary mode for the dimension with index n = 1 (which uses
the motor specified by Source[1]). This 2-bit component has the possible values as for dimension
n = 0.
Bits 6 and 7 of Ctrl determine the boundary mode for the dimension with index n = 2 (which uses
the motor specified by Source[2]). This 2-bit component has the possible values as for dimension
n = 0.
Examples
For a 3D table with 3rd-order interpolation in all dimensions, and maintain-last-correction
boundary mode in all dimensions, Ctrl should be set to 01010111 binary, which is $57
hexadecimal, or 87 decimal. The value can be entered in decimal or hexadecimal form. It will be
reported in decimal form.
For a 1D table with 3rd-order interpolation and rollover boundary mode, Ctrl should be set to
xxxx0001 binary, where x represents a “don’t-care” bit. Generally the don’t-care bits are set to 0,
so the value is $01 hexadecimal, or 1 decimal.
For a 2D table with 1st-order interpolation in both dimensions, and mirror boundary mode, Ctrl
should be set to xx101000 binary. where x represents a “don’t-care” bit. Generally the don’t-care
bits are set to 0, so the value is $28 hexadecimal, or 40 decimal.
If all the Target[q] elements for a table have a value of 0, the table will have no effect, even if
enabled (although processor time will still be devoted to the computation of corrections.) Setting
these elements to 0 can be a simple way of temporarily disabling an individual table. However, in
doing this, the last computed correction(s) will be left in the target register(s); it may be desirable
to then set the register value to 0 by writing directly to the register.
Note that Turbo PMAC has separate classes of tables for position compensation, backlash
compensation, and torque compensation. In Power PMAC, every table can provide each of these
types of compensation, depending on which target register is specified.
The following diagram shows how the different target registers are used by the target motor:
FF CompDac
Des Pos
+ + + +
Pos Error
PI
+ + ServoOut
+ - -
Comp
Des ActPos
D
Pos
ActPos2
CompPos2 Pos2
+ +
CompPos + Pos
+ +
BlCompSize
Note that the corrections are added to actual position values, not to command position values (as
they were in Turbo PMAC). This means that the corrections do not affect the feedforward into the
servo loop. (However, if Power PMAC is not actually closing the servo loop and instead is
outputting command position with Motor[x].Ctrl set to Sys.PosCtrl, as for networked
positioning drives, the position compensation values are subtracted from the command position
value, and the difference is output.) The corrections do affect the reference position for software
overtravel limits and compensation tables.
CompTable[1].Target[0] = Motor[1].CompPos.a
CompTable[1].Target[1] = Motor[1].CompPos2.a
However, Power PMAC also has dedicated “cam” tables for this functionality. These dedicated
cam tables have several features optimized for commanding true motion, such as slewing into
synchronization with the master at a controlled rate on enabling, and the ability to have the final
position in a cycle different from the starting position. Refer to the User’s Manual chapter on cam
tables for details.
When Motor[x].CompDesPos is the target register, the corrections do affect the feedforward into
the servo loop. The corrections do not affect the reference position for software overtravel limits
or position-correction compensation tables. The command values from cam command tables are
superimposed on top of programmed calculated trajectory motion for the target motor.
Note that the direction of motion caused in the target motor for a table value of a given sign is the
opposite of that for a position correction table.
CompTable[3].Target[0] = Motor[2].CompDesPos.a
Torque-compensation tables are most commonly used to correct for “cogging”, or reluctance-
torque variations in motors. They virtually always have the same source and target motors, and
use “rollover” boundary mode, so they only have to be defined for a single revolution or electrical
cycle of the motor.
Correction values for torque-compensation tables can easily be determined by moving the
unloaded motor to each point in the table, waiting for it to settle into position (with integral gain
active) and reading the servo torque command required to hold position against the cogging
torque. This value can then be put into the table entry for that point.
CompTable[5].Target[0] = Motor[1].CompDac.a
Backlash-compensation tables are most often used to create bi-directional position compensation,
when different corrections are required for positive and negative-going motion. Corrections for
moving in the positive direction are contained in a standard position compensation table; the
backlash-compensation table contains the difference between positive-going and negative-going
corrections over the travel of the motor.
CompTable[8].Target[0] = Motor[1].BlCompSize.a
This is true for both position compensation tables, for which a scale factor of 1.0 means the table
entries are in the defined position units of the target motor, and for torque compensation tables,
for which a scale factor of 1.0 means the table entries are in units of a signed 16-bit output device,
the same scaling as the setup units for the servo output command setup elements.
If the table is the only table writing to the Target[q] register, bit q of OutCtrl must be set to 0, so
a new value is written to this register every servo cycle. If multiple tables write to the same target
register (as with coarse and fine corrections), the lowest-numbered table (which executes first
each servo cycle) writing to the Target[q] register must use bit q of OutCtrl = 0 to overwrite the
previous cycle’s value, and any higher-numbered tables writing to this register must use bit q of
OutCtrl = 1 so their corrections for this servo cycle are added to the first table’s correction.
Note carefully that for a multi-dimensional table, the last location index, denoted by [i] here, is
for the first dimension of the table, the one using the position of the motor specified by
Source[0].
It is also possible to enter multiple consecutive points in a single command, with the last location
index i incrementing for each value entered. For example, the command:
If there is more than one active dimension, only the last location index i corresponding to
dimension index n = 0 can be incremented in a single command. But it is possible to enter an
entire “row” of the table in a single command. This can make the text file for the table compact
and relatively easy to read.
In a 1D table, constant values for the data-point index i can range from 0 to 16,777,215, and any
L-variable can be used for the index.
In a 2D table, constant values for the data-point indices i and j can range from 0 to 65,533. Only
variable L0 can be used for the index i, and only L0 and L1 can be used for the index j.
In a 3D table, constant values for the data-point index i can range from 0 to 65,533, and indices j
and k can range from 0 to 252. Only variable L0 can be used for the index i, only L0 and L1 can
be used for the index j, and only L0, L1, and L2 can be used for the index k.
When using an L-variable for an index, the value of the variable can exceed the highest constant
value permitted for that index. Whether a constant or a variable is used for the index, it is not
possible to set a value for a data point outside the number of zones defined for the table.
The table data points are accessed with a pointer variable that can be declared something like:
float *CompDataPtr;
This pointer can be set to the start of the data points for table m with a program line like:
(The OffsetTblSHM term is not needed if executing from a user servo or user phase, but those
tasks are not recommended for writing to.)
*(CompDataPtr + i) = MyVal;
MaxI = pshm->CompTable[m].Nx[0] + 1;
*(CompDataPtr + j*MaxI + i) = MyVal;
MaxI = pshm->CompTable[m].Nx[0] + 1;
MaxJ = pshm->CompTable[m].Nx[1] + 1;
*(CompDataPtr + k*j*MaxJ*MaxI + j*MaxI + i) = MyVal;
If the user wants to effectively disable a table in the enabled range of tables, there are a couple of
options. The first is to set CompTable[m].Sf[q] to 0.0, which forces the correction to 0.0. If it is
desired to reduce the correction gradually, the value of this element can be ramped down in a
timed loop (and ramped back up to re-enable the table).
The second method is to set CompTable[m].Target[q] to 0. This leaves the most recent
correction in the target register. However, because this register is no longer being written to
automatically, the user can overwrite this value manually to clear the correction.
To compute the correction, Power PMAC uses the table entries on both sides of the present
desired position of the source motor in each active dimension of the table to calculate a weighted
average of the entries. If 1st-order interpolation is selected in the dimension, just the single entry
on each side of the present desired position is used. If 3rd-order interpolation is selected in the
dimension, two entries on each side of the present desired position are used.
When motor actual position, or the matching axis actual position, is queried with the p command,
Power PMAC reports the corrected, not raw, position. The raw measured motor position can be
read in the element Motor[x].Pos; the corrected motor position can be read in the element
Motor[x].ActPos. The correction from the table can be monitored at any time by querying the
value of the target register (e.g. Motor[x].CompPos).
All of the compensation-table calculations are performed after the commanded trajectories for
that servo cycle are updated to get the new net commanded position for the cycle. (This
eliminates a servo cycle delay that was present in older controllers.) The calculations are
performed immediately before the servo-loop closure for the motor whose number is contained in
the saved setup element Sys.CompMotor, so after the servo-loop closure for any lower-
numbered motors.
Unless a 0D compensation table is used to cascade servo loops, as explained in the next section,
Sys.CompMotor should be left at the default value of 0, so all tables work without a cycle’s
delay.
One use of this feature is to inject calculated offsets and/or corrections into multiple registers,
providing an algorithmic, rather than table-based, compensation.
Another use of this feature is to “cascade” multiple servo loops, writing the output of one loop
into an input of another loop. This is commonly employed to close a “force loop” or “gap loop”
around a standard position loop to provide multi-mode control. See the section on cascading
servo loops in the Setting Up Servo Loops chapter of the User’s Manual for details.
In a 0D table, if bits 0 and 1 of the Ctrl element are greater than 0, then the value of the servo-
loop output from the motor specified by Source[0] for the table is automatically used to write to
the specified target registers, usually the CompDesPos register for the inner-loop motor. In this
mode, the Data[0] value is not used, but this element must still contain a valid numerical value. It
is suggested to set it to 0 in the configuration of the table.
If the OutCtrl bit for the table is set to 0, the table overwrites the value of the target register each
servo cycle. For cascaded loops, this is desirable when the modification of the inner loop is
limited, as in gap-control applications. However, if OutCtrl is set to 1, the table adds to the
existing value in the target register each servo cycle, performing a numerical integration. This is
useful when the modification of the inner loop can be effectively unlimited, as in web-tensioning
applications. Note, however, that this integration makes a runaway condition possible, so it is
essential to get the outer loop tuning correct.
For the highest performance in cascaded servo loops, the inner loop should use the command
from the outer loop that was calculated in the same servo cycle. For this to occur, two things must
be true. First, the outer loop must be closed in a motor whose number is less than that of the inner
loop.
Second, the transfer performed by the compensation table must occur between the inner-loop
closure and the outer-loop closure of the same servo cycle. The timing of the compensation table
calculations is controlled by saved setup element Sys.CompMotor, which specifies the number
of the motor before whose servo loop closure all active compensation tables are updated. The
default value for Sys.CompMotor is 0, which means the tables are updated before any motor
servo loops are closed (but after the command trajectories for all motors are updated).
Unless compensation tables are used for cascading servo loops, this value will probably be left at
0. However, to optimize the performance of a cascaded servo loop, Sys.CompMotor should be
set to a value higher than the number of the motor used for the outer loop, but not higher than that
of the number of the motor used for the inner loop.
Note that it is possible to cascade servo loops without a 0D compensation table, but with other
techniques, there will always be a servo-cycle delay in the cascading process.
ILC algorithms for compensation tables are new in V2.1 firmware, released 1st quarter 2016.
These algorithms can provide a quick and easy method to set the values for a torque
compensation table when the resulting position errors are largely repeatable.
The ILC algorithm for a table is only active if CompTable[m].DacEnable is set to a value
greater than 0. In this case, the value of DacEnable specifies the number of the target motor
whose servo loop output (“torque”) is corrected and whose position error values are evaluated.
The number of the target motor does not have to be the same as that of the source motor
(specified by CompTable[m].Source) for the table – the motor whose position values are used to
determine what zone of the table is used for the correction. When the table is used to reduce
errors from cogging torque in the motor, source and target motor will be the same. When the table
is used to reduce errors in one motor from action/reaction effects from the imbalance of another
motor, the source and target motors will be different.
When CompTable[m].DacEnable is set to a value greater than 0, the table is always treated as a
one-dimensional (1D) torque-compensation table. The correction from the table is always written
only to the Motor[x].CompDac register for the motor specified by DacEnable, where it is added
to the torque command from the servo algorithm for the motor. The scaling of the correction is
specified by CompTable[m].Sf[0]. The table should be defined as a 1D table, with
CompTable[m].Nx[1] and CompTable[m].Nx[2] both set to 0.
The user must set three saved setup elements to specify how the ILC algorithm will work.
CompTable[m].DacGain specifies how aggressively Power PMAC will change the correction
for a given position error value. If it is set too low, corrections may take many cycles to reduce
the error significantly. If it is set too high, overcorrection and limit-cycling about the ideal
correction can occur. DacGain must be set greater than 0.0 in order for the ILC calculations to
have any effect. Changing the value back to 0.0 can “freeze” the values currently in the table.
CompTable[m].MaxDac specifies the magnitude of the maximum torque correction the ILC will
use in any zone of the table. Even if the algorithm computes a larger value based on the detected
position errors and the value of DacGain, no value with a larger magnitude than MaxDac will be
written to any CompTable[m].Data[i] table point.
CompTable[m].MinPosError specifies the magnitude of the position error for any table zone
below which Power PMAC will not attempt to reduce further by adjustments to Data[i] for the
element.
Correct Motor 1’s position based on Motor 1’s raw position value
In addition, a torque offset to the output of the target motor’s servo loop can be specified for each
point in the table, with the commanded offset computed every servo cycle, also using a third-
order interpolation between table points. A set of digital outputs can be specified for each zone in
the table as well.
Note that Power PMAC compensation tables can be used for rudimentary electronic cam
positioning capabilities, but the dedicated electronic cam tables are much more full-featured for
this purpose.
Position Commands
The most common use of an electronic cam table is to specify the commanded position of a motor
as a function of another position. Power PMAC’s cam tables can compute these commanded
positions every servo cycle to create a rapid but smooth response to the “source” motor position.
These table-based command positions can be superimposed on directly commanded (trajectory)
motor positions from jogging moves and programmed axis moves; the directly commanded
positions are often used to provide a reference (base) position for the table.
Often these offsets are determined through techniques such as “iterative learning control”, which
monitor the errors and resulting servo commands and converge on offsets that minimize the
errors. Less formal methods can also be used.
frequency-modulated (PFM) output. Any number of consecutive bits in a single 32-bit register
can be commanded from a table in this way.
In external time base, the motion of multiple motors relative to a single master can be
described in a single structure by commanding multiple axes within the same motion
program running in a coordinate system. With electronic cam tables, a separate table is
required for each slave motor, but it is easy to keep these motors fully synchronized.
In external time base, the specified (programmed) points do not need to be evenly spaced,
and several modes of interpolation between points are possible, with the interpolation
function in most modes not passing exactly through the specified points. With electronic
cam tables, the specified points must be evenly spaced, and there is always a cubic
interpolation between the points, with the interpolation function passing exactly through
the specified points.
It is easier to compute and re-compute point values in a motion program running under
external time base than in a cam table, especially if values in the program use variables.
A separate task must be used to re-compute point values in a cam table.
The electronic cam tables provide a “direct output” word that can be different for each
small zone of the table, and that execute in a fully reversible manner.
The electronic cam tables provide a torque-offset value for each zone of the table that can
directly compensate for repeatable angle-specific error-causing loads, executing in a fully
reversible manner.
In applications where both techniques are possible, many people will decide which approach to
use based on a personal preference as to whether they prefer a program-based technique or a
table-based technique.
Here we see a sample screen shot of the Cam Sculptor software being used to design a cam table
for the Power PMAC.
Source: The number of the “source motor”, whose desired position is read each servo
cycle to determine the location in the table
X0: The desired starting position of the source motor for the table.
SlewX0: The rate of change (per servo cycle) of the starting position of the source motor
for the table, if the desired starting position X0 is different from the present starting
position. This permits controlled changes in the “phase” of the table.
Dx: The span of the table in units of the source motor. The spacing between points in the
table is Dx/Nx. (It is doubtful that there would be a need for slew control on changes to
this value.)
Target: The number of the “target motor”, where the table position and torque results are
applied each servo cycle (to the CompDesPos and CompDac registers, respectively).
PosSf: The desired output scale factor for the position command, multiplying the
calculated interpolated position value from the table.
PosBias: The user-set target motor position offset value that is added to the value
calculated from the table itself and the value in non-saved setup element PosOffset.
SlewPosOffset: The rate of change (per servo cycle) of the output position offset for the
table, which is used to bring the target motor into synchronization with the source motor
on enabling of the table.
DacEnable: On/off control for the torque offset value for the table.
DacSf: The desired output scale factor for the torque command, multiplying the
calculated interpolated torque value from the table.
pOut: The address of the register, if any, for the digital output word from the table.
pOutBuf: The address of the register for a buffered digital output word from the table. If
the values written to the actual output register cannot be read back, a buffered register
where the values can be read back should be used as well.
OutLeftShift: The number of bits the output data value is shifted left before being
written to the specified register. Equal to the lowest bit number in the output register this
table will control.
OutBits: The number of (consecutive) bits in the output word this table will control
DacGain: For automatic adjustment of torque offset in iterative learning control, the gain
factor used to try to reduce repeating following errors in each sector of the table by
adjusting DacData[i] for the sector.
MaxDac: The magnitude of the maximum adjustment of torque offset that will be made
in iterative learning control
MinPosError: The smallest magnitude of following error for which the iterative learning
control algorithm will attempt to reduce further through automatic torque adjustment.
OutData[i]: The “ith” digital output data point for the table
PosOffset: The value of this element is added to the interpolated result from the table. It
is automatically set by Power PMAC on enabling of the table to the (signed) difference
between the present location of the slaved motor and where the motor would be to be
properly synchronized to the defined table. It is then incremented by SlewPosOffset each
servo cycle until synchronized. The user can subsequently adjust this value to adjust the
results of the entire table.
There must be sufficient memory reserved in this buffer for all of the tables used. Each location
index for the table requires the storage of 3 32-bit values (2 single-precision floating-point and 1
integer), which occupies a total of 12 bytes of memory. The memory required for the data entries
of a table can be calculated as:
where Nx is the table header element (CamTable[m].Nx) specifying the number of zones of the
table.
The best way of changing this memory allocation is through the “Project Properties” control in
the Integrated Development Environment (IDE) PC software, which allows you to set the “Table
Buffer” size in megabytes. In the Power PMAC, the buffer memory allocation is set only at
power-on/reset, so to change the allocation, you must change the setting the IDE project control,
download the project to the Power PMAC, issue the save command to store this value to flash
memory, then reset the Power PMAC.
The memory for the entire table is allocated when the first data entry value is set in a Script
command (e.g. CamTable[3].PosData[0] = -7.3). The starting location is the first word past the
last table already defined, and a memory space is allocated to the table according to the above
equation. This means that the size of the table must be defined before any data points are entered.
If all of the tables are defined just one time after power-on/reset, whether from flash memory or
from project download, memory space is allocated to tables in the order they are defined, from
the start of the buffer toward the end. As long as there is sufficient buffer space for all tables, this
goes smoothly, with the details hidden from the user.
However, if the user wishes to redefine the size of an already loaded table, the ramifications for
memory allocation must be understood. Any time Power PMAC executes a Script command that
changes the value of an existing table dimension CamTable[m].Nx, the pointer to the table data
entries in the buffer is cleared.
The pointer to the start of table data entries is not set again until the first Script command that sets
a data entry value. At that time, the pointer is set to the address of the register in the buffer
immediately following the last existing table. This means that if the table whose dimensions were
changed was not the last table in the buffer, the memory that was allocated for the table data is
lost until the next power-on/reset.
Note that it is possible to set table dimension and table data values in C, but doing so does not
trigger any of the memory management functions that the Script commands do. If defining or
redefining tables in C, the commands to set the dimension values and the first data value should
still be done with Script commands. This can be done from a C routine using the command""
function to execute the Script command within the quotes. Then the subsequent entry of data
points, including possibly overwriting the first data point, can be done with much faster C
commands.
“source” motor alone. This source motor is specified by setting CamTable[m].Source to the
number of the motor that is to be used as the source for the table.
This “source motor” can be a physical motor that is under the control of the Power PMAC, or it
can be a Power PMAC “virtual motor” that is reading the position sensor that is the master
driving the table. This virtual motor should be activated (Motor[x].ServoCtrl = 1) so it is
monitoring its actual position source, but not enabled, so it is not trying to compute its own
desired position values, instead just copying its actual position values into the desired position
registers.
Alternatively, it can be a completely virtual motor with no actual feedback sensor that is
generating its own positions mathematically. It is best to make sure that a virtual motor, whether
with a real or synthesized position sensor, is not in a coordinate system with any physical motors,
so the enabling, disabling, and faulting of the real motors does not affect the behavior of the
virtual motor.
The first zone is the space between the data point with a location index of 0 and the data point
with a location index of 1. The second zone is the space between the data points with location
indices of 1 and 2, and so on.
The discrete outputs for a zone use the output words with a location index matching the position
and torque values on the negative end of the zone. That is, the first zone uses the output word
with location index 0, the second zone uses the output word with location index 1, and so on.
Power PMAC’s CamTable structure supports up to 16,777,216 (224) zones in a table, provided
sufficient memory is reserved for the table. A typical table will have several hundred to several
thousand zones.
Note that cam tables are often designed with a tool such as Delta Tau’s “Cam Sculptor” that
breaks the full cam into several “sections”, each with its own equation. These sections do not
have to be evenly spaced, and a typical cam will have 6 to 20 sections. To implement the table in
Power PMAC from the design, the section equations are solved at even intervals to compute the
position data points that will be entered into the table.
The choice of number of zones is usually determined by assigning a tolerance for the cubic
interpolation’s approximation of the desired cam function and spacing the table points close
enough together that the error in the approximation from the cubic interpolation between points is
always less than the required tolerance.
This reference location can easily be changed in a controlled fashion. Saved setup element
CamTable[m].SlewX0 specifies the rate at which the actual reference location used for table
computations, CamTable[m].ActiveX0, changes when the user sets a new value for
CamTable[m].X0. This permits smooth phase adjustments of the table operation.
Source Span: Dx
CamTable[m].Dx specifies the “span” of the table, expressed in units of the source motor. The
table is directly defined for source-motor positions from X0 to (X0 + Dx). The spacing between
adjacent table points can be calculated as (Dx / Nx).
specifies the desired torque scale factor for the table. Most commonly, it is set to 1.0, so the table
entries can be in units of a 16-bit output, just as the servo-loop outputs are.
The most common output registers where the written registers cannot necessarily be read back are
the general-purpose I/O registers of the DSPGATE3 IC (Gate3[i].GpioData[j]) or the MACRO-
ring output registers of the DSPGATE2 IC (Gate3[i].Macro[j][k]). It is also possible to set up a
register of an IOGATE IC (GateIo[i].DatReg[j]) so that written values cannot be read back, but
by default they can.
The buffered output register is treated as a 32-bit integer. It is almost always a memory register.
When used, this buffered register is changed by the table using a read/modify/write sequence, and
then the entire 32-bit value is copied to the register specified by CamTable[m].pOut each servo
cycle. This means that no other task, whether another cam table or PLC program, should be
writing directly to the output register.
Output Shifting:OutLeftShift
CamTable[m].OutLeftShift specifies how many bits the masked output data is shifted left
before being written to the specified register. This permits the user to specify the output word for
each zone of the table starting in bit 0, regardless of where on the 32-bit bus these outputs are
actually written.
Valid location index values i are integers ranging from 0 to Nx, inclusive. Commands to set
points out of this range will be rejected with an error. Multiple consecutive data points of a
particular type with increasing location indices may be entered in a single command.
With Nx zones defined for a table, there are (Nx + 1) data points of each type. PosData[Nx] is
used by the table, through its difference from PosData[0], to define the target motor offset, if any,
from cycle to cycle, determining whether it is a “returning” or “non-returning” table (see next
section). DacData[Nx] and OutData[Nx], while they can be set by the user without error, are not
used in the operation of the table.
PosData[i] and DacData[i] values are stored as single-precision (32-bit) floating-point values.
OutData[i] values are stored as 32-bit integers and reported back in unsigned format (although
they can be used to output signed values).
The default value for all data points of all types is 0. If you want to leave the points at zero, it is
not necessary to command values for those points. For example, if you only want to use the
position function of a cam table, there is no need to set every DacData[i] and OutData[i] value
to 0.
Torque offset commands are always “returning” commands, repeating each table cycle without
offset. Data outputs are also “returning”, with no offsets between cycles.
Target Motor
Cam Position
Position
at Enable
Directly Slewed
Offset
Defined to Table
Table
PosData[Nx]
=PosData[0]
Source
X0 X0+Dx X0+2Dx Motor
Postion
Target Motor
Cam Position
4PosData[Nx]
-PosData[0]
3PosData[Nx]
-PosData[0]
2PosData[Nx]
-PosData[0]
Slewed Offset
to Table
Position
PosData[Nx] Directly at Enable
Defined
Table
PosData[0]
Note that, unlike the returning cam, there are many possible “instances” of the cam profile, all in
parallel with each other. The “reference” profile is the one that includes the cycle of the directly
defined table. Each other instance of the profile is offset from the reference profile by a multiple
of (PosData[Nx] - PosData[0]). The actual profile used will be one of the two on either side of
the position at the enabling of the table. (Which of these two is selected is dependent on the
enabling mode.)
When a table is enabled, the target motor position will, in general, not be in the position specified
by the table for the present source motor position. Power PMAC will bring the motor into the
proper position at a controlled rate specified by the saved setup element
CamTable[m].SlewPosOffset. This slewing into synchronization can be accomplished while the
master motor is in motion.
If the table is “non-returning”, the user has the choice as to which “instance” of the table (see
diagram above) to approach on enabling by the setting of CamTable[m].Enable. A value of 1
always moves in the positive direction to the next instance; a value of 2 always moves in the
negative direction to the next instance; a value of 3 moves in the direction of the closest instance.
Any torque-offset or output-word values from the table are applied immediately upon enabling,
without any slew control.
In the servo cycle, the cam table updates are calculated after the new desired positions for all of
the motors have been calculated, and if Sys.CompMotor is set to its default value of 0, before
any of the servo loops have been closed. (If Sys.CompMotor is set to a value greater than 0, the
tables will update immediately before the servo loop of that motor number is closed.) Cam tables
are updated each servo cycle before compensation tables are updated.
To compute the position and torque output values, Power PMAC uses the two table entries on
each side of the present zone of the source motor to compute the values using 3rd-order
interpolation. For example, if the source motor is in the 7th zone of the table, the PosData[i] and
DacData[i] entries with location indices 5, 6, 7, and 8 will be used. The 3rd-order interpolation
ensures that both the commanded values and their rate of change are always continuous, even as
table points are passed, changing into different zones of the table.
For the direct output values, Power PMAC simply selects the output word matching the present
zone of operation. For example, if the source motor is in the 7th zone of the table, the OutData[6]
entry will be used. Only the first (lowest) N bits of this word (where N is equal to
CamTable[m].OutBits) are used. These bits are shifted left by CamTable[m].OutLeftShift bits
before being applied to the output register whose address is specified by CamTable[m].pOut. If
pOut is set to the default value of 0, no direct outputs are written.
If CamTable[m].pOutBuf is set to the address of a buffered holding register, the specified bits
are set and cleared within this holding register, and the resulting full-word value is copied to the
output register specified by CamTable[m].pOut. This two-stage process should be used when it
is not possible to read back the value written to the actual output register.
If CamTable[m].pOutBuf is set to the default value of 0, there is no holding register, and the
specified bits are set and cleared within the output register itself in a single-stage process.
The values for position, torque, and direct output always overwrite the existing values in their
target registers. There is not an option to add to the existing value as compensation tables can do.
The position and torque values are written to motor registers that can also be written to by
compensation tables. It is the user’s responsibility to avoid conflicts when using both types of
tables.
It is also possible to adjust the cam table action along the target-motor axis by changing the value
of CamTable[m].PosBias. When this PosBias element is changed, the actual offset added to the
value interpolated from table points each servo cycle CamTable[m].ActivePosOffset is changed
by the amount set in saved setup element CamTable[m].SlewPosOffset. This permits the offset
to be changed in a controlled fashion.
In the case of a returning position cam table, adjusting the target motor reference position has a
fundamentally different effect from adjusting the source motor reference position. However, in
the case of a non-returning cam table, adjustments to the target motor reference position and
source motor reference position ultimately have the same type of effect.
The user can then calculate where this value is within the cam cycle and compare it to where it
should ideally be. The source motor desired reference position CamTable[m].X0 can then be
adjusted by this difference. The rate of change in the actual reference position used each servo
cycle Motor[x].ActiveX0 is set by saved setup element Motor[x].SlewX0, permitting a smooth
adjustment.
The method of position capture for this monitoring function is the same as for triggered moves
such as homing-search moves. A variety of different methods can be used. Note, however, that
unlike in triggered moves, the monitoring function has no effect on the motion of the motor. This
means it can even be used when the motor is simply a Power PMAC software construct used to
process the sensor position, as is often the case with a cam table master “source motor”.
The position-capture monitoring function is discussed in more detail in the User’s Manual chapter
Synchronizing Power PMAC to External Events, in the section on position capture. The various
methods of setting up position capture for a motor are described in the User’s Manual chapter
Basic Motor Moves, in the section on triggered moves. Both sections will refer to specific data
structure elements described in detail in the Software Reference Manual.
In this example, Motor “x” is the source motor for cam table “m”, which has a span of Dx units of
the source motor. The user variable DesTrigPhase contains the location in the span where the
trigger would ideally occur (0 <= DesTrigPhase < Dx). We calculate the actual location in user
variable TrigPhase by subtracting the present source motor reference X0.
We next compute user variable PhaseError by first taking the difference between desired and
actual and then reducing this difference to with one cycle by dividing by the cycle span Dx,
rounding to the nearest integer number of cycles with the rint function, and multiplying again by
Dx to return to motor units. Once the error is processed this way, we change the value of X0 by
this amount. Note that we change X0 in the negative direction for a positive phase error (desired
minus actual).
By using the rint (round to nearest integer) function, we ensured that the correction would be in
the “shortest” direction, always less than one-half cycle in length. If we instead used the floor
(round negative) or ceil (round positive) function, we would always correct in the same direction,
with a correction up to a full cycle in length.
The adjustment to the target motor offset for a value of PhaseError would be Slope *
PhaseError. This adjustment could be performed in two ways. First, it can be done by changing
the value of CamTable[m].PosOffset by this amount:
(This program line would simply replace the last line in the above example.) Note that we change
the target position offset in the positive direction for a positive phase error (desired minus actual).
The rate of change of this adjustment is controlled by CamTable[m].SlewPosOffset, so this is a
constant-velocity adjustment (without acceleration control) superimposed on whatever motion is
commanded by the cam.
In a second method, a trajectory commanded move could be superimposed on top of the cam
motion. For this adjustment, an incremental jog command is appropriate. It could be commanded
out of the PLC program with a command like:
jog6:(Slope * PhaseError);
(Once again, this program line would replace the last line in the above example.) The advantage
of using a jog command like this is that it would have controlled acceleration and jerk as well as
controlled velocity, so it would be a very smooth adjustment.
The user must set three saved setup elements for the table to activate this feature.
CamTable[m].DacGain specifies how aggressively Power PMAC will change the offset for a
given position error value. If it is set too low, corrections take many cycles to reduce the error
significantly. If it is set too high, overcorrection and limit-cycling about the ideal correction can
occur. DacGain must be set greater than 0.0 for the ILC calculations to be active. (In addition,
the table itself must be activated and the torque offsets activated with CamTable[m].DacEnable
= 1.)
CamTable[m].MaxDac specifies the magnitude of the maximum torque offset the ILC will use
in any zone of the table. Even if the algorithm computes a larger value based on the detected
position errors and the value of DacGain, no value with a larger magnitude than MaxDac will be
written to DacData[i].
CamTable[m].MinPosError specifies the magnitude of the position error for any table zone
below which Power PMAC will not attempt to reduce further by adjustments to DacData[i] for
the zone.
However, it is very common to use trajectory motion or position following to put the motor in a
reference position for the operation of the cam table. Commanded positions from the cam table
are added on top of this reference position. For example, if the motor is jogged to a position of
1200, and the cam table commands 250 units of the target motor, the net position command for
this motor will be 1450, not 250.
It is possible to alter the trajectory command position or the master following position while the
cam table is enabled, even when the cam table source motor is in motion. This provides the
capability for the operator to adjust the “location” of the target motor interactively. (This is
usually a better technique than adjusting CamTable[m].PosOffset while the table is enabled.)
If saved setup element Motor[x].PosReportMode is set to its default value of 0, the component
of motion from the cam table is not reported when motor position is queried with an on-line p or
d command or a buffered pread or dread command. Continuing the above example where the
motor is jogged to 1200 units before the cam table is enabled, a d command would always return
a value of 1200, no matter how much added motion the cam table was commanding. This value is
important if you want to know the distance another trajectory command would cause.
If Motor[x].PosReportMode is set to 1, the component of motion from the cam table is reported
when motor position is queried. If the motor had been jogged to 1200 units and the cam table
were commanding a further 250 units, the desired position would report as 1450 units. This value
is important to if you want to know the net physical position of the motor.
If the target motor is assigned to an axis, and the axis position is queried, the component of
motion from the cam table is never reported in response to the query, regardless of the setting of
Motor[x].PosReportMode.
After this table position output reaches 0.0, the value of CamTable[m].Disable is decremented
by 1 each servo cycle until it reaches 0. At this point, CamTable[m].Enable is automatically set
to 0. The intent of this second stage is to allow time for the motor to settle at this new position
before it is commanded to take some other action.
In both disabling methods, the table’s torque output and general-purpose outputs are left in their
final state from before the disabling process started. If it is desired to change these, the user must
write to the target registers for these values directly.
In most of these applications, multiple tables will be pre-loaded into Power PMAC memory, then
at most one per motor enabled at any given time. Note that if more than one table is enabled with
the same target motor, only the higher-numbered table will have any effect, as it will overwrite
the results of any lower-numbered table.
While it is possible to change the values in table data points at any time, it is not recommended to
do so when the table is enabled.
Watchdog Timer
Power PMAC systems provide “watchdog timer” functionality to verify fundamental operation of
hardware and software. If the timer’s monitoring does not verify that this operation is occurring,
it will shut down the operation in a fail-safe manner. There are both “software” and “hardware”
watchdog timers.
All Power PMACs have the software watchdog timer functionality. Power PMACs with local
interface circuitry have on-board hardware watchdog timer circuitry. The EtherCAT-only Power
PMAC configurations (e.g. µPowerPMAC [CK3E] and IPC) do not provide a hardware watchdog
timer, but the EtherCAT network provides similar automatic shutdown capabilities.
The hardware watchdog timer provides a fail-safe shutdown to guard against many types of
software and hardware malfunction. To keep it from tripping, the hardware circuit for the
watchdog timer requires that two base conditions be met. First, the nominal 5-volt DC power
supply must be greater than approximately 4.75V. If the supply voltage is below this value, the
circuit will trip and the Power PMAC system will go into a “hard” watchdog failure. This feature
is intended to prevent corruption of registers due to insufficient supply voltage.
The second necessary condition is that the timer must see a square-wave input (provided by the
Power PMAC software) of a frequency greater than approximately 20 Hz, which means the
digital signal must be toggled more than 40 times per second. In the foreground, the real-time
interrupt routine decrements a counter (as long as the counter value is greater than zero), causing
the least significant bit of the timer to toggle. This bit is fed to the timer itself.
At the end of each background cycle, after one scan of one active background Script PLC
program and one scan of all active background C PLC programs, the background software resets
the counter to the value specified by saved setup element Sys.WDTReset. (If this is set to a value
less than 100, the counter is reset to 5000 each background cycle.)
The hardware of the watchdog timer circuit is disabled so it cannot shut down the processor
completely. A $$$ reset command or $$$*** re-initialization command must be given, or the
electrical power to the system must be removed and re-applied, in order to (try to) clear a soft
watchdog trip.
The purpose of a soft watchdog trip is to detect certain conditions that would likely lead to a hard
watchdog trip and provide a safe shutdown of the system while keeping the processor alive so it
is easier to figure out what the underlying problem is and to fix it. Soft watchdog trips are usually
caused by user configurations that do not permit all tasks to execute in a timely fashion.
This diagram shows a sample soft watchdog timer trip due to a failure of background tasks to
reset the watchdog timer value before it reaches zero.
Sys.
WdTimer
Sys.
WDTReset
RTI
Soft
Background (Failure of Watchdog Trip
Cycle Background (Sys.WDTFault=1)
Cycle)
0
time
Timer
Input
Signal
that if it is set too large, it may not be able to detect this type of condition before a hard trip
occurs.
This diagram shows a sample soft watchdog timer trip due to a failure of foreground tasks to
decrement the watchdog timer value through several background cycles.
Sys.
WdTimer
Sys.BgWDTReset
Sys.
WDTReset
Soft
Watchdog Trip
(Sys.WDTFault=2)
(Interrupt
Failure)
RTI
Background
Cycle
0
time
Timer
Input
Signal
Note that if no phase or servo clock interrupt signals are detected by the processor during power-
up/reset, Power PMAC goes into a special “stay alive” mode executing background software
only. In this case, global status bit Sys.NoClocks is set to 1. This mode is similar to, but distinct
from, a soft watchdog trip. No motors may be enabled in this mode, but the interface hardware is
still active, permitting the user to configure the clock signal sources correctly. However, if the
clock signal interrupts were present at power-up/reset and subsequently lost, a soft watchdog trip
would occur because no real-time interrupt algorithms would execute to decrement the counter.
The industrial PC (IPC) configurations of Power PMAC do not have a hardware watchdog timer
circuit. They can provide a software watchdog timer trip.
In the event of a hard watchdog trip, the solid-state watchdog relay on the Power PMAC CPU
board toggles. The “normally open” contact opens (as it does when no power is present) and the
“normally closed” contact closes (again, as it does when no power is present). The system
designer can make use of this relay output as part of a “safety string” to make sure output devices
are properly disabled on a watchdog trip.
The CK3E configurations of the Power PMAC do not have a watchdog relay output. They do
have a hardware watchdog timer circuit that can provide a full shutdown, and can have a soft
watchdog trip.
A hard watchdog trip is usually caused by a fundamental hardware problem that permits neither
foreground (interrupt) nor background tasks to operate properly, so a soft trip is not possible. The
electrical power to the system must be removed and re-applied in order to (try to) clear a hard
watchdog trip.
The Power Brick has a fail-safe input intended for this purpose. When a Power Brick is re-
initialized, the software is automatically configured to use this input. If 24-volt DC power is not
supplied to this input, it will trip, and with the software left in its default configuration, a global
abort will be issued to the Power PMAC.
Software Setup
Sys.pAbortAll is set to the address of the register containing the “global abort” input. For the
Power Brick’s dedicated input, the setting is Gate3[i].GpioData[0].a. If Sys.pAbortAll is set to
0 (which is the default for Power PMAC configurations other than the Brick), this functionality is
not enabled.
Sys.AbortAllBit specifies the bit number on the 32-bit bus will be used for the input. For the
Power Brick’s dedicated input, the setting is 31. Sys.AbortAllLimit specifies the maximum
number of accumulated scans the Power PMAC can find this input in the abort state before
commanding the global abort. Power PMAC will check the input every real-time interrupt (RTI)
period. Values greater than 0 permit protection against false trips due to electrical noise.
There is no software polarity control of the input. A value of “1” in the bit is always considered a
fault. With common circuitry, including the dedicated circuitry in the Power Brick, a circuit
failure will almost certainly leave the bit in a “1” state, so this is the failsafe polarity.
Action on Trip
When the specified bit is found in the “1” state for the required cumulative number of scans, each
coordinate system reacts as determined by the setting of saved setup element
Coord[x].AbortAllMode.
If Coord[x].AbortAllMode is set to the default value of 0, all motors in the coordinate system
are immediately commanded to come to a controlled stop as if an abort command had been
issued, with deceleration profiles determined by Motor[x].AbortTa and Motor[x].AbortTs.
This provides a “Category 2” controlled safe stop under the IEC-61800-5-2 machine safety
standard.
If Coord[x].AbortAllMode is set to 2, all motors in the coordinate system are first commanded
to come to a controlled stop as if an abort command had been issued, then as each motor
reaches its “desired-velocity-zero” state, a “delayed kill” is commanded for the motor ” (open-
loop, zero output command, amplifier disabled) as if a ddisable command had been issued,
with a delay for brake engagement if Motor[x].BrakeOnDelay is greater than 0.
The action in this mode is similar to that of a “Category 1” safe stop under the IEC-61800-5-2
machine safety standard, with a controlled stop followed by disabling of the motor. However, that
standard requires that power be removed from the motor or circuits necessary to drive the motor.
To be compliant with this standard, the same action that toggles this input should also start a
qualified time-delay relay which will then drop out power from a key circuit (usually either bus
power or gate-driver power).
If Coord[x].AbortAllMode is set to 3, the coordinate system does not react to the “abort all”
input.
In addition, the interlock circuit must detect the presence of the high-frequency “DAC clock”
signal coming from the digital circuitry. If this signal is not present, whether due to loss of digital
power, having the ASIC channel configured for PWM instead of DAC outputs, or hardware
malfunction, the interlock circuit will remove power from the analog outputs and the amplifier-
enable signals. This will keep the analog circuitry from creating spurious output voltages from
erroneous or missing signals.
The coordinate system status bit Coord[x].FeFatal is set to 1 if the comparable motor status bit is
set to 1 for any motor in the coordinate system. Motors in other coordinate systems are not
affected.
If the coordinate system was executing a motion program at the time, the program execution
would be aborted as well. Aborting a motion program stops program calculations, resets the
program counter to the beginning, and discards any already computed motion equations from the
queue. Execution cannot simply be resumed at the aborted point (this point in the program can be
determined by use of the list apc on-line query command).
Motor[x].FatalFeLimit is expressed in the user’s motor units. The magnitude of these units is
determined by the feedback resolution, the encoder table entry’s scaling factor
EncTable[i].ScaleFactor, and the motor’s position-loop scaling factor Motor[x].PosSf. Most
users will scale the motor to units of “counts” or “LSBs” of the feedback sensor. However, others
may wish to use (much larger) engineering units such as millimeters, inches, or degrees. If the
user changes the definition of the motor units, the physical size of the fatal following error limit is
automatically changed. When changing from small to large motor units, the limit may be
increased so much as to be ineffective.
Good tuning of your motor’s servo loop is important for safety reasons as well as performance
reasons. The smaller you can make your true following errors during proper operation, the tighter
you can set your fatal following error limits without getting nuisance trips. Particularly important
in this regard are the feedforward terms that can dramatically reduce the errors at high speeds and
accelerations. It is common practice to set this limit to about twice the maximum error expected
in normal operation.
If Motor[x].CaptureMode is set to 2, the status bit Motor[x].FeWarn will be used as the trigger
flag for Power PMAC’s automatic triggered moves (homing-search moves, jog-until-trigger,
programmed rapid-mode move-until-trigger) instead of the default input trigger. This permits
easy implementation of tasks such as homing into a hard stop, torque-limited screwdriving, etc.
When the software limits are active, Power PMAC uses these limits at both move calculation time
and move execution time. The checks at move calculation time are made directly against the
limits at Motor[x].MaxPos and Motor[x].MinPos. The ongoing checks made at move execution
time can be made against positions offset from these, using saved setup element
Motor[x].SoftLimitOffset. Checks at the positive end of travel are made against
(Motor[x].MaxPos + Motor[x].SoftLimitOffset). Checks at the negative end of travel are made
against (Motor[x].MinPos - Motor[x].SoftLimitOffset).
Jogging Moves
For jog moves, if the commanded destination position is past the software limit in the direction of
motion, the destination position is changed to that software limit position. Note that the
“destination” position of an indefinite jog command (j+ or j-) is always past the software limit
in that direction, so this command is changed to a definite jog to a software limit. Note that this
checking at move calculation time permits the motor to come to a controlled stop at the software
limit, not begin to decelerate as the motor passes the limit. The Motor[x].SoftLimit status bit is
set to 1 at the beginning of a jog move whose destination has been altered due to a software limit.
Other status bits can be set when and if the limit is actually reached – see below.
When the program is stopped because a move would have exceeded a software limit,
Coord[x].SoftLimit is set to 1 (Coord[x].ErrorStatus = 32).
With the special lookahead buffer active (lookahead buffer defined, Coord[x].LHDistance > 0),
then for segmented moves in the coordinate system, these checks of segment destination positions
can be performed well in advance of the segment actually executing. With
Coord[x].SoftLimitStopDis at 0, the stop can occur well within the software limit. With
Coord[x].SoftLimitStopDis at 1, this advance calculation provides time to compute a controlled
deceleration to a stop at the limit for the offending motor.
When the motor is in closed-loop mode, the net desired position is the sum of the trajectory
command position, the master following position, and the table-based desired position (from an
“electronic cam” table). When the motor is in open-loop mode, the net desired position is simply
copied from the actual position for the motor.
However, subsequently if the leader motor has still not exceeded its own software limit position,
it can be commanded further in the same direction, and the gantry follower will attempt to track
the leader, even if it is still past its own software limit. Note that this configuration is not an
intended use of the gantry leader/follower functionality. In the intended use, both leader and
follower motors will have very similar ranges of travel, and so would exceed any software
overtravel limits at approximately the same time.
The following diagram shows typical relative positions of software limits at calculation time,
software limits at execution time, and hardware limits.
SoftMinusLimit = 1 SoftPlusLimit = 1
Range at Move Execution Time
Soft Soft
Limit Limit
Offset Offset
MLIM PLIM
Range at Move Calculation Time
MinusLimit = 1 PlusLimit = 1
Range for Physical Motion
- +
MinPos 0 MaxPos
Motor Position
However, if bit 1 of Motor[x].FaultMode is set to 1 when the motor passes a software limit in
open-loop mode, Power PMAC “kills” (disables) the motor. This immediately causes a zero
output command and disables the amplifier. Other motors in the coordinate system are not
affected in this mode.
Anything that stops current from flowing through the opto-isolator, whether from actually hitting
the limit, from cable disconnection, or from loss of power supply for the limit circuit, produces a
“1” state in the Servo IC. When the processor sees this, it will not permit motion in that direction.
Some users will want to do this permanently, as for a continuously rotating rotary axis; others
will want to do this temporarily, as when homing into a limit switch.
Settings of 32 or greater for Motor[x].LimitBits are new in V2.1 firmware, released 1st quarter
2016.
Saved setup element Motor[x].LimitLimit specifies how many accumulated scans are required
before a limit fault is declared, tripping the motor. Each real-time input scan, Power PMAC
checks the specified input bits. If a bit is in the fault state, Motor[x].LimitPlusCount or
Motor[x].LimitMinusCount is incremented by 1. If it is not in its fault state, the count element
is decremented by 1 (but will never go below 0).
If saved setup element Sys.MotorsPerRtInt is set to a value greater than zero (generally only
true for very high block rate applications), this check for the motor will not occur every RTI, but
rather every few RTI periods; this could possibly alter the optimal value for
Motor[x].LimitLimit.
The Motor[x].MinusLimit and Motor[x].PlusLimit software status bits reflect the present state
of the specified limit hardware inputs (0 is not into limit; 1 is into limit). The
Motor[x].LimitStop software status bit indicates that motion has stopped due to a limit (even if
the motor is not presently in the limit.
Controlled Stop
When a motor hits a limit when the servo loop is closed, the action is dependent on the setting of
bit 2 (value 4) of Motor[x].FaultMode. If this bit is set to its default value of 0, Power PMAC
automatically “aborts” the motor. Aborting a motor causes a controlled deceleration to a closed-
loop zero-velocity state, using the saved setup elements Motor[x].AbortTa and
Motor[x].AbortTs. If these values are positive, they represent the overall deceleration time and
the S-curve time, respectively, in milliseconds. If these values are negative they represent the
inverse of the deceleration rate (in msec2 / motor unit) and inverse of the S-curve jerk rate (in
msec3 / motor unit).
If the motor hit the limit during a motor move such as a jog move, the other motors in the
coordinate system are not affected. However, if the motor hit the limit during a motion program
commanded move, the motion program is stopped and all of the motors in the coordinate are
aborted as well. Note that if the coordinate system has been executing a path move, this
deceleration will not necessarily be along that path. Motors in other coordinate systems are not
affected in either case.
Disabled Stop
However, if bit 2 (value 4) of Motor[x].FaultMode is set to 1, then this motor is “killed” (open-
loop, zero command output, amplifier disabled) on hitting a hardware limit. (Note, however, that
if the motor is already in an “abort” deceleration from exceeding a software overtravel limit, no
further action will be taken when the hardware limit is hit.) Other motors are affected just as for
an “abort” stop of this motor.
The behavior of this mode of operation is based on the idea that the software limits should be
used to catch controlled excursions out of the intended range of operation, as when too large a
position is commanded. In this case, a controlled stop is quicker, covers a shorter distance, and is
easier to recover from. The hardware limit switches, which should be set just outside the software
limit positions, are used to catch uncontrolled excursions out of the intended range of operation,
when there is a problem with feedback so the software limits do not work.
Controlled Stop
The user has a choice for what happens when a motor hits a limit switch when the servo loop is
open. If bit 1 (value 2) of saved setup element Motor[x].FaultMode is set to the default value of
0, Power PMAC “aborts” the motor. This closes the servo loop with the initial commanded
velocity being equal to the present actual velocity, and causes a controlled deceleration to a stop,
just as if the loop were closed when the limit switch was encountered.
Disabled Stop
However, if bit 1 (value 2) of Motor[x].FaultMode is set to 1 when the motor hits a limit switch
in open-loop mode, Power PMAC “kills” (disables) the motor. This immediately causes a zero
output command and disables the amplifier.
In either case, other motors, whether in the same coordinate system or in a different coordinate
system, are not affected.
If a move for the motor has been prevented by either interlock bit, the status bit
Motor[x].InterlockStop is set to 1. If this bit is set for any motor in a coordinate system, the
status bit Coord[x].InterlockStop is set to 1.
If the move that has been prevented comes from a motion program move command, the program
is aborted, stopping all motors in the coordinate system. In this case, Coord[x].ErrorStatus is set
to 23, a value unique to this failure mode.
Software motor interlocks are new in V2.5 firmware, released 3rd quarter 2018.
Many of Power PMAC’s servo interfaces have circuitry dedicated to monitoring the presence of a
proper feedback signal. In addition, Power PMAC can automatically check these circuits for loss
of sensor signal and take appropriate shutdown action.
This diagram shows the XOR encoder-loss circuitry for a phase of a quadrature encoder.
+5V
R aR
A+ + A
A- -
1
2
bR 3
A?
When there is no longer a proper signal driving the inputs on the interface, both lines are pulled to
a high logical level internally (with proper configuration of the particular interface circuitry), so
the XOR gate outputs a low level indicating encoder loss. These gate outputs from the A and B
encoder channels are logically combined to create a single present/lost signal for the encoder (if
either channel is invalid, it will indicate “lost”).
For interfaces using the PMAC2-style DSPGATE1 ASIC, such as the ACC-24E2x UMAC axis-
interface boards, this flag is found in the low-true element Gate1[i].Chan[j].EncLossN. For
interfaces using the PMAC3-style DSPGATE3 ASIC, such as the ACC-24E3 UMAC axis-
interface boards and the Power Brick products, this flag is found in the high-true element
Gate3[i].Chan[j].LossStatus.
In the DSPGATE3 ASIC, the initially detected loss signal is passed through a multi-stage digital
delay filter driven by a special “filter clock” before it reaches the register. This clock signal is
divided down from the encoder sampling clock (SCLK) as specified by saved setup element
Gate3[i].FiltClockDiv. Lowering the frequency of the filter clock can help prevent spurious
faults due to noise or other anomalies.
The DSPGATE3 ASIC also a status bit Gate3[i].Chan[j].LossCapt, which latches at a value of 1
if the transparent LossStatus bit ever goes to 1. This bit can be useful in setting up the system to
identify potential signal problems.
If a different threshold is desired, the encoder-loss check can be configured to look for the state
where all of the high “n” bits of SumOfSquares are zero, as is explained below.
This diagram shows the “Lissajous pattern” for a sinusoidal sensor, plotting the sine signal
against the cosine signal. The radius from the center is the overall magnitude of the sensor
signals, the square root of the sum of the squares of the individual signal magnitudes. When this
gets too small, the signal can be considered to be lost.
A(sin)
Rmax
Rsig
θsig B(cos)
Rmin
Serial Encoders
Power PMAC provides interfaces for many of the most popular serial encoder protocols. For
most of these interfaces, the receiving logic can detect that no data has been received in response
to the cycle’s “position request” output, and set a “timeout error” flag that can be read by the
processor. This flag bit can be used to detect encoder loss. Note that the SSI and SPI protocols
cannot provide this detection.
If the serial-encoder interface of the PMAC3-style DSPGATE3 ASIC used on the ACC-24E3
UMAC axis-interface board and in the Power Brick products is used, this “timeout error” flag is
bit 31 of the element Gate3[i].Chan[j].SerialEncDataB. If the FPGA-based ACC-84E UMAC
serial-encoder-interface board is used, this flag is bit 31 of the element
Acc84E[i].Chan[j].SerialEncDataB.
It is also possible to utilize an error-checking mechanism in the data such as parity or cyclic
redundancy check (CRC) bits. The Power PMAC interfaces for serial encoders can evaluate these
mechanisms and determine whether the data set was valid or not. This is particularly
recommended for the SSI and SPI protocols, where the data patterns cannot be used to detect a
timeout error. Typically, multiple consecutive cycles with an error should be required in this case
to create a fault; this is done by setting a relatively high value of Motor[x].EncLossCount (see
below).
For the SSI protocol, the parity error flag is bit 31 of Gate3[i].Chan[j].SerialEncDataB or
Acc84E[i].Chan[j].SerialEncDataB. For the SPI protocol, any error reporting is vendor specific,
but would be found (if it exists) in a high bit of one of these registers.
Note that if Motor[x].pEncLoss is set to its default value of 0, loss detection is disabled for the
motor. Therefore, there is no automatic sensor-loss detection by default. The user must explicitly
configure it in an application.
Typical settings of these elements for the common types of feedbacks are discussed below.
Note that instead of the Gate1[i] structure name, it is also possible to use the alias name for the
particular board: Acc24E2[i], Acc24E2A[i], or ACC24E2S[i]. Socketed resistor packs on the
circuit boards must be reversed from their default orientation to enable the creation of the loss
signal in the accessory. Consult the Hardware Reference Manual for the accessory for details.
For digital quadrature encoders connected to an ACC-24E3 UMAC axis-interface board with a
PMAC3-style DSPGATE3 ASIC, or to a Power Brick control board, the following settings
should be used:
Note that instead of the Gate3[i] structure name, it is also possible to use the alias name for the
particular board: Acc24E3[i] or PowerBrick[i].
Note that instead of the Gate3[i] structure name, it is also possible to use the alias name for the
particular board: Acc24E3[i] or PowerBrick[i].
The magnitude threshold at which the channel’s SosError bit is automatically set to 1 by the
ASIC is suitable for many applications, eliminating both false positives and false negatives.
However, in some cases it may not be appropriate, particularly if the signal magnitude decreases
significantly at higher frequencies. In these cases, a user PLC program should directly monitor
the value of Gate3[i].Chan[j].SumOfSquares and kill the motor if it falls below a different
(usually lower) threshold.
It is also possible to look at the register containing the sum-of-squares magnitude to see if it has
fallen below a certain threshold. The register addressed by Motor[x].pEncLoss can either be the
hardware register in the DSPGATE3 ASIC – Gate3[i].Chan[j].SumOfSquares – if the
interpolation was performed in the ASIC, or the software register in the encoder conversion table
– EncTable[n].SumOfSqr – if the interpolation was performed in software (EncTable[n].type =
4, 6, or 7).
If Motor[x].EncLossBit is set to n = 224 to 255, then the values of the high (256 – n) bits of the
32-bit register are all evaluated instead of just that of a single bit. This setting is appropriate for
evaluating the EncTable[n].SumOfSqr magnitude. This capability is new in V2.4 firmware,
released 1st quarter 2018.
If Motor[x].EncLossBit is set to n = 208 to 223, (new in V2.6 firmware, released 3rd quarter
2020) then the values of the high (224 – n) bits of the low 16-bit field of the 32-bit register are all
evaluated instead of just that of a single bit. This setting is appropriate for evaluating the
Gate3[i].Chan[j].SumOfSquares magnitude.
If Motor[x].EncLossLevel is set to 0, then if all n high bits of the source register are 0, the
encoder will be considered “lost” for that scan. This permits the user to determine what
magnitude of signal will be the threshold for “loss”, particularly allowing more flexibility for
encoders whose signal magnitudes decrease significantly at high frequencies.
When the analog signals into the interpolator just reach their maximum voltage (+/-1.2Vpp for
most Delta Tau interpolators), the digital signal values will have a range of +/-215 (+/-32,768). In
this case, the sum-of-squares magnitude will be 230, and the high 2 bits of the 32-bit register will
always be zero.
If the signal magnitude is half of the maximum range for the ADCs, the digital signal values will
have a range of +/-214, the sum-of-squares magnitude will be 228, and the high 4 bits of the 32-bit
register will always be 0.
If the signal magnitude is one-quarter of the maximum range for the ADCs, the digital signal
values will have a range of +/-213, the sum-of-squares magnitude will be 226, and the high 6 bits of
the 32-bit register will always be 0.
To set up the motor to trip on encoder loss when all 6 of the high bits of the 16-bit hardware
magnitude element in the DSPGATE3 are 0, the following settings should be used:
To set up the motor to trip on encoder loss when all 8 of the high bits of the software magnitude
register in the ECT entry are 0, the following settings should be used:
Serial Encoders
For serial encoders connected to an ACC-24E3 UMAC axis-interface board or to a Power Brick
control board with a PMAC3-style DSPGATE3 ASIC, the following settings should be used for
encoder protocols with a “timeout error” flag (EnDat, Hiperface, Sigma I, Sigma II/III/V,
Tamagawa, Panasonic, Mitutoyo, and Kawasaki):
Note that instead of the Gate3[i] structure name, it is also possible to use the alias name for the
particular board: Acc24E3[i] or PowerBrick[i].
The same settings are valid for an SSI encoder with parity checking to use the parity-error bit.
It is also possible to consider the high n bits of an encoder status word collectively, and if any of
them is set to 1, consider this a loss state. This capability is new in V2.4 firmware, released 1st
quarter 2018.
If Motor[x].EncLossBit is set to n = 224 to 255, then the values of the high (256 – n) bits of the
32-bit register are all evaluated instead of just that of a single bit. Note that it is possible to
command the setting of EncLossBit to a negative number (n), but the value will be stored and
reported as (256 – n).
If Motor[x].EncLossLevel is set to 1, then if any of the (256 – n) high bits of the source register
is 1, the encoder will be considered “lost” for that scan. This permits the user to look at multiple
error bits collectively and consider any of them to indicate “loss” of proper feedback.
To set up the motor to trip on encoder loss when any of the 3 high bits of the serial encoder status
register in the DSPGATE3 is 1, the following settings should be used:
To set up the motor to trip on encoder loss when any of the 4 high bits of the serial encoder status
register in an ACC-84x is 1, the following settings should be used:
Each real-time interrupt (RTI) period, Power PMAC will check for encoder loss on each motor
with this functionality enabled. If the specified bit is in its “loss” state, Power PMAC will
increment the status element Motor[x].EncLossCount by 1. If the specified bit is not in its “loss”
state, Power PMAC will decrement this element by 1 (but never take it below 0).
If saved setup element Sys.MotorsPerRtInt is set to a value greater than zero (generally only
true for very high block rate applications), this check for the motor will not occur every RTI, but
rather every few RTI periods; this could possibly alter the optimal value for
Motor[x].EncLossLimit.
The optimal setting of Motor[x].EncLossLimit must balance quick response to a true error while
robustly avoiding any nuisance trips. Typically a setting of 3 or 4 will provide this balance.
If bit 0 (value 1) of Motor[x].FaultMode is set to its default value of 0, any other motors in the
coordinate system will be “aborted” (decelerated to a closed-loop enabled stop according to
Motor[x].AbortTa and Motor[x].AbortTs). If this bit is set to 1, any other motors in the
coordinate system are also “killed”. Motors in other coordinate systems are not affected in either
case. Note that the action on an encoder-loss fault is identical to that for a fatal following error
fault, amplifier fault, or I2T fault.
Note that if Motor[x].pAuxFault is set to its default value of 0, this fault detection is disabled for
the motor. Therefore, there is no automatic auxiliary-fault detection by default. The user must
explicitly configure it in an application.
Most commonly, the auxiliary-fault detection function looks at a single bit in the specified
register. This is the case if Motor[x].AuxFaultBit is set in the range 0 – 31. If the value of this
bit matches the value of Motor[x].AuxFaultLevel, it is considered to be in the fault state.
However, if Motor[x].AuxFaultBit is in the range 224 – 255 (new in V2.4 firmware, released 1st
quarter 2018), the detection function looks at the high (256 – AuxFaultBit) bits of the register. If
Motor[x].AuxFaultLevel is 0, then if all of these bits are 0, this is the fault state. If
Motor[x].AuxFaultLevel is 1, then if any of these bits is 1, this is the fault state. These two
configurations are commonly used for sinusoidal encoder signal loss and serial encoder
transmission errors, respectively. More details can be found in the description of encoder-loss
detection, above.
If Motor[x].AuxFaultBit is set to n = 208 to 223, (new in V2.6 firmware, released 3rd quarter
2020) then the values of the high (224 – n) bits of the low 16-bit field of the 32-bit register are all
evaluated instead of just that of a single bit. If Motor[x].AuxFaultLevel is 1, then if any of these
bits is 1, this is the fault state.
Each real-time interrupt (RTI) period, Power PMAC will check for auxiliary on each motor with
this functionality enabled. If the specified bit is in its “loss” state, Power PMAC will increment
the status element Motor[x].AuxFaultCount by 1. If the specified bit is not in its “loss” state,
Power PMAC will decrement this element by 1 (but never take it below 0).
If saved setup element Sys.MotorsPerRtInt is set to a value greater than zero (generally only
true for very high block rate applications), this check for the motor will not occur every RTI, but
rather every few RTI periods; this could possibly alter the optimal value for
Motor[x].AuxFaultLimit.
The optimal setting of Motor[x].AuxFaultLimit must balance quick response to a true error
while robustly avoiding any nuisance trips. Typically a setting of 3 or 4 will provide this balance.
If bit 0 (value 1) of Motor[x].FaultMode is set to its default value of 0, any other motors in the
coordinate system will be “aborted” (decelerated to a closed-loop enabled stop according to
Motor[x].AbortTa and Motor[x].AbortTs). If this bit is set to 1, any other motors in the
coordinate system are also “killed”. Motors in other coordinate systems are not affected in either
case. Note that the action on an auxiliary-fault error is identical to that for a fatal following error
fault, encoder-loss fault, amplifier fault, or I2T fault.
Motor[4].pBrakeOut = Acc24E3[1].Chan[0].OutFlagB.a
Motor[5].pBrakeOut = Acc68E[0].DataReg[5].a
If there is no element name for the register, as with an ACC-11E UMAC I/O board, the address
can be specified directly. For example:
Motor[x].BrakeOutBit specifies which bit in this 32-bit register is to be used for the output
control. It is the location on the 32-bit data bus, not necessarily the offset from the lowest bit with
an output. For example, I/O boards using the IOGATE IC have outputs only in bits 8 – 15 of the
32-bit bus, so a value from 8 to 15 should be used to specify one of these outputs.
Note that there is no software polarity control of the brake output bit. The bit is always set to 0 to
engage the brake, and to 1 to release the brake. This is to encourage “fail-safe” implementations
of the brake control, because a 0 typically sets a non-conducting output state, and most failure
modes are non-conducting. In additions, output bits are forced to zero on controller reset
(including watchdog timer trip) or shutdown.
Motor[x].BrakeOnDelay specifies the delay in milliseconds from the time the specified brake-
control output is set to 0 to engage the brake to the time the motor is disabled on a controlled
(delayed) disabling. The purpose of the delay is to provide enough time for the brake to engage
fully before servo control is removed. Delayed disabling is performed using the motor dkill
command or the coordinate-system ddisable command; both of these can be given as on-line
commands or buffered program commands.
Delayed
Enable Disable
Command Command
Amp 1
Enable 0
+
Servo
0
Command
-
BrakeOff BrakeOn
Delay Delay
Brake 1
Control
0
Output
time
If saved setup element Sys.MotorsPerRtInt is set to a value greater than zero (generally only
true for very high block rate applications), this check for the motor will not occur every RTI, but
rather every few RTI periods; this will alter the scaling of these delay parameters.
There is no delay if standard disabling commands (k, kill, disable) are used, or if the motor
is disabled due to a fault condition (fatal following error, amplifier fault, encoder loss). In these
cases, the motor is killed at the same time the brake engagement is commanded.
Saved setup element Motor[x].AmpEnableBit specifies which bit of the 32-bit register specified
is written to for the control of the amplifier-enable output. This should be set to 22 when using a
PMAC2-style “DSPGATE2” IC, as on an ACC-24E2x UMAC board, or when using the standard
MACRO-ring protocol. It should be set to 8 when using a PMAC3-style “DSPGATE3” IC, as on
an ACC-24E3 UMAC board.
The enable/disable polarity of the amplifier-enable line cannot be changed in software. From the
software viewpoint, a 0 in the bit controlling the line means “disable”, and a 1 means “enable”.
Failures such as watchdog-timer trips use hardware circuits to force the output to a “disable” (0)
state (which is why software polarity control is not permitted).
Saved setup element Motor[x].AmpFaultBit specifies which bit of the 32-bit register specified is
read for the status of the amplifier-fault input. This should be set to 23 when using a PMAC2-
style “DSPGATE1” IC, as on an ACC-24E2x UMAC board, or when using the standard
MACRO-ring protocol. It should be set to 7 when using a PMAC3-style “DSPGATE3” IC, as on
an ACC-24E3 UMAC board.
Polarity Control
The fault/no-fault polarity of the amplifier-fault input is determined by bit 0 (value 1) of saved
setup element Motor[x].AmpFaultLevel. If set to the default value of 1, the input state that
produces a 1 in the bit read by the processor is viewed as a fault condition. If set to 0, the input
state that produces a 0 in the bit read by the processor is viewed as a fault condition.
If bit 1 (value 2) of Motor[x].AmpFaultLevel is set to 1, two consecutive scans in the fault state
are required to cause an amplifier fault trip.
If more scans are desired before a trip, saved setup element Motor[x].AmpFaultLimit can be set
greater than 0, specifying how many accumulated scans are required before an amplifier fault is
declared, tripping the motor. Each real-time input scan, Power PMAC checks the specified input
bit. If the bit is in the fault state, Motor[x].AmpFaultCount is incremented by 1. If it is not in its
fault state, the count element is decremented by 1 (but will never go below 0).
If saved setup element Sys.MotorsPerRtInt is set to a value greater than zero (generally only
true for very high block rate applications), this check for the motor will not occur every RTI, but
rather every few RTI periods; this could possibly alter the optimal value for
Motor[x].AmpFaultLimit.
Action on Fault
On detecting an amplifier fault condition, the motor is automatically “killed” (open-loop, zero-
output, amplifier disabled). If bit 0 (value 1) of Motor[x].FaultMode is set to the default value of
0, other motors in the coordinate system (even if they just have the “null” definition – #x->0 –
in that coordinate system) are automatically “aborted” (controlled deceleration to enabled, closed-
loop stop). If bit 0 (value 1) of Motor[x].FaultMode is set to 1, other motors in the coordinate
system are automatically “killed” as well.
Current Limits
Power PMAC provides the capability for checking for both intermittent and time-integrated
current limits in the most common control modes to protect the motor and/or the amplifier.
However, if Power PMAC is outputting either position or velocity commands from the servo
algorithm, it has no access to either commanded or measured current values, and so cannot
provide any current protection.
Direct-PWM “power block” amplifiers accept phase voltage commands, so only have access to
measured current values. Most of these do have the capability to shut down immediately if the
measured current exceeds its intermittent threshold, but this should be confirmed with the
amplifier manual.
Servo motors have an intermittent current limit rating as well. If the current exceeds this limit
even for a few milliseconds, the permanent magnets can suffer a permanent reduction in strength.
Winding wire insulation could also be damaged. Since motors cannot protect themselves, this
protection must be done in the amplifier or controller. Sometimes, particularly with a matched
amplifier/motor pair, this protection comes automatically in the amplifier. Other times, amplifier
limits can be set lower as needed to protect a lower-rated motor. Many users will want to put this
protection in the controller, either because the amplifier cannot do it, or as redundant protection.
Saved setup element Motor[x].MaxDac sets the maximum “torque” (quadrature) current
magnitude value that the Power PMAC can command for the motor (or sometimes the amplifier).
It is scaled in the internal units of the Power PMAC, with a maximum possible range of ±32,768.
The method for converting these units to physical current units is dependent on the mode of
operation and is covered separately for each mode in the following sections.
Setting MaxDac to a value less than 32,768 limits the command output range further. If the
position/velocity servo loop computes a command value of a magnitude greater than MaxDac for
the servo cycle, the command magnitude is reduced to that of MaxDac. When MaxDac is set for
protective purposes, it is set to the lesser value of the motor’s intermittent limit or the amplifier’s.
In a servo cycle where the command magnitude has been limited by MaxDac, the error integrator
from the integral gain term Motor[x].Servo.Ki in the servo loop is not active. This functionality,
known as “anti-windup” protection, keeps the integrator value from increasing too much while
the servo is saturated, for the purpose of preventing instability when the servo comes out of
saturation.
When Power PMAC is performing commutation for a motor in either sinewave or direct-PWM
output mode, it also commands the “field” (direct) current magnitude for the motor with the value
of Motor[x].IdCmd. While this element is almost always set to 0 for brushless servo motor
control, it must be set greater than 0 for induction motor control.
This current component is orthogonal to the “torque” (quadrature) current component output from
the servo loop. The total current magnitude is the vector sum of these two components. As such,
the more general constraint for MaxDac is given by the equation:
Both amplifiers and motors can operate at levels above this continuous limit for short periods of
time without excessive heating. In a typical application, this capability will be used, notably for
accelerations and decelerations. The greater the level above the continuous limit, the shorter the
time permitted. Proper thermal protection requires evaluating both the levels and times of currents
on an ongoing basis.
Power PMAC implements the most common type of this protection, called “I2T” (Eye-Squared-
Tee). It uses the square of the current value, because resistive heat generation is proportional to
the square of current. Each cycle, the algorithm squares the present current value, subtracts from
this the square of the continuous current limit Motor[x].I2tSet, and adds the difference (which
could be negative) multiplied by the cycle time to the previous cycle’s integrated value. It then
compares this integrated sum to the integrated limit value you have set in the saved setup element
Motor[x].I2tTrip, and if the sum, found in status element Motor[x].I2tSum, is greater than this
limit, the motor is disabled with a fault.
In torque mode and sinewave mode, Power PMAC performs these calculations based on
commanded current levels, as it does not have access to the measured actual current levels. In
direct-PWM mode, Power PMAC performs these calculations based on measured current levels.
2
I2 I norm
32768 2 1 .0 2
2 Saturation
MaxDac
MaxDac 2
32768 I2t Fault
Integrator
Charge-Up
2
I 2tSet
I 2tSet 2
32768
Integrator
Discharge
time (sec)
When the current level is above the continuous limit, the integrated value “charges up”, and when
it is below the continuous limit, the integrated value “discharges”. The integrated value is
represented in this diagram by the net area above the continuous limit minus the net area below.
Under I2T protection, when the level of squared current above the continuous level is doubled
(the current itself is increased by a factor of sqrt(2), or about 1.4), the time permitted at this level
is halved. In other words, the square of the current level above continuous and the time permitted
at that level are inversely proportional. The following diagram shows this relationship for a
sample case where the motor is specified for peak current operation for 2 seconds:
2
I2 I norm
32768 2 1 .0 2
2
MaxDac
MaxDac 2
32768
2
I 2tSet
I 2tSet2
32768
2 4 6 8 10 12 14 16
time(sec)
The integrated current limit Motor[x].I2tTrip is expressed in units of the square of current
multiplied by time. The current is expressed in the same internal PMAC units that have a full
range of ±32,768, and time is expressed in seconds (not in servo cycles, as in Power PMAC).
Proper calculation of the integrated current values depends on a correct setting of saved setup
element Sys.ServoPeriod, which specifies the time per servo cycle.
The most common way that users specify the value of I2tTrip is to use the data sheet value for
the motor or amplifier being protected for time permitted at the maximum momentary current
value. In many cases, this value will be 2 or 3 seconds. This value can be used along with the
values for MaxDac and I2tSet to compute the value of I2tTrip according to the following
equation:
I 2tTrip MaxDac2 I 2tSet 2 * TimePermitted (sec)
If Motor[x].IdCmd is set greater than zero, as for Power PMAC computation of induction
motors, the above equation becomes:
I 2tTrip MaxDac2 IdCmd 2 I 2tSet 2 * TimePermitted (sec)
Sys.ServoMotors 1
N ceil
Sys.MotorsPerRtInt
where “ceil” is the “ceiling” function, indicating a rounding up to the next integer (if necessary)
and status element Sys.ServoMotors is the highest-numbered active motor. The value of
Motor[x].I2tTrip should be divided by N compared to cases where motor status updates are
performed every real-time interrupt.
In the older PMAC and Turbo PMAC controllers, the equivalent parameter to Power PMAC’s
Motor[x].I2tTrip is Ixx58. The scaling of both the current values and the time in Ixx58 is
different from I2tTrip. The equation for setting Ixx58 in these older controllers is:
where Ixx69 is the equivalent of MaxDac, Ixx77 is the equivalent of IdCmd, and Ixx57 is the
equivalent of I2tSet, all with the same units in both controllers.
If you have a setting of Ixx58 in an older PMAC controller and you want to set I2tTrip in Power
PMAC for the same functionality, use the following equation to determine I2tTrip:
Sys.ServoPeriod
I 2tTrip Ixx58 * 32,768 2 *
1000
2 2
I peak I peak
i 2 t I peak
2
* sin 2 t * cos2 t
2 2
Taking the mean value of this signal over one or more full cycles simply leaves the first term of
the expression:
2
I peak
i
2
2
Next, taking the square root of this mean gives us:
1
I rms I peak
2
So the RMS magnitude of a sinusoidal waveform is 0.707 times the peak magnitude. Conversely,
the peak magnitude can be calculated as 1.414 times the RMS magnitude. So if a motor is rated as
having a 10Arms continuous current capability, the peak current value of each AC waveform can
be just above 14A.
In a simple example, our application motion profile consists of indefinite repetitions of the
following sequence of a trapezoidal move and dwell:
The “average” current for this profile is computed using the root of the mean of the squares of the
sections:
The motor and amplifier selected for this application must each have a continuous current rating
of at least 6.6A.
The following diagram shows this application motion profile, required current levels, square of
current levels, and the resulting average squared-current value with the associated RMS current
level.
I (A) I2 (A2)
400
20
18 300
Velocity vs Time Move Profile
16
14
12 200
10
8
RMS(I)
6 100
4
Mean(I2)
2
0
1 2 3 4 5 7
-2 time (sec)
-4
-6
-8
-10
-12
-14
-16
The potential confusion comes from the fact that for brushless motors, the individual current
requirements for each section of the profile are themselves RMS values of the AC waveforms
during that section. So these calculations can be computing RMS values of RMS values!
It is very important for the user to distinguish between the two types of RMS calculations. The
terminology used by different suppliers is not always consistent, so the context must always be
taken into account. This chapter uses “intermittent” to describe short-term sections of motion
profiles, such as high-current accelerations and decelerations. The Motor[x].MaxDac
“intermittent current limit” must be high enough to cover these. “Instantaneous” in this chapter
refers to the individual current samples taken at high frequencies, such as the phase current
readings, and “peak” is the maximum instantaneous reading of a waveform.
The other reference frame is the “field” frame, which is tied to the magnetic field on the rotor. In
brushless servo motors, this frame is fixed with respect to the mechanical structure of the rotor
and the permanent magnets in it. In AC induction motors, this frame “slips” with regard to the
mechanical structure of the motor by an amount proportional to the torque producing current.
If Power PMAC is performing commutation for the motor, the quadrature-current command from
the servo loop is one of two current-command inputs to the commutation algorithm. The other is
the direct, or field-producing, component. In Power PMAC, the direct current command input to
the commutation algorithm is the value of saved setup element Motor[x].IdCmd. For brushless
servo motors, IdCmd is almost always set to 0. For AC induction motors, IdCmd must be set to
a value greater than 0 to induce a magnetic field in the rotor. Common values of IdCmd for
induction motors are around 3,000.
Because all of the limits discussed in this note use commanded current values in the field frame,
the user does not need to consider the reference frame conversion in this mode.
In standard “academic” presentations of this transformation for 3-phase systems, the overall
vector magnitude of the combined values is conserved during the transformation, but this requires
additional multiplications to achieve. Since Power PMAC is performing this transformation
10,000 or more times per second, in order to save computation time, these scaling multiplications
are not used, and the magnitude of the transformed quantity is somewhat reduced
In Power PMAC, the resulting magnitude in field coordinates has a magnitude of cos(120°-90°) =
0.866 times that of the peak values in the phase current coordinates. For example, if the phase
current measurements were sine waves with peak values of the full range ±32,768, the resulting
magnitude of the field-frame current values would be 32,768*cos(30°) = 28,377. Note that while
these phase-frame measurements are AC waveforms in the steady state, the conversion to field-
frame coordinates create DC values. Phase-current sine waves with peak measurements of
±32,768 would convert to constant DC field-frame current values of 28,377.
Remember that the peak values of the phase current measurements are sqrt(2) = 1.414 times the
RMS values of the sine waves. Phase-current sine waves with peak measurements of ±32,768
would have RMS current magnitudes of 32,768 / 1.414 = 23,174 in the same converter units. This
is what would result from current commands with a magnitude in the field frame of 28,377.
Note that for 2-phase motors, as with most stepper motors, the magnitude of the current after the
transformation is the same as before, because cos(90°-90°) = 1.0.
MaxDac
Vmax 10 *
32,768
At the default value for MaxDac of 20,480, the output range is limited to ±6.25V.
Note that these calculations refer to the voltage of the DAC+ output relative to the reference
voltage signal AGND (0V). If you are using the DAC+ and DAC- outputs, the output range is
±20V, and the effective gain of the output circuitry is 20 / 32,768 (Volts / LSB). If the amplifier
can only tolerate ±10V, the value of MaxDac should not be greater than 16,384.
Motor[x].MaxDac can be set to limit the intermittent current output magnitude to protect either
the amplifier or the motor. Note, however, that virtually all amplifiers of this type can safely take
the full-range command of ±10V for at least a few seconds, so there is almost never a need to
reduce the value of MaxDac for amplifier protection. (There can be reasons other than motor or
amplifier protection to reduce the value of MaxDac.)
It is quite common that the motor will have a lower intermittent current rating than the amplifier.
In this case, MaxDac should be set to a value lower than its largest possible value. The equation
for MaxDac can be given as:
ItopMtr
MaxDac 32,768 *
ImaxAmp
This equation assumes that the intermittent current rating for the motor (ItopMtr) is expressed in
the same type of units as the maximum intermittent current value for the amplifier (ImaxAmp).
For brushless motors and amplifiers, these are typically both expressed as RMS quantities. If you
are limiting the intermittent current command output from the Power PMAC for reasons other
than motor protection, simply substitute your current limit in place of ItopMtr in the above
equation.
For example, if the brushless-motor amplifier has a 25Arms maximum intermittent current
capability (i.e. a ±10V input commands a ±25Arms current), but the brushless motor itself has a
20Arms intermittent current limit, MaxDac is calculated as:
20 Arms
MaxDac 32,768 * 26,214
25 Arms
Continuing our example, if the brushless motor has a 10Arms continuous current rating, and is
used with an amplifier that has a peak current capability of 25Arms, I2tSet is calculated as:
10 Arms
I 2tSet 32,768 * 13,107
25 Arms
I 2tTrip 26,2142 13,107 2 * 2 1.03 109
In torque output mode, it is important that Motor[x].IdCmd be set to its default value of 0 so
proper I2T calculations will be done. A non-zero value would not affect the control calculations,
but it would be used as a real commanded current value in the I2T calculations.
Each phase command value is then multiplied by Motor[x].PwmSf / 32,768, and the results are
written to two D/A converters, each with an output range of ±10V, corresponding to the full
numeric range of ±32,768. (The default value of PwmSf is +32,767, making this second scaling
effectively equal to 1.0. The magnitude of PwmSf is seldom changed from the default in this
mode, but changing the sign has the same effect as swapping two motor leads.) The output
circuitry can therefore be considered to have a “gain” of 10 / 32,768 (Volts / LSB).
When used to control a 3-phase motor – the most common configuration – the amplifier controls
the third phase with a “balance loop”, commanding it so its current will be equal to the negative
of the sum of the two phases commanded from the Power PMAC.
MaxDac PwmSf
Vmax 10 * *
32,768 32,768
At the default value for MaxDac of 20,480 and for PwmSf of 32,767, the output range is limited
to ±6.25V for each DAC.
Note that these calculations refer to the voltage of the DAC+ output relative to the reference
voltage signal AGND (0V). If you are using the DAC+ and DAC- outputs, the output range is
±20V, and the effective gain of the output circuitry is 20 / 32,768 (Volts / LSB). If the amplifier
can only tolerate ±10V, the value of MaxDac should not be greater than 16,384.
A sinewave-input amplifier with two analog inputs has a “transconductance gain” expressed in
amperes per volt. Since this style of amplifier simply produces an instantaneous phase current
that is proportional to the instantaneous voltage of the phase command signal, this gain can be
thought of either in terms of instantaneous or RMS current. In terms of peak current for a phase:
A MaxDac PwmSf
I max A K amp * 10 * *
V 32,768 32,768
However, if the motor ratings are in terms of RMS currents, as they usually are for electronically
commutated brushless motors, the conversion from instantaneous current values in Power PMAC
to RMS motor current values must be performed at some point. For RMS current:
A MaxDac PwmSf
I max Arms
1
* K amp * 10 * *
2 V 32,768 32,768
* I max Arms
32,768 32,768 2
MaxDac * *
10 PwmSf K amp
For example, a sine-wave input amplifier with a transconductance gain for each phase of 4
amps/volt could produce a current output of 40A (peak) on each phase from a full-range (±10V)
sinewave command from a Power PMAC with PwmSf at the default setting of 32,767. This
corresponds to an RMS magnitude of 40/sqrt(2) = 28.3Arms. If the motor has an intermittent
current limit of 20Arms, MaxDac can be set by the following equation:
32,768 32,768 2
MaxDac * * * 20 23,170
10 32,767 4
For the case of an AC induction motor driven by this sinewave amplifier (not common!) with a
20Arms intermittent current limit and a value of Motor[x].IdCmd of 3,000, the calculation
becomes:
32,768 32,768 2
MaxDac2 IdCmd 2 * * * 20 23,170
10 32,767 4
Continuing our above example, if the brushless motor has a continuous current limit of 10Arms,
I2tSet is calculated as:
32,768 32,768 2
I 2tSet * * * 10 11,585
10 32,767 4
If the AC induction motor operated with a value of 3,000 for IdCmd has a continuous current
limit of 10Arms, I2Set is calculated as:
32,768 32,768 2
I 2tSet 2 IdCmd 2 * * * 10 11,585
10 32,767 4
I 2tTrip 23,1702 11,5852 * 3 1.21109
The calculations for the AC induction motor with the same current ratings come out the same.
The “gain” of the ADCs, in LSBs/Ampere, is the factor that ties the numerical current values in
the Power PMAC to physical current units. Each direct-PWM “power block” amplifier provides
this value, either directly as a gain term, or as a full-range current value representing a
measurement of 32,768 LSBs. Typically, this full-range measured current value is somewhat
greater than the true maximum current (even at the peak of the largest intermittent-duty sinewave)
ever expected in normal operation, to aid in the detection of overcurrent fault conditions.
The full-range measurements of instantaneous phase currents (and the associated ADC “gains”)
in several Delta Tau power-block amplifiers are listed below:
The Geo Book amplifiers listed include both the Geo PWM amplifiers and the Geo MACRO
amplifiers.
In Power PMAC’s direct-PWM mode, the phase current numbers produced by the ADCs are
converted to field-frame current values. The resulting vector magnitude of the field-frame (direct
and quadrature) current values includes a multiplication by cos(φ-90°), where φ is the electrical
angle between phases, as set by Motor[x].PhaseOffset. For 3-phase motors, where PhaseOffset
is set to ±683 (out of a cycle of 2048), φ is 120°, and cos(φ-90°) is 0.866.
DC brush motors can be controlled by Power PMAC in direct-PWM output mode by forcing the
commutation angle to 0 at all times. In this case, there is no need for conversion between RMS
and peak values, or between phase and field reference frames.
For brushless servo motors, IdCmd is virtually always set to 0, so MaxDac itself sets the
maximum net current command magnitude for these motors.
Several stages of calculation must be used to convert the intermittent current limit of a motor,
usually given in RMS amperes, to the units of MaxDac.
The RMS value must be multiplied by sqrt(2) to convert to a peak current value in
amperes.
The peak value must be multiplied by the “gain” of the ADC (Kadc) for the amplifier to
convert into (16-bit) LSBs of the ADC.
The ADC value must be converted to field-coordinate magnitude by multiplying by
cos(φ-90°).
For a 3-phase brushless servo motor with an 8Arms intermittent current limit controlled by a Geo
Brick AC 5A/10A amplifier, MaxDac can be computed as:
* cos30 20,553
32,768
MaxDac 8 * 2 *
15.62
For a 2-phase stepper motor with a 2.5Arms intermittent current limit controlled by a Geo Brick
LV 1A/3A amplifier, MaxDac can be computed as:
* cos0 17,112
32,768
MaxDac 2.5 * 2 *
6.770
For a 3-phase induction motor with a 25Arms intermittent current limit controlled by a Geo Book
15A/30A amplifier, with IdCmd set to 2,800, MaxDac can be computed as:
* cos30 20,558
32,768
MaxDac 2 IdCmd 2 25 * 2 *
48.8
For a DC brush motor with a 2.75A intermittent current limit controlled by a Geo Brick LV
1A/3A amplifier, no RMS or frame conversions are required, so MaxDac can be computed as:
32,768
MaxDac 2.75 * 13,310
6.770
For a 3-phase brushless servo motor with a 4Arms continuous current limit controlled by a Geo
Brick AC 5A/10A amplifier, I2tSet can be computed as:
* cos30 10,277
32,768
I 2tSet 4 * 2 *
15.62
For a 2-phase brushless motor with a 1.0Arms continuous current limit controlled by a Geo Brick
LV 1A/3A amplifier, I2tSet can be computed as:
* cos0 6,845
32,768
I 2tSet 1.0 * 2 *
6.770
Note that if this motor is driven as an open-loop stepper in “direct microstepping” mode, where
the motor current comes from IdCmd, this equation determines the maximum magnitude of
IdCmd that should be used.
For a 3-phase induction motor with a 10Arms continuous current limit controlled by a Geo Book
15A/30A amplifier, with IdCmd set to 2,800, I2tSet can be computed as:
* cos30 8,223
32,768
I 2tSet 2 IdCmd 2 10 * 2 *
48.8
For a DC brush motor with a 1.25A continuous current limit controlled by a Geo Brick LV
1A/3A amplifier, no RMS or frame conversions are required, so I2tSet can be computed as:
32,768
I 2tSet 1.25 * 6,050
6.770
I 2tTrip MaxDac2 IdCmd 2 I 2tSet 2 * TimePermitted (sec)
For a 3-phase brushless servo motor with a 4Arms continuous current limit and an 8Arms
intermittent current limit for 3 seconds controlled by a Geo Brick AC 5A/10A amplifier, I2tTrip
can be computed as:
I 2tTrip 20,5532 0 2 10,277 2 * 3 9.50 108
For a 2-phase brushless motor with a 1.0Arms continuous current limit and a 2.5Arms intermittent
current limit for 2 seconds controlled by a Geo Brick LV 1A/3A amplifier, I2tTrip can be
computed as:
I 2tTrip 17,1122 0 2 6,8452 * 2 4.92 108
For a 3-phase induction motor with a 10Arms continuous current limit and a 25Arms intermittent
current limit for 5 seconds controlled by a Geo Book 15A/30A amplifier, with IdCmd set to
2,800, I2tTrip can be computed as:
I 2tTrip 20,3662 2,8002 7,7322 * 5 1.81109
For a DC brush motor with a 1.25A continuous current limit and a 2.75A intermittent current
limit for 2 seconds controlled by a Geo Brick LV 1A/3A amplifier, I2tTrip can be computed as:
I 2tTrip 13,3102 0 2 6,0502 * 5 2.81108
Velocity Limits
Power PMAC provides several limits on the velocities that can be commanded of axes and
motors.
In addition, for linear, circle and PVT-mode moves executed with segmentation enabled
(Coord[x].SegMoveTime > 0) and the special lookahead buffer active (lookahead buffer defined,
Coord[x].LHDistance > 0), it serves as the maximum velocity for each segment of the motion.
This can be particularly valuable for non-Cartesian coordinate systems defined with Power
PMAC’s kinematic equations; very high motor velocities can inadvertently be commanded near
“singularities”. The lookahead algorithm can detect these problems beforehand, and slow the
motion down along the path into the problem point, observing the Motor[x].InvAmax motor
acceleration limits for all axes in the coordinate system.
Velocities are compared to these limits assuming the % value for the coordinate system is 100
(real time), as the % value is used after this limit check. This means that other % values will
result in different effective limits. However, for segmented moves, this limit check occurs after
the segmentation override value Coord[x].SegOverride is used, so the effective limit remains the
same regardless of what segmentation override value is used.
Acceleration Limits
Power PMAC provides several limits on the accelerations that can be commanded of axes and
motors.
Coord[x].CornerAccel specifies the acceleration in blending between any two linear and/or
circle-mode moves, calculated based on the corner angle in the specified plane and the
programmed speed of the moves. It calculates the blending time necessary to achieve this
acceleration without exceeding it, ignoring the value in Coord[x].Ta, but will not use a time less
than Coord[x].Td.
First, for simple linear-mode moves with move segmentation disabled (Coord[x].SegMoveTime
= 0), Motor[x].InvAmax specifies the magnitude of the maximum acceleration permitted,
calculated on a move-by-move basis. If the commanded acceleration requested of a motor for a
move by the change in velocity and the acceleration times exceeds the limit for the motor, the
acceleration times are extended so that the acceleration limit is not exceeded. In a multi-axis
programmed move, the times for all axes in the coordinate system are identically extended so that
full coordination is maintained.
Motor[x].InvDmax specifies the magnitude of the maximum final deceleration permitted for a
linear move sequence. Motor[x].InvAmax specifies the maximum magnitude for all blending
between moves in a sequence, regardless of whether this blending causes an acceleration or
deceleration.
Note that in blending linear-mode moves, the acceleration time occurs half in the incoming move
and half in the outgoing move. Extending the acceleration time of a blend therefore causes the
blend to occupy more time in both the incoming and outgoing moves. It is not possible to extend
the acceleration time past the start of the constant-speed portion of the incoming move. In this
mode of operation, if observing the acceleration limit requires that the blend time be extended
past this point, the blend time will only be extended to this point, and the acceleration limit will
be violated. (If your application requires more sophisticated acceleration limiting than this, you
will need to use the special buffered lookahead function that can spread acceleration over
multiple moves. This is discussed below.)
Second, for linear, circle, and PVT-mode moves executed with segmentation enabled
(Coord[x].SegMoveTime > 0) and the special lookahead buffer active (lookahead buffer defined,
Coord[x].LHDistance > 0), it serves as the maximum acceleration for each segment of the
motion. The lookahead algorithm can detect these problems beforehand, and slow the motion
down along the path into the problem point, observing the Motor[x].InvAmax motor
acceleration limits for all axes in the coordinate system.
Accelerations are compared to these limits assuming the % value for the coordinate system is 100
(real time), as the % value is used after this limit check. This means that other % values will
result in different effective limits. However, for segmented moves, this limit check occurs after
the segmentation override value Coord[x].SegOverride is used, so the effective limit remains the
same regardless of what segmentation override value is used.
programmed moves, only the component of acceleration from the following is limited by this
parameter; total acceleration could be greater. For more detail on this feature, refer to position-
following section of the chapter Synchronizing Power PMAC to External Events.
Jerk Limits
Power PMAC provides a limit on the commanded “jerk” (rate of change of acceleration) that can
be commanded of axes and motors in some classes of moves. The jerk level can be commanded
or limited in the “S-curve” acceleration sections of moves that start or stop at zero acceleration.
Note that there is no jerk limiting in the buffered lookahead function.
In this section, we cover the stopping commands and modes that are usually used for safety
reasons, considered “emergency” stops. It is not possible simply to resume a motion program
after issuing one of these commands.
motor’s Motor[x].AbortTa and Motor[x].AbortTs saved setup elements. These elements can
specify deceleration and S-curve times, or more commonly, deceleration and jerk rates.
This type of commanded stop qualifies as a “Category 2” safe stop under the IEC-61800-5-2
machine safety standard. Since it does rely on the servo loop to keep the motor’s actual position
close to the commanded deceleration profile, it should only be used as a safety stop in those cases
where reasonable servo control is present.
This type of commanded stop is similar in action to a “Category 0” safe stop under the IEC-
61800-5-2 machine safety standard. However, under the standard, there must be an actual
removal of power from the motor or a circuit needed to drive the motor, usually either bus power
or gate-driver power. This command is still useful for this category of safe stop because it puts
the Power PMAC in a state consistent with the removal of power. Many users will have the same
signal that causes the removal of power also to issue this command.
The motor “kill” command (k on-line, kill programmed) performs the same action for each
commanded motor, but it cannot be used if the motor is in a coordinate system that is executing a
motion program.
Hybrid Abort/Disable
The coordinate-system “abort/disable” command (adisable on-line, adisable programmed)
causes the Power PMAC to break into the present trajectory of each motor in the coordinate
system and immediately begin a commanded deceleration to a controlled stop, just as it would for
an “abort” command. However, as each motor reaches its “desired velocity zero” state, it
automatically executes a “delayed kill” command, where brake engagement is started
immediately, and the motor is killed (open-loop, zero-output, amplifier-enable) after a delay of
Motor[x].BrakeOnDelay milliseconds.
This type of commanded stop is similar in action to a “Category 1” safe stop under the IEC-
61800-5-2 machine safety standard. However, under the standard, there must be an actual
removal of power from the motor or a circuit needed to drive the motor, usually either bus power
or gate-driver power, after the controlled stop is complete. This command is still useful for this
category of safe stop because it puts the Power PMAC in a state consistent with the removal of
power. Many users will have the same signal that issues this command also to cause the removal
of power using a time-delay relay.
Another type of simple motor move is the homing-search move. This is basically a “jog-until-
trigger” type of move, where Power PMAC commands the motor to move until it sees a pre-
defined trigger. It then brings the motor to a stop and returns to the trigger position (possibly with
an offset), and sets the motor position to zero.
A homing-search move should be performed when you do not know where home position is. If
you have an incremental position sensor, you do not know where you are on power-up; therefore,
the homing search move is typically the first move done in this type of system. However, if you
already know where the home position is, but just wish to return to that position, there is no need
to do a homing search move; simply command a move to the zero position (e.g. J=0 or X0).
The trajectories for jogging and homing moves are essentially the same as for rapid-mode
program moves. However, these moves are specified directly to the motor, specified by number,
rather than the axis, specified by letter. The moves are described in basic motor units, not axis
units.
For example, to command a jog speed of 30 meters per minute with motor units of 5 microns,
calculate:
If Motor[x].JogTs is greater than zero, it specifies the jog “S-curve” time (the time in each half
of the “S”) in milliseconds. During the “S-curve” portion of the profile, the acceleration is
increasing or decreasing at a constant rate (so these sections of the profile have a constant “jerk”).
This time is used regardless of the value of the peak acceleration, so the rate of jerk will be
different for different peak accelerations. If it is set to 0, there are no S-curve sections in the
acceleration profiles.
If Motor[x].JogTa is greater than Motor[x].JogTs, the total acceleration time is JogTa + JogTs.
(Note that this is different from PMAC and Turbo PMAC.) If Motor[x].JogTa is less than
Motor[x].JogTs, the total acceleration time is 2 * JogTs, and JogTa is not used. The profiles for
both cases are shown in the figure below.
Vel Acc
JogSpeed
ΔV/JogTa
V0
JogTs JogTs
JogTa
Vel Acc
JogSpeed
ΔV/JogTs
V0
JogTs JogTs
JogTs
These parameters are specified as inverse rates, which permits Power PMAC to use them in its
move calculations by multiplication instead of division. This provides significant improvements
in computational efficiency.
If Motor[x].JogTa is less than zero, it specifies the inverse of the peak acceleration magnitude, in
msec2 / motor unit. This rate is used regardless of the change in speed due to a jog command, so
the acceleration time will be different for different changes in speed. Note that, depending on the
speed and jerk values specified, this acceleration value may not be reached.
For example, to set a maximum acceleration of 5 m/s2 (~0.5g) with motor units of 10 μm,
calculate:
s 2 10 6 ms 2 10 5 m
ms 2
Motor [ x].JogTa * * 2.0
5m 2 motor unit motor unit
s
If Motor[x].JogTs is less than zero, it specifies the inverse of the jerk (rate of change of
acceleration) magnitude during each half of the “S-curve” portion of the acceleration profile, in
msec3 / motor unit. This rate is used regardless of the value of the peak acceleration, so the S-
curve time will be different for different peak accelerations. If it is set to 0, there are no S-curve
sections in the acceleration profiles. Note that if JogTs is less than 0, JogTa must also be set less
than 0.
For example, to reach the peak acceleration of 5 m/s2 in 50 msec (but lower peak accelerations in
proportionally less time), calculate:
50ms 10 6 ms 2 10 5 m ms 3
Motor [ x].JogTs * * 100
motor unit
5m s2 s2 motor unit
The following figure shows the acceleration profiles for these rate specifications of acceleration
and jerk, both for the case where the specified maximum acceleration is reached, and where this
acceleration is not reached before it must start returning to 0.
Vel Acc
JogSpeed
-1
JogTa
V0
JogTs JogTs
JogTa JogTa
ΔV*JogTa
Vel Acc
JogSpeed
-1
JogTa
√-ΔV/JogTs
V0
√-ΔV*JogTs √-ΔV*JogTs
√-ΔV*JogTs
Jog Commands
Jog moves can be commanded using either on-line commands or buffered program direct
commands. In this section, the on-line commands will be shown first, followed by the equivalent
buffered program direct commands in square brackets.
Generally, the buffered program commands will be issued from PLC programs. A motion
program should not attempt to jog a motor that is assigned to the coordinate system running the
program.
When a jog command is issued to a motor, if the motor is not enabled and in closed-loop mode, it
will be put in enabled and closed-loop mode at the start of the action from the command. The
starting speed for the jog move will be the actual velocity at the time of the command (which will
usually, but not always, be zero).
However, if the software overtravel limits for the motor are enabled (Motor[x].MaxPos >
Motor[x].MinPos), these commands are executed as “definite” jogs to the software limit
position: a j+ [jog+] command is executed as a jog to Motor[x].MaxPos; a j- [jog-]
command is executed as a jog to Motor[x].MinPos. Note that these moves will stop at the
overtravel limit position, not just begin to decelerate as the overtravel limit position is passed.
The on-line jog command (no program command equivalent) will take a motor that is open-loop
and close the loop using a command velocity for an indefinite jog move that is equal to the actual
velocity at the time of the command.
The j/ [jog/] jog stop command brings the motor to a closed-loop zero-velocity state. If the
motor was executing a motor move (jog or homing-search) at the time of the command, it will use
the instantaneous desired velocity and acceleration values at the time of the command as the
starting states and compute a deceleration to a stop based on the values of Motor[x].JogTa and
Motor[x].JogTs. If the motor was open loop at the time of the command, it will use the
instantaneous actual velocity (often zero) and zero acceleration as the starting states and compute
a deceleration to a stop based on the values of these parameters.
If a double equals sign is used in the above commands (j=={constant} , j==*), the move
executes exactly the same as with the single equals sign, but the motor’s “pre-jog” position (for
j= [jogret] commands) is set to the endpoint of the move.
The on-line commands for a “relative” jog from the present actual position are j^{constant}
and j^*. The destination distance is specified by the numerical constant in the command in the
first case (e.g. j:-4300), and the present value of Motor[x].ProgJogPos in the second case,
both in motor units relative to the present motor actual position. The direct program command
equivalent for both cases is jog^{data}, where {data} can be a constant without parentheses
(e.g. jog^-2.75) or a mathematical expression in parentheses (e.g.
jog^(125*tand(P10)) ). Note that because these commands are relative to the actual
position, their destination position is dependent on the value of the following error at the instant
of the command.
If the motor is closed loop when the jog command is received, Power PMAC uses the present
commanded position, velocity, acceleration, and jerk of the motor trajectory as the starting state
for its trajectory calculations resulting from the command. This can produce seamless blending
into the new move, particularly when the acceleration profile is specified by rate and not time.
If the motor is open loop when the jog command is received, Power PMAC uses the present
actual position and velocity of the motor (and assumes zero acceleration and jerk) as the starting
state for its (closed loop) trajectory calculations resulting from the command.
1. Homing-search moves
2. Jog-until-trigger moves
3. Program rapid-mode move-until trigger
These three types of moves all work in basically the same manner, but in different contexts.
Triggering and position-capture functions are the same in all three move types. Each will be
described in detail below.
Trigger Conditions
There are fundamentally two types of triggers for these triggered moves: input triggers and
following-error triggers. If Motor[x].CaptureMode is set to 0, 1, or 3, input triggering is used. If
Motor[x].CaptureMode is set to 2, following-error triggering is used.
Input Triggering
If Motor[x].CaptureMode is set to 0 or 1, Power PMAC will look for an individual trigger bit in
the register whose address is specified in Motor[x].pCaptFlag at the bit number specified by
Motor[x].CaptFlagBit. When this bit value becomes 1 during the pre-trigger move, Power
PMAC knows that the trigger has occurred, and it will read and process the captured position so it
can compute the trajectory for the post-trigger move.
Most commonly, this specified trigger bit is the “position captured” bit in the flag status register
for a servo channel of a Servo IC, or in the input flag register of a MACRO node. The value of
this bit is typically from a user-specified input choice of signal(s) and edge(s), permitting great
flexibility in the choice of trigger condition.
PMAC2-Style Interface
In a PMAC2-style “DSPGATE1” Servo IC, as used in the ACC-24E2x and ACC-51E UMAC
accessories, the position-captured trigger bit is found in bit 19 of the channel status register, so
Motor[x].pCaptFlag = Gate1[i].Chan[j].Status.a and Motor[x].CaptFlagBit = 19.
The element Gate1[i].Chan[j].CaptCtrl specifies whether the trigger bit uses a channel input
flag or not, the encoder index channel or not, and which edge of the selected signal(s) create the
trigger. Gate1[i].Chan[j].CaptFlagSel determines which of the four input flags for the channel
(HOME, PLIM, MLIM, USER) is selected if flag use is specified by CaptCtrl.
The following diagram shows the trigger signals selected by the CaptCtrl element for the
PMAC2-style ICs. For the PMAC3-style ICs, the settings for 3 and 15 are reversed, as are the
settings for 7 and 11.
Gaten[i].Chan[j].CaptCtrl
(1) C = 1 or 9
(2) C = 5 or 13
(3) FLAG = 2 or 6
(4) FLAG = 10 or 14
If the encoder index pulse is used, a further refinement is possible. Typically the index pulse is a
full encoder line wide, spanning 4 quadrature counts. It is possible to “gate” this logically to a
single quadrature state width before its use in the trigger signal by setting
Gate1[i].Chan[j].GatedIndexSel to 1. This quadrature state will be the “high-high” state (A = 1
B = 1) if Gate1[i].Chan[j].IndexGateState is 1; it will be the “low-low” state (A = 0 B = 0) if
Gate1[i].Chan[j].IndexGateState is 0. Gating the index pulse makes the count at the trigger
edge more repeatable and ensures that the captured count is the same in both directions.
The following diagram shows how this “gating” process works for the “high-high” state.
C
(Index)
Gated
Index
The position capture in a PMAC2-style IC is level-triggered. For most purposes, the difference
between level-triggered and edge-triggered captures is not important. However, there are a couple
of issues that could be important. First, if a triggered move is started when the inputs are already
in the trigger-causing state, the trigger will occur before the move even starts, and there will be no
actual move commanded, with the move considered to have completed successfully. Second, if
the inputs are still in the trigger-causing state when the Power PMAC reads the captured position
(which re-arms the trigger), there will be an immediate re-trigger and a new captured position.
This will not affect the functionality of the triggered move, but if another software task reads the
captured-position register, it may get the position at the re-trigger.
PMAC3-Style Interface
In a PMAC3-style “DSPGATE3” IC, as used in the ACC-24E3 UMAC accessory family, the
Power Clipper, and the Power Brick, the position-captured trigger bit is found in bit 20 of the
channel status register, so Motor[x].pCaptFlag = Gate3[i].Chan[j].Status.a and
Motor[x].CaptFlagBit = 20.
The element Gate3[i].Chan[j].CaptCtrl specifies whether the trigger bit uses a channel input
flag or not, the encoder index channel or not, and which edge of the selected signal(s) create the
trigger. Gate3[i].Chan[j].CaptFlagChan specifies which of the four servo channels on the IC
the flag used (if used) will come from. Gate3[i].Chan[j].CaptFlagSel determines which of the
four input flags (HOME, PLIM, MLIM, USER) for the specified channel is selected if flag use is
specified by CaptCtrl.
If the encoder index pulse is used, a further refinement is possible. Typically the index pulse is a
full encoder line wide, spanning 4 quadrature counts. It is possible to “gate” this logically to a
single quadrature state width before its use in the trigger signal by setting
Gate3[i].Chan[j].GatedIndexSel to 1. This quadrature state will be the “high-high” state (A = 1
B = 1) if Gate3[i].Chan[j].IndexGateState is 1; it will be the “low-low” state (A = 0 B = 0) if
Gate3[i].Chan[j].IndexGateState is 0. Gating the index pulse makes the count at the trigger
edge more repeatable and ensures that the captured count is the same in both directions.
The position capture in a PMAC3-style IC is edge-triggered. For most purposes, the difference
between edge-triggered and level-triggered captures is not important. However, there are issues
that could be important. First, if a triggered move is started when the inputs are already in the
trigger-causing state, there will be no edge to cause the trigger, and the move will likely fail, and
possibly not end until a fault condition such as an overtravel limit is reached. For this reason, it is
important to check to see if the inputs could be in the trigger-causing state before a triggered
move is commanded.
MACRO Interface
In a MACRO interface, the position-captured trigger bit is found in bit 19 of Register 3 for the
node, so Motor[x].pCaptFlag = Gate2[i].Macro[j][3].a for a PMAC2-style “DSPGATE2” IC,
as on the ACC-5E, or Gate3[i].MacroIn[j][3].a for a PMAC3-style “DSPGATE3” IC, as on the
ACC-5E3 or the Power PMAC Brick MACRO option. Motor[x].CaptFlagBit should be set to
19 in both cases.
Following-Error Triggering
Sometimes it is desired that a trigger occur when an obstruction such as a hard stop is
encountered, as when using an end stop for the homing reference. To support this type of
functionality, Power PMAC permits triggering on a warning-following-error condition instead of
an input flag. This is sometimes called “torque-mode” triggering, because it effectively triggers
on a torque level (except for velocity-mode amplifiers), as output torque command is generally
proportional to following error. It is also called a “torque-limited” mode, because it provides an
easy way to create moves that are limited in torque, and that stop when the torque limit is reached
(as in torque-limited screw driving).
When using torque-mode triggering, it is a good idea to set the integral gain term
Motor[x].Servo.Ki to 0 to prevent a large “charge-up” of the integrator when it hits the hard
stop. It may also be desirable to set the Motor[x].MaxDac output limit lower to limit the possible
torque directly when the obstruction is reached.
Note that if the warning following error status bit is true at the start of the move, the trigger will
occur almost immediately.
Hardware Capture
The Servo ICs of a Power PMAC have dedicated registers to latch the encoder counter instantly
upon receipt of the pre-specified input trigger state. The latching action occurs entirely in the IC
hardware, requiring no software action, so the captured position is accurate to the exact count
regardless of motor speed. This means that there is no need to slow down the move to get an
accurate capture.
Hardware capture is selected for the motor’s triggered moves by setting Motor[x].CaptureMode
to the default value of 0, specifying both hardware capture and input triggering. If hardware
capture is selected, the position-loop servo feedback as selected by Motor[x].pEnc must come
through the encoder counter of a Servo IC. It must use the same hardware channel as the flag set
selected by Motor[x].pCaptFlag. This means that if you are using dual feedback on the motor,
the flag set specified by Motor[x].pCaptFlag should be the same channel as your position-loop
feedback, not your velocity-loop feedback.
When hardware capture is selected, the hardware register where the captured position is to be
found must be specified by Motor[x].pCaptPos, which should contain the address of the register
in the Servo IC where the position at the time of the trigger was latched.
PMAC2-Style Interface
In a PMAC2-style “DSPGATE1” Servo IC, as used in the ACC-24E2x and ACC-51E UMAC
accessories, the trigger-captured position is found in the “home capture” register for the channel
of the IC used for the encoder interface, so Motor[x].pCaptPos should be set to
Gate1[i].Chan[j].HomeCapt.a. This must be the same channel of the IC as for the trigger input.
PMAC3-Style Interface
In a PMAC3-style “DSPGATE3” IC, as used in the ACC-24E3 UMAC accessory family, the
Power Clipper, and the Power Brick, the trigger-captured position can be found in the “home
capture” register of the IC used for the encoder interface, and if saved setup variable for the
channel Gate3[i].Chan[j].TimerMode is set to its default value of 0, it can also be found in the
“timer B” register for the channel.
To use the “home capture” register, which has whole-count data in the high 24 bits and fractional-
count data in the low 8 bits (so units of 1/256 of a count), Motor[x].pCaptPos should be set to
Gate3[i].Chan[j].HomeCapt.a. If TimerMode for the channel is set to 0, timer-based fractional
count estimation is present in the low 8 bits. If TimerMode is greater than 0, the fractional count
value is always ½ of a count. The resolution of this register matches that of the servo-captured
register for digital quadrature feedback, so its value will not have to be adjusted through shift
operations to create the match (see Processing the Hardware-Captured Position, below).
To use the “timer B” register, which has whole-count data in the high 20 bits and fractional-count
data in the low 12 bits (so units of 1/4096 of a count), Motor[x].pCaptPos should be set to
Gate3[i].Chan[j].TimerB.a. Saved setup element TimerMode for the channel must be set to the
default value of 0 for this register to contain the trigger-captured position for the channel. The
resolution of this register matches that of the servo-captured register for sinusoidal feedback
processed with Gate3[i].Chan[j].AtanEna set to 1, so its value will not have to be adjusted
through shift operations to create the match (see Processing the Hardware-Captured Position,
below).
With AtanEna set to 1, the 12 bits of fractional count data in the servo-captured position comes
from the arctangent of the “sine” and “cosine” ADCs. The 12 bits of fractional count data in the
trigger-captured position comes from the timers for the channel.
Software Capture
The use of hardware capture requires that the position-loop servo feedback be processed through
the counter circuitry of an IC channel, because it is the counter value at the instant of the trigger
that the hardware “captures” (latches). If this is not the case, as with serial encoders, parallel
encoders, directly-converted resolvers, LVDTs, MLDTs, etc., then hardware capture cannot be
used, and software capture must be used instead.
When software capture is used, there is a potential delay between the actual trigger and Power
PMAC’s position capture of one real-time interrupt (Sys.RtIntPeriod + 1 servo interrupts). This
delay can lead to inaccuracies in the captured position; the speed of the motor at the time of the
trigger must be kept low enough to achieve an accurate enough capture. For homing, a two-step
procedure can often be used: a fast, inaccurate capture followed by a slow, accurate capture.
The following diagram shows a sample trajectory for triggered moves such as homing search
moves, and highlights the difference in captured position accuracy between hardware and
software capture techniques.
HomeComplete = 1
Gaten[i].Chan[j].PosCapt = 1 HomeInProgress = 0
(TriggerMove = 0)
Vel
Time
Trigger Occurs
Hardware Capture Occurs
Gate3[i].Chan[ j ].Pfm
f PFM f PFMCLK
2 32
The frequency of the PFMCLK clock signal is determined by saved setup element
Gate3[i].PfmClockDiv. The default value of 5 for this element, which specifies a frequency of
3.125 MHz (3125 kHz), should always be satisfactory for this use.
Rearranging this equation to solve for the value of the Pfm element in order to generate a pulse
frequency 16 times the servo frequency, we get:
16 f Servo f
Gate 3[i].Chan [ j ].Pfm 2 32 2 36 Servo
f PFMCLK f PFMCLK
With the default servo frequency of 2.259 kHz, and the default PFMCLK frequency of 3125 kHz
(it is important to use consistent units!) we calculate:
2.259
Gate3[i].Chan[ j ].Pfm 2 36 49,675,935
3125
This value can be saved into non-volatile flash memory so it is automatically loaded into the
active register on power-up/reset.
To feed this pulse signal into the channel’s encoder counter, saved setup element
Gate3[i].Chan[j].EncCtrl is set to 8, which causes a connection inside the ASIC. No external
wiring is required, and it does not matter what is connected to the channel’s encoder inputs. Also,
it does not matter what mode the channel’s Phase D output signal is configured for, so this will
work regardless of the setting of Gate3[i].Chan[j].OutputMode.
However, it is necessary that the Phase D command register for the Pfm element be accessed
individually, in “unpacked” mode, so Gate3[i].Chan[j].PackOutData be set to 0. If this ASIC
channel is used for direct-PWM control, the commutation I/O must be done in this “unpacked”
mode, so Motor[x].PhaseCtrl must be set to 4 instead of 1, and Gate3[i].Chan[j].PackInData
must also be set to 0.
The ASIC channel’s trigger condition is set up as for any other trigger capture mode, with saved
setup elements Gate3[i].Chan[j].CaptCtrl, Gate3[i].CaptFlagSel, and
Gate3[i].Chan[j].CaptFlagChan specifying the signals and edges used for the capture.
Motor Setup
For the motor to use the channel’s trigger flag, Motor[x].pCaptFlag must be set to
Gate3[i].Chan[j].Status.a and Motor[x].CaptFlagBit must be set to 21. These will probably be
the default settings from the auto-configuration process done on system re-initialization.
For proper interpolation, Power PMAC needs to know when during the servo interrupt period the
servo position sensor is sampled (e.g. latched or strobed). Ideally, the sensor would be sampled
right at the servo interrupt for minimum servo delay, but often this is not possible, as there can be
conversion and transport delays, particularly for the serial data transfers common with absolute
encoders and analog-to-digital converters.
Motor[x].ServoCaptTimeOffset tells this algorithm what the delay is from the time the sensor is
sampled for servo feedback and the following servo algorithm. It is scaled in units of 1/65,536 of
a servo cycle. For example, if the delay is ¼ of a servo cycle (that is, it is sampled ¾ of the way
through the cycle), this element should be set to 65,536/4, or 16,384.
Commonly, analog-to-digital converter interfaces for Power PMAC are strobed on the rising edge
of the phase clock signal so the data can be transferred by the falling edge interrupt. With this
type of interface, the delay is ½ of a phase cycle, and since the phase frequency is n times the
servo frequency, Motor[x].ServoCaptTimeOffset would be set to 65,536 / (2*n).
Serial encoder interfaces for Power PMAC can be strobed on the rising or falling edge of either
the phase clock or the servo clock. Generally, the clock edge that produces the minimum delay to
the start of the servo interrupt is chosen, given the servo frequency and the required response
time.
The figure below shows how Power PMAC performs the timer-based interpolation for this
capture mode.
Position
ServoPos1
CaptPos
ServoPos0
time
Potential mismatch in scaling comes about because the servo-loop feedback position may have
sub-count resolution due to 1/T extension of quadrature encoders or arctangent extension of
sinusoidal encoders, and the hardware-captured position does not. Alternatively, the servo-loop
feedback position may use a high-resolution arctangent extension (12 fractional bits per count)
but the hardware-captured position uses a lower-resolution extension (8 fractional bits per count).
There are other possibilities as well.
Note that software capture always uses already-scaled motor position values, so none of these
processing steps is necessary when software capture is used. The settings of the processing-
control elements are not used in that case.
Processing Steps
Power PMAC employs three discrete processing steps after it reads the hardware-captured
counter position over the 32-bit bus and before it uses it as the motor’s position at the trigger for
the purposes of computing the post-trigger offset move.
Right-Shift Operation
First, it takes the 32-bit read value and shifts it right (toward the least significant end) by the
number of bits specified in Motor[x].CaptPosRightShift. This is done to eliminate any
unwanted bits at the low end of the 32-bit value read, either because the bits did not come from
real hardware (as in the case of the 24-bit PMAC2-style ICs) or because the captured data
included sub-count estimated data that we do not wish to use, or both.
Left-Shift Operation
Next, it takes the right-shifted result and shifts it left (toward the most significant end) by the
number of bits specified in Motor[x].CaptPosLeftShift. This is done to make the resulting value
have the same scaling as the position-loop feedback value.
Half-Count-Offset Operation
Finally, it can optionally offset the captured position one-half count to match the servo feedback,
if necessary. When Power PMAC performs sub-count extension of position data, either through
the “1/T” timer data, or from arctangent calculations of sine/cosine readings, it offsets the
position data by a half count to put the integer count value halfway in between the whole-count
edges, eliminating offset between directions. Simple whole-count data from the hardware counter
does not have this offset, so to match the two data types properly, it can be necessary to offset the
captured data by half a count.
So if the position-loop servo feedback utilizes sub-count extension, whether done in hardware or
software, and the hardware-captured position does not (or, in theory, vice versa), the captured
position value should be offset a half count before being used as motor trigger position. If
Motor[x].CaptPosRound is set to 1, Power PMAC will provide this offset. If it is set to 0, no
offset will be performed.
The following diagram shows how this process is done for this setup:
31 8 7 0
However, if this IC type is used for quadrature feedback when the servo loop is closed in the
phase interrupt, only the whole-count position value in Gate1[i].Chan[j].PhaseCapt is used for
servo-loop feedback. This is a 24-bit value, present in the high 24 bits of the 32-bit Power PMAC
bus, just as for the hardware captured position. In this case Motor[x].CaptPosRightShift should
be set to 8 to eliminate the indeterminate low 8 bits, Motor[x].CaptPosLeftShift should be set to
8 to match the resolution of the servo-loop feedback, and Motor[x].CaptPosRound should be set
to 0, because no half-count offset is needed.
The following diagram shows how this process is done for this setup:
31 8 7 0
8
31 24 23 0
Type = 4). This conversion provides 10 bits of sub-count extension (12 bits per cycle, for 4096x
interpolation).
The following diagram shows how this process is done for this setup:
31 8 7 0
The following diagram shows how this process is done for this case, where the fractional-count
value is not used, even if captured:
31 8 7 0
8
31 24 23 0
The following diagram shows how the process is done for this case, where the fractional-count
value is used. In this case, there is no net processing of the captured data.
31 8 7 0
0
31 0
the IC, found in Gate3[i].Chan[j].ServoCapt (or PhaseCapt if the servo loop is closed in the
phase interrupt). This processing, enabled if Gate3[i].Chan[j].TimerMode = 0 (the default)
provides 12 bits of sub-count extension (14 bits per cycle, for 16,384x interpolation).
The following diagram shows how the process is done for this case:
31 8 7 0
0
31 0
31 12 11 4 3 0
If the extended arctangent interpolation conversion is used for servo feedback (EncTable[n].type
= 7), as is appropriate with the Auto-Correcting Interpolator, this conversion provides 14 bits of
sub-count interpolation (16 bits per cycle, for 65,536x interpolation), then
Motor[x].CaptPosLeftShift should be set to 6 instead of 4 here to account for the extra two bits
of interpolation. The same is true if the software extension (EncTable[n].type = 4) is used with a
PMAC3-style IC, which also provides 14 bits of sub-count interpolation.
The following diagram shows how the process is done for this case:
31 8 7 0
0
31 0
The following diagram shows how this process is done for this case, where the fractional-count
value is not used, even if captured:
31 8 7 0
8
31 24 23 0
If the extended arctangent interpolation conversion is used for servo feedback (EncTable[n].type
= 7), as is appropriate with the Auto-Correcting Interpolator, this conversion provides 14 bits of
sub-count interpolation (16 bits per cycle, for 65,536x interpolation), then
Motor[x].CaptPosLeftShift should be set to 14 instead of 12 here to account for the extra two
bits of interpolation. The same is true if the software extension (EncTable[n].type = 4) is used
with a PMAC3-style IC, which also provides 14 bits of sub-count interpolation.
The following diagram shows how the process is done for this case:
31 8 7 0
8
31 24 23 0
The following diagram shows how the process is done for this case:
31 24 23 0
Captured Position Processing for Quadrature Encoder into Remote MACRO Node
Whole Count Only, With Servo Using 5-Bit Software 1/T Extension
The following diagram shows how the process is done for this case:
31 24 23 0
Captured Position Processing for Quadrature Encoder into Remote MACRO Node
Whole Count Only, With Servo Using No Extension
In this case, the hardware-captured position is acquired through a special software request over
the ring. The resulting value is in whole counts, with a single count residing in bit 0 of the 32-bit
word. In this case, users should set Motor[x].CaptPosRightShift to 0 to keep all of the whole-
count information, Motor[x].CaptPosLeftShift to 18 to match the resolution of the servo-loop
position, and Motor[x].CaptPosRound to 1 to match the half-count offset of the interpolated
servo feedback.
The following diagram shows how the process is done for this case:
31 24 23 0
Captured Position Processing for Quadrature Encoder into Remote MACRO Node
Whole Count Only, With Servo Using 10-Bit Software Arctangent Extension
In the case of timer-assisted software capture, Power PMAC automatically interpolates between
two recent servo-feedback positions for the motor based on the trigger-captured time stamp. Since
these positions have already been processed into the units of the motor, there is nothing for the
user to specify on this processing.
Post-Trigger Move
Once the trigger position has been found and processed into a motor position, Power PMAC can
compute the post-trigger move. The post-trigger move ends at a commanded position that is a pre-
specified distance from the actual position captured at the trigger. This signed distance value is
specified by a saved setup element in the case of homing-search moves, and by the last value in
the command in the case of triggered jog moves and programmed trigger moves.
The post-trigger move, including the blending from the pre-trigger move, is governed by the same
velocity and acceleration parameters as the pre-trigger move. Usually, the post-trigger move will
involve a reversal from the pre-trigger move, but this is not necessarily the case.
Homing-Search Moves
The purpose of a homing-search move is to establish an absolute position reference when an
incremental position feedback sensor is used. The “move until trigger” construct is ideal for
finding the sensor that establishes the home position and automatically returning to this position.
Note the important distinction between a homing-search move, in which the home location is not
known at the start of the move, and a move to the already-known home position, which can be
accomplished with a motor command such as j=0 or an axis command such as X0.
Home Commands
A homing-search move can be executed either from an on-line hm command (e.g. #5hm,
#6..8hm), or from a buffered program home command (e.g. home5, home6..8). The
buffered program command can be used in either a motion or a PLC program.
When commanding homing-search moves from an on-line command or a PLC program, the
command simply starts the homing-search move, and other action must be taken to monitor for
the end of the move and possible error conditions.
In homing-search moves, it is common practice to use a combination of a homing switch and the
index channel as the home trigger condition. The index channel of an encoder, while precise and
repeatable, is not unique in most applications, because the motor can travel more than one
revolution. The homing switch, while unique, is typically not extremely precise or repeatable. By
using a logical combination of the two, you can get uniqueness from the switch, and precision and
repeatability from the index channel. The IC setup element Gaten[i].Chan[j].CaptCtrl can set
up the trigger circuitry to perform this logical combination automatically in the IC hardware. In
this scheme, the homing switch is effectively used to select which index channel pulse is used as
the home trigger.
Although the homing switch does not need to be placed extremely accurately in this type of
application, it is important that its triggering edge remain safely between the same two index
channel pulses. Also, the homing switch pulse must be wide enough to always contain at least one
index channel pulse.
Post-Trigger Move
Motor[x].HomeOffset specifies the (signed) distance from the trigger-captured position to the
end of the post-trigger move, in motor units. The endpoint of the commanded post-trigger move
is the new motor position zero (the motor’s “home” position). The change of the motor’s reported
position reference occurs at the beginning of the post-trigger move. As soon as this is done,
reported positions are referenced to this new zero position. Also at this point, the motor’s “home
search in progress” status bit is cleared, and the “home complete” status bit is set.
If the post-trigger move fails with an error condition, it is not necessary to re-home the motor, as
the home position is already known. A command such as j=0 can move the motor to the home
position once the source of the problem has been cleared up.
If software overtravel limits are used (Motor[x].MaxPos > Motor[x].MinPos), they are re-
enabled at the beginning of the pre-trigger move after having been automatically disabled during
the search for the trigger. The trajectory to this new zero position is then calculated, including
deceleration and reversal if necessary. Note that if a software limit is too close to zero, the motor
may not be able to stop and reverse before it hits the limit. In normal termination, the motor will
stop under position control with its commanded position equal to the home position. If there is a
following error, the actual position will be different by the amount of the following error.
The following code section shows a simple example of commanding a homing-search move from
a PLC program and monitoring for proper finish:
A robust monitoring algorithm will also look for the possibility that the homing search move
could end in an error condition. Often this is just part of the general error monitoring that is done
at all times, looking for overtravel limits, fatal following errors, and amplifier faults. If an error
does occur during the homing move, it is important to distinguish between one that occurs before
the trigger has been found, and one that occurs after. If the error occurs after, Power PMAC
knows where the home position is, and the homing search does not need to be repeated. Once the
error cause has been fixed, the motor can simply be moved to the home position with a command
such as j=0.
In this gantry leader/follower mode, the leader motor is set up as a “normal” motor, with
Motor[x].ServoCtrl set to 1, so it generates its own commanded position trajectory, as well as
performing its own servo-loop closure, and commutation if specified. One or more “follower”
motors are set up with Motor[x].ServoCtrl set to 8, so they do not generate their own
commanded position trajectories (but still perform their own servo-loop closure, and
commutation if specified). Instead, they use the commanded trajectory of the motor specified by
Motor[x].CmdMotor, which is set to the number of the “leader” motor.
To perform a homing search move sequence for this set of motors, all of the motors in the set
should be commanded to perform a homing search move simultaneously. For example, if Motor 5
is the leader motor, and Motor 6 is the follower motor, an on-line #5..6hm or a program
home5..6 command could be used.
Leader Motor
Skew
Removed Power-On
On Skew
Homing
Follower Motor
During the pre-trigger portion of the move, any follower motors will simply track the trajectory of
the leader motor, so the power-on skew will remain during this part of the sequence. But as soon
as the home triggers have been found for both leader and follower motors, the difference between
the trigger positions and therefore the skew will be calculated, and the process of removing it will
be started.
It does not matter which trigger is found first, and while it is strongly recommended that the
deceleration distance for the leader motor after its own trigger is found be long enough that it will
always cause the follower motor trigger to be hit, it is possible to find the follower motor trigger
even after the leader’s post-trigger move is finished if some other move is then commanded.
Once both triggers have been found, the skew of a follower motor is removed at a rate set by
saved setup element Motor[x].GantrySlewRate in motor units per servo cycle. Note that the
factory default value for this element is 0.0, which does not permit the skew to be removed. The
skew removal offset is written into Motor[x].MasterPos for the follower motor, accumulating at
this slew rate until it compensated for the power-on skew. At this time, status bit
Motor[x].GantryHomed for the follower motor is set to 1.
The skew is determined by the difference in the captured positions for the two motors and by the
difference in the saved setup elements Motor[x].HomeOffset for the motors. The user can
calibrate the difference in physical location between the home triggers for the motor by setting
different values for these elements – the difference between the two values should correspond to
the physical difference.
Jog-Until-Trigger Moves
The jog-until-trigger function permits a jog move to be interrupted by a trigger and terminated by
a move relative to the position at the time of the trigger. It is very similar to a homing search
move, except that the motor zero position is not altered, and there is a specific destination in the
absence of a trigger.
Jog-Until-Trigger Commands
The “jog-until-trigger” function for a motor is specified by adding a ^{constant} or ^*
specifier to the end of a regular on-line “definite” jog command for the motor, or a ^{data}
specifier to the end of a regular program “definite” jog command for the motor. In all three cases,
this added syntax specifies the signed distance from the actual position captured at the trigger to
the desired position at the end of the programmed move, in motor units.
In the case of the on-line command with ^{constant}, it must be a numerical constant value.
In the case of the on-line command with ^*, the post-trigger distance comes from the value of
Motor[x].JogOffset. In the case of the program command with ^{data}, this distance can be a
numerical constant without parentheses, or a mathematical expression in parentheses.
The jog-until-trigger function cannot be used with the j+ and j- indefinite jog commands.
Trigger Condition
The trigger condition for the motor is set up just as for homing search moves, explained above.
Program Move-Until-Trigger
The move-until-trigger construct can be used from within a motion program. In this version it is a
variant of the rapid move mode, commanding motors through the axes they are assigned to.
These moves execute exactly like on-line jog-until-trigger moves, but they are described a little
differently.
The commanded acceleration for the move is specified by Motor[x].JogTa and Motor[x].JogTs,
as for other trigger moves. The magnitude of the peak velocity for the move is specified by
Motor[x].MaxSpeed if Motor[x].RapidSpeedSel is at the default value of 0, or by
Motor[x].JogSpeed if Motor[x].RapidSpeedSel is set to 1. The trigger conditions and capture
methods are specified as for other triggered moves, as described above. Status bits are set as for
on-line jog-until-trigger moves.
Open-Loop Moves
The on-line motor command out{constant} and the program direct motor command
cout:{data} specify “open-loop moves” for the motor. The position/velocity servo loop is
opened, and a fixed value is placed in the servo loop output. The signed numerical value at the
end of the command specifies this output value as a percentage of Motor[x].MaxDac, the largest
permitted magnitude for the servo loop output. If Power PMAC does not commutate the motor,
this command creates a constant signal on the single output for the motor. If Power PMAC does
commutate the motor, this command sets the sign and magnitude of the torque (quadrature)
command input to the commutation algorithm for the motor.
In the on-line command, the output value must be specified as a numerical constant (e.g. out-
50, #2out75.3) in the +/-100 range. In the program command, it may be specified as a
numerical constant without parentheses (e.g. cout:-50, cout2:75.3), or as a mathematical
expression in parentheses (e.g. cout:(P1), cout5,6:(sind(Q700) ).
These commands are typically used for diagnostic purposes, but they can also be used in the
actual applications.
If the Sys.PosCtrl position-output servo algorithm is selected for the motor, the position loop is
not closed in the PMAC, so there is no open-versus-closed-loop distinction. The open-loop output
command is not appropriate in this case. It can enable a disabled motor, but the output magnitude
is not used, and it does not change the open/closed-loop mode of the drive.
The coordinate systems, which take numbers from 0 to (Sys.MaxCoords – 1), can be addressed
in on-line commands with the &x command, where x is the number of the coordinate system.
Each coordinate system has its own independent data structure Coord[x] with control and status
variables for that coordinate system, with x again being the number of the coordinate system.
It is expected that most Power PMAC users will not have an active C.S. 0 (&0), with motors
assigned to axes in that coordinate system. Motors that have not been assigned to an axis in any
coordinate system automatically use the “time base” (% override value) of C.S. 0. At power-
on/reset, Power PMAC is automatically addressing C.S. 0, and an explicit &x command is
required to address another coordinate system in any communications thread.
It is possible to put all of your active motors in a single coordinate system for completely
coordinated action; it is also possible to put each motor in a separate coordinate system (up to the
limit of the number of possible coordinate systems) for completely independent action.
A coordinate system must first be established by assigning motors to axes in that coordinate
system. For simple relationships between motors (actuators) and axes (tool coordinates), this is
done with on-line commands called “axis-definition statements” (see below). For more complex
relationships, this is done by writing special “kinematic subroutines” that describe the
relationship (covered in a following section).
If a coordinate system has no motors assigned to axes in it, it can only execute motion programs
in a fast “simulation” mode. In this mode, the moves take no time, and the program is executed as
fast as Power PMAC can perform the calculations. This can be useful for certain “dry run”
capabilities to evaluate a program.
When a program is written for a coordinate system, if simultaneous motions are desired of
multiple motors, their move commands are simply put on the same line, and the moves will be
coordinated.
Fault Sharing
All of the motors in a coordinate system react to an automatic fault of any motor in the coordinate
system during a program move, including fatal following error, amplifier fault, integrated current
limit, hardware or software overtravel limit, and encoder loss fault. This is true for motors
assigned to position axes, spindle axes, or even the “null definition”. The specific reaction –
enabled stop or disabled state – for various types of faults is determined by the value of saved
setup element Motor[x].FaultMode for each motor.
However,, if a motor in a coordinate system faults during an independent motor move (e.g. jog,
home, open-loop) instead of coordinated program move, other motors in the coordinate system
will not react.
Motors do not automatically react to faults of motors in other coordinate systems. If you wish
motors to react to these faults, you must implement this feature in your own routine, probably in a
PLC program.
What is an Axis?
An axis is an element of a coordinate system. It can be thought of as one of the coordinates of the
tool, or of the mechanics relative to the tool. An axis in Power PMAC is often similar to a motor,
but not the same thing. An axis is referred to by letter. There can be up to 32 independent axes in
a coordinate system, selected from the X, Y, Z, A, B, C, U, V, and W single letters, plus the AA
through HH, and LL through ZZ double letters.
Axes, and their relationships to motors, are established either through on-line “axis-definition”
commands, which set up a mathematically linear relationship between axis positions and motor
positions, or through “kinematic subroutines” which permit these relationships to be defined
algorithmically, with extensive math and logic. Both methods are covered below.
Single-Motor Axes
In the vast majority of cases, there will be a one-to-one correspondence between motors and axes.
That is, a single motor is assigned to a single axis in a coordinate system. Even when this is the
case, however, the matching motor and axis are not completely synonymous. The axis is scaled
into engineering units, and deals only with commanded positions. Except for the pmatch
function and axis query commands, calculations go only from axis commanded positions to motor
commanded positions, not the other way around.
Multiple-Motor Axes
More than one motor may be assigned to the same axis in a coordinate system. This is common in
gantry systems, where motors on opposite ends of the cross-piece are always trying to do the
same movement. By assigning multiple motors to the same axis (e.g. #1->X, #2->X), a single
programmed axis move in a program causes identical commanded moves in multiple motors. This
is commonly done with two motors, but it is possible to assign even more motors to a single axis
in Power PMAC. Remember that the motors still have independent servo loops, and that the
actual motor positions will not necessarily be exactly the same.
Coordinating parallel gantry motors in this fashion is in general superior to using a master/slave
technique (which can be done on Power PMAC with the “position following” feature). In the
master/slave technique, the actual trajectory of the master as measured at the encoder, with all of
the disturbances and quantization errors, becomes the commanded trajectory for the slave, whose
actual trajectory will have even more errors. The roughness in the slave motor’s commanded
trajectory makes it difficult or impossible to use feedforward properly, which introduces a lag.
True, if the master gets a disturbance, the slave will see it and attempt to match it, but if the slave
gets a disturbance, the master will not see it.
Other motor(s) mechanically linked to this motor are designated “follower” motors. These motors
are activated in a special follower mode by setting Motor[x].ServoCtrl to 8. In this mode, the
motors close their own servo loops, but do not calculate their own trajectories. Instead, they use
the trajectory calculated by the motor whose number is specified in Motor[x].CmdMotor, which
should be that of the gantry leader motor.
These follower motors are then assigned to the “null” definition (#x->0) in the same coordinate
system as the leader motor, which is assigned to the desired axis. Note that by default, all motors
have the null definition in Coordinate System 0. It is important that the follower motors be moved
the working coordinate system, even though they are not directly assigned to an axis in that
coordinate system.
This mode of operation provides fundamentally equivalent motion to the technique of assigning
multiple motors to the same axis, in that the motors use the same commanded trajectory, but close
servo loops individually. However, it provides several important advantages. First, calculation
time is reduced, because only one motor needs to calculate the commanded trajectory. Second, it
makes it possible to move the motors together interactively just by jogging the leader motor.
Finally, it makes the initial homing and “de-skewing” easier, because the follower motors can
find their home triggers when the leader motor is homed, and have the skew (difference in
position of their home trigger from the leader motor’s home trigger) automatically removed at the
programmed rate set by Motor[x].GantrySlewRate.
Phantom Axes
An axis in a coordinate system can have no motors attached to it (a “phantom” axis), in which
case programmed moves for that axis cause no movement, although the fact that a move was
programmed for that axis can affect the moves of other axes and motors. For instance, if
sinusoidal profiles are desired on a single axis, the easiest way to do this is to have a second,
“phantom” axis and program circularly interpolated moves.
Note: Some users will set the motor units to a value other than the basic “counts” or “LSBs” of
the feedback device by setting Motor[x].PosSf to a value other than its default value of 1.0. This
is typically done to make the motor units as common engineering units. In most cases where this
is done, the scale factor in the axis definition statement will be 1.0, so the motor and the axis have
the same units.
In addition the axis definition statement can provide for a fixed offset between the motor zero
position (the “home position”) and the axis zero position. The statement #1->10000X+20000
also sets the axis zero at 20,000-count (2-axis-unit) distance from the motor zero (home position).
This offset is rarely used, as most people who desire offsets will want to change them
dynamically, which can be done with the axis matrix transformations (see below).
In addition, a motor with a null definition in one coordinate system can be redefined to another
coordinate system, whereas a motor with a true axis definition cannot. Therefore, the null
definition is used as an intermediate step in the process of transferring a motor to a different
coordinate system.
For example, if Motor 4 were assigned to the C-axis in C.S. 1, and it was desired to re-assign it to
the C-axis in C.S. 2, the following commands would be used:
&1 #4->0
&2 #4->C
#1->8660.25X-5000Y
#2->5000X+8660.25Y
Mathematically speaking, this makes the motor’s axis definition a linear combination of the
multiple axes. It is even possible to make the motor’s axis definition a combination of all 32
possible axes, although it will be very rare that there will be a combination of more than 3 axes.
There are two common uses of these linear axis combinations. One is to create a rotation of the
axis coordinates in a Cartesian reference frame relative to the underlying motors. The above
example provides a 30° rotation from the motors to the axes. The second, and more common, use
is to create a correction for a physical squareness error. Examples of both of these cases are
shown in the following diagram, along with a more standard definition.
Technically, the relationship between motors and axes in a coordinate system is defined in a giant
matrix, as shown below.
Motor[i].CoordSf [0] k Ai
Motor[i].CoordSf [32] d i
The data structure elements Motor[i].CoordSf[j] contain the axis definition scale factors for
Motor i with regard to the “jth” axis. “j” is 0 for the A-axis, 1 for the B-axis, and so on.
Motor[i].CoordSf[32] is the offset term for the motor’s axis definition. For example, the axis-
definition statement #3->5000Z-2000 will set Motor[3].CoordSf[8] to 5000,
Motor[3].CoordSf[32] to -2000, and all other Motor[3].CoordSf[j] to 0. In almost all
applications, the vast majority of these elements will be equal to zero.
Each Cartesian axis set has three vector components associated with it. For the X/Y/Z set, the
vector components are I, J, and K. For the XX/YY/ZZ set, the vector components are II, JJ, and
KK.
Circular interpolation and 2D cutter radius compensation can be performed on any plane within
the 3-D Cartesian space (and not just the three primary planes). The plane for both functions is
defined by the buffered program normal command. The I, J, and K components, or the II, JJ,
and KK components, declared in the command define the vector perpendicular to the plane, and
therefore the orientation of the plane.
The plane defined by the normal command for the X/Y/Z Cartesian axis set is also used when
calculating corner angles for decisions on blending, dwell addition, and 2D cutter radius
compensation outside corner arc addition. It is the angle of the corner projected into this plane
that is calculated for the purposes of making these decisions.
In a move command in circular interpolation mode, the I, J, and K components, or the II, JJ, and
KK components declared in the command define the vector from the starting point of the move to
the center of the circular arc, and therefore the location of the center.
Each of these axes has a saved setup element Coord[x].PosRollover[i] (i = 0 to 5 for the A, B, C,
AA, BB, CC axis, respectively) that specifies its rollover behavior. If this element for the axis is
set to its default value of 0.0, the axis has no rollover capability and is commanded just as for a
linear axis.
However, if Coord[x].PosRollover[i] is set to a non-zero value, rollover is enabled for the axis,
with the magnitude specifying the rollover range. This magnitude is almost always set to 360,
specifying a full rotation for an axis programmed in degrees. Rollover affects how abs mode
moves for the axis are processed. It does not affect inc mode moves.
If Coord[x].PosRollover[i] is set to a value greater than zero (usually +360), the “short-
direction” rollover mode is enabled. In this mode, Power PMAC computes the shortest distance to
the specified destination angle, so no abs mode move is longer than ½-cycle in length.
If Coord[x].PosRollover[i] is set to a value less than zero (usually -360), the “sign-is-direction”
rollover mode is enabled. In this mode, the sign of the abs mode move destination value is the
direction taken in the move.
If saved setup element Coord[x].SignIsDirType (new in V2.6 firmware, released 3rd quarter
2020) is set to its default value of 0, or for earlier versions without this element, the sign in the
command is also the sign of the destination angle. For example, the abs mode move command
B-25 causes a move in the negative direction to -25, which is equal to +335 for a 360-unit cycle.
In both types, a positive value in the move command causes a move in the positive direction to a
destination specified as a positive value. The abs mode move command B25 causes a move in
the positive direction to +25.
In the older PMAC and Turbo PMAC controllers, rollover was handled by the motor assigned to
the rotary axis. The Power PMAC method of processing rollover on the programmed axis
provides more flexibility, permitting rollover capability when motors are assigned to axes through
kinematic subroutines.
The following diagram illustrates how the rollover modes work for zero values of
Coord[x].PosRollover[i], positive values, and negative values with Coord[x].SignIsDirType =
1:
There are three forms of the spindle axis definition, each with its own rule for the motor’s “time
base”. With a definition of the form #x->S, the motor uses the time-base value of the coordinate
system it is defined in, so it speeds up and slows down along with the positioning axes of the
coordinate system. (It does not obey the segmentation override value in this or any of the other
spindle modes.)
With a definition of the form #x->S0, the motor uses the time-base value of Coordinate System
0 instead of the coordinate system it is defined in. This mode provides independent override
control for the spindle.
With a definition of the form #x->S1, the motor uses a fixed 100% time-base value, so it is not
affected by the time-base value of any coordinate system.
In the case of axes defined with axis-definition statements, Power PMAC simply “plugs” the axis
values into the equation of the definition statement, and computes the resulting motor position.
(The axis-definition statement is therefore an inverse-kinematic equation.) In the case of axes
defined using kinematic subroutines, Power PMAC executes the user-written inverse-kinematic
subroutine to compute these (see the next section of the manual).
Axis Definition
Statements
Inverse Kinematic
Subroutine
Automatically Inverted
Axis Definitions
Forward Kinematic
Subroutine
First, when a motion program is started with an r (run) or s (step) command, Power PMAC
automatically executes a pmatch command internally to compute the starting axis position(s) for
the first move calculations. Within a motion program, it normally assumes that the endpoint of
the previous move is the starting point for the subsequent move, and so does not do these
calculations each move. However, when a program is started, it does these calculations because
there is a good chance that motors may have been moved independently (e.g. jog moves, open-
loop moves, stopping on an error condition); in other words, the axes do not know where the
motors have gone and motor and axis positions may not match properly.
Second, if you do anything to change the relationship between motor and axis positions inside a
motion program (e.g. changing position-following offset mode, directly writing to the position-
bias or axis scaling registers), you must explicitly issue a pmatch command before the next
programmed move. Otherwise, the next move will not execute properly.
For axes defined with a simple definition statement, the pmatch function effectively inverts the
equations contained in the axis-definition statements for the coordinate system, using motor
commanded positions, and solves for axis commanded positions. If there is a one-to-one
assignment of motors to axes, each axis definition statement can be inverted individually. If there
is a cross-coupling of motors and axes through longer axis definitions, a matrix inversion must be
performed for these calculations.
If a proper matrix inversion cannot be done, Power PMAC cannot compute the starting axis
positions, and it will not permit programmed moves in the coordinate system. The coordinate
system Boolean data structure status element Coord[x].Csolve indicates whether a valid solution
can be found for the coordinate system when set up by axis definitions and not kinematic
subroutines. If it is 1, the starting axis positions can be computed, and motion programs can
execute.
If more than one motor is assigned to the same axis (e.g. #1->10000X, #2->10000X), the
commanded position of the lower-numbered motor is used in the pmatch calculations. The
motor Boolean data structure status element Motor[x].Csolve indicates whether that motor is
used in these calculations (yes if 1).
For axes in a coordinate system with a user-written forward-kinematic subroutine (see below),
this subroutine is automatically executed for the pmatch function.
The pmatch function assumes that the position referencing – either a homing search move or an
absolute position-sensor read – has been done for each motor in the coordinate system. Each
motor has a “home complete” status bit that is set true if either has been done, but if the user
wants to check for this, this must be done at the application level.
The same motor-to-axis conversion is automatically performed (if possible) when the positions,
velocities, or following errors of the axes are queried with the on-line coordinate-system
commands &xp (actual position query), &xd (desired position query), &xv (actual velocity
query), or &xf (following-error query).
This capability permits the motion for the machine to be programmed in the natural coordinates
of the tool-tip, usually Cartesian coordinates, whatever the underlying geometry of the machine.
The kinematic routines are embedded in the controller by the integrator, and operate invisibly to
the people programming paths and the machine operators. These routines can be unchanging for
the machines, but with parameterization and/or logic, they can adapt to normal changes such as
tool lengths and different end-effectors.
In Power PMAC terminology, the tool-tip coordinates are for “axes”, which are specified by
letter, and have user-specified engineering units. The joint coordinates are for “motors”, which
are specified by numbers, and may have the raw units of “counts”.
The “forward-kinematic” calculations use the joint positions as input, and convert them to tool-tip
coordinates. These calculations are required at the beginning of a sequence of moves programmed
in tool-tip coordinates to establish the starting coordinates for the first programmed move. The
same calculations can also be used to report the actual position, velocity, and following error of
the actuator in tool-tip coordinates, converting from the sensor positions on the joints.
The “inverse-kinematic” calculations use the tool-tip positions as input, and convert them to joint
coordinates. These calculations are required for the end-point of every move that is programmed
in tool-tip coordinates, and if the path to the end-point is important, they must be done at periodic
intervals during the move as well.
After any execution of the forward-kinematic program, Power PMAC will take the values in local
variables C0 – C31 for the coordinate system or communications thread (which are the same as
L(MAX_MOTORS) to L(MAX_MOTORS+31) for the C.S. or thread, where
MAX_MOTORS is the largest permitted value for Sys.MaxMotors in the Power PMAC,
usually 256), as masked by 32 bits of local variable D0 (bit i of D0 set to 1 tells Power PMAC to
use Ci), and use them as the resulting axis positions in the user’s engineering units. For the
pmatch function, it will copy the specified values into the axis target position registers to be
used as starting positions for the next programmed move. For on-line query commands, it will use
the values for the specified axes in its response to the query.
When working in the Integrated Development Environment (IDE) on the PC, the
editor/downloader of the Project Manager automatically provides user names for these variables:
KinPosMotorx for Lx, KinPosAxisα for the α-axis variable Ci, and KinAxisUsed for the axis-
mask output variable D0. This permits the programmer to use meaningful names for the
kinematic motor and axis position variables.
The following table shows for each axis name the variable where the position is expected to be
found and the value of the D0 bit that tells Power PMAC to use the axis position value.
Axis Var. IDE Var. Name D0 Bit Axis Var. IDE Var. Name D0 Bit
Name Value Name Value
A C0 KinPosAxisA $1 HH C16 KinPosAxisHH $10000
B C1 KinPosAxisB $2 LL C17 KinPosAxisLL $20000
C C2 KinPosAxisC $4 MM C18 KinPosAxisMM $40000
U C3 KinPosAxisU $8 NN C19 KinPosAxisNN $80000
V C4 KinPosAxisV $10 OO C20 KinPosAxisOO $100000
W C5 KinPosAxisW $20 PP C21 KinPosAxisPP $200000
X C6 KinPosAxisX $40 QQ C22 KinPosAxisQQ $400000
Y C7 KinPosAxisY $80 RR C23 KinPosAxisRR $800000
Z C8 KinPosAxisZ $100 SS C24 KinPosAxisSS $1000000
AA C9 KinPosAxisAA $200 TT C25 KinPosAxisTT $2000000
BB C10 KinPosAxisBB $400 UU C26 KinPosAxisUU $4000000
CC C11 KinPosAxisCC $800 VV C27 KinPosAxisVV $8000000
DD C12 KinPosAxisDD $1000 WW C28 KinPosAxisWW $10000000
EE C13 KinPosAxisEE $2000 XX C29 KinPosAxisXX $20000000
FF C14 KinPosAxisFF $4000 YY C30 KinPosAxisYY $40000000
GG C15 KinPosAxisGG $8000 ZZ C31 KinPosAxisZZ $80000000
For example, if the X, Y, Z, and C-axis values were calculated and placed in C6, C7, C8, and C2,
respectively, D0 should be set to $40 + $80 + $100 + $4 = $1C4.
It is the responsibility of the user writing the forward kinematic program to place the calculated
axis values in the proper variables and ensure that the proper bits of D0 are set before exiting the
program.
The basic purpose of the forward-kinematic program, then, is to take the joint-position values
found in Lx for the motors used in the coordinate system, compute the matching tip-coordinate
values, and place them in variables in the C0 – C31 range.
Double-Pass Option
If the forward-kinematic routine is to be used for computing axis velocities using the &xv
command or axis following errors using the &xf command, it is necessary to permit a second
pass through the computations using a callsub statement. On calling this routine, the Power
PMAC will automatically set the local variable D0 (used as an input) greater than 0 in these
cases, so the callsub statement is contingent on this condition. Note that D0 is also used as an
output to specify which axis positions have been calculated, so it must be set explicitly in the
routine every time. In the IDE, the declared name KinVelEna can be used for D0 here.
open forward
if (KinVelEna > 0) callsub 100;
KinAxisUsed = {axis mask}
n100:
{kinematic calculations}
return;
close
If the routine has been called from a motion program, bit 6 (value $40) of the local data element
Ldata.Status will be set to 1. If the routine has been called from a query command, this bit will
be zero. So the routine can use the following logic:
In this type of case, the subroutine should prevent further motion program execution. It can do
this by issuing a program-direct abort command, or preferably by setting
Coord[x].ErrorStatus to 255, a value reserved for errors detected by the user’s application, not
the automatic firmware.
Since the forward-kinematic subroutine can also be called by axis query commands, this aborting
action should only be taken when the routine is called from a motion program. When called from
an axis query command, it is recommended that some illegal value be returned. For example:
Example
Y
(X,Y)
L2
B
L1
A
Take the example of a 2-axis “shoulder-elbow” robot, with an upper-arm length (L1) of 400mm,
and a lower-arm length (L2) of 300mm. Both the shoulder joint (A) and the elbow joint (B) have
resolutions of 1000 counts per degree. When both joints are at their zero-degree positions, the two
links are both extended along the X-axis. The forward-kinematic equations are:
X L1 cos( A) L2 cos( A B)
Y L1 sin( A) L2 sin( A B)
&1
Len1 = 400 // Upper-arm link of 400mm
Len2 = 300 // Lower-arm link of 300mm
CtsPerDeg = 1000 // Counts per degree for A and B
This example explicitly checks to see that all motors in the coordinate system have performed a
position referencing (homing search or absolute position read) by looking at the
Coord[x].HomeComplete status bit. If this bit is not set, the routine sets an error flag and aborts
the program.
The forward-kinematic program must calculate the axis positions for all of the axes in the
coordinate system whether or not all of the motor positions are calculated in the inverse-
kinematic program (see below). For instance, if this arm had a perpendicular vertical axis at the
tip with a normal axis definition statement in C.S. 1 of #3->100Z (100 counts per millimeter – a
linear relationship between motor and axis, independent of other positions), the above program
would still need to perform the forward-kinematic calculation for this motor/axis with a line such
as KinPosAxisZ = KinPosMotor3 / 100.
Iterative Solutions
Some systems, particularly parallel-link mechanisms such as Stewart platforms (“hexapods”), do
not have reasonable closed-form solutions for the forward-kinematic equations, and require
iterative numerical solutions. These cases are typically handled by a looping do…while
construct in the forward-kinematic program. The user should not permit indefinite looping – if the
solution does not converge in the expected number of cycles, the program should be stopped (see
the inverse-kinematic equations, below, for examples of how to stop the program).
The number of loops (“jumps back”) in the forward-kinematic subroutine that can be executed
before automatically creating an automatic abort on an error condition is set by the local variable
Ldata.GoBack. This is not a saved element, and it has a default value of 10. If you wish to use a
different value, it should be set explicitly at the top of the subroutine. It is strongly recommended
that you explicitly trap a convergence failure in your own code before the automatic limit is
tripped.
Before any execution of the inverse-kinematic program, Power PMAC will automatically place
the present axis target positions for each axis in the coordinate system into local variables C0 –
C31 for the coordinate system. For PVT-mode moves, it will also automatically place the present
commanded axis velocities for each axis in the coordinate system into local variables C32 – C63
(numbered 32 greater than the position variable for the same axis) for the coordinate system.
These are floating-point values, in engineering units. The program can then use these variables as
the “inputs” to the calculations. The table in the forward-kinematic section above shows the
position variables for each axis.
After any execution of the inverse-kinematic program, Power PMAC will take the values in those
variables Lx that correspond to Motors x in the coordinate system with axis-definition statements
of #x->I. These are floating-point values, and Power PMAC expects to find them in the motor
units. Power PMAC will automatically use these values as the target position values for the next
segment or move for these motors.
There can be other motors in the coordinate system that are not defined as inverse-kinematic
axes; these motors get their position values directly from the axis-definition statement and are not
affected by the inverse-kinematic program. (This is generally not recommended, as it makes it
hard for others to understand the complete transformation.)
The basic purpose of the inverse-kinematic program, then, is to take the tip-position values found
in C0 – C31 for the axes used in the coordinate system, compute the matching joint-coordinate
values, and place them in variables Lx for the Motors x defined to inverse-kinematic axes in the
coordinate system.
(Do not assume that L-variable values computed in the previous cycle of the I.K. subroutine will
still be valid on entering a new cycle. Other tasks, particularly query commands that use the F.K.
subroutine, could have overwritten these values. Any values to be retained should use user-
declared variables.
Example
Continuing with our example of the two-axis “shoulder-elbow” robot, and for simplicity’s sake
limiting ourselves to positive values of elbow angle B (the “right-armed” case), we can write our
inverse-kinematic equations as follows:
Y
X 2 Y 2 L12 L22 (X,Y)
B cos
1
2 L1 L2
A C atan2Y, X
X 2 Y 2 L2 B
X 2 Y 2 L2 L2
C cos 1 1 2
2L X 2 Y 2
1 L1
A
A A C A C
By choosing the positive arc-cosine solutions, we are automatically selecting the “right-
armed” case. In a more general solution, we would have to choose whether the positive or
negative solution is used, based on some criterion.
This example stops the program for cases where no inverse kinematic solution is possible. It
does this by setting Coord[x].ErrorStatus to 255. Other strategies may be used to cope with
this problem.
If this robot had a vertical axis at the tip, the relationship between motor and axis could be
defined with a normal linear axis-definition statement (e.g. #3->100Z for 100 counts per
millimeter), and the motor position would be calculated without the special inverse-kinematic
program. Alternately, the motor could be defined as an inverse-kinematic axis (#3->I) and the
motor position could be calculated in the inverse-kinematic program (e.g.
KinPosMotor3=KinPosAxisZ*100 to set Motor 3 position from the Z-axis with 100
counts per unit).
are used. (This is unlike Turbo PMAC, where it had to be handled “manually” when kinematics
subroutines were used.) Coord[x].PosRollOver[i] for the axis must be set (usually to 360) to
enable the rollover capability for the specific rotary axis.
It is important to understand how and when the rotary axis rollover works in conjunction with
inverse kinematics. The axis rollover calculations are performed and the appropriate axis overall
move trajectory is calculated before any inverse-kinematic calculations are made for the move.
For example, if the C-axis position at the start of the move were 350 degrees and the commanded
move destination were 10 degrees, then with the “short move” rollover mode, Power PMAC
would calculate an axis move to 370 degrees, a 20-degree move in the positive direction. Multiple
move segments with C-axis intermediate positions increasing from 350 to 370 degrees would be
passed to the inverse-kinematic subroutine as the move is executed.
With PVT-mode moves sent directly to the inverse-kinematic routine (no segmentation), the
position calculations are done just as for any other move mode. An additional set of velocity-
conversion calculations must also be done.
When executing PVT-mode moves with inverse-kinematic axes (#x->I) and no segmentation
(Coord[x].SegMoveTime = 0), Power PMAC will automatically place the commanded axis
velocity values from the PVT statements into local variables C32 – C63 (numbered 32 greater
than the corresponding C-variable for position) for the coordinate system before each execution
of the inverse-kinematic program. These are signed floating-point values in the engineering
velocity units defined by the engineering length/angle units and the coordinate system’s
Coord[x].FeedTime time units (e.g. mm/min or deg/sec). The following table shows the variable
used for each axis:
Axis Vel. Var. Axis Vel. Var. Axis Vel. Var. Axis Vel. Var.
A C32 Z C40 HH C48 SS C56
B C33 AA C41 LL C49 TT C57
C C34 BB C42 MM C50 UU C58
U C35 CC C43 NN C51 VV C59
V C36 DD C44 OO C52 WW C60
W C37 EE C45 PP C53 XX C61
X C38 FF C46 QQ C54 YY C62
Y C39 GG C47 RR C55 ZZ C63
The IDE program permits you to use the variable name KinVelAxisα for the α-axis velocity
variable to make the code more understandable.
Power PMAC will also set coordinate system local variable D0 (which can be substituted in the
IDE with KinVelEna) to 1 in this mode as a flag to the inverse-kinematic program that it should
use these axis (tip) velocity values to compute motor (joint) velocity values.
In this mode, after any execution of the inverse-kinematic program, Power PMAC will read the
values in those variables Rx for each Motor x (which can be substituted in the IDE with
KinVelMotorx) in the coordinate system defined as an inverse-kinematic axis. These are
floating-point values, and Power PMAC expects to find them scaled in motor units of counts per
(Coord[x].FeedTime milliseconds). Power PMAC will use them as motor (joint) velocity values
along with the position values in Lx to create a PVT move for the motor.
For PVT moves, then, the inverse-kinematic program must not only take the axis (tip) position
values in C0 – C31 and convert them to motor (joint) position values in Lx; it must also take the
axis (tip) velocity values in C32 – C63 and convert them to motor (joint) velocity values in Rx.
Technically, the velocity conversion consists of the solution of the “inverse Jacobian matrix” for
the mechanism.
Example
Continuing with the “shoulder-elbow” robot of the above examples, the equations for joint
velocities as a function of tip velocities are:
B
L1 cos A L2 cos( A B)X L1 sin A L2 sin( A B)Y XX YY
L1 L2 sin B L1 L2 sin B
The angles A and B have been computed in the position portion of the inverse-kinematic
program. Note that the velocities become infinite as the angle B approaches 0 degrees or 180
degrees. Since in our example we are limiting ourselves to positive values for B, we will trap any
solution with a value of B less than 1° or greater than 179° (sin B < 0.0175) as an error.
&1
open inverse
Note that in this case the check to see if B is near 0° or 180° is redundant because we have
already done this check in the position portion of the inverse-kinematic algorithm. This check is
shown here to illustrate the principle of the method. In this example, the program is aborted if too
near a singularity; other strategies are possible.
Iterative Solutions
Some systems do not have reasonable closed-form solutions for the inverse-kinematic equations,
and require iterative numerical solutions. These cases are typically handled by a looping
do…while construct in the inverse-kinematic program. The user should not permit indefinite
looping – if the solution does not converge in the expected number of cycles, the program should
be stopped.
The number of loops (“jumps back”) in the inverse-kinematic subroutine that can be executed
before automatically creating an error condition is set by the local variable Ldata.GoBack. This
is not a saved element, and it has a default value of 10. If you wish to use a different value, it
should be set explicitly at the top of the subroutine. . It is strongly recommended that you
explicitly trap a convergence failure in your own code before the automatic limit is tripped.
MyVar = CfromScript(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7);
The CfromScript subroutine is discussed in detail in the User’s Manual chapter “Writing C
Functions and Programs in Power PMAC”.
have separate forward and inverse kinematic subroutines for each coordinate system, it is possible
to make these “instances” of the routines identical for each coordinate system.
This can be implemented by using a subroutine called by the kinematics routines that returns the
motor numbers used in that coordinate system. An example subroutine (with IDE substitutions)
for a system with three coordinate systems of two motors each could be:
switch (CSNum)
{
case 1:
FirstMotor = 1;
SecondMotor = 2;
break;
case 2:
FirstMotor = 3;
SecondMotor = 4;
break;
case 3:
FirstMotor = 5;
SecondMotor = 6;
break;
}
return;
close
To use these values in the kinematics routines, it is useful to provide meaningful names for the
variables that will be used:
Then the kinematics routines can use this information with the proper local variable definitions.
This example is for the same serial-link two-joint arm as above.
ThisCs = Ldata.Coord;
For most axes, the matrix transformations permit only additional scaling and offset terms.
However for four 3-axis sets (X/Y/Z, U/V/W, XX/YY/ZZ, and UU/VV/WW), they also permit
transformations such as rotations, mirroring, and skewing by providing full 3-by-3 matrix terms.
A k A 0 ... 0 A' d A
B 0 kB 0 ... B' d
B
C 0 kC 0 0 0 ... C' dC
U 0 kU kUV kUW 0 ... U ' dU
V 0 kVU kV kVW 0 ... V ' dV
W 0 kWU kWV kW 0 0 0 ... W ' dW
X 0 0 0 kX k XY k XZ 0 ... X ' d
X
Y 0 kYX kY kYZ 0 ... Y ' dY
Z 0 k ZX k ZY kZ 0 ... Z ' d
Z
AA 0 0 0 k AA ... AA' d AA
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
TT ... kTT 0 0 0 TT ' d TT
UU ... 0 kUU kUUVV kUUWW 0 UU ' dUU
VV ... 0 kVVUU kVV kVVWW 0 VV ' d
VV
WW ... 0 kWWUU kWWVV kWW 0 0 0 WW ' dWW
XX ... 0 0 0 k XX k XXYY k XXZZ XX ' d XX
YY ... 0 kYYXX kYY kYYZZ YY ' d YY
ZZ 0 ... 0 k ZZXX k ZZYY k ZZ ZZ ' d ZZ
The column vector of axes on the left contains the “base” axis coordinates (e.g. A) as established
by the axis-definition statements or the kinematic subroutines. The column vector of axes on the
right contains the “transformed” axis coordinates (e.g. A') that will be programmed.
This matrix is similar to the axis definition matrix shown earlier in the chapter, but there are some
important differences. First, while the axis definition matrix is “full”, with all of the off-diagonal
elements capable of being set to non-zero values, only a few off-diagonal elements can be set to
non-zero values in the transformation matrix. Second, while the axis definition matrix relates
motors to axes, the transformation matrix relates the base axes to the transformed axes.
The following diagram shows how and when Power PMAC converts between transformed axes,
base axes, and motors:
Axis Definition
Selected Statements
Transformation Matrix Inverse Kinematic
Subroutine
Automatically Inverted
Automatically Inverted Axis Definitions
Transformation Matrix Forward Kinematic
Subroutine
Transformation matrices can be used regardless of whether the underlying axes are established
with axis definition statements or with kinematic subroutines.
Each matrix has 32 offset elements Tdata[i].Bias[j] (j = 0 to 31), where j is the axis index. These
elements are primarily to create offsets between the base axis origin and the transformed axis
origin.
The four 3-axis sets that have off-diagonal terms permit other transformation operations besides
scaling and offsets. Rotations (about arbitrary points), mirrorings (about arbitrary lines), and
skewing are all possible.
Looking at the portion of an axis transformation matrix that operates on the X/Y/Z axis triplet, we
have a 3x3 “rotation matrix” and a 1x3 “offset vector” comprised of the following elements:
Looking at the portion of an axis transformation matrix that operates on the U/V/W axis triplet,
we have a 3x3 “rotation matrix” and a 1x3 “offset vector” comprised of the following elements:
Looking at the portion of an axis transformation matrix that operates on the XX/YY/ZZ axis
triplet, we have a 3x3 “rotation matrix” and a 1x3 “offset vector” comprised of the following
elements:
Looking at the portion of an axis transformation matrix that operates on the UU/VV/WW axis
triplet, we have a 3x3 “rotation matrix” and a 1x3 “offset vector” comprised of the following
elements:
The presently selected matrix for a coordinate system can be read at any time in the data structure
element Coord[x].Tsel. A value of -1 indicates that no matrix is selected. This is the power-up
default value.
Values can be assigned directly to any transformation matrix element, for a selected or unselected
matrix, with on-line or program assignment commands (e.g. Tdata[1].Diag[6]=25.4). In
addition there are two functions in the script language that act on an entire matrix.
“identity matrix, so all of the transformed axis positions using the matrix are equal to the
untransformed axis positions.
The tinit function returns the determinant of the resulting matrix. This, of course, should be
1.0 for a valid initialization. It will return 0.0 for an invalid initialization (e.g. an illegal matrix
number). A typical use of this function will be:
Tdet = tinit(2);
where Tdet has been declared as a local or global variable. It is possible to check Tdet to
ensure that a valid initialization has been performed.
Propagating Transformations
The tprop function permits the “propagation” of one matrix transformation by another. In this
propagation, the square rotation matrix of the first transformation is multiplied by the square
rotation matrix of the second transformation, yielding the square rotation matrix of the resulting
transformation. The square rotation matrix of the first transformation matrix is then multiplied by
the column offset vector of the second transformation matrix, and the resulting column matrix is
added to the first transformation’s column offset vector, yielding the column offset vector of the
resulting transformation matrix. The returned value of the function is the determinant of the
resulting transformation’s rotation matrix. It will be 0.0 for an invalid operation.
Tdet = tprop(1,3,4);
where Tdata[3] is the first transformation, Tdata[4] is the second transformation, Tdata[1] is the
resulting transformation. Tdet has been declared as a local or global variable. It is possible to
check Tdet to ensure that a valid operation has been performed.
Examples
Often the second transformation is used as an “operator” to modify the first transformation. The
resulting transformation can be the same as one of the first two transformations. The following
section of code shows the simple example of using this principle to perform an incremental
rotation in the XY plane about the origin on top of an existing transformation.
The next section of code rescales the XYZ space whose axis definitions have specified
millimeters to inches.
The next section of code offsets the XYZ space incrementally by 3 user-specified variable values.
However, starting in V1.6 firmware, released 1st quarter 2014, it is possible to compensate for the
scaling of the XYZ space by the value of status element Coord[x].TxyzScale. When it is changed
from its power-on default value of 0.0, the programmed vector feedrate and tool-radius offset
values are divided by the value of TxyzScale. (Of course, a value of 1.0 means no change.)
Continuing the above example, with the XYZ space scaled up by a fact of 2, a value of 2.0 for
TxyzScale would rescale the vector feedrate and tool-radius offset back to the physical units for
the axes, even though all moves would be twice as long.
It is also possible to have this rescaling done automatically. If saved setup element
Coord[x].AutoTxyzScale is set to 1, then Coord[x].TxyzScale is calculated automatically to
compensate for the scaling of XYZ space done by the selected transformation matrix for the
coordinate system when the buffered program command tsel{data} is executed. Technically,
TxyzScale is computed as the cube root of the determinant of the 3x3 XYZ portion of the
transformation matrix. Note that all 3 axes must be scaled to the same extent for this to be useful.
Segmentation Mode
Each coordinate system can be put into “segmentation mode” or not. If the coordinate system is
in segmentation mode, most programmed path-based motion trajectories are computed using a
two-stage interpolation process. In the first stage, the equations of motion that were derived from
the programmed move command are solved at a coarse-interpolation (segmentation) interval.
Then a fine-interpolation stage executing at the servo update rate computes intermediate points
between the coarsely interpolated points using the computationally efficient cubic B-spline
algorithm (employing the same equations as the programmed spline move mode).
The reason for this two-stage process is that there are many types of calculations that need to be
done more than once per programmed move, but doing them at the servo update rate would
overload the processor without performing much better than at a somewhat slower update rate. In
Power PMAC, the segmentation interval specifies the intermediate rate at which these
calculations are done.
Special lookahead for dynamic limiting: The lookahead algorithm scans ahead in the
planned trajectory looking for possible violations of dynamic limits. In order to optimize
the resulting trajectories properly, this needs to be done more than once per programmed
move, but doing this at the servo rate would probably overload the processor. So these
calculations are done segment by segment, checking each for position, velocity, and
acceleration violations.
There is a trade-off between the computational load of a small segmentation time (high
segmentation frequency) and greater resulting path errors of a large segmentation time (low
segmentation frequency). The path error in a Cartesian space resulting from the cubic B-spline
fine-interpolation algorithm approximating the true path can be expressed as:
V 2T 2
E
6R
where E is the (perpendicular) path error, V is the path velocity, T is the segmentation time, and R
is the local radius of curvature of the path. In virtually all applications, a satisfactory compromise
between computational load and path accuracy can be achieved easily. In most applications, the
segmentation time will be set to a value equivalent to 10 to 20 servo cycles.
Segmentation mode must be enabled to execute circle mode moves, cutter radius compensation,
inverse kinematics, and the mode where programmed linear moves are executed as PVT moves.
Standard linear and PVT mode moves can be executed as segmented moves or not. Rapid and
spline mode programmed moves, and jogging and homing-search motor moves, are never
segmented, even if segmentation mode is enabled for the coordinate system.
Time-Base Control
Fundamentally, time-base control works by varying the numerical value for the time elapsed in a
single servo cycle by the “fine interpolation” algorithms that generate a new commanded
trajectory position for input to the servo loop each servo cycle. Note that the physical time
between servo cycles remains constant, so servo-loop dynamics are not affected.
CPn is the commanded position for the present servo cycle n, CPn-1 is the commanded position for
the previous servo cycle, CVn is the commanded velocity for the present servo cycle, and Δtn is
the numerical value for time elapsed in the present servo cycle.
The global saved setup element Sys.ServoPeriod should contain the true time elapsed in one
servo cycle, expressed in milliseconds. If the Δtn value used in the fine-interpolation equation
deviates from this value, the move will execute at other than the programmed speed. For example,
if Δtn is only half of the true value, the move will execute at half of the programmed speed.
Each coordinate system has a saved setup element Coord[x].pDesTimeBase (pointer to desired
time base) that contains the address of the register that Power PMAC reads for the coordinate
system’s desired Δtn value each servo cycle. It expects to find a double-precision floating-point
value at this register, with units of milliseconds. Depending on what register this is, various
interesting effects can be produced.
The actual Δtn value used each servo cycle in the fine-interpolation equations is found in the data
structure element Coord[x].TimeBase, also a double-precision floating-point value with units of
milliseconds. This value tracks the desired value in the register specified by
Coord[x].pDesTimeBase, but its rate of change is limited by the saved setup element
Coord[x].TimeBaseSlew, which specifies how much the actual Δtn value can change each servo
cycle.
This functionality makes it easy to override the programmed speeds without changing the
programmed motion parameters or sequences. Many people will use this command to try out
motion sequences slowly at first to examine their safety and effectiveness. Some will also use it
to implement “feedrate override” in CNC-style applications, although the “segmentation
override” technique explained below is probably better for that application.
This technique is described in detail in the User’s Manual chapter Synchronizing Power PMAC to
External Events.
Within a motion section or segment with a given (cubic) equation of motion, it is just as easy to
interpolate in the negative direction as in the positive direction. However, if the accumulated
negative time increment causes the motion to go back past the beginning of this section or
segment in the negative direction, then things get more complicated.
If this buffer exists for a motor, if a negatively incrementing time base for the motor’s coordinate
system causes the time value to pass the beginning of the presently executing section or segment,
the equations for the previous section or segment are loaded from the trace buffer, enabling
motion to continue properly in the reverse direction.
Of course, for proper extended reversal of coordinated motion, all motors in the coordinate
system should have equivalently sized trace buffers defined. With these buffers, fully coordinated
motion along a path can proceed as well in the reverse direction as in the forward direction.
Reversal of trajectory through the lookahead buffer using the on-line < command or buffered
lh< command is appropriate for modal state changes, as when an operator presses a “retrace”
button. Reversal of the trajectory through the trace buffer using negative time base values is
appropriate for continuously variable changes, uniting both speed and direction on a continuum.
Many users will simply keep the rate of time base change small by setting low values of
Coord[x].TimeBaseSlew and Coord[x].FeedHoldSlew, so that any increase in acceleration or
deceleration due to time base changes will be negligible. However, this can lead to sluggish
response to desired time base changes.
If the commanded motion was computed so that this acceleration limit was not violated at
standard time base (%100), and the time base values are changed within the +/-%100 range, this
algorithm will ensure that acceleration limits are not violated due to time base changes. This can
permit higher magnitudes of the set slew rates, providing quicker response in most cases, while
guaranteeing that excessive acceleration magnitudes will not be commanded.
Segmentation Override
A newer technique for overriding the programmed speed, called “segmentation override”,
overcomes limitations of older methods such as PMAC’s time base control and the traditional
CNC method of generating acceleration profiles with low-pass filters after override. In
conjunction with Power PMAC’s trajectory profiles and segmented lookahead buffer,
segmentation override permits the rate of acceleration to be maintained over the entire range of
override values, while still maintaining the path precisely.
Segmentation Process
For several move modes (linear, circle, and pvt), Power PMAC can perform a two-stage
interpolation process. At the first, coarse, interpolation stage, called segmentation, the complex
calculations such as the circle trigonometric calculations, inverse-kinematic transformations, and
lookahead acceleration-control calculations are performed. Then a simple fine-interpolation
algorithm (using a cubic B-spline for smoothness) is performed at the servo-cycle rate to generate
the instantaneous commanded positions for each servo update.
The segmentation period for these moves is set by the saved data structure element
Coord[x].SegMoveTime, expressed in milliseconds. That is, every SegMoveTime milliseconds
(without override), Power PMAC will perform coarse interpolation calculations to compute an
intermediate segment point for each axis in the coordinate system, advancing SegMoveTime
milliseconds in the move equations.
With override control at the segmentation stage, the numerical value of the time update, does not
have to match the physical time elapsed per segment. For example, if SegMoveTime were set to
5 to define a physical segment time of 5 milliseconds, but a value of 3 milliseconds were used for
the time-update calculations in the segmentation algorithms, an override of 60% would be
produced.
Effect on Acceleration
Because this override function is performed before the acceleration-control function of the special
lookahead buffer, the combination of segmentation override and lookahead acceleration control
yields an override capability that controls velocity but maintains acceleration. For this reason, this
technique is generally used for “feedrate override” functionality in CNC-style applications.
Segmentation override control occurs after acceleration profiles determined by Coord[x].Ta and
Coord[x].Ts times are created in the generation of the basic move equations. Therefore, these
acceleration times vary inversely with the override (and the acceleration rates they produce vary
inversely with the square of the override). However, in applications utilizing segmentation
override and lookahead override control, these times are usually set very small (because the
lookahead is used to control rates of acceleration), and used mainly to define the size of corner
blends in the path. Significantly, the operation of the segmentation override and lookahead
acceleration control functions do not change the size or shape of these corner blends.
The section on buffered lookahead in the User’s Manual chapter “Power PMAC Move Mode
Trajectories” provides details on calculating the value of Coord[x].LHDistance (at 100%
override). Fundamentally, the equation for the optimal lookahead distance is:
2 Vmax
LHDist( segments)
3 Amax * SegMoveTime
As the top velocity changes with override, this optimal lookahead distance should change as well.
This can be incorporated easily into the algorithm that sets the override value.
Examples
The plot below shows a simple move position and velocity profiles executed at 100% and 50%
using time-base control in Power PMAC. At 50% override, the acceleration takes twice the time
to achieve half the speed, so the rate of acceleration is 25% of what it is without override.
The next plot shows the same simple move position and velocity profiles executed at 100% and
50% using segmentation override. Note that the rate of acceleration is the same at both override
values, so that acceleration at 50% override occurs in half the time as the 100% case.
The following plot shows the velocity profiles for one axis at 100% and 50% for a three move
sequence, with a linear move blending smoothly into a semi-circle move, blending smoothly into
another linear move. (The path including a second axis is that of the letter “U”.) Note that the
rates of initial acceleration and final deceleration are the same in both cases.
At 50% override, the centripetal acceleration of the semi-circle move does not violate
acceleration constraints and so can execute at the programmed speed multiplied by the override
percentage. However, at 100% override, the semi-circle move cannot move at the programmed
speed without violating acceleration limits, so the lookahead algorithm slows the arc down. It also
decelerates the end of the incoming linear move and accelerates the beginning of the outgoing
linear move so the transition can be made within constraints. In this way, the segmentation
override technique combined with lookahead acceleration control produces the minimum-time
profile for any override value that stays within machine constraints.
and splining require move calculations 2 moves ahead of the presently executing move, so
Coord[x].TPSize must be set at least to 3 to cover this simple case.
If special lookahead control for acceleration, velocity, and position limiting is enabled by
defining a lookahead buffer and setting Coord[x].LHDistance greater than 0, the “gap” between
calculation and execution can be much larger. The lookahead distance is specified in terms of
intermediate segments each of Coord[x].SegMoveTime milliseconds, not of programmed moves,
so the number of extra moves whose target positions need to be buffered must be calculated by
dividing the number of segments of lookahead by the minimum number of segments per
programmed move.
If move reversal/retrace using the lookahead buffer is utilized, then the target position buffer must
be sized large enough to cover the largest possible “gap” between the calculated move and the
furthest extent of reversal. In this case, the number of extra moves whose target position need to
be buffered must be calculated by dividing the number of segments defined for the lookahead
buffer, not the number of segments in Coord[x].LHDistance, by the minimum number of
segments per programmed move.
If 2D cutter radius compensation is enabled, this will require additional moves to be buffered
from calculation to execution time. The most basic compensation requires the buffering of one
additional move because the direction of that move must be known to calculate the compensated
end position of the previous move. Additional moves must be pre-computed if interference
checking is desired, and/or if there could be any moves with zero distance in the plane of
compensation. The user specifies how many moves can be buffered for 2D compensation in the
saved setup element Coord[x].CCSize. This value should be added to the value of
Coord[x].TPSize.
For querying the target positions themselves, the user must specify which axes’ positions will be
reported. This is done by setting the value of saved setup element Coord[x].TPCoords. This is a
32-bit “mask” element, with one bit per axis. If a bit is set to 1, that axis’ target position will be
reported; if it is set to 0, the target position will not be reported. Bit 0 (value 1) is for the A-axis;
bit 1 (value 2) is for the B-axis, and so on. The following table shows the complete list of bits i
and the axes they control:
Each bit i that is set to 1 adds a value of 2i to Coord[x].TPCoords. This element is usually
specified as a hexadecimal value so it is easy to see which bits are set.
Note that values for “distance to go” are reported for all defined axes in the coordinate system,
regardless of the setting of Coord[x].TPCoords.
Both commands report data in text form back over the communications port to the computer
issuing the query command. This is probably the most efficient way to get data to the host
computer for display purposes. For each of the specified axes, the axis letter name is returned,
followed by the queried value for the axes (e.g. X37.5 Y-21.23).
In the target position reporting, if cutter compensation is enabled for the move, a double value
will be reported for the X, Y, and Z axes if the compensated target position for the axis differs
from the programmed target position. First the programmed target position is reported, then a
colon character followed by the signed offset distance from compensation for that axis (e.g.
X21.2:-0.047 Y-17.45:0.139). If compensation is enabled, but the axis does not have an
offset due to compensation at the move end, no second value is reported.
In the distance-to-go reporting, Power PMAC computes the present desired axis positions from
the present desired motor positions, using the coordinate system definition information. Either the
equations in the axis definition statements are automatically inverted to do this, or if a forward
kinematic subroutine exists for the coordinate system, this subroutine is called to compute these
positions. In either case, the calculations are the same as if the d desired-position query command
were used for the coordinate system. These desired position values are then subtracted from the
target position values for the axes, and the differences are reported.
The distance values reported as signed quantities; if only magnitudes of distances are desired,
absolute values should be taken. If cutter compensation is active, the compensated target
positions for the X, Y, and Z axes are used in these calculations. The distances reported are
simple differences between present and target positions; in a Cartesian geometry, their vector sum
reflects the linear distance between the present desired point and the move target point, even if
the path to the target point is not a straight line, as with a circle mode move.
For blended moves, as soon as blending from one move to the next begins, the target positions
used are those of the new moves. Because the blending starts before the programmed target
position is reached, this means that the reported distance to go will in general not go all the way
to zero in any move that is blended into another move.
If reverse execution is performed using the “retrace” feature of the special lookahead buffer, the
target positions reported, and used for distance-to-go calculations, are those of the end of the
furthest “forward” move so far executed, even if reverse execution has transitioned into a
previous move. This remains true for all reverse execution and for subsequent forward “recovery”
motion of already executed trajectory.
from the present desired positions to the target positions for all defined axes in the addressed
coordinate system. These commands are generally used by PLC programs; they are not very
useful in motion programs because of the lookahead and calculation sequencing of the motion
programs. The commands query the values of the coordinate system selected by the value of
Ldata.Coord for the program.
Both commands cause Power PMAC to place the queried values into local D-variables in the D0
– D31 range for the program using the query command. The D-variable used to report an axis
value has a number equivalent to the bit number of Coord[x].TPCoords that specified reporting
for that axis: D0 for the A-axis, D1 for the B-axis, and so on. In addition, local variable D32 is
used to report which axes’ values have been calculated. It is a 32-bit mask word, with the bit
matching the bit of Coord[x].TPCoords set to 1 when that axis’ value is calculated.
The values returned into these D-variables should immediately be used for any subsequent
calculations, as the values in these local variables can be lost if the program context changes, or if
another function that utilizes these variables is called.
The calculations to produce these values are identical to those used for the comparable on-line
query commands discussed above. That section describes details of these calculations.
Note that the similar buffered program querying commands dread (for desired position),
pread (for actual position), vread (for actual velocity) and fread (for following error) do not
require buffering of the axis target positions. However, they do also return their values into the
same local D-variables for the program.
There are no comparable elements for the immediate (servo cycle by servo cycle) axis desired
positions. Immediate motor desired position values are calculated every servo cycle, and can be
found in Motor[x].DesPos. In some cases, especially with simple axis definitions, it is easy to
convert the motor values to matching axis values, but this is not done automatically.
This instantaneous commanded vector speed can differ from the programmed speed (“feedrate”)
due to acceleration, deceleration, or blending profiles, feedrate override, lookahead limiting, or
other factors. Note that this value is the commanded speed at move execution time, not at the
earlier move calculation time.
These commanded motor velocities are also used as the “cosine” and “sine” terms, respectively,
for the arctangent function that computes the path angle in the plane they define. The vector path
angle calculations in a cycle are only performed if the vector speed for the cycle is greater than
saved setup element Coord[x].MinAtanSpeed, with the value stored in Coord[x].PathAngleC.
(Typically, a machine’s “C” axis is used for orientation in this plane.)
SinMotor
Pos
PathSpeed
vSinMotor
PathAngleC
vCosMotor
Command
Path
CosMotor Pos
If MinAtanSpeed is set to 0.0, the angle is calculated for any non-zero speed, no matter how
small. If the vector speed for the cycle is not greater than this threshold, the previous cycle’s
angle value is retained, and Coord[x].ValidAngle bit 0 is set to 0 to indicate this situation.
Note that at the end of a programmed move sequence, there can be a tiny adjustment for a single
servo cycle to make the ending commanded motor positions exactly correct. This adjustment can
be in the opposite direction from the programmed direction of the move. The non-zero default
value of Coord[x].MinAtanSpeed should be large enough to prevent this adjustment from
yielding a reversal in the calculated direction.
The reported angle value in Coord[x].PathAngleC is scaled in degrees. It is always in the range
of -180 to +180. If a rotary axis is commanded to use this as a destination position,
Coord[x].PosRollover[i] should be set to 360 so it can handle the +/- transition properly.
However, Coord[x].ExtPathAngleC extends the reported angle past a single rotation, handling
the +/- transition itself. (Typically, a machine’s “C” axis is used for orientation in this plane.)
If 3D vector angle calculations are also enabled by setting Coord[x].PathCalcEna to 3, the path
angle in the plane defined by Coord[x].NormMotor and Coord[x].CosMotor (commonly the
“ZX” plane) is calculated and stored in Coord[x].PathAngleB, with the multi-turn value stored
in Coord[x].ExtPathAngleB. (Typically, a machine’s “B” axis is used for orientation in this
plane.)
NormMotor
+Pos
PathAngleB
PathAngleA
PathAngleC
CosMotor SinMotor
+Pos +Pos
In almost all cases, the intent is to permit standard programming of the Cartesian mechanism
itself, without it needing to consider the control of actions dependent on vector path speed and/or
direction. This allows the use of commercially available CAM programs to generate the Cartesian
path programs. All of the actions depending on vector path characteristics can be written in the
Power PMAC independently of the part program.
It is possible to use Coord[x].PathDistance as the master position for a real or virtual motor.
First, it must be processed through an Encoder Conversion Table entry (EncTable[n].type = 11
to specify a floating-point source, EncTable[n].index6 = 1 to specify a double-precision source,
and EncTable[n].pEnc = Coord[x].PathDistance.a to specify the source itself).
This motor then specifies the ECT entry result as its master position by setting
Motor[x].pMasterEnc = EncTable[n].a and enables the following of this master by setting
Motor[x].MasterCtrl = 1. If Motor[x].MasterPosSf is set to its default value of 1.0, the units of
this motor will be the same as those of the Cartesian motors.
Note that this motor should not be assigned to an axis in the same coordinate system as the
physical motors whose path it tracks. It should either be given the null definition (#x->0) in this
coordinate system, which allows for automatic fault sharing, or defined in a different coordinate
system.
At this point, the motor commanded position tracks the value in Coord[x].PathDistance,
automatically updated every servo cycle. There are many possible ways to use this. In one use, a
virtual motor position could, in turn, be used as the master for a cyclic cam table whose operation
repeats along the path at even intervals.
In another use, a virtual motor could be used with a Gate1 or Gate3 ASIC hardware channel, set
up as if to command an external pulse-and-direction open-loop stepper drive with simulated
feedback. This simulated feedback can be used like real encoder feedback with the ASIC’s
encoder hardware capture and compare circuitry. The compare circuitry with its auto-increment
functionality can generate precise output pulses at even intervals along the path.
This coordinate system executes a motion program whose core functionality loops rapidly with a
single programmed move inside the loop commanding the rotary axis to an angle equal to, or at
least a function of, the value in Coord[x].PathAngleC. Generally, this rotary axis should be
programmed to handle rollover by setting Coord[y].PosRollover[i] for the axis in its own
coordinate system (“y”) to 360.
It is also possible to use the path angle value as the master position for a virtual motor. In this
case, the extended value in Coord[x].ExtPathAngleC should be used to handle possible rollover
issues. The method for using this value as a virtual motor master are the same as for using
Coord[x].PathDistance this way, as explained above.
A few applications can make use of the path angle values in the “secondary planes” that are
perpendicular to the “primary plane” used for Coord[x].PathAngleC. The values in
Coord[x].PathAngleA and Coord[x].PathAngleB, and their extended versions, can be used in
the same manner as for Coord[x].PathAngleC.
tiny override percentage can be given (e.g. %0.001) to the Cartesian coordinate system so that
the move has technically begun, but the distance from the start is a fraction of a feedback count
for several seconds.
Even in this state, the Coord[x].PathAngleC value computed here is an accurate representation
of the starting angle of motion. (Coord[x].MinAtanSpeed should be set to a value small enough
to permit angle calculations at this point in this type of application.) This provides time for the
cutter to be oriented in the new direction of motion, possibly including a full lift/turn/lower
sequence. The Cartesian coordinate system can then be commanded to standard override
percentage.
Commonly, there will be a dwell at the corner, often automatically added due to the setting of
Coord[x].CornerBlendBp and Coord[x].CornerDwellBp, with a time specified by
Coord[x],AddedDwellTime. The program that determines the action of the tangent cutter can
detect the Coord[x].SharpCornerStop status bit set to 1 (during the incoming move) and the
Coord[x].DesVelZero status bits set to 1 (when the corner is reached), then set a very small
override value (e.g. Coord[x].DesTimeBase=Sys.ServoPeriod*0.00001). Since the dwell itself
always executes at 100%, the dwell will complete normally, and the new move will technically
begin, but without real movement.
All of this can be done with a standard part program, often generated automatically by CAM
software, that just commands the Cartesian axes. This part program does not need to do anything
special to allow the vector path functionality to be implemented by other routines in the Power
PMAC.
Computational Priorities
As a multitasking, real-time computer, Power PMAC has an elaborate prioritization scheme to
ensure that vital tasks get accomplished when needed, and that all tasks get executed reasonably
quickly. The scheme was designed to hide its complexity from the user as much as possible, but
also to give the user some flexibility in optimizing the controller for his particular needs. The
tasks at the different priority levels are:
If the system phase clock comes from a PMAC2-style “DSPGATE1” Servo IC, the phase clock
frequency is determined by the settings of Gate1[i].PwmPeriod and Gate1[i].PhaseClockDiv.
If the system phase clock comes from a PMAC2-style “DSPGATE2” MACRO IC, the phase
clock frequency is determined by the settings of Gate2[i].PwmPeriod and
Gate2[i].PhaseClockDiv.
If the system phase clock comes from a PMAC3-style “DSPGATE3” machine-interface IC, the
phase-clock frequency is determined by the setting of Gate3[i].PhaseFreq.
Servo Update
The servo update is the next highest priority after the phase update. Every cycle of the system
servo clock, the processor will compute the “servo tasks”. First it processes each active entry of
the “encoder conversion table” to prepare feedback and master data for use in subsequent servo
tasks. Then it computes the servo update calculations for each active motor (Motor[x].ServoCtrl
> 0). This update consists of the interpolation calculations to compute the next instantaneous
commanded position, and the servo-loop closure calculations that use this value, the actual
position value, and the servo gain terms to compute the commanded output. (The servo-loop
closure algorithms for a motor can skip cycles if Motor[x].Stime > 0.)
If the system phase clock comes from a PMAC2-style “DSPGATE1” Servo IC, the servo-clock
frequency is determined by the phase-clock frequency and the setting of Gate1[i].ServoClockDiv
for the same IC.
If the system phase clock comes from a PMAC2-style “DSPGATE2” MACRO IC, the servo-
clock frequency is determined by the phase-clock frequency and the setting of
Gate2[i].ServoClockDiv for the same IC.
If the system phase clock comes from a PMAC3-style “DSPGATE3” machine-interface IC, the
servo-clock frequency is determined by the phase-clock frequency and the setting of
Gate3[i].ServoClockDiv.
In addition, a single compiled C PLC program can be scheduled to run in the real-time interrupt.
Background Tasks
In the time not taken by any of the higher-priority tasks, Power PMAC will be executing
background tasks. These include the Script PLC programs numbered higher than Sys.MaxRtPlc,
background C PLCs, plus C applications executing under the general-purpose operating system
(GPOS).
Numerical Values
Power PMAC can receive, send, store, and process numerical values in many forms, with both
fixed-point and floating-point values. The Power PMAC’s CPU is a floating-point processor with
built-in 32-bit and 64-bit arithmetic capability.
Internal Formats
Power PMAC uses standard formats to store and process numerical values internally, both
floating-point and fixed-point (integer).
The Power PMAC processor contains a hardware engine for processing this data format very
efficiently. The format is organized in this fashion:
The smallest magnitude values that can be represented are +2-1074 ≈ +5 x 10-324. This requires
“denormalization” of the mantissa, which uses less than the full range of the mantissa. Without
denormalization, the smallest-magnitude numbers that can be represented are +2-1022 ≈ +2.22 x
10-308.
The largest (finite) magnitude numbers that can be represented are +21024 ≈ +1.80 x 10308.
The single-precision format has a 23-bit fractional mantissa (the most significant bit is not
stored), an 8-bit exponent, and a sign bit.
The smallest magnitude values that can be represented are +2-149 ≈ +1.4 x 10-45. This requires
“denormalization” of the mantissa, which uses less than the full range of the mantissa. Without
denormalization, the smallest-magnitude numbers that can be represented are +2-128 ≈ +1.22 x
10-38.
The largest (finite) magnitude numbers that can be represented are +2128 ≈ +3.4 x 1038.
Plus/Minus Zero: There are separate representations for “+0” and “-0”. In general, the only
operations that produce “-0” involve underflow or modulo of a negative value. Mathematically,
“+0” and “-0” behave identically. In the evaluation of any conditional comparison, “+0” is equal
to “-0”. Note, however, that 1/0 equals “plus infinity”, and 1/-0 equals “minus infinity” (see
below), so this operation could be used to distinguish between the two cases.
It is possible to set a variable directly equal to +infinity, and to compare it directly to +infinity in
a condition. In a conditional comparison, plus infinity evaluates as equal to plus infinity and as
greater than any true numerical value or minus infinity; minus infinity evaluates as equal to minus
infinity, and as less than any true numerical value or plus infinity.
However, it is better programming practice to check for the conditions that could create an “inf”
result before the calculation is performed in the first place.
Power PMAC also uses the “not-a-number” representation when the value of a hardware element
that is not present in the system is read, as in a query command. For example:
Gate3[14].Chan[0].ServoCapt
nan
Another method of checking involves the Boolean isnan (is not-a-number) function in the
Power PMAC script language. For example:
However, it is better programming practice to check for the conditions that could create a “nan”
result before the calculation is performed in the first place.
Integer Values
Most input-output registers are encoded as integer values of varying widths, up to 32 bits. (There
is no 64-bit integer format in the Power PMAC script environment.) Some internal memory
registers (e.g. control and status words) are also encoded as integers. These are accessed with
either pre-defined data structures or user-defined pointer variables. It is also possible to define
general-purpose pointer variables as integers.
Decimal values can be positive or negative, and can include fractional values. The Power PMAC
value interpreter can accept both standard decimal notation and exponential notation. In
exponential notation, the mantissa must immediately be followed (no spaces) by the letter “E”
(upper or lower case), with the power of 10 immediately following the “E”. The mantissa does
not need to be normalized. The exponent value must be an integer constant. If it has a decimal
point, it will be treated as an E-axis command.
Power PMAC can accept numerical values to the full range of what can be stored in a particular
variable type. For floating-point variables, values of too great a magnitude result in the variable
taking a value of +infinity; values of too small a magnitude result in the variable taking a value of
+zero.
Examples
1234
3
03 (leading zeros OK)
-27.656
0.001
.001 (integer zero not required)
P1=1.1
P1
1.10000000000000009
If it is desired to display reported values to a fixed number of decimal digits, user software will
need to perform the required formatting, potentially rounding or truncating the reported value.
Data-structure elements include both “control” and “status” registers. Many of the control register
values – those considered part of the basic system setup – are retained in non-volatile flash
memory on a save command, and copied back into the active element registers on the next
power-up/reset.
The elements of these data structures are defined in detail in the Software Reference manual. This
section gives a quick overview.
Note that the index numbers start a 0 for each indexable structure.
Individual elements within these structures can be used as variables in user commands and
programs. The elements are of different formats, integer and floating-point, and of varying sizes.
Because the Power PMAC script language performs automatic type matching when accessing
these elements, the formatting is not a serious issue in the script environment. However, when
structure elements are accessed in user C programs through the provided header file, the
programmer must be aware of the data type of each element.
If a local variable is used to specify the index, it must be used by itself. No mathematical
expressions are permitted in the index specifier. The value of the local variable must be set prior
to its use as a data structure index. A typical example is:
L0 = Ldata.Motor + 1;
Motor[L0].JogSpeed = 100;
Of course, under the IDE project manager, declared or defined user names for the local variables
may be used.
In any indexed structure, the valid index values start at 0 and go to a value one less than the
possible numbers of that structure. The index ranges for the most commonly used structures are
shown here:
When local variables are used to specify an index value, only the variables in the range L0 to
L(1022 – MaxConstantIndex) can be used. For example, for motors, L0 to L767 (1022 – 255 =
767) can be used.
In many applications, some of the data structures with index value of 0 will not be used. Servo
hardware interface channels are auto-assigned to motors and encoder conversion table entries
starting with index values of 1. Coordinate System 0 is typically used just to “park” motors that
have not been assigned to axes in active coordinate system.
User Variables
The Power PMAC script environment provides programmers with large numbers of user
variables of several types with multiple methods of access, providing both flexibility and ease of
use. These variables are held in shared memory in the Power PMAC, providing access from both
tasks running under the real-time kernel and the general-purpose operating system, and both
Power PMAC script programs and compiled C programs.
System global (“P”) variables: user variables accessible to any task in Power PMAC
Pointer (“M”) variables: global variables that have been assigned by the user to specific
addresses or data structure elements
Legacy setup (“I”) variables: global variables that have been pre-assigned to specific data
structure elements that are useful for system setup and are stored to flash memory.
Intended as a shortcut for experienced Turbo PMAC users.
Local (“L”) stack variables: user variables local to a given program or “command
processor” (communications stream)
Stack/return (“R”) variables: local user variables for passing and returning arguments to
subroutines and subprograms; equivalent to differently numbered L-variables
Coordinate-system axis (“C”) variables: local user variables for passing axis positions
and velocities to or from kinematic subroutines; equivalent to differently numbered L-
variables
Non-stack local (“D”) variables: local user variables for creating subroutine arguments
from the letter/number format of the RS-274 “G-code” syntax, for kinematic routine
flags, for axis data queries.
User shared memory buffer (“Sys.Xdata”) variables: global user array variables in a user-
defined buffer space; several variable formats can be used.
Each variable type is documented in more detail below. There is a fixed number of each of these
variables, documented under the specific variable type, with reserved memory locations for each;
there is no dynamic memory allocation.
If the constant specifier of the variable number is not in the valid range (or not an integer), the
statement using this variable specification will be rejected with an error when it is sent to Power
PMAC. If the expression specifying the variable number evaluates to an out-of-range number at
run time, the results will be unpredictable, but no error will be generated. It is the programmer’s
responsibility to ensure that such an expression always evaluates in the proper range. If the
expression does not evaluate exactly to an integer value, it is rounded down to the next integer
(not necessarily the closest integer: 27.9999999 is rounded to 27). If the calculations only involve
integers in the range of possible variable numbers, this is not a concern, but if any floating-point
operations are used to calculate the variable number, the user should force a proper rounding to
the nearest integer before using the resulting value to specify a variable number.
The IDE will then automatically assign the user name to a particular variable in the Power
PMAC. In normal use, it is not necessary for the user to know which variable the name has been
assigned to. The IDE and the Power PMAC keep coordinated and synchronized “symbol tables”
containing the full mapping of user names to Power PMAC variables.
global CycleCount;
the IDE will reserve a system global (“P”) variable for the user’s CycleCount variable. In
subsequent use of the variable in user programs, the IDE will replace the user’s variable name
with the reserved internal variable name. If the IDE reserved variable P517 for CycleCount, it
would replace CycleCount with P517 every time it was used in the entire project.
The IDE will start assigning the underlying variables of each type to user-specified names at the
variable number determined by the xVARSTART directive in the automatically generated
pp_proj.ini file, where “x” is the letter representing the variable type, and the following
number represents the starting variable number used for automatic assignments. Variables with
numbers below this value are safe for “direct” usage. For example, with the PVARSTART 256
directive, system global variables P0 – P255 can be used directly or with manually defined
variable names; P256 and up will be allocated to user-specified variable names.
The default values of the xVARSTART directives in the pp_proj.ini file are:
PVARSTART=8192
QVARSTART=1024
MVARSTART=8192
These can be changed in the “Project Properties” window of the IDE’s project manager.
Through use of the symbol tables, the user can utilize the custom variable names in all windows
of the IDE – the editor, the terminal window, the “watch” window, and more.
global IncrementDist(512);
the IDE will reserve 512 consecutive system global (“P”) variables for the IncrementDist
array. In subsequent use of the array in user programs, the IDE will add the “base number” of the
array to the user’s specified array index. For example, if the IDE assigned variables starting at
P860 to this array, if the program used IncrementDist(CycleNum) in the program, the IDE
would replace this with P(860+CycleNum).
With a declared array name, the name can be used in vector or matrix function calls that require
the starting variable number as an argument. With the above declaration, the following could be
used:
instead of:
to calculate the sum of all values in the array. This means the programmer does not need to know
which numbered variables are assigned to the array.
It is strongly recommended that any of these manual definitions be assigned to variables with
numbers below the start of the automatically assigned (declared) definitions. If this practice is
maintained, it will not be possible for “declared” variable names to use the same underlying
variable numbers as “defined” variable names.
When this is done, the communications application will check command lines against the
automatically generated “symbol table” for variable names and substitute the underlying
numbered variable name. This process is invisible to the user. It does add some computational
overhead to communications, but in most applications, this is not noticeable.
In most applications, use of these variables will be managed through the IDE. In the IDE, the user
will declare a variable as “global”, followed by the user’s name for the variable. As a global
variable, the declaration must be outside of any program in the project. Sample declarations
include:
The IDE will automatically assign a unique system global variable (or consecutive set of
variables in the case of an array declaration) to that user name, and no programmer or operator
will need to know which internal variable register is used for that name.
It is also possible to access these variables directly. With direct access, these are known as “P”
variables, and an individual variable is specified by the letter “P” followed by a numerical value.
The numerical value can either be specified as an integer constant immediately following the
letter “P”, or as a mathematical expression in parentheses. Examples include:
P17=3.14159;
P200=P100+1;
P(P1)=7;
P2=L(Q13+Q14-1);
It is also possible in the Script environment to access numbered P-variables through the
corresponding data structure elements: Sys.P[i] for variable Pi. In the C environment, these can
be accessed through the pointer to shared memory: pshm->P[i] for variable Pi.
These system global variables are 64-bit floating-point values, but can also be used for integer-
type calculations. Power PMAC provides 8,192 of these coordinate-system-specific global
variables per coordinate system, without any overlap (so all 8,192 are available for every
coordinate system, no matter how many coordinate systems are active).
In most applications, use of these variables will be managed through the Integrated Development
Environment (IDE). In the IDE, the user will declare a variable as “csglobal”, followed by the
user’s name for the variable. As a global variable, the declaration must be outside of any program
in the project. Sample declarations include:
The IDE will automatically assign a set of unique coordinate-system-specific global variables –
one for each coordinate system – to that user name, and no programmer or operator will need to
know which internal variable registers are used for that name.
It is also possible to access these variables directly. With direct access, these are known as “Q”
variables, and an individual variable is specified by the letter “Q” followed by a numerical value.
The numerical value can either be specified as an integer constant immediately following the
letter “Q”, or as a mathematical expression in parentheses. Examples include:
Q17=3.14159;
Q200=Q100+1;
Q(Q1)=7;
Q2=P(L13+L14-1);
In an on-line command, the presently addressed coordinate system (from the most recent &n
command) determines which set of Q-variables the command accesses. In a motion program, the
number of the coordinate system running the program determines which set of Q-variables the
command accesses. In a PLC program, the coordinate system specified by the data structure
element Ldata.Coord determines which set of Q-variables the command accesses.
It is also possible in the Script environment to access numbered Q-variables through the
corresponding data structure elements: Coord[x].Q[i] for variable Qi in Coordinate System x. In
the C environment, these can be accessed through the pointer to shared memory:
pshm->Coord[x].Q[i] for variable Qi in Coordinate System x.
In most applications, use of these variables will be managed through the IDE. In the IDE, the user
will declare a variable as “ptr”, followed by the user’s name for the variable, the “->” pointing
symbol, and the assignment of the pointer. As a global variable, the declaration must be outside
of any program in the project. Sample declarations include:
ptr LaserOn->u.io.$A00000.8.1
ptr LaserMag->Gate1[4].Chan[3].Dac[1]
It is also possible in the Script environment to access numbered M-variables through the
corresponding data structure elements: Sys.M[i] for variable Mi. It is not possible to access M-
variables (which are actually functions) directly in the C environment. They must be accessed
instead through API function calls.
For example, the Power PMAC structure element Motor[x].HomeVel sets the commanded
velocity of a homing search move for the specified motor. This same function was accomplished
by variable Ixx23 in Turbo PMAC. So Motor[1].HomeVel (for Motor 1 in Power PMAC) can
alternately be accessed as I123.
To see which structure element is addressed by a given I-variable, the Power PMAC can be
queried with the I{data}-> on-line command. For example, the command
I123->
Motor[1].HomeVel
Similarly, for coordinate systems, structure elements whose functions are the same as for Turbo
PMAC controllers can also be accessed through those I-variable names. The command:
I5198->
Coord[1].MaxFeedRate
Note that Power PMAC motor and coordinate-system numbering start with zero, although Motor
0 and C.S. 0 are seldom used. I0 – I99 are reserved for the setup variables of Motor 0; I5000 –
I5099 are reserved for the setup variables of C.S. 0. For example I23 is the homing velocity for
Motor 0; I5098 is the maximum feedrate for C.S. 0.
Existing global setup variable numbers have been moved to the I8000 – I8099 range For example,
the old I10 is now I8010, and the command:
I8010->
Sys.ServoPeriod
Saved control elements for newly added functions or for additional items (e.g. increased numbers
of motors and coordinate systems) do not have I-variables assigned to them. However, they
function exactly the same as those that do have I-variables assigned to them.
I-variables that are not assigned to a Power PMAC data structure element (their assignment is
reported as “*”) can be used as general-purpose double-precision floating-point variables. All I-
variables from I8192 through I16383 can be used this way.
These local variables are 64-bit floating-point values, but can also be used for integer-type
calculations. The standard software configuration of the Power PMAC provides 8192 of these
local variables per top-level program or communications thread, but alternate configurations may
provide a different number of these.
In most applications, use of these variables will be managed through the Integrated Development
Environment (IDE). In the IDE, the user will declare a variable as “local”, followed by the user’s
name for the variable. As a local variable, the declaration must be inside of any program in the
project. Sample declarations include:
The IDE will automatically assign a unique local variable to that user name, and no programmer
or operator will need to know which internal variable registers are used for that name.
It is also possible to access these variables directly. With direct access, these are known as “L”
variables, and an individual variable is specified by the letter “L” followed by a numerical value.
The numerical value can either be specified as an integer constant immediately following the
letter “L”, or as a mathematical expression in parentheses. Examples include:
L17=3.14159;
L200=L100+1;
L(L1)=7;
L2=L(P13+P14-1);
In a subprogram called with a call statement, or a subroutine in the same program called with a
callsub statement, variable L0 of the called subprogram/subroutine is the same variable as R0
in the calling program/routine, L1 in the called is the same as R1 in the calling, and so on. This
permits true argument passing and returning in subprograms and subroutines.
The following diagram shows the relationships between local variables in the calling and called
routines for the default stack offset.
L0
L255
R0/L256 L0
R255/L511 L255
R0/L256 L0
R255/L511 L255
R0/L256
R255/L511
It is possible to access these local L-variables from outside the routine, a capability that is mainly
used for debugging purposes. Status elements Coord[x].Ldata.Lindex or Plc[i].Ldata.Lindex
contain the number of L0 for the presently executing (or suspended) routine relative to the “base”
L0 for the coordinate system or PLC program. Coord[x].Ldata.L[n] or Plc[i].Ldata.L[n]
contain the value of Ln for the presently executing (or suspended) routine.
Variable Ri of a calling program or routine is the same as variable Li in the called subprogram or
subroutine. Within the calling program or routine, Ri is the same as L(StackOffset+i), where
StackOffset is declared for the program in the open command that precedes the downloading of
program text. If no value is explicitly declared, Power PMAC sets StackOffset to 256. If the
program is downloaded through the IDE project manager, the IDE automatically calculates and
declares the smallest value of StackOffset needed to support the number of local variables used in
that program.
This scheme permits the use of generic subprograms that can be called from many different
higher-level programs with true independent argument passing and returning. As a simple
example, we will look at a subprogram that uses the Pythagorean Theorem to compute and return
a “diagonal” value from two “perpendicular values passed to it. In “raw” Power PMAC code,
without variable declarations and substitutions, the code for this subprogram could be:
This subprogram could then be invoked with Power PMAC code (again without variable
declarations and substitutions) like:
R0=3; R1=4;
call 100;
// Returned result is available in R2
The IDE project manager supports user names for the variables and subprogram/subroutine
names, so the subprogram could be written in the IDE as:
This would result in actual Power PMAC code like that shown above.
In the IDE, this subprogram would be invoked with a program statement like:
where P8207, P8208, and P8215 are the auto-assigned (global) variables for Xvelocity,
Yvelocity, and VectorVel, respectively.
It is possible to access these local R-variables from outside the routine, a capability that is mainly
used for debugging purposes. Coord[x].Ldata.R[n] or Plc[i].Ldata.R[n] contain the value of Rn
for the presently executing (or suspended) routine for the coordinate system or PLC program.
C-variables are simply renamed L-variables for the coordinate system. C0 is the same as
L(MAX_MOTORS), C1 is the same as L(MAX_MOTORS + 1), and so on, where
MAX_MOTORS is the largest permitted value for Sys.MaxMotors (256 in most Power PMAC
implementations).
The IDE project manager automatically provides user names for these C-variables: KinPosAxisA
for C0, KinPosAxisB for C1, and so on. For more details on C-variables, refer to the section on
kinematic subroutines in the Coordinate System chapter of the User’s Manual.
It is possible to access these local C-variables from outside the routine, a capability that is mainly
used for debugging purposes. Coord[x].Ldata.C[n] or Plc[i].Ldata.C[n] contain the value of Cn
for the presently executing (or suspended) routine for the coordinate system or PLC program.
If a subroutine or a subprogram executes a read command, the values associated with the
specified single or double letters are automatically assigned to D-variables for the coordinate
system executing the motion program, or the top-level PLC program. The main purpose of this
functionality is to provide arguments for subroutines while keeping the top-level program in the
traditional letter/number format of RS-274 “G-codes”.
Values associated with single letters A – Z are assigned to D1 – D26, respectively. Values
associated with double letters AA – ZZ are assigned to D27 – D52, respectively. Bit n-1 of D0 is
set to 1 if the most recent read command assigned a value to Dn; it is 0 otherwise.
D-variables are also used to hold the responses to axis query commands, including the buffered
program commands dread, dtogread, fread, pread, tread, and vread, plus the on-line
commands (when immediately preceded by an &x coordinate-system specifier) d, f, g, p, t, and
v. In this case, D0 – D31 are used for the values for the A – ZZ axes, respectively.
Variable D0 for a coordinate system has several uses with the kinematic subroutines. Power
PMAC will automatically set D0 on the entry to the forward-kinematic routine to denote whether
it wants one or two passes through the routine (two passes are needed to compute velocities and
following errors.) The user’s forward kinematic code must set D0 on exiting the routine to tell
Power PMAC which axis values have been computed, with bits 0 – 31 used for the A – ZZ axes,
respectively.
Power PMAC will automatically set D0 on the entry to the inverse-kinematic routine to denote
whether it wants to compute motor velocities from axis velocities (as well as motor positions
from axis positions) or not. Velocity calculations are only used for PVT-mode moves when the
coordinate system is not in segmentation mode.
It is possible to access these local D-variables from outside the routine. Coord[x].Ldata.D[n] or
Plc[i].Ldata.D[n] contain the value of Dn for the presently executing (or suspended) routine for
the coordinate system or PLC program.
By default, Power PMAC reserves 1 Mbyte of memory for the user shared memory buffer. This
can be changed by the user as part of his project management. In the IDE’s Project Manager
“Properties” control window, the “User Buffer” size can be defined (in Mbytes). The resulting
size is stored in the “ppproj.ini” project configuration file.
The base address of this buffer can be found in the global status element Sys.pushm. It is seldom
needed to know the numerical value of this address, but this element can be useful to derive the
address of specific registers without the need to specify the absolute address of a register.
The index value i for the element can be an integer constant (e.g. Sys.Ddata[3975]) or a local
variable (e.g. Sys.Udata[L43]). Expressions cannot be used directly for the index number;
instead, their value must first be assigned to a local variable (e.g. L43=P92*P93-1).
It is important to note that all of these data structures access the same registers in the buffer. If the
user wishes to employ multiple formats in the buffer, it is his responsibility to make sure there are
no conflicts.
The following table shows how the first 16 bytes of the buffer can be accessed in the different
formats:
M-Variable Access
In some applications, it may be useful to access user shared memory buffer registers through
Power PMAC’s M-variable pointers. This is particularly valuable in conjunction with the IDE
Project Manager’s facility for declared variable names. For example, the declaration:
ptr LineSpeed->Sys.Fdata[4096];
permits the use of the declared variable name in programs and commands.
The M-variable can also declared with a local variable for the index in brackets, permitting access
to an entire array with a declared variable name. For example, with the declaration:
ptr CycleTime->Sys.Fdata[L100];
TotalTime = 0.0;
L100=5000;
while (L100 < 10000) TotalTime += CycleTime; L100++;
For example:
ptr InsertionComplete->u.user:$3000.7.1
int *MyUshmIntVar;
double *MyUshmDarray;
Operators
Power PMAC Script operators work like those in any computer language: they combine values to
produce new values. Detailed descriptions of the operators are given in the Software Reference
manual; overviews are given here.
Arithmetic Operators
Power PMAC uses the four standard arithmetic operators: +, -, *, and /. The standard algebraic
precedence rules are used: multiply and divide are executed before add and subtract, operations of
equal precedence are executed left to right, and operations inside parentheses are executed first.
Modulo Operator
Power PMAC Script also has the % modulo operator, which produces the resulting remainder
when the value in front of the operator is divided by the value after the operator. Values may be
integer or floating-point. This operator is particularly useful for dealing with counters and timers
that roll over. The modulo operation has equal precedence with multiplication and division
operations.
When the modulo operation is done by a positive value x, the results can range from 0 to x (not
including x itself). When the modulo operation is done by a negative value x, the results can range
from -x to 0 (not including -x itself). Note that operation with a negative divisor works differently
from in PMAC and Turbo PMAC, but is consistent with the C standard. The “rem” remainder
function can be used to obtain results like those with the negative modulo divisor in PMAC and
Turbo PMAC.
Bit-Wise Operators
Power PMAC Script has three logical operators that do bit-by-bit operations: & (bit-by-bit AND),
| (bit-by-bit OR), and ^ (bit-by- bit EXCLUSIVE OR). If floating-point numbers are used, the
operation works on the fractional as well as the integer bits. & has the same precedence as * and
/; | and ^ have the same precedence as + and -. Use of parentheses can override these default
precedence levels.
Power PMAC also provides the << “shift-left” operator, where the value preceding the operator is
shifted left by the number of bits specified by the value to the right of the operator, and the >>
“shift-right” operator, where the value preceding the operator is shifted right by the number of
bits specified by the value to the right of the operator.
In addition, Power PMAC provides the unary ~ “complement” operator, which logically inverts
the bits of the value following it.
Only the basic “=” assignment operator can be used in on-line commands. All of the compound
operators can only be used in motion and PLC program commands.
This set of assignment operators is “standard” in that the value is written to the variable(s) as
soon as it is computed in the normal program flow. This is different from the “synchronous”
assignment operators, for which the actual value assignment is delayed until the start of actual
execution of the next programmed move.
The standard assignment operators provided are: =, +=, -=, *=, /=, %=, &=, |=, ^=, >>=, <<=,
++, and --.
These can only be used in buffered program commands, not in on-line commands. With a
synchronous assignment operator, the actual assignment to the variable is delayed until the start
of actual execution of the next commanded move in the program.
The basic synchronous operator is ==. It can be used to assign a value to either an integer or a
floating-point variable.
The arithmetic synchronous operators are +==, -==, *==, /==, %==, ++=, and --=. The *==,
/==, and %== can only be used to assign values to floating-point variables.
The logical synchronous operators are &==, |==, and ^==. They can only assign values to
integer variables.
For more details on the use of these operators, refer to Synchronous Variable Value Assignment,
below.
Functions
Power PMAC provides a full set of mathematical functions operating on scalar, vector, and
matrix operands. These make sophisticated mathematical operations simple, compact, and
efficient.
Scalar Functions
The Power PMAC script language provides an extensive set of “scalar” functions, which return a
single numeric value. Each function is documented in detail in the Software Reference Manual.
Log/exponent functions: log (or ln), log2, log10, exp, exp2, exp10, pow
General functions: abs, sgn, rem, isnan, madd (combined multiply and add)
Vector Functions
The Power PMAC script language provides several functions that operate on entire vectors,
where a set of continuously numbered system global (“P”) variables or local (“L”) variables is
treated as a vector. Since a 2D matrix is also formed by a set of continuously numbered system
global variables, these operations can also be used on matrices.
If it is desired to use P-variables in the vectors, non-saved setup element Ldata.Control for the
program or thread should be set to its power-on default value of 0. If it is desired to use L-
variables in the vectors, Ldata.Control should be set to 1. If it is desired to use Sys.Ddata[i]
elements in the vectors, Ldata.Control should be set to 2.
Functions that produce new vectors (the returned value is a Boolean flag indicating whether the
function operated successfully; lack of “success” would usually be to an out-of-range argument,
such as a negative number of elements) are:
vscale: Multiplies each element of the vector/matrix by a common factor, putting the
results into a second vector/matrix.
Functions that produce scalar quantities (as the returned value) only are:
sum: Adds a number of evenly spaced elements of the vector/matrix together, returns the
sum. Useful for calculating trace of a matrix.
These functions require as an argument the variable number to be used as the start of a vector. If
the vector has been declared in the IDE project manager as an array with a user variable name,
then the user variable name, preceded by the “&” character, can be used instead of the variable
number. For example, with the following declarations:
global SurfaceNormal(3);
global ToolNormal(3);
This will take the dot product of these two vectors without needing to know what the underlying
variable numbers are.
Matrix Functions
The Power PMAC script language provides multiple matrix functions. These operate on entire 2D
matrices, where a set of continuously numbered system global (“P”) variables or local (“L”)
variables is treated as a matrix organized into rows and columns.
If it is desired to use P-variables in the matrices, non-saved setup element Ldata.Control for the
program or thread should be set to its power-on default value of 0. If it is desired to use L-
variables in the matrices, Ldata.Control should be set to 1. If it is desired to use Sys.Ddata[i]
elements in the matrices, Ldata.Control should be set to 2 (new in V1.5 firmware, released 2nd
quarter 2012).
Functions that produce new matrices (the returned value is either a Boolean flag indicating
whether the function operated successfully; lack of “success” would usually be to an out-of-range
argument, such as a negative number of elements, or the determinant of an input matrix to the
function; in either case, a returned value of 0 means the operation did not produce a valid result)
are:
mmadd: Multiplies two matrices together and adds the product matrix to a third matrix
Functions that produce scalar quantities (as the returned value) only are:
mminor: Calculates the minor determinant of a square matrix with the specified row and
column removed
These functions require as an argument the variable number to be used as the start of a matrix. If
the matrix has been declared in the IDE project manager as an array with a user variable name,
then the user variable name, preceded by the “&” character, can be used instead of the variable
number. For example, with the following declarations:
global RotationA(9);
global RotationB(9);
global NetRotation(9);
global NetRotDet;
This will multiply these two 3x3 matrices without needing to know what the underlying variable
numbers are.
Expressions
A Power PMAC script-language expression is a mathematical construct consisting of constants,
variables, and functions, connected by operators. Expressions can be used to assign a value to a
variable, to determine a motion-program parameter, or as part of a condition. A constant alone
can be an expression, so if the syntax calls for {expression}, a constant may be used as well
as a more complicated expression. In this case, no extra parentheses are required for more
complicated expressions, unlike the case where the {data} syntax is specified (see below).
512
P1
P1+512
1000*cosd(Q25*3.14159/180)
I100*abs(M347)/atand(P(Q3+1)/6.28)+5
For example, if the listed command syntax is R{data}, it is legal to use R100,
R(P1+250*P2), or R(100) (which is legal but inefficient).
In program execution, the expression value is calculated and used in the assignment to the
variable, immediately as the statement is encountered in the program flow. This can occur
significantly before the actual execution of moves commanded from the program immediately
following in the program flow, as the move execution can be delayed for various reasons.
When this type of statement is encountered during program execution flow, the value of the
expression is evaluated immediately. Then this value and the assignment operator are placed in a
dedicated assignment queue. When the next move commanded from the program actually
commences execution, the value and assignment operator are pulled from the queue and used for
the actual assignment to the specified variable. This assignment is done at the real-time interrupt
(RTI) priority level.
For segmented moves (linear, circle, or pvt with Coord[x].SegMoveTime > 0), the assignment is
done at the beginning of the first segment to start within the new programmed move.
Note carefully that for synchronous assignments other than the == direct assignment, the value of
the target variable is read at the delayed “synchronous” time and combined with the value of the
expression that was evaluated at the earlier “lookahead” time.
Also, “self-defined” M-variables, which use part of their definition to store a value, cannot have
values synchronously assigned. In older PMACs, synchronous assignment to self-defined M-
variables was a way of using the functionality for effective general-purpose variables. In Power
PMAC, the assignment can be made directly to general-purpose user variables.
The multiplication and division synchronous assignments *== and /== can only be made to
floating-point variables. The logical AND, OR, and XOR synchronous assignments &==, |==,
and ^== can only be made to integer variables.
When assigning values to variables is part of the program calculation, the variables will get their
new values ahead of their place in the program when looking at actual move execution. For many
internal variables, this is generally not a problem, because they exist only to aid further motion
calculations. However, for some variables, particularly those representing physical outputs, this
can be a problem, because with a normal variable value assignment statement, the action will take
place sooner than is expected, looking at the statement’s place in the program.
Q1 = 30; // Set Q1 to 30
M1 = 1; // Turn on Output 1 10
M2 == 1; // Turn on Output 2
X(Q1); // Move X-axis to Q1
time
Assume that the motion program is calculating t1 t2 t3
one move ahead of the resulting move execution
to permit blending, but other advanced functions
such as the lookahead buffer are not enabled. 1
M1
The command M1=1, which turns on Output 1, is also a standard assignment that is executed
immediately. Even though this assignment occurs after the X20 move command in the program,
it will be executed before the execution of this move. Generally, this is not the desired behavior
for setting outputs during motion.
However, if the PLC code were implemented like this, there is a good chance that the condition
would be evaluated before the move execution actually started, because that move execution
could not begin until the next servo cycle at the earliest. This means that the output could get set
at the beginning, not the end of the move.
In addition, in many applications of this type, there is a possibility that the commanded move
could be of zero distance, and therefore never create any actual motion. In these cases, it can be
very difficult to create general logic to cover both zero and non-zero-distance moves.
Synchronous assignments permit a good general solution. The following PLC code is robust for
starting a move and waiting until it is finished.
Note that synchronous assignment buffers are a coordinate-system function. The PLC program
must be addressing the same coordinate system as the motor executing the move with which the
output is to be synchronous, whether an axis move or a motor move (e.g. jog or home).
To change the buffer size for a coordinate system, it is necessary to change the value of
Coord[x].SyncOps, issue a save command, and reset the Power PMAC. Only on power-
up/reset does Power PMAC re-organize the synchronous assignment buffers.
Execution Details
With linear and circle-mode blended moves, the actual synchronous assignment is performed
where the blending to the new move begins, which is generally ahead of the programmed point.
This blending occurs V*Ta/2 distance ahead of the specified intermediate point, where V is the
commanded velocity of the axis, and Ta is the acceleration (blending) time.
Also, note that the assignment is synchronous with the commanded position, not necessarily the
actual position. It is the responsibility of the servo loop to make the commanded and actual
positions match closely. (The hardware position-compare function can be used to set outputs on
actual position values.)
Power PMAC checks to see whether it is time to pull synchronous assignments out of the queue
and execute them every real-time interrupt (every Sys.RtIntPeriod + 1 servo cycles). The smaller
Sys.RtIntPeriod is, and the smaller the servo cycle time is, the tighter the timing control of the
synchronous outputs is.
Synchronous assignments after the last move or dwell in the program do not execute when the
program ends or temporarily stops. Use a dwell as the last statement of the program to execute
these statements.
Comparators
A comparator evaluates the relationship between two values (constants or expressions). It is used
to determine the truth of a condition in a motion or PLC program. The valid comparators for
Power PMAC are:
== (equal to)
!= (not equal to)
> (greater than)
>= (greater than or equal to)
< (less than)
<= (less than or equal to)
~ (approximately equal to -- within one)
!~ (not approximately equal to -- at least one apart)
Note that the single equals sign = is not a valid comparator in Power PMAC, although it was in
PMAC and Turbo PMAC. Outside of a condition, the double equals sign == is the synchronous
assignment operator.
Power PMAC can accept three alternate comparators, but these are stored and reported back in
standard form. The comparator <> will be stored and reported as !=; !< will be stored and
reported as >=; !> will be stored and reported as <=.
These are described in detail in the Software Reference manual under Mathematical Features.
Conditions
Power PMAC conditional statements (if branching statements or while looping statements)
can use either explicit comparisons or mathematical expressions. If just a mathematical
expression is used, it must evaluate exactly to 0.0 (with full floating-point resolution) to be
“false” – a value of 0.0000000000001 evaluates as “true”.
Explicit Comparisons
An explicit comparison consists of three parts:
If the relationship between the two expressions defined by the comparator is valid, then the
condition is true; otherwise, the condition is false. Examples of simple conditions in commands
are:
Explicit comparisons may not be used outside of conditional parentheses (e.g. P3=P2>1 is not
legal syntax). Comparisons result in a logical value (true or false), distinct from a numerical
value.
Compound Conditions
A compound condition is a series of simple conditions connected by the logical combinatorial
operators && and ||. The compound condition is evaluated from the values of the simple
conditions by the rules of Boolean algebra. In the Power PMAC, && (AND) has execution
precedence over || (OR); that is, ORs operate on blocks of ANDed simple conditions. Power
PMAC will stop evaluating compound AND conditions once one false simple condition has been
found. Examples of compound conditions in command lines are:
if (Q16 >= Q17 && Q16 <= Q18 || M136 < 256 && M137 < 256)
Unlike the older PMAC and Turbo PMAC, Power PMAC does not permit compound conditions
across multiple program lines (but individual program lines can be very long).
Condition Negation
The ! conditional negation operator can be useful in conditions. It logically negates the explicit
comparison or mathematical value inside the parentheses immediately following. If the
comparison yields a true condition, the negation results in a false condition; if the comparison
yields a false condition, the negation results in a true condition. If the mathematical value has any
non-zero value, the negation yields a false condition; if the mathematical value is exactly equal to
0.0, the negation yields a true condition.
Examples:
This chapter summarizes the general-purpose digital I/O capabilities of the Power PMAC family.
Another chapter does the same for general-purpose analog I/O. More details can be found in the
manuals for specific controllers and I/O accessories. The chapter is organized as follows:
Refer to the manual for the particular hardware configuration to see how to set up and access
these dedicated I/O points. Remember that no active motor should be using any of these dedicated
outputs, or servo tasks could overwrite the general-purpose use of these points. It is generally
recommended that even the inputs should not be accessed by any active motor, because the
automatic motor status and safety checks could lead to unintended consequences.
On all of these boards except the ACC-14E, the inputs and outputs are optically isolated from the
core UMAC digital circuitry.
These boards are mapped as “I/O” boards on the UMAC backplane. They share an addressing
space with other UMAC digital I/O boards (ACC-14E, 65E, 66E, 67E, and 68E), ACC-28E ADC
boards, ACC-36E and ACC-59E boards, and serial-encoder interface boards such as ACC-84E.
Each board in this class has a 4-point DIP switch SW1 that sets its address location in this space
and its IC index i. No two boards in this class can have the same setting, or there will be an
addressing conflict.
The following table shows the IC index numbers and base address offset (from the start of I/O
space at Sys.piom) of the board for UMAC I/O-type boards for all of the SW1 switch settings:
Addressing
These boards are mapped as “I/O” boards on the Compact UMAC backplane. They share an
addressing space with other Compact UMAC ACC-11C digital I/O boards, and ACC-84C serial-
encoder interface boards. Each board in this class has a 4-point DIP switch SW1 that sets its
address location in this space and its IC index i. No two boards in this class can have the same
setting, or there will be an addressing conflict.
Refer to the table “Power PMAC UMAC I/O Board Indices and Addresses” in the section
above on UMAC I/O boards to see how the switch settings correspond to IC index numbers and
I/O address offsets.
Addressing
These boards are mapped as “MACRO” boards on the UMAC backplane. Each board in this class
has a 4-point DIP switch SW1 that sets its address location in this space. No two boards in this
class can have the same setting, or there will be an addressing conflict.
On re-initialization, Power PMAC automatically maps the “DSPGATE2” ICs on the detected
ACC-5E boards based on the order of SW1 settings for the boards. The first IC on the ACC-5E
with the lowest SW1 setting is assigned to Acc5E[0]. If the optional second IC is present on this
board, it is assigned to Acc5E[1]. Note that the digital I/O on an ACC-5E only uses the first IC.
If there are additional ACC-5E boards detected, the ICs on these boards are assigned Acc5E[i]
index values in consecutive order, whether one or two ICs are present per board.
Direction Selection
On the ACC-5E3, if jumper E1 connects pins 1 and 2, the buffer IC is configured so that GPIO00
– GPIO07 can be used as outputs. If E1 connects pins 2 and 3, the buffer IC is configured so that
GPIO00 – GPIO07 can be used as inputs.
If jumper E2 connects pins 1 and 2, the buffer IC is configured so that GPIO08 – GPIO15 can be
used as outputs. If E2 connects pins 2 and 3, the buffer IC is configured so that GPIO08 –
GPIO15 can be used as inputs. (Software configuration for direction control in the ASIC is
required as well. This is covered in the next section.)
Addressing
The UMAC ACC-5E3 board is mapped as a “PMAC3” board on the UMAC backplane. It shares
an addressing space with other ACC-5E3 boards, ACC-24E3 servo interface boards and ACC-
59E3 ADC/DAC boards. Each board in this class has a 4-point DIP switch SW1 that sets its
address location in this space and its IC index i. No two boards in this class can have the same
setting, or there will be an addressing conflict.
The following table lists the possible switch settings for UMAC boards based on the PMAC3-
style “DSPGATE3” ASIC such as the ACC-5E3, along with the IC index numbers and base
address offsets (from the start of I/O space) they select. The ON/OFF polarity of the switches for
index number selection is the opposite of older boards.
The element indices and addresses of the I/O points are fixed on the Power Brick. No hardware
addressing setup is required.
Jumpers E14 – E17 on the Power Clipper specify the direction of the 4 byte-wide buffers. If the
jumper is ON, the buffer is configured for inputs; if it is OFF, the buffer is configured for outputs.
In addition, there is software setup of the ASIC required as well to set the directions at the ASIC.
(This is explained in the next section.) The jumpers and the I/O points they affect are:
If Delta Tau’s Clipper Interface board is used, these 32 I/O points can be used as 16 inputs and 16
outputs, all isolated, all sinking or sourcing by user connection choice. The E14 – E17 jumpers
must be in their default settings in this case.
The element indices and addresses of the I/O points are fixed on the Power Clipper, with separate
indices and addresses for the base and piggyback boards.
The ACC-34 boards connect to the Power PMAC system through an 8-input/8-output 5V
CMOS/TTL-level I/O port, with the I/O points on the ACC-34(s) accessed in a serial multiplexed
fashion. Up to 32 ACC-34 boards can be daisychain-connected on a single Power PMAC port.
Each board on a chain must have a separate address on that chain as set by the 5-point DIP-
switch, which specifies the board’s multiplexing index n, where n = 0 to 31.
ACC-34 boards are accessed serially through a background software task. They should not be
used for any I/O that requires a quick (low-latency) response time.
The following table shows how SW1 on the ACC-34x should be set for one or more ACC-34x
boards connected to the same PMAC.
The JTHW ports on the UMAC ACC-5E board and on the Power Clipper boards can be used
with a direct flat-cable connection to an ACC-34 board. Other ports can be used as well with
custom cabling.
These boards have 48 I/O points organized as two hardware ports (A and B) and 6 byte-wide
software data registers (indices j = 0 to 5). Port A, brought out on the top edge of the card, uses
data registers with indices 0 to 2. Port B, brought out on the bottom edge of the card, uses data
registers with indices 3 to 5.
Each UMAC I/O board has a saved initialization sub-structure GateIo[i].Init (or AccxxE[i].Init).
The values in this sub-structure are automatically copied to the active control registers in the
ASIC on power-on/reset. If the value of an element in this sub-structure is changed, save and
reset operations must be performed before the value takes effect in the active registers.
The following are the suggested settings for the UMAC general-purpose I/O boards.
Direction Control
GateIo[i].Init.CtrlReg should be set to $3F to disable outputs on all 6 byte-wide registers (both
Ports A and B) for the ACC-66E 48-input board, and for an ACC-14E being used for all inputs.
This is the re-initialization default value for the ACC66E and ACC-14E. (It is not absolutely
necessary to disable outputs on pins used for inputs, but if the outputs are not disabled, a write
operation that turns on an output will “override” the input value on that pin.)
GateIo[i].Init.CtrlReg should be set to $07 to disable outputs the first three byte-wide registers
(just Port A) for the ACC-65E and ACC-68E 24-input/24-output boards, and for an ACC-14E
being used for inputs on Port A and outputs on Port B. This is the re-initialization default value
for the ACC-65E and ACC-68E, but not for the ACC-14E.
GateIo[i].Init.CtrlReg should be set to $00 to enable outputs on all 6 byte-wide registers (both
Ports A and B) for the ACC-67E 48-output board, and for an ACC-14E being used for all outputs.
This is the re-initialization default value for the ACC-67E, but not for the ACC-14E.
Inversion Control
GateIo[i].Init.DataReg64[j] (j = 0 to 5) sets the inversion-control value for each bit of the byte-
wide register GateIo[i].DataReg[j], whether the I/O point is used as an input or an output. The
default value of 0 in the control bit sets the I/O point as “inverting” into or out of the ASIC itself.
In this setting, if the input to the IC is pulled low, the processor will read a 1 in the input bit. If the
open-collector output on the line is commanded by a value of 1, it will turn on and pull low.
On the ACC-65E, 66E, 67E, and 68E, where there is isolation and buffering between the IC and
the outside world, the “inverting” setting means that a 0 represents a non-conducting state on the
input or output, and a 1 represents a conducting state. That is, writing a 1 to an output bit causes
the output transistor, whether sinking or sourcing, to turn on and conduct. Similarly, when a
circuit driving an input causes current to conduct in the opto-isolator in either direction, the
processor will read a 1 in the input bit.
This “inverting” setting is strongly recommended for these I/O cards, both because it matches the
intuitive sense of most users that a logical “1” means “ON” – that is, conducting, and because it is
more fail-safe, in that a failure of the Power PMAC such as a watchdog timer trip will turn
outputs off. For this setting, GateIo[i].Init.DataReg64[j] (j = 0 to 5) should be set to $00.
On the ACC-14E, the I/O points of the IOGATE ASIC are directly exposed to the outside world,
each with a 3.3-kohm pull-up resistor to +5V. In the “inverting” setting, the input must actively
be pulled low for the processor to read a 1; if it is not, the pull-up resistor will bring the input to a
high state and the processor will read a 0. A command value of 1 will turn on the open-collector
output, pulling the output voltage low; a command value of 0 will turn off the open-collector
output, allowing the pull-up resistor to bring the output to a high state.
On the ACC-14E, this default “inverting” setting is strongly recommended if the accessory is
used with Opto-22, Grayhill, or similar I/O modules.
(When using the ACC-14E for direct interface to TTL logic, as with parallel-data servo feedback,
often the non-inverting setting will be used. For the non-inverting setting,
GateIo[i].Init.DataReg64[j] (j = 0 to 5) should be set to $FF for the byte.)
Read Control
GateIo[i].Init.DataReg128[j] (j = 0 to 5) determines what state is reported for each bit when the
byte-wide register is read by the processor. Its action is dependent on the setting of the matching
bit in GateIo[i].Init.DataReg192[j] (see below).
If the matching bit of DataReg192[j] is 0 (no latching), as is typical for general-purpose I/O use,
when the bit of DataReg128[j] is set to 0, the state reported comes from the voltage of the pin at
that moment. This is the setting that should be used for any general-purpose input point. For a
general-purpose output point, this setting allows the user to confirm whether the commanded
output level has actually occurred.
If the matching bit of DataReg192[j] is 0, when the bit of DataReg128[j] is set to 1, the state
reported comes from the last value written to the bit. This is not desirable for an input point, but
for an output point, it allows the user to confirm what the last software action was.
If the matching bit of DataReg192[j] is 1 (latched inputs), when the bit of DataReg128[j] is set
to 0, the state reported is that of the input at the most recent falling edge of the selected clock
(phase or servo). If you want to read latched inputs for general-purpose I/O, you should use this
setting.
If the matching bit of DataReg192[j] is 1, when the bit of DataReg128[j] is set to 1, the state
reported is that derived from the input word at the most recent falling edge of the selected clock
Latch Control
GateIo[i].Init.DataReg192[j] (j = 0 to 5) determines what value is reported for each bit when the
byte-wide register is read by the processor. If the bit is set to 0, the “transparent” value at the
moment of the read operation is reported. If the bit is set to 1, the value latched at the most recent
falling edge of the selected clock (phase or servo as selected by jumper E2 on the board) is read.
For each setting of DataReg192[j], the setting of DataReg128[j] determines which transparent or
latched value is read, as described in the preceding section.
Acc11C[i].Init.CtrlReg = $07
Acc11C[i].Init.DataReg0 = $00
Acc11C[i].Init.DataReg64 = $00
Acc11C[i].Init.DataReg128 = $00
Acc11C[i].Init.DataReg192 = $00
The I/O24 – I/O31 and DISP0 – DISP7 lines are always configured as general-purpose outputs,
so the settings for these groups are not actually necessary.
The index j for the Cid[j] data structure can be found in the “UMAC Addressing Summary” table
in the “Power PMAC I/O Address Offsets” chapter of the Software Reference Manual.
For Acc5E[0], by far the most common setting used, Cid[4] is used. For Acc5E[1], Cid[20] is
used. For Acc5E[2], Cid[36] is used. For Acc5E[3], Cid[52] is used.
For example, on Acc5E[0], to set I/O00 – I/O15 buffers for inputs, I/O16 – I/O31 buffers for
outputs, DAT0 – DAT7 buffer for inputs, SEL0 – SEL7 buffer for outputs, and DISP0 – DISP7
for outputs, the following command lines could be used (on-line or Script program):
A value of 0 in the bit sets the point for input; a value of 1 in the bit sets the point for output.
To continue the above example, on Acc5E[0], to set I/O00 – I/O15 as inputs, I/O16 – I/O31 as
outputs, DAT0 – DAT7 as inputs, SEL0 – SEL7 as outputs, and DISP0 – DISP7 as outputs, the
following settings should be made:
Acc5E[0].LowIoDir=$FF0000
Acc5E[0].HighIoDir=$FF
Acc5E[0].MuxDir=$FF00
Acc5E[0].DispDir=$FF
To use the JTHW port with DAT0 – DAT7 and SEL0 – SEL7 to interface to one or more ACC-
34 family boards through a standard flat cable, Acc5E[0].MuxDir should be set to $FF00 as in
this example.
If the control bit is 0, the point is non-inverting, and a value of 1 corresponds to a high voltage at
the I/O point on the ASIC. If the control bit is 1, the point is inverting and a value of 1
corresponds to a low voltage at the I/O point on the ASIC.
To set I/O00 – I/O31 as inverting, DAT0 – DAT7 and SEL0 – SEL7 as non-inverting, and DISP0
– DISP7 as inverting, the following settings should be made:
Acc5E[0].LowIoPol=$FFFFFF
Acc5E[0].HighIoPol=$FF
Acc5E[0].MuxPol=$0000
Acc5E[0].DispPol=$FF
To use the JTHW port with DAT0 – DAT7 and SEL0 – SEL7 to interface to one or more ACC-
34 family boards through a standard flat cable, Acc5E[0].MuxPol should be set to $0000 as in
this example.
Direction Control
Bit n of Acc5E3[i].GpioDir[0] sets the direction of I/O point GPIOn at the ASIC. Although each
I/O point in the ASIC is individually selectable as to direction, because the buffer ICs are jumper-
selectable as to direction, the direction of ASIC I/O points must be specified in groups of 8. The
directions are set with Acc5E3[i].GpioDir[0]. The useful settings are:
The setting of $FF00 permits this I/O port to be used to interface to one or more ACC-34
multiplexed I/O boards. The setting of the high 16 bits of this 32-bit element does not matter here.
Polarity Control
Bit n of Acc5E3[i].GpioPol[0] sets the polarity of I/O point GPIOn, whether it is used as an input
or an output. If the bit is 0, non-inverting I/O is selected, so that a 0 value corresponds to a low
voltage at the port, and a 1 value corresponds to a high voltage. If the bit is 1, inverting I/O is
selected, so that a 0 value corresponds to a high voltage at the port, and a 1 value corresponds to a
low voltage.
To use this port to interface to ACC-34 multiplexed I/O port, all input and output points should be
non-inverting, so Acc5E3[i].GpioPol[0] should be set to $0000.
The I/O bank is configured with several saved setup elements for the ASIC. These elements are
write-protected; to change their values with Script commands, Sys.WpKey should first be set to
$AAAAAAAA.
Direction Control
For each set of I/O, PowerBrick[i].GpioDir[0] must be set to $00FF0000 to set the low 16 bits
of the associated data word as inputs and the next 8 bits as outputs. (The highest 8 bits of the 32-
bit bank are set as inputs for other purposes.) This is the default value set at re-initialization.
Polarity Control
For each set of I/O, PowerBrick[i].GpioPol[0] should be set to $00000000 to select non-
inverting I/O so that a 0 value represents an OFF (non-conducting) state, and a 1 represents an
ON (conducting) state, whether the I/O point is used in a sinking or sourcing mode. In the non-
inverting mode, the outputs will automatically be turned off if the controller goes into a reset or
watchdog state. This is the default value set at re-initialization.
The I/O bank is configured with several saved setup elements for the ASIC. These elements are
write-protected; to change their values with Script commands, Sys.WpKey should first be set to
$AAAAAAAA.
Direction Control
While the direction of the I/O points is selectable by bit from the ASIC itself, the direction of the
buffer ICs is only selectable in byte-wide sections using jumpers E14 – E17 (ON for inputs, OFF
for outputs). If Delta Tau’s Clipper breakout board is used, two of these byte-wide sections must
be used as inputs and two as outputs.
The 32-bit saved setup element Clipper[i].GpioDir[0] sets the direction of the 32 general
purpose I/O points. The element is organized as follows:
For the case where Delta Tau’s Clipper Breakout board is used, Clipper[i].GpioDir[0] must be
set to $00FFFF00. The last two hex digits at $00 set the DAT0 – DAT7 lines as inputs. The
preceding two hex digits at $FF set the SEL0 – SEL7 lines as outputs. The earlier two hex digits
at $FF set the MO1 – MO8 lines as outputs. The first two hex digits at $00 set the MI1 – MI8
lines as inputs.
Polarity Control
The 32-bit saved setup element Clipper[i].GpioPol[0] sets the polarity of the 32 general-purpose
I/O points, whether they are used as inputs or outputs. The bits of the element are organized in the
same way as the direction control documented immediately above. If the bit is 0, non-inverting
I/O is selected, so that a 0 value corresponds to a low voltage at the port of the Clipper, and a 1
value corresponds to a high voltage. If the bit is 1, inverting I/O is selected, so that a 0 value
corresponds to a high voltage at the port of the Clipper, and a 1 value corresponds to a low
voltage.
For the case where Delta Tau’s Clipper Breakout board is used, Clipper[i].GpioPol[0] should be
set to $00000000 to select non-inverting I/O, whether the I/O point is used in a sinking or
sourcing mode. This means that a 0 corresponds to a non-conducting state, and a 1 corresponds to
a conducting state. In the non-inverting mode, the outputs will automatically be turned off if the
controller goes into a reset or watchdog state.
The address of the Power PMAC port to use for inputs from ACC-34 boards is specified by
MuxIo.pIn. The bit of this register on the 32-bit data bus on which the input data is transferred
serially is specified by MuxIo.InBit. This Power PMAC port must be set up for non-inverting
inputs.
If ACC-34AA boards are (all) jumpered to use DAT7 for transferring input data to the controller
(which reduces crosstalk with the clock on the flat cable), MuxIo.InBit should be set to 15
instead. This hardware and software configuration can only be used if there are only ACC-34AA
boards on the port.
If ACC-34AA boards are (all) jumpered to use DAT7 for transferring input data to the controller,
MuxIo.InBit should be set to 7 instead. This hardware and software configuration can only be
used if there are only ACC-34AA boards on the port.
If ACC-34AA boards are (all) jumpered to use DAT7 for transferring input data to the controller
(which reduces crosstalk with the clock on the flat cable), MuxIo.InBit should be set to 7 instead.
This hardware and software configuration can only be used if there are only ACC-34AA boards
on the port.
If the parity checking is enabled and a parity error is detected in a transfer, the 32-bit input value
received is not copied into its image word in Power PMAC memory (MuxIo.PortA[n].Data),
and the last scan’s value will remain in the image word. Whether or not this software function is
enabled, the hardware parity check is performed, and the result of the check can be found in
status bit MuxIo.PortA[n].ParityStatus, where 0 indicates a parity error.
On the Delta Tau ACC-34 boards, hardware parity checking is automatically performed on the
enabled output ports, and the 32-bit output value received by the board is not latched into the
actual output circuits if a parity error is detected. No special software setup is required for this.
Status bit MuxIo.PortB[n].ParityStatus is 0 if a parity error has been detected on the most
recent transfer.
Saved setup element MuxIo.UpdatePeriod specifies how often Power PMAC communicates
with enabled ACC-34 ports. If it is set to 0, communications is in “one-shot” mode. In this mode,
after communicating with each enabled port, the Enable element for that port is automatically
cleared to 0.
The overall activation element MuxIo.Enable should not be confused with the individual board
port activation elements MuxIo.PortA[n].Enable and MuxIo.PortB[n].Enable.
If a lower-priority task has started this multi-step operation, but is interrupted by a higher-priority
task that executes this multi-step operation on the same register, when the lower-priority task
resumes, it will undo the changes made by the higher-priority task. The chances of this occurring
on any given interrupt are small, but given the thousands of interrupts occurring per second, the
chances of this happening eventually (if not protected against) are very large, and the intermittent
nature of the problem can make it very hard to track down.
In the Script environment, whenever a “partial-word” element or variable is written to, the Script
execution engine automatically performs this read/modify/write sequence invisibly to the user. In
the C environment, the user code must perform this sequence explicitly.
Real-time interrupt: RTI Script PLCs, RTI C PLC, motion programs, synchronous
variable assignments
Different tasks operating at the same priority level cannot interrupt each other, and so do not
present this problem.
If the application needs to write to outputs at multiple priority levels, the best solution is to use
different output registers for different priority levels. This will avoid the problem altogether. If
this is not feasible, the user application must protect against this problem explicitly.
Process-Locking Mechanism
The Power PMAC Script environment has a special process-locking mechanism for this purpose.
It supports 32 separate processes, permitting the user application to transfer control of each
process robustly between tasks at different priority levels.
When a Script command reads the Boolean element Sys.Lock[i] (i = 0 to 31), if it reads a 1 value,
it knows that the process is “locked” by another task. If it reads a 0, it knows that the process is
not locked, and so is available to it. But the very act of reading the element this way and seeing a
0 value also sets the bit to 1 in an uninterruptible “atomic” operation, automatically giving this
routine control of the process.
One common way this can be used is shown in the following Script code example:
It is possible to monitor the status of a process without the possibility of taking control of it by
reading 32-bit status element Sys.Lock and evaluating the state of bit i for process i.
The following table shows how each 8-bit element corresponds to the signal pins on each of the
UMAC digital I/O boards:
Once the assignment is made, the application can use the declared variable name in the
application.
It is also possible to assign an M-variable to a bit or bits of the 32-bit register using the address of
the register rather than the element name. For the standard digital I/O boards, this does not
provide additional capabilities, but for older I/O boards such as the ACC-11E, this is the only way
of accessing the registers in the board. The byte-wide data registers are found in bits 8 – 15 of the
32-bit bus.
To replicate the above definitions in this method, the assignments would be:
These declare that the variable is an unsigned integer (u) in I/O (io) space. In this assignment,
the six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $C00 in the first example, are dependent on the accessory index alone,
as the base address offset of the I/O IC with index 2 is $C00000. The last three hex digits are
dependent on the offset of the register from the IC base index ($014 for DataReg[5]).
The first digit after the address is the starting bit number of the variable on the 32-bit bus. Note
that this value is 8 greater than the value of the starting bit in the pre-defined data structure
element, because the element itself starts at bit 8 on the 32-bit bus.
The second digit after the address specifies the number of bits to use in the variable. If there is no
second digit, the declaration is for a 1-bit variable.
Refer to the above section on UMAC digital I/O boards to see how each 8-bit element
corresponds to the signal pins on the ACC-11C. The Compact UMAC ACC-11C correspondence
is the same as the ACC-65E and 68E UMAC boards.
On the JIO port, the 24 lines I/O00 – I/O23 can be accessed through the Acc5E[i].LowIoData
element. Individual bits on the port can be accessed with Acc5E[i].LowIoData.k (k = 0 to 23).
Bits 0 to 23 correspond to I/O00 – I/O23 lines, respectively.
Also on the JIO port, the 8 lines I/O24 – I/O31 can be accessed through the
Acc5E[i].HighIoData element. Individual bits on the port can be accessed with
Acc5E[i].HighIoData.k (k = 0 to 7). Bits 0 to 7 correspond to I/O24 – I/O31 lines, respectively.
On the JDISP port, the 8 lines DISP0 – DISP7 can be accessed through the Acc5E[i].DispData
element. Individual bits on the port can be accessed with Acc5E[i].DispData.k (k = 0 to 7). Bits 0
to 7 correspond to DISP0 – DISP7 lines, respectively.
Once the assignment is made, the application can use the declared variable name in the
application.
Once the assignment is made, the application can use the declared variable name in the
application.
The IC index i is 0 for the first set of I/O points, which comes with the first four axes. It is 1 for
the second set of I/O points, which comes with the second four axes. The bit index k is 0 to 15 for
the 16 inputs, and 16 to 23 for the 8 outputs, of a set.
So for the first set of I/O points, inputs GPIN01 to GPIN16 correspond to
PowerBrick[0].GpioData[0].0 to .15, respectively. (Note that the bit number is one less than the
hardware channel number.) In this set, GPOUT01 to GPOUT08 correspond to
PowerBrick[0].GpioData[0].16 to .23, respectively.
For the second set of I/O points, inputs GPIN17 to GPIN32 correspond to
PowerBrick[1].GpioData[0].0 to .15, respectively. In this set, GPOUT09 to GPOUT16
correspond to PowerBrick[1].GpioData[0].16 to .23, respectively.
Once the assignment is made, the application can use the declared variable name in the
application.
The IC index i is 0 for the set of I/O points on the base board. It is 1 for the set of I/O points on
the piggyback board.
The bit index k is 0 to 7 for the DAT0 – DAT7 lines, respectively. It is 8 to 15 for the SEL0 –
SEL7 lines, respectively. It is 16 to 23 for the MO1 – MO8 lines, respectively. It is 24 to 31 for
the MI1 – MI8 lines, respectively.
Once the assignment is made, the application can use the declared variable name in the
application.
The data structure elements for these image words are MuxIo.PortA[n].Data and
MuxIo.PortB[n].Data, where n (= 0 to 31) is the index for the board as set by the DIP switches
on the board. With standard ACC-34 boards, Port A is always an input port and Port B is always
an output port, but it is possible to use boards where this is not the case.
These elements are 32-bit unsigned integers, with their bits 0 to 31 corresponding to I/O points 0
to 31 on the matching hardware point. Individual bits of the element, and so matching individual
I/O points, can be accessed with MuxIo.PortA[n].Data.k and MuxIo.PortB[n].Data.k, where k
is the bit number. Consecutive sets of bits can be accessed with MuxIo.PortA[n].Data.k.l and
MuxIo.PortB[n].Data.k.l, where k is the starting bit number and l is the number of bits to access.
An M-variable can be assigned to the entire element, an individual bit of the element, or to a
consecutive set of bits. When the assignment is made through the IDE, an application-specific
name can be given to the variable. For example:
The user is not required to use this functionality to work with inputs and outputs. It is possible to
access the actual input and output registers directly at any time, which can be done instead of this
buffered process, or in addition to it.
With this functionality, up to 64 user-specified input registers can be read at the beginning of
each scan and copied into input holding registers. Input bits can be digitally filtered for
“debouncing” purposes, so that multiple consecutive scans in the new state are required before
the corresponding bit in the holding register changes.
When the bit in the holding register does change in a scan, a corresponding bit in a “rise” or “fall”
register is automatically set to make it easy for user algorithms to act on the edge. Bit values in
the input register can be overridden by values in “forcing” registers, allowing for easy simulation
and debugging.
Up to 64 user-specified output registers can be written to at the end of each scan, copied from
output holding registers.
I/O can be scanned each real-time interrupt (RTI) cycle for use in foreground Script PLC
programs, or each background cycle for use in background Script PLC programs. It is possible to
scan some I/O in the RTI and some in background. The timing of this I/O scanning may not be
useful for C PLC programs, either foreground or background, particularly with regard to the
rising and falling edge detection.
This diagram shows a block diagram for the process of using buffered I/O in the Power PMAC:
BufIo[i]. BufIo[i].
31 ForceInOn.j ForceOutOn.j 31
BufIo[i].
InScans Output Register
Input Register
BufIo[i]. BufIo[i].
0
pIn pOut
0 1 User Script
j
PLC
j 0 1 2 BufIo[i]. BufIo[i].
Programs
In.j Out.j
0 1 2 3
RiseIn.j
RiseInLatch.j
FallIn.j
0 BufIo[i]. BufIo[i]. 0
FallInLatch.j
ForceInOff.j ForceOutOff.j
This buffered I/O functionality is new in V2.1 firmware, released 1st quarter 2016.
If an element BufIo[i].pIn is set to its default value of 0, no input register is read for that index
value. Furthermore, no input register is read for any higher index value for that scan. Note,
however, that a value of 0 for a BufIo[i].pIn in the RTI scan range (i < Sys.MaxRtBufIn) does
not inhibit the use of elements with higher index values in the background scan range (i >=
Sys.MaxRtBufIn).
To specify the read of an input register, BufIo[i].pIn is set to the address of that register. This is
usually done by specifying the name of that element, followed by the “.a” (address of) suffix. For
example:
BufIo[1].pIn = Acc65E[2].Data[1].a
With an address specified and the function enabled, Power PMAC will copy the 32-bit value read
at this address into memory for further processing, with the end result in holding register
BufIo[i].In. This is a full 32-bit operation, even if there is not “real” data in all 32 bits. In the
above example, there is only input data in bits 8 to 15 of the ACC-65E data register, so there will
only be real data in bits 8 to 15 of the 32-bit holding register.
With this configuration, the registers specified by BufIo[0].pIn, BufIo[1].pIn, and BufIo[2].pIn
would be read at the start of each RTI scan. Since BufIo[3].pIn is set to 0, the RTI scan inputs
stop here. BufIo[4].pIn and BufIo[5].pIn are not used, even though Sys.MaxRtBufIn is set to 6.
With Sys.MaxRtBufIn set to 6, background scan inputs start with index value 6. So the registers
specified by BufIo[6].pIn and BufIo[7].pIn are read at the start of each background scan. Since
BufIo[8].pIn is set to 0, the background scan inputs stop here. BufIo[9].pIn and higher are not
used, even if set to non-zero values.
Most commonly, the input registers specified are those of actual hardware inputs. However, it is
also possible to specify a few classes of memory registers: motor, coordinate-system, and global
status registers, or mapped network input registers, such as EtherCAT data registers and MuxIo
data registers.
Note that all enabled input registers are read every scan, regardless of whether the PLC programs
use any data in those registers. If these are hardware registers, which have a much longer access
time than memory registers, it is possible that unneeded reads can add significant computational
time. However, using a single read of the entire hardware input register, followed by multiple
reads of the holding register in memory to access individual bits, can provide a significant time
savings.
This forcing capability is useful for simulation, testing, and debugging purposes. It will not often
be used in the actual application execution.
Because leaving an input forced to an “on” or “off” state at the end of a debugging session can
prevent proper normal operation of a machine, Power PMAC provides special status words that
permit a quick and easy check to see if any input bits remain forced. Sys.FgForceInOr contains
the logical OR of all of the forcing words for the buffered inputs scanned each foreground cycle.
Sys.BgForceInOr contains the logical OR of all of the forcing words for the buffered inputs
scanned each background cycle. If either of these is non-zero, one or more input bits is being
forced.
Sys.ForceOr contains the logical OR of all of the forcing words for both inputs and outputs,
whether scanned in foreground or background. In normal operation, this should generally be zero.
The on-line command bufioforceclear clears all forcing bits for both buffered inputs and
outputs. Its use is strongly recommended after a debugging session to return to normal operation.
Resetting the Power PMAC also clears all forcing bits.
Filtering of Inputs
Sometimes electrical noise or pushbutton “bounce” creates a false edge, and it can be difficult for
users to distinguish these false transitions from real ones. Power PMAC’s scanned cyclic input
function provides an automatic function that makes it easy to filter out most of these false
transitions.
If BufIo[i].InScans is set to a value greater than 0, then a bit in the input register specified by
Sys.pBufIn[i] must be in its new state for multiple (InScans + 1) scans before that change is
reflected in the corresponding bit of resulting holding register BufIo[i].In. If BufIo[i].InScans is
set to it maximum value of 3, 4 consecutive scans of the new state are required.
This filtering function does not require any additional code in the application algorithms that use
the resulting bit value in BufIo[i].In. They do let the user have much greater confidence that their
algorithm is reacting to a real transition in the input instead of a spurious one. The user must be
aware of the delay in responding to a real transition that this filtering introduces, but in most
cases, this delay is not significant to the application.
All 32 bits in a single input word will have the same delay from the requirement for multiple
scans of this filtering function, but separate input words can have differing delays.
Resulting Registers
The 32-bit value at the address specified by BufIo[i].pIn will be transferred, possibly with
filtering, and possibly with some bits “forced”, into the shared memory holding register
BufIo[i].In. Bits of BufIo[i].In can be used directly in user Script PLC programs.
In addition to the “state” input bits in BufIo[i].In, Power PMAC automatically computes “edge”
bits for each input state bit, both transparent and latched. These bits make it easier to take action
on a transition of an input bit. Some users will prefer the transparent bits; others the latched bits.
If a bit of BufIo[i].In has changed from 0 to 1 in the most recent scan, Power PMAC will
automatically set the corresponding bit of transparent edge element BufIo[i].RiseIn to 1 for the
scan. If a bit of BufIo[i].In has changed from 1 to 0 in the most recent scan, Power PMAC will
automatically set the corresponding bit of BufIo[i].FallIn to 1 for the scan. Note that bits in these
elements are only true for a single scan, so the user algorithms must be checking these elements
every scan to be able to detect the edges.
When the assignment is made through the IDE, an application-specific name can be given to the
variable. For example:
When the assignment is made through the IDE, an application-specific name can be given to the
variable. For example:
This forcing capability is useful for simulation, testing, and debugging purposes. It will not often
be used in the actual application execution.
Because leaving an output forced to an “on” or “off” state at the end of a debugging session can
prevent proper normal operation of a machine, Power PMAC provides special status words that
permit a quick and easy check to see if any output bits remain forced. Sys.FgForceOutOr
contains the logical OR of all of the forcing words for the buffered outputs scanned each
foreground cycle. Sys.BgForceOutOr contains the logical OR of all of the forcing words for the
buffered outputs scanned each background cycle. If either of these is non-zero, one or more
output bits is being forced.
Sys.ForceOr contains the logical OR of all of the forcing words for both inputs and outputs,
whether scanned in foreground or background. In normal operation, this should generally be zero.
The on-line command bufioforceclear clears all forcing bits for both buffered inputs and
outputs. Its use is strongly recommended after a debugging session to return to normal operation.
Resetting the Power PMAC also clears all forcing bits.
If an element BufIo[i].pOut is set to its default value of 0, no output register is written to for that
index value. Furthermore, no output register is written to for any higher index value for that scan.
Note, however, that a value of 0 for a BufIo[i].pOut in the RTI scan range (i <
Sys.MaxRtBufOut) does not inhibit the use of elements with higher index values in the
background scan range (i >= Sys.MaxRtBufOut).
To specify the writing of an output register, BufIo[i].pOut is set to the address of that register.
This is usually done by specifying the name of that element, followed by the “.a” (address of)
suffix. For example:
BufIo[i].pOut = Acc68E[1].Data[5].a
With an address specified and the function enabled, Power PMAC will copy the 32-bit value
result in holding register BufIo[i].Out to the register specified at this address at the end of each
scan. This is a full 32-bit operation, even if there is not “real” data in all 32 bits. In the above
example, there is only output circuitry in bits 8 to 15 of the ACC-68E data register, so there will
only be useful data in bits 8 to 15 of the 32-bit holding register.
With Sys.MaxRtBufOut set to 6, background scan outputs start with index value 6. So the
registers specified by BufIo[6].pOut and BufIo[7].pOut are written to at the end of each
background scan. Since BufIo[8].pOut is set to 0, the background scan outputs stop here.
BufIo[9].pOut and higher are not used, even if set to non-zero values.
If you need to access the same input word multiple times for different tasks and need to make
sure the same word value is used each time, you should read the actual input register only once,
copying it to an image in a software variable, then access this software variable multiple times.
This is both more robust and faster to execute.
The variable declarations for general-purpose digital I/O will look like:
These declared variables can then be assigned to particular ICs with function calls in program
statements like the following. These must be executed every time the Power PMAC is started up.
The returned value of the function is the base address of the IC (whose numerical value does not
usually need to be known by the user). If the IC is not found, a NULL value is returned.
Using this technique, the variable declarations for the base IC pointers will look like:
int MyFirstGate2Adr;
int MySecondGate3Adr;
int MyFourthIOICAdr;
The base IC pointer variables are then assigned to the ICs using Power PMAC’s address auto-
detection elements. This can be done with program statements like the following. For global
variables, these must be executed once each time the Power PMAC is started up. For local
variables, these must be executed every time the routine is entered.
These variables will contain the non-zero base address offset of the IC if it has been detected.
They will contain a zero value if it has not been detected.
Next, the address of each individual register must be computed as the sum of the pointer to I/O
memory (piom), the base address offset of the IC computed above, and the offset of the register
in the IC from its base. These offsets are given for all ICs in the Software Reference Manual
chapter “Power PMAC ASIC Register Element Addresses”. Register offsets for specific general
purpose I/O are given in sections below.
The register pointer variables can be computed with program statements like the following. For
global variables, these must be executed once each time the Power PMAC is started up. For local
variables, these must be executed each time the routine is entered.
The “shift-right 2” (>> 2) operation converts the “byte addressing” of the offset values into the
“word addressing” that the program requires. This effective division by 4 reflects the fact that
there are 4 bytes per 32-bit word.
Once these pointer variables are properly assigned to addresses, the values in them can be
accessed.
To copy the 3 8-bit input values from the first three data registers of the I/O card defined above
into the low 24 bits of a 32-bit integer software variable, the following code could be used.
To copy the low 24 bits of a 32-bit integer software variable into 3 8-bit output values of the last
three data registers of the I/O card defined above, the following code could be used.
The following table shows the byte address offset of each data register in the UMAC I/O boards.
So pointers to the 6 data registers of a single UMAC card could be defined as follows:
int MyFourthIOICAdr;
volatile int *MyFourthIODataReg0;
volatile int *MyFourthIODataReg1;
volatile int *MyFourthIODataReg2;
volatile int *MyFourthIODataReg3;
volatile int *MyFourthIODataReg4;
volatile int *MyFourthIODataReg5;
...
To copy the 3 8-bit input values from the first three data registers of the I/O card defined above
into the low 24 bits of a 32-bit integer software variable, the following code could be used.
To copy the low 24 bits of a 32-bit integer software variable into 3 8-bit output values of the last
three data registers of the I/O card defined above, the following code could be used.
The element MyFirstGate2IC->LowIoData has real data in bits 08 – 31 of the 32-bit bus,
corresponding to signals I/O00 – I/O23, respectively.
To isolate the value of the bit corresponding to signal I/O02 (bit 10) in the LowIoData register
into a software variable, the following code could be used:
The element MyFirstGate2IC->HighIoData has real data in bits 08 – 15 of the 32-bit bus,
corresponding to signals I/O24 – I/O31, respectively.
To set the bit of the HighIoData register corresponding to signal I/O30 (bit 14), the following
code could be used:
MyFirstGate2IC->HighIoData |= 0x4000;
The element MyFirstGate2IC->MuxData has real data in bits 8 – 23 of the 32-bit bus,
corresponding to signals DAT0 – DAT7 and SEL0 – SEL7, respectively.
To copy the value of a Boolean variable into the bit of the MuxData register corresponding to
signal SEL1 (bit 17), the following code could be used:
The element MyFirstGate2IC->DispData has real data in bits 08 – 15 of the 32-bit bus,
corresponding to signals DISP0 – DISP7, respectively.
To copy the value of a full byte to the bits of the DispData register corresponding to signals
DISP0 – DISP7 (bits 8 – 15), the following code could be used:
The following table shows the byte address offset of each data register in the ACC-5E.
So pointers to the 4 data registers of a single ACC-5E card could be defined as follows:
int MyFirstGate2Adr;
volatile int *MyFirst5ELowIoData;
volatile int *MyFirst5EHighIoData;
volatile int *MyFirst5EMuxData;
volatile int *MyFirst5EDispData;
...
MyFirstGate2Adr = pshm->OffsetGate2[0]; // Gate2[0]
MyFirst5ELowIoData = (int *) piom + (MyFirstGate2Adr >> 2);
MyFirst5EHighIoData = (int *) piom + ((MyFirstGate2Adr + 0x04) >> 2);
MyFirst5EMuxData = (int *) piom + ((MyFirstGate2Adr + 0x08) >> 2);
MyFirst5EDispData = (int *) piom + ((MyFirstGate2Adr + 0x0C) >> 2);
To isolate the value of the bit corresponding to signal I/O02 (bit 10) in the LowIoData register
into a software variable, the following code could be used:
To set the bit of the HighIoData register corresponding to signal I/O30 (bit 14), the following
code could be used:
*MyFirst5EHighIoData |= 0x4000;
To copy the value of a Boolean variable into the bit of the MuxData register corresponding to
signal SEL1 (bit 17), the following code could be used:
To copy the value of a full byte to the bits of the DispData register corresponding to signals
DISP0 – DISP7 (bits 8 – 15), the following code could be used:
For I/O points in this hardware element set up as outputs, it is not possible to read back the values
that have been written to the element. For this reason, there is a matching software element
Gate3PartData[i].GpioOutData[0] (Gate3[i].GpioOutData[0] in the Script environment) that
can contain an image of the outputs in the hardware element. Because values written to this
element can be read back, it can be used for manipulation of individual output points through
read/modify/write operations, with the entire element value then copied to the hardware element.
(This does not affect the reported value of inputs in the hardware register.) The Script
environment does this automatically; it can be done through explicit program statements in C.
The element MySecondGate3IC->GpioData[0] has real data for the ACC-5E3 JIO port in
bits 0 – 15 of the 32-bit bus.
To set the bit in the GpioData[0] register corresponding to I/O12 (bit 12), the following code
could be used:
To isolate the value of the bit corresponding to signal I/O05 (bit 5) in the GpioData[0] register
into a software variable, the following code could be used:
So pointers to the I/O data register of an ACC-5E3 card could be defined as follows:
int MySecondGate3Adr;
volatile int *MySecond5E3GpioData;
...
MySecondGate3Adr = pshm->OffsetGate3[1]; // Gate3[1]
MySecond5E3GpioData = (int *) piom + ((MySecondGate3Adr + 0x250) >> 2);
To clear the bits in the GpioData[0] register corresponding to I/O08 and I/O09 (bits 8 and 9), the
following code could be used:
To isolate the value of the bit corresponding to signal I/O03 (bit 3) in the GpioData[0] register
into a software variable, the following code could be used:
The 8-axis Power Brick has a second 24-bit general-purpose digital I/O port that is mapped into
the Gate3[1].GpioData[0] element. The 16 inputs are mapped into the low 16 bits (00 – 15) of
the element; the 8 outputs are mapped into the next 8 bits (16 – 23).
For I/O points in this hardware element set up as outputs, it is not possible to read back the values
that have been written to the element. For this reason, there is a matching software element
Gate3PartData[i].GpioOutData[0] (Gate3[i].GpioOutData[0] in the Script environment) that
can contain an image of the outputs in the hardware element. Because values written to this
element can be read back, it can be used for manipulation of individual output points through
read/modify/write operations, with the entire element value then copied to the hardware element.
(This does not affect the reported value of inputs in the hardware register.) The Script
environment does this automatically; it can be done through explicit program statements in C.
So data structures for the ICs in an 8-axis Power Brick can be defined as shown above:
To set the bit in the first IC’s GpioData[0] register corresponding to GPOUT07 (bit 22), the
following code could be used:
To isolate the value of the bit corresponding to signal GPIN27 (bit 10) in the second IC into a
software variable, the following code could be used:
So pointers to the I/O data register of Power Brick ICs could be defined as follows:
...
MyFirstICAdr = pshm->OffsetGate3[0]; // Gate3[0]
MyFirstICGpioData = (int *) piom + ((MyFirstICAdr + 0x250) >> 2);
MySecondICAdr = pshm->OffsetGate3[1]; // Gate3[1]
MySecondICGpioData = (int *) piom + ((MySecondICAdr + 0x250) >> 2);
To clear the bits in the GpioData[0] register corresponding to GPOUT02 and GPOUT03 (bits 17
and 18) in the first IC, the following code could be used:
To isolate the value of the bit corresponding to signal GPIN28 (bit 11) in the second IC into a
software variable, the following code could be used:
The optional 4-axis Power Clipper piggyback board has identical mapping of general-purpose
digital I/O ports and lines into the 32-bit Gate3[1].GpioData[0] element.
For I/O points in this hardware element set up as outputs, it is not possible to read back the values
that have been written to the element. For this reason, there is a matching software element
Gate3PartData[i].GpioOutData[0] (Gate3[i].GpioOutData[0] in the Script environment) that
can contain an image of the outputs in the hardware element. Because values written to this
element can be read back, it can be used for manipulation of individual output points through
read/modify/write operations, with the entire element value then copied to the hardware element.
(This does not affect the reported value of inputs in the hardware register.) The Script
environment does this automatically; it can be done through explicit program statements in C.
So data structures to the ICs in an 8-axis Power Clipper stack can be defined as shown above:
To set the bit in the first IC’s GpioData[0] register corresponding to SEL1 (bit 9) used as an
output, the following code could be used:
To isolate the value of the bit corresponding to signal MI3 (bit 26) in the second IC into a
software variable, the following code could be used:
So pointers to the I/O data register of Power Clipper ICs could be defined as follows:
...
MyFirstICAdr = pshm->OffsetGate3[0]; // Gate3[0]
MyFirstICGpioData = (int *) piom + ((MyFirstICAdr + 0x250) >> 2);
MySecondICAdr = pshm->OffsetGate3[1]; // Gate3[1]
MySecondICGpioData = (int *) piom + ((MySecondICAdr + 0x250) >> 2);
To clear the bits in the GpioData[0] register corresponding to MO05 and MO06 (bits 20 and 21)
in the IC on the base Clipper board, the following code could be used:
To isolate the value of the bit corresponding to signal MI2 (bit 25) in the piggyback Clipper board
into a software variable, the following code could be used:
In C, these are best accessed through their data structure element names:
pshm->MuxIo.PortA[n].Data and pshm->MuxIo.PortB[n].Data, where n (= 0 to
31) is the index for the board as set by the DIP switches on the board. With standard ACC-34
boards, Port A is always an input port and Port B is always an output port, but it is possible to use
boards where this is not the case. These elements are 32-bit unsigned integers, with their bits 0 to
31 corresponding to I/O points 0 to 31 on the matching hardware point.
To isolate the value of the bit corresponding to IN19 (bit 19) in the PortA[1].Data element into a
separate variable, the following code could be used:
To set the bit of the PortB[0].Data element corresponding to signal OUT10 (bit 10), the
following code could be used:
pshm->MuxIo.PortB[1].Data |= 0x00000400;
This chapter summarizes the general-purpose analog I/O capabilities of the Power PMAC family.
Another chapter does the same for general-purpose digital I/O More details can be found in the
manuals for specific controllers and I/O accessories. The chapter is organized as follows:
Refer to the manual for the particular hardware configuration to see how to set up and access
these dedicated I/O points. Remember that no active motor should be using any of these dedicated
outputs, or servo tasks could overwrite the general-purpose use of these points. It is generally
recommended that even the inputs should not be accessed by any active motor, because the
automatic motor status and safety checks could lead to unintended consequences.
Unipolar/Bipolar Configuration
On the ACC-28E, if jumper En (n = 1 to 4) for hardware channel ADCn connects pins 1 and 2 to
select unipolar conversion, then the range of input voltage difference (V[ADCn+] - V[ADCn-]) is
0 to +10V, corresponding to converted values of 0 to 65,535.
If jumper En connects pins 2 and 3 to select bipolar conversion, then the range of input voltage
difference (V[ADCn+] - V[ADCn-]) is -10V to +10V, corresponding to converted values of 0 to
65,535.
Addressing
The UMAC ACC-28E ADC board is mapped as an “I/O” board on the UMAC backplane. It
shares an addressing space with the UMAC digital I/O boards (ACC-14E, 65E, 66E, 67E, and
68E), other ACC-28E boards, ACC-36E and ACC-59E ADC boards, and serial-encoder interface
boards such as the ACC-84E. Each board in this class has a 4-point DIP switch SW1 that sets its
address location in this space and its IC index i. No two boards in this class can have the same
setting, or there will be an addressing conflict.
The following table shows the IC index numbers and base address offset (from the start of I/O
space at Sys.piom) of the board for UMAC I/O-type boards for all of the SW1 switch settings:
Unipolar/Bipolar Configuration
On the ACC-36E, if the software convert code specifies unipolar conversion, then the range of
input voltage difference (V[ADCn+] - V[ADCn-]) is 0 to +20V, corresponding to converted
values of 0 to 4,095.
If the software convert code specifies bipolar conversion, then the range of input voltage
difference (V[ADCn+] - V[ADCn-]) is -10V to +10V, corresponding to converted values of
-2,048 to +2,047.
These software convert codes are explained in a following section for this board.
Addressing
The UMAC ACC-36E ADC board is mapped as an “I/O” board on the UMAC backplane. It
shares an addressing space with the UMAC digital I/O boards (ACC-14E, 65E, 66E, 67E, and
68E), ACC-28E ADC boards, other ACC-36E and ACC-59E boards, and serial-encoder interface
boards such as the ACC-84E. Each board in this class has a 4-point DIP switch SW1 that sets its
address location in this space and its IC index i. No two boards in this class can have the same
setting, or there will be an addressing conflict.
Refer to the table “Power PMAC UMAC I/O Board Indices and Addresses” in the section
above on the UMAC ACC-28E to see how the switch settings correspond to IC index numbers
and I/O address offsets.
If the software convert code specifies bipolar conversion, then the range of input voltage
difference (V[ADCn+] - V[ADCn-]) is -10V to +10V, corresponding to converted values of
-2,048 to +2,047.
These software convert codes are explained in a following section for this board.
If jumper J3 connects pins 2 and 3 to select unipolar conversion of all the DAC outputs, then a
numerical range of 0 to 4,095 corresponds to a range of -10V to +10V between DACn+ and the
AGND reference, or -20V to +20V between DACn+ and DACn-. Note that in this mode, the
power-on default value of 0 in the DAC register does not produce zero output voltage. To get
zero voltage output, a value of 2,047 should be written.
Addressing
The UMAC ACC-59E ADC/DAC board is mapped as an “I/O” board on the UMAC backplane.
It shares an addressing space with the UMAC digital I/O boards (ACC-14E, 65E, 66E, 67E, and
68E), ACC-28E ADC boards, other ACC-36E and ACC-59E boards, and serial-encoder interface
boards. Each board in this class has a 4-point DIP switch SW1 that sets its address location in this
space and its IC index i. No two boards in this class can have the same setting, or there will be an
addressing conflict.
Refer to the table “Power PMAC UMAC I/O Board Indices and Addresses” in the section
above on the UMAC ACC-28E to see how the switch settings correspond to IC index numbers
and I/O address offsets.
ADC Conversions
On an ACC-59E3 configured for voltage inputs, the range of input voltage difference
(V[ADCn+] - V[ADCn-]) is -10V to +10V, corresponding to converted values of -32,768 to
+32,767.
On an ACC-59E3 configured for current inputs, the range of input currents from ADCn+ to
ADCn- is -20mA to +20mA, corresponding to converted values of -32,768 to +32,767. Typically,
only current values in the +4mA to +20mA are used, corresponding to converted values of +6,554
to +32,767.
DAC Conversions
On an ACC-59E3 purchased with voltage outputs, a numerical range of -32,768 to +32,767
corresponds to a range of -10V to +10V between DACn+ and the AGND reference, or -20V to
+20V between DACn+ and DACn-.
Addressing
The UMAC ACC-59E3 ADC/DAC board is mapped as a “PMAC3” board on the UMAC
backplane. It shares an addressing space with the UMAC ACC-24E3 servo interface boards and
the ACC-5E3 MACRO interface boards. Each board in this class has a 4-point DIP switch SW1
that sets its address location in this space and its IC index i. No two boards in this class can have
the same setting, or there will be an addressing conflict.
The following table lists the possible switch settings for UMAC boards based on the PMAC3-
style “DSPGATE3” ASIC such as the ACC-59E3, along with the IC index numbers and base
address offsets (from the start of I/O space) they select. Note that the ON/OFF polarity for setting
index numbers on these boards is the opposite of that for older boards.
In a separate option, the Power Brick products with an 8-axis control board configuration, but 4
or 6-axis amplifier configuration, can provide 2 or 4 16-bit “true DAC” analog outputs using
precision standard resistor-bridge DACs.
It is not possible to command internal amplifiers on the same channel as one of these DACs for
the Power Brick AC or Power Brick LV controller/amplifiers. It is not possible to command
external amplifiers through the amplifier interface board on the same channel as one of these
DACs for the Power Brick Controller configurations.
Addressing
The element indices and addresses of the I/O points are fixed on the Power Brick.
These on-board ADCs can be used even when amplifier current feedback ADCs are used on the
same channels.
Addressing
The element indices and addresses of the I/O points are fixed on the Power Clipper.
The ACC-28B ADCs cannot be used on a Power Clipper channel if the Clipper is receiving
amplifier current feedback on the same channel, whether from the Clipper LV amplifier, or
through an ACC-8FS.
Unipolar/Bipolar Configuration
On the ACC-28B, if jumper En (n = 1 to 4) for hardware channel ADCn connects pins 1 and 2 to
select unipolar conversion, then the range of input voltage difference (V[ADCn+] - V[ADCn-]) is
0 to +10V, corresponding to converted values of 0 to 65,535.
If jumper En connects pins 2 and 3 to select bipolar conversion, then the range of input voltage
difference (V[ADCn+] - V[ADCn-]) is -10V to +10V, corresponding to converted values of 0 to
65,535.
The DACs on the ACC-8AS use the A and B phase data for a servo channel, and so can be used
on the same channel as the filtered-PWM DAC output on the Clipper Board itself (which uses the
C phase) and the pulse output on the Clipper board (which uses the D phase).
Some applications will use the ACC-8AS DACs for servo outputs, particularly for “sinewave
output” control of brushless motors. Use for that purpose is covered in the motor setup chapters.
The element indices and addresses of the I/O points are fixed on an ACC-8AS board connected to
a Power Clipper board.
Power PMAC’s automatic de-multiplexing algorithms select one register to read each phase cycle
(which selects two ADCs on the ACC-36E). To create a “ring” cycle of reading all 8 channels of
a multiplexed ADC takes 8 phase cycles. The ring should complete fast enough that there is a
new value available to the software each time the software task repeats. If the ADC values are
used only in background tasks such as PLCs, the default timing settings will typically permit this
to be the case. Otherwise, the phase update rate may need to be raised to ensure this happens.
To configure the ring cycle, the saved setup elements AdcDemux.Address[i] must be set to the
address offset of the card in Power PMAC’s I/O space (e.g. to $A00000 for Acc36E[0] or
Acc59E[0]). Refer to the table “Power PMAC UMAC I/O Board Indices and Addresses” in
the above section for a complete list. If every entry in the ring cycle is for the same card, each of
these elements will be set to the same value. For example, to configure an 8-way ring cycle for
the ADCs of Acc36E[1], the elements AdcDemux.Address[0] through AdcDemux.Address[7]
should all be set to $B00000.
Next, the ADC or pair of ADCs at the specified address for each ring slot, and the conversion
format(s), must be selected with AdcDemux.ConvertCode[i]. These elements take a value of
$m00n00, although for the ACC-59E, only the last 3 hex digits ($n00) are needed. The value of
the variable hex digit n specifies the software index of the selected channel in the “low” 8-
channel ADC, which is 1 less than the hardware channel number (e.g. 3 for ADC4). The value of
the variable hex digit m is 9 less than the hardware channel number of the “high” 8-channel ADC
on the ACC-36E (e.g. 5 for ADC14). If the ADC is to be sampled as a bipolar voltage, returning a
signed value (rather than as a unipolar voltage, returning an unsigned value), a value of 8 should
be added to the digit.
For example, to sample all eight ADC channels of an ACC-59E as unipolar values in an 8-slot
ring, the following settings would be made:
AdcDemux.ConvertCode[0] = $000
AdcDemux.ConvertCode[1] = $100
AdcDemux.ConvertCode[2] = $200
AdcDemux.ConvertCode[3] = $300
AdcDemux.ConvertCode[4] = $400
AdcDemux.ConvertCode[5] = $500
AdcDemux.ConvertCode[6] = $600
AdcDemux.ConvertCode[7] = $700
In another example, to sample all sixteen ADC channels of an ACC-36E as bipolar values in an
8-slot ring, the following settings would be made:
AdcDemux.ConvertCode[0] = $800800
AdcDemux.ConvertCode[1] = $900900
AdcDemux.ConvertCode[2] = $A00A00
AdcDemux.ConvertCode[3] = $B00B00
AdcDemux.ConvertCode[4] = $C00C00
AdcDemux.ConvertCode[5] = $D00D00
AdcDemux.ConvertCode[6] = $E00E00
AdcDemux.ConvertCode[7] = $F00F00
Finally, AdcDemux.Enable must be set to specify the number of slots in the ring cycle. Setting it
to a value of 8 will cause Power PMAC to use the values of AdcDemux.Address[i] and
AdcDemux.ConvertCode[i] for i = 0 to 7.
The de-multiplexed values will be found in AdcDemux.ResultLow[i] for both ACC-36E and
ACC-59E, and also in AdcDemux.ResultHigh[i] for ACC-36E.
To enable the use of these control bits, saved direction-control element Acc59E3[i].GpioDir[0]
must be set to $FFFFFFFF – not the default – so that all 32 of the IC’s 32 digital I/O lines are
configured as outputs, and the saved polarity-control element Acc59E3[i].GpioPol[0] should be
left at its default value of $00000000.)
The value of the 32-bit non-saved element Acc59E3[i].GpioData[0] determines the value of
these two control bits for each of the 16 inputs. To set all 16 analog inputs to the same cutoff
frequency, the following settings can be used:
Since Acc59E3[i].GpioData[0] is not a saved element, it must be explicitly set after each power-
on/reset. This can be done in pp_startup.txt or in a power-on PLC program. If no explicit
action is taken, all inputs are configured for a 24.5 kHz cutoff frequency. If you wish to set
different cutoff frequencies for different inputs, refer to the ACC-59E3 manual for details.
Further filtering can be done digitally in the encoder conversion table entry that processes the
input.
On the Power Brick PWM Controller when used with most external direct-PWM amplifiers, once
the ASICs have been set up to accept current feedback from the amplifier sections, they can
accept data from the optional general-purpose ADCs as well.
On the Power Brick Analog Controller, there is no amplifier ADC current feedback, so the user
must make sure the setup is correct for the on-board optional ADCs. This can be done with the
following settings:
PowerBrick[i].AdcAmpStrobe = $FFFFFC
PowerBrick[i].AdcAmpDelay = 0
PowerBrick[i].AdcAmpUtoS = 0
PowerBrick[i].AdcAmpHeaderBits = 0
The full-word element PowerBrick[i].AdcAmpCtrl that contains all of these elements is equal
to $FFFFFC00 with these settings.
The frequency of the PWM signal into the filter circuitry is set by PowerBrick[i].PhaseFreq and
PowerBrick[i].Chan[j].PwmFreqMult. This frequency is not independent of the frequency used
for the A, B, and C phases of the same channel. In most Power Brick configurations – Power
Brick AC, Power Brick LV, and Power Brick PWM Controller – the PWM frequency for the
channel will be set to a value appropriate to control the PWM amplifier.
The resolution of this analog output is equal to log2 (300 MHz /[2*PwmFreq]). At a 15 kHz
PWM frequency, this is log2(10,000), about 13.3 bits. The analog filtering has a cutoff (-3dB)
frequency of 4.5 kHz.
PowerBrick[1].DacStrobe should be set to $FFFF0000 for the 16-bit DACs on this option.
Clipper[i].AdcEncStrobe = $FFFFFC
Clipper[i].AdcEncDelay = 0
Clipper[i].AdcEncUtoS = 0
Clipper[i].AdcEncHeaderBits = 1
The full-word element Clipper[i].AdcEncCtrl that contains all of these elements is equal to
$FFFFFC00 with these settings.
The frequency of the PWM signal into the filter circuitry is set by PowerBrick[i].PhaseFreq and
PowerBrick[i].Chan[j].PwmFreqMult. This frequency is not independent of the frequency used
for the A, B, and C phases of the same channel. If the Power Clipper is used with the Clipper
Stack LV amplifier, the PWM frequency for the channel will be set to a value appropriate to
control the PWM amplifier.
The resolution of this analog output is equal to log2 (300 MHz / [2*PwmFreq]). At a 30 kHz
PWM frequency, this is log2(5,000), about 12.3 bits. The analog filtering has a cutoff (-3dB)
frequency of 20 kHz.
Clipper[i].AdcAmpStrobe = $FFFFFC
Clipper[i].AdcAmpDelay = 0
Clipper[i].AdcAmpUtoS = 0
Clipper[i].AdcAmpHeaderBits = 0
The full-word element Clipper[i].AdcAmpCtrl that contains all of these elements is equal to
$FFFFFC00 with these settings.
It is also possible to use the “generic” Gate3[i] data structure name instead of the product-
specific Clipper[i].
To use an ECT entry for the purpose of filtering an ADC value, set EncTable[n].type = 1 for
“single-register read”. Set EncTable[n].pEnc to the address of the ADC register (e.g.
Acc59E3[i].Chan[j].AdcAmp[k].a or AdcDemux.ResultLow[i].a). The filter properties are set
by EncTable[n].index1, index2, and index4. The filtered result will be found in
EncTable[n].PrevEnc.
If the ACC-28E hardware channel n is configured by jumper En for bipolar conversion, the
AdcSdata[j] element should be used. If it is configured for unipolar conversion, the AdcUdata[j]
element should be used.
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. Depending on
whether the M-variable is assigned to the AdcUdata[j] or AdcSdata[j] element, the variable will
be treated as an unsigned or signed value, respectively. For example:
For the ADC1 – ADC8 inputs on either the ACC-36E or ACC-59E, the de-multiplexed value can
be found in status element AdcDemux.ResultLow[i], where the index i matches that of saved
setup elements AdcDemux.Address[i] and AdcDemux.ConvertCode[i].
For the ADC9 – ADC16 inputs on the ACC-36E, the de-multiplexed value can be found in status
element AdcDemux.ResultHigh[i], where the index i matches that of saved setup elements
AdcDemux.Address[i] and AdcDemux.ConvertCode[i].
An M-variable can be assigned to the de-multiplexed element. When the assignment is made
through the IDE project manager, an application-specific name can be given to the variable. For
example:
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
ptr LaserPower->Acc59E[3].DAC[6]
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
ptr ChamberTemp->Acc59E3[5].Chan[1].AdcAmp[3]
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a signed 32-bit integer. Each LSB of the ADC is an increment of 65,536 in the
variable. To convert to LSBs of the ADC, the user can divide by 65,536 or shift right by 16 bits
(>>16).
Address Access
It is also possible to assign an M-variable to the high 16 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above example, the
assignment would be:
ptr ChamberTemp->s.io:$91408C.16.16
This declares that the variable is a signed integer (s) in I/O (io) space. In this assignment, the
six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $914 in this example, are dependent on the accessory index alone, as
the base address offset of the IC with index 5 is $914000. The last three hex digits are dependent
on the offset of the channel from the IC base index ($080 for Chan[1]) and the offset of the
element from the channel base ($02C for AdcAmp[3]).
The first “16” in this assignment says that the LSB of the variable is bit 16 of the 32-bit register.
The second “16” in the assignment says that 16 bits are to be used. Therefore, this assignment
uses bits 16 – 31 of the specified 32-bit register.
The address offsets for each input are shown in the following table:
The second and third hex digits of the address, represented by “xx” in this table, can be calculated
as $04 times the index number of the board.
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
ptr JetPressure->Acc59E3[3].Chan[2].Dac[1]
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a signed 32-bit integer. Each LSB of the DAC is an increment of 65,536 in the
variable. To convert from DAC units to element units, the user can multiply by 65,536 or shift
left by 16 bits (<<16).
Address Access
It is also possible to assign an M-variable to the high 16 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above example, the
assignment would be:
ptr JetPressure->s.io:$90C144.16.16
This declares that the variable is a signed integer (s) in I/O (io) space. In this assignment, the
six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $90C in this example, are dependent on the accessory index alone, as
the base address offset of the IC with index 3 is $90C000. The last three hex digits are dependent
on the offset of the channel from the IC base index ($100 for Chan[2]) and the offset of the
element from the channel base ($044 for Dac[1]).
The first “16” in this assignment says that the LSB of the variable is bit 16 of the 32-bit register.
The second “16” in the assignment says that 16 bits are to be used. Therefore, this assignment
uses bits 16 – 31 of the specified 32-bit register.
The address offsets for each output are shown in the following table:
The second and third hex digits of the address, represented by “xx” in this table, can be calculated
as $04 times the index number of the board.
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
ptr AirFlow->PowerBrick[0].Chan[3].AdcAmp[2]
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a signed 32-bit integer. Each LSB of the ADC is an increment of 65,536 in the
variable. To convert to LSBs of the ADC, the user can divide by 65,536 or shift right by 16 bits
(>>16) – assuming the most common case of AdcAmpHeaderBits = 0.
Address Access
It is also possible to assign an M-variable to the high 16 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above example, the
assignment would be:
ptr AirFlow->s.io:$9001A8.16.16
This declares that the variable is a signed integer (s) in I/O (io) space. In this assignment, the
six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $900 in this example, are dependent on the accessory index alone, as
the base address offset of the IC with index 0 is $900000. The last three hex digits are dependent
on the offset of the channel from the IC base index ($180 for Chan[3]) and the offset of the
element from the channel base ($028 for AdcAmp[2]).
The first “16” in this assignment says that the LSB of the variable is bit 16 of the 32-bit register.
The second “16” in the assignment says that 16 bits are to be used. Therefore, this assignment
uses bits 16 – 31 of the specified 32-bit register.
The address offsets for each input are shown in the following table:
Compatibility Issues
In the rare case where the current feedback data from the ADCs in an external direct-PWM
amplifier has one or more header bits, the data found in the AdcAmp[2] element from the
optional ADCs must be re-arranged before it can be used, because the MSB(s) were “rolled over”
to low bits in the register. For the case where there is one header bit in the current feedback data
(as when using a Geo PWM amplifier with the Power Brick PWM Controller), the following code
could be used to do this:
Temp = PowerBrick[0].Chan[0].AdcAmp[2];
MyAdcVal = int(Temp >> 17) - ((Temp & $100) << 7);
The variables Temp and MyAdcVal are declared user variables, which could be global or local.
By first copying the value in the hardware register into a software variable, the use of the same
value in both manipulations is assured, and a second slow hardware read is eliminated.
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
ptr SpindleSpeed->PowerBrick[1].Chan[0].Pwm[3]
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a signed 32-bit integer. Each LSB of the “DAC” is an increment of 65,536 in
the variable. To convert from DAC units to element units, the user can multiply by 65,536 or shift
left by 16 bits (<<16).
Address Access
It is also possible to assign an M-variable to the high 16 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above example, the
assignment would be:
ptr SpindleSpeed->s.io:$90404C.16.16
This declares that the variable is a signed integer (s) in I/O (io) space. In this assignment, the
six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $904 in this example, are dependent on the IC alone, as the base address
offset of the IC with index 1 is $904000. The last three hex digits are dependent on the offset of
the channel from the IC base index ($000 for Chan[0]) and the offset of the element from the
channel base ($04C for Pwm[3]).
The first “16” in this assignment says that the LSB of the variable is bit 16 of the 32-bit register.
The second “16” in the assignment says that 16 bits are to be used. Therefore, this assignment
uses bits 16 – 31 of the specified 32-bit register.
The address offsets for each output are shown in the following table:
DAC5: PowerBrick[1].Chan[0].Dac[0]
DAC6: PowerBrick[1].Chan[1].Dac[0]
DAC7: PowerBrick[1].Chan[2].Dac[0]
DAC8: PowerBrick[1].Chan[3].Dac[0]
If the 2-channel option is used, only the DAC7 and DAC8 outputs are supported.
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
ptr SpindleSpeed->PowerBrick[1].Chan[0].Dac[0]
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a signed 32-bit integer. Each LSB of the “DAC” is an increment of 65,536 in
the variable. To convert from DAC units to element units, the user can multiply by 65,536 or shift
left by 16 bits (<<16).
Address Access
It is also possible to assign an M-variable to the high 16 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above example, the
assignment would be:
ptr SpindleSpeed->s.io:$904040.16.16
This declares that the variable is a signed integer (s) in I/O (io) space. In this assignment, the
six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $904, are dependent on the IC index alone, as the base address offset of
the IC with index 1 is $904000. The last three hex digits are dependent on the offset of the
channel from the IC base index ($000 for Chan[0]) and the offset of the element from the
channel base ($040 for Dac[0]).
The first “16” in this assignment says that the LSB of the variable is bit 16 of the 32-bit register.
The second “16” in the assignment says that 16 bits are to be used. Therefore, this assignment
uses bits 16 – 31 of the specified 32-bit register.
The address offsets for each output are shown in the following table:
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
ptr CoolantFlow->Clipper[0].Chan[0].AdcEnc[2]
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a signed 32-bit integer. Each LSB of the ADC is an increment of 1,048,576 in
the variable. To convert to LSBs of the ADC, the user can divide by 1,048,576 or shift right by 20
bits (>>20).
Address Access
It is also possible to assign an M-variable to the high 12 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above example, the
assignment would be:
ptr CoolantFlow->s.io:$900038.20.12
This declares that the variable is a signed integer (s) in I/O (io) space. In this assignment, the
six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $900 in this example, are dependent on the accessory index alone, as
the base address offset of the IC with index 0 is $900000. The last three hex digits are dependent
on the offset of the channel from the IC base index ($000 for Chan[0]) and the offset of the
element from the channel base ($038 for AdcEnc[2]).
The “20” in this assignment says that the LSB of the variable is bit 20 of the 32-bit register. The
“12” in the assignment says that 12 bits are to be used. Therefore, this assignment uses bits 20 –
31 of the specified 32-bit register.
The address offsets for each input are shown in the following table:
Input Base Clipper Option Clipper Input Base Clipper Option Clipper
Address Offset Address Offset Address Offset Address Offset
ADC1 $900030 $904030 ADC3 $900038 $904038
ADC2 $900034 $904034 ADC4 $90003C $90403C
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a signed 32-bit integer. Each LSB of the “DAC” is an increment of 65,536 in
the variable. To convert from DAC units to element units, the user can multiply by 65,536 or shift
left by 16 bits (<<16).
Address Access
It is also possible to assign an M-variable to the high 16 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above examples, the
assignment would be:
ptr LaserPower->s.io:$90014C.16.16
ptr ConveyorSpeed->s.io:$90414C.16.16
These declare that the variables are signed integers (s) in I/O (io) space. In these assignments,
the six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $900 and $904 in these examples, are dependent on the accessory index
alone, as the base address offset of the IC with index 0 is $900000 and with index 1 is $904000.
The last three hex digits are dependent on the offset of the channel from the IC base index ($100
for Chan[2]) and the offset of the element from the channel base ($04C for Pwm[3]).
The first “16” in these assignments say that the LSB of the variable is bit 16 of the 32-bit register.
The second “16” in the assignments say that 16 bits are to be used. Therefore, these assignments
use bits 16 – 31 of the specified 32-bit registers.
The indices for each input are shown in the following table:
The “1st” ACC-28B is connected to the JSIOA connector on the ACC-8xS board. The “2nd” ACC-
28B is connected to the JSIOB connector on the ACC-8xS board.
An M-variable can be assigned to the element. When the assignment is made through the IDE
project manager, an application-specific name can be given to the variable. For example:
ptr ChamberTemp->Clipper[0].Chan[1].AdcAmp[0]
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a signed 32-bit integer. Each LSB of the ADC is an increment of 65,536 in the
variable. To convert to LSBs of the ADC, the user can divide by 65,536 or shift right by 16 bits
(>>16).
Address Access
It is also possible to assign an M-variable to the high 16 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above example, the
assignment would be:
ptr ChamberTemp->s.io:$9000A0.16.16
This declares that the variable is a signed integer (s) in I/O (io) space. In this assignment, the
six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $900 in this example, are dependent on the IC index alone, as the base
address offset of the IC with index 0 is $914000. The last three hex digits are dependent on the
offset of the channel from the IC base index ($080 for Chan[1]) and the offset of the element
from the channel base ($020 for AdcAmp[0]).
The first “16” in this assignment says that the LSB of the variable is bit 16 of the 32-bit register.
The second “16” in the assignment says that 16 bits are to be used. Therefore, this assignment
uses bits 16 – 31 of the specified 32-bit register.
The address offsets for each input are shown in the following table:
1st Base Clipper Option Clipper 2nd Base Clipper Option Clipper
ACC-28B Address Offset Address Offset ACC-28B Address Offset Address Offset
Input Input
ADC1 $900020 $904020 ADC1 $900120 $904120
ADC2 $900024 $904024 ADC2 $900124 $904124
ADC3 $9000A0 $9040A0 ADC3 $9001A0 $9041A0
ADC4 $9000A4 $9040A4 ADC4 $9001A4 $9041A4
The indices for each output are shown in the following table:
An M-variable can be assigned to the element. When the assignment is made through the IDC
project manager, an application-specific name can be given to the variable. For example:
ptr DesiredTemp->Clipper[0].Chan[3].Dac[1]
ptr ThrottleAngle->Clipper[1].Chan[1].Dac[0]
When using either the element name directly or an M-variable assigned to the element, the
resulting value is a singed 32-bit integer. Each LSB of the DAC is an increment of 65,536 in the
variable. To convert from DAC units to element units, the user can multiply by 65,536 or shift
left by 16 bits (<<16).
Address Access
It is also possible to assign an M-variable to the high 16 bits of the 32-bit element using the
address of the register rather than the element name. To do this for the above examples, the
assignments would be:
ptr DesiredTemp->s.io:$9001C4.16.16
ptr ThrottleAngle->s.io:$9040C0.16.16
These declare that the variables are signed integers (s) in I/O (io) space. In these assignments,
the six-digit hexadecimal value is the offset of the register address from the start of I/O. (It is not
necessary to know the starting I/O address, but it can be found at Sys.piom.) This offset can be
computed using the values found in the Software Reference chapter “Power PMAC I/O Address
Offsets”.
The first three hex digits, $900 and $904 in these examples, are dependent on the board used
alone, as the base address offset of the IC on the base Clipper board is $900000 and on the
optional piggyback Clipper board, it is $904000. The last three hex digits are dependent on the
offset of the channel from the IC base index ($180 for Chan[3] and $080 for Chan[1]) and the
offset of the element from the channel base ($044 for Dac[1] and $040 for Dac[0]).
The first “16” in these assignments say that the LSB of the variable is bit 16 of the 32-bit register.
The second “16” in the assignments say that 16 bits are to be used. Therefore, these assignments
use bits 16 – 31 of the specified 32-bit registers.
The address offsets for each output are shown in the following table:
ACC-8AS Base Clipper Option Clipper ACC-8AS Base Clipper Option Clipper
Output Address Offset Address Offset Output Address Offset Address Offset
DAC1A $900040 $904040 DAC3A $900140 $904140
DAC1B $900044 $904044 DAC3B $900144 $904144
DAC2A $9000C0 $9040C0 DAC3A $9001C0 $9041C0
DAC2B $9000C4 $9040C4 DAC3B $9001C4 $9041C4
The variable declarations for general-purpose analog I/O will look like:
These declared variables can then be assigned to particular ICs with function calls in program
statements like the following. These must be executed every time the Power PMAC is started up.
The returned value of the function is the base address of the IC (whose numerical value does not
usually need to be known by the user). If the IC is not found, a NULL value is returned.
Using this technique, the variable declarations for the base IC pointers will look like:
int MySecondGate3Adr;
int MyFourthIoICAdr;
The base IC pointer variables are then assigned to the ICs using Power PMAC’s address auto-
detection elements. This can be done with program statements like the following. For global
variables, these must be executed once each time the Power PMAC is started up. For local
variables, these must be executed every time the routine is entered.
These variables will contain the non-zero base address offset of the IC if it has been detected.
They will contain a zero value if it has not been detected.
Next, the address of each individual register must be computed as the sum of the pointer to I/O
memory (piom), the base address offset of the IC computed above, and the offset of the register
in the IC from its base. These offsets are given for all ICs in the Software Reference Manual
chapter “Power PMAC ASIC Register Element Addresses”. Register offsets for specific general
purpose I/O are given in sections below.
The register pointer variables can be computed with program statements like the following. For
global variables, these must be executed once each time the Power PMAC is started up. For local
variables, these must be executed each time the routine is entered.
The “shift-right 2” (>> 2) operation converts the “byte addressing” of the offset values into the
“word addressing” that the program requires. This effective division by 4 reflects the fact that
there are 4 bytes per 32-bit word.
Once these pointer variables are properly assigned to addresses, the values in them can be
accessed.
One should always first read the ADC register using a volatile unsigned int pointer, and then
properly scale the value before storing in either an unsigned int variable for unipolar inputs, or
an int for bipolar inputs. Jumpers E1 through E4 on ACC-28E determine the polarity of the
inputs.
To obtain the unipolar ADC value, simply shift the register right 16 bits. To obtain the bipolar
ADC value, first shift the register right 16 bits, and then subtract 32768 from the shifted value.
The ADC values can be obtained through program statements like those below (e.g. for a card
with index i = 1):
For the ADC1 – ADC8 inputs on either the ACC-36E or ACC-59E, the de-multiplexed value can
be found in pshm->AdcDemux.ResultLow[i], where the index i matches that of saved
setup elements AdcDemux.Address[i] and AdcDemux.ConvertCode[i].
For the ADC9 – ADC16 inputs on the ACC-36E, the de-multiplexed value can be found in status
element pshm->AdcDemux.ResultHigh[i], where the index i matches that of saved setup
elements AdcDemux.Address[i] and AdcDemux.ConvertCode[i].
Always write unsigned values to these registers. One can manipulate registers with program
statements like the following (e.g. for a card of index i = 1):
To copy the value from the high 16 bits of the element for ADC5 of this IC into a software
variable, the following statement could be used:
So the pointer to the register corresponding to ADC6 of an ACC-59E3 card with index 1 could be
defined as follows:
int MySecondGate3Adr;
volatile int *MySecond59E3Adc6;
...
MySecondGate3Adr = pshm->OffsetGate3[1]; // Gate3[1]
MySecond59E3Adc6 = (int *) piom + ((MySecondGate3Adr + 0x0A4) >> 2);
To read the value of this 32-bit hardware register into a software variable with 16 bits, the
following code could be used:
To write a value into the high 16 bits of the 32-bit hardware element for DAC3 from a software
variable with 16 bits, the following code could be used:
So the pointer to the register corresponding to DAC3 of an ACC-59E3 card with index 1 could be
defined as follows:
int MySecondGate3Adr;
volatile int *MySecond59E3Dac3;
...
MySecondGate3Adr = pshm->OffsetGate3[1]; // Gate3[1]
MySecond59E3Dac3 = (int *) piom + ((MySecondGate3Adr + 0x0C0) >> 2);
To write a value into the high 16 bits of this 32-bit hardware register from a software variable
with 16 bits, the following code could be used:
For the ADC1 – ADC4 values on the Power Brick, the data can be found in
PowerBrick[0].Chan[j].AdcAmp[2], where j (= 0 to 3) is one less than the hardware channel
number. For the ADC5 – ADC8 values, the data can be found in
PowerBrick[1].Chan[j].AdcAmp[2], where j (= 0 to 3) is five less than the hardware channel
number. In both cases, the structure name Gate3[i] can be used instead of PowerBrick[i]. The
indices for each input are shown in the following table:
So a data structure to the first Power Brick IC can be defined as shown above:
To copy the value from the high 16 bits of the element for ADC3 of this IC into a software
variable, the following statement could be used:
So the pointer to the register corresponding to ADC3 of a Power Brick could be defined as
follows:
int MyFirstGate3Adr;
volatile int *MyBrickAdc3;
...
MyFirstGate3Adr = pshm->OffsetGate3[0]; // Gate3[0]
MyBrickAdc3 = (int *) piom + ((MyFirstGate3Adr + 0x128) >> 2);
To read the value of this 32-bit hardware register into a software variable with 16 bits, the
following code could be used:
For the DAC1 – DAC4 values on the Power Brick, the data is written to
Gate3[0].Chan[j].Pwm[3], where j (= 0 to 3) is one less than the hardware channel number. For
the DAC5 – DAC8 values, the data is written to Gate3[1].Chan[j].Pwm[3], where j (= 0 to 3) is
five less than the hardware channel number.
The indices for each output are shown in the following table:
To write a value into the high 16 bits of the 32-bit hardware element for DAC8 from a software
variable with 16 bits, the following code could be used:
So the pointer to the register corresponding to DAC8 of a Power Brick could be defined as
follows:
int MySecondGate3Adr;
volatile int *MyBrickDac8;
...
MySecondGate3Adr = pshm->OffsetGate3[1]; // Gate3[1]
MyBrickDac8 = (int *) piom + ((MySecondGate3Adr + 0x1CC) >> 2);
To write a value into the high 16 bits of this 32-bit hardware register from a software variable
MyDac8Value with 16 bits, the following code could be used:
For the DAC5 – DAC8 outputs on the Power Brick, the data is written to the following elements:
DAC5: Gate3[1].Chan[0].Dac[0]
DAC6: Gate3[1].Chan[1].Dac[0]
DAC7: Gate3[1].Chan[2].Dac[0]
DAC8: Gate3[1].Chan[3].Dac[0]
If the 2-channel option is used, only the DAC7 and DAC8 outputs are supported.
So a data structure to the second Power Brick IC can be defined as shown above:
To write a value into the high 16 bits of the 32-bit hardware element for DAC7 from a software
variable with 16 bits, the following code could be used:
So the pointer to the register corresponding to DAC7 of a Power Brick could be defined as
follows:
int MySecondGate3Adr;
volatile int *MyBrickTrueDac7;
...
MySecondGate3Adr = pshm->OffsetGate3[1]; // Gate3[1]
MyBrickTrueDac7 = (int *) piom + ((MySecondGate3Adr + 0x140) >> 2);
To write a value into the high 16 bits of this 32-bit hardware register from a software variable
MyDac7Value with 16 bits, the following code could be used:
For the ADC1 – ADC4 values on the base Power Clipper board, the data can be found in
Gate3[0].Chan[0].AdcEnc[k], where k (= 0 to 3) is one less than the hardware channel number.
For the ADC1 – ADC4 values on the piggyback Power Clipper board, the data can be found in
Gate3[1].Chan[0].AdcEnc[k], where k (= 0 to 3) is one less than the hardware channel number.
So a data structure to the first Power Brick IC can be defined as shown above:
To copy the value from the high 12 bits of the element for ADC3 of this IC into a software
variable, the following statement could be used:
So the pointer to the register corresponding to ADC3 of a base Power Clipper could be defined as
follows:
int MyFirstGate3Adr;
volatile int *MyClipperAdc3;
...
MyFirstGate3Adr = pshm->OffsetGate3[0]; // Gate3[0]
MyClipperAdc3 = (int *) piom + ((MyFirstGate3Adr + 0x038) >> 2);
To read the value of this 32-bit hardware register into a software variable with 12 bits, the
following code could be used:
For the optional analog output on the base Power Clipper board, the data is written to
Clipper[0].Chan[2].Pwm[3]. For the optional analog output on the piggyback Power Clipper
board, the data is written to PowerBrick[1].Chan[2].Pwm[3]. In both cases, the structure name
Gate3[i] can be used instead of Clipper[i]. The indices for each output are shown in the
following table:
To write a value into the high 16 bits of the 32-bit hardware element for this output from a
software variable with 16 bits, the following code could be used:
So the pointer to the register corresponding to HWANA of a Power Clipper could be defined as
follows:
int MyFirstClipperAdr;
volatile int *MyClipperHwAna;
...
MyFirstClipperAdr = pshm->OffsetGate3[0]; // Gate3[0]
MyClipperHwAna = (int *) piom + ((MyFirstClipperAdr + 0x14C) >> 2);
To write a value into the high 16 bits of this 32-bit hardware register from a software variable
MyDacValue with 16 bits, the following code could be used:
The indices for each input are shown in the following table:
The “1st” ACC-28B is connected to the JSIOA connector on the ACC-8xS board. The “2nd” ACC-
28B is connected to the JSIOB connector on the ACC-8xS board.
So a data structure to the first Power Brick IC can be defined as shown above:
To copy the value from the high 16 bits of the element for ADC2 of the first ACC-28B for this IC
into a software variable, the following statement could be used:
So the pointer to the register corresponding to ADC1 of the 1st ACC-28B connected to a base
Power Clipper could be defined as follows:
int MyFirstGate3Adr;
volatile int *MyClipperAdc3;
...
MyFirstGate3Adr = pshm->OffsetGate3[0]; // Gate3[0]
MyClipperAdc3 = (int *) piom + ((MyFirstGate3Adr + 0x0A0) >> 2);
To read the value of this 32-bit hardware register into a software variable with 16 bits, the
following code could be used:
These registers can be accessed with their data structure element names:
Gate3[i].Chan[j].Dac[k]. The board index i is 0 for the base Clipper board, or 1 for the optional
piggyback Clipper board. The channel index j has a range of 0 to 3, corresponding to a hardware
channel number on the ACC-8AS of 1 to 4, respectively. The phase index k is 0 for the A-phase
output, or 1 for the B-phase output.
The indices for each output are shown in the following table:
To write a value into the high 16 bits of the 32-bit hardware element for DAC3A from a software
variable with 16 bits, the following code could be used:
The byte offsets of these registers are shown in the following table:
int MyFirstClipperAdr;
volatile int *MyClipperDac1B;
...
MyFirstClipperAdr = pshm->OffsetGate3[0]; // Gate3[0]
MyClipperDac1B = (int *) piom + ((MyFirstClipperAdr + 0x044) >> 2);
To write a value into the high 16 bits of this 32-bit hardware register from a software variable
MyDac1BValue with 16 bits, the following code could be used:
Motion Programs
Power PMAC motion programs allow for the automatic sequenced execution of axis moves, with
associated input/ output operations and mathematical/logical calculations. While a motion
program is executed by a coordinate system, it does not “belong” to a coordinate system. Any
active coordinate system can execute any motion program, and multiple coordinate systems can
execute the same motion program at the same time.
Power PMAC can have up to 1023 of these “fixed” motion programs at any one time, each taking
a number from 1 to 4,294,967,295 (232-1). There is no need for the numbers to be consecutive, or
to have any pattern. There is no execution priority for lower or higher-numbered programs. The
program numbers simply act as numeric identifying labels.
Each coordinate system in Power PMAC can have one (and only one) rotary program buffer. The
rotary program buffer is automatically motion program 0 for the coordinate system.
PLC Programs
Power PMAC “PLC” programs, while commonly used for the type of logical response and
input/output control of traditional Programmable Logic Controllers, are capable of managing
many other tasks. Unlike motion programs, they are not sequenced by the programmed move, so
they can be used for many tasks that are asynchronous to the programmed motion.
The Script PLC programs provide a general computing capability, executing much more like
traditional high-level programming languages than the motion programs do. (For this reason,
many users will find it better to implement this type of functionality in “CPLCs”, using the C
programming language.)
Power PMAC can have up to 32 Script PLC programs, numbered 0 to 31. Up to 4 of these can
execute in foreground, under the real-time interrupt; the remainder will execute in “round robin”
fashion as background tasks. At a given priority level, lower-numbered PLC programs execute
before higher-numbered PLC programs.
Subprograms
Power PMAC Script subprograms are not executed directly; instead they are called from other
Script programs. A subprogram can be called from a “fixed” motion program, a rotary motion
program, a PLC program, or a subprogram.
Power PMAC can have up to 1023 of these subprograms at any one time, each taking a number
from 1 to 4,294,967,295 (232-1). There is no need for the numbers to be consecutive, or to have
any pattern. The program numbers simply act as numeric identifying labels.
Kinematic Subroutines
Each coordinate system in Power PMAC can have a forward-kinematic subroutine (forward)
and an inverse-kinematic subroutine (inverse), defining the relationship between motor
coordinates and axis coordinates. These subroutines permit more complex relationships between
motors and axes than the mathematically linear relationships defined by the more common (and
simpler) axis-definition statements.
Mathematical Capabilities
The Power PMAC Script language provides a full set of mathematical capabilities, with
constants, variables, operators, and functions. These are explained in detail in the Power PMAC
Computation Features chapter of the User’s Manual, and in the Power PMAC Script
Mathematical Feature Specification chapter of the Software Reference Manual.
A very important feature of the Script language is its automatic “type matching” of different
variable formats. The user can mix and match different formats together in any mathematical
expression, fixed-point and floating-point, from Boolean to 64-bit width, without any explicit
type conversions. This makes working with the multiple data types present in a system,
particularly when dealing with input and output registers, very simple.
Branching Structures
The Script language provides several branching structures for conditional execution of certain
program commands or sections.
“If/Else” Branching
In the if({condition}) structure, when the condition evaluates as “true”, the command(s)
immediately following are executed. If this structure is not immediately followed by a “left curly
bracket” (“{”), only the single command following is conditionally executed in this way. If this
structure is immediately followed by a “left curly bracket” (“{”), all the commands up to the next
“right curly bracket” (“}”) are conditionally executed in this way.
In a rotary motion program, all actions to be executed on a true “if” condition must be on the
same line as the condition, and no “else” branch is permitted.
“Switch/Case” Branching
In the switch({expression}) structure, the expression value is evaluated (and truncated to
an integer value if necessary). Program execution is transferred to the case command below that
specifies the matching integer value, if such a case command exists. Execution continues from
this command until a break command is encountered, even if this continues execution into a
subsequent case branch. When the break command is encountered, execution jumps to the
program command immediately following the end of the entire switch structure.
If no break command is encountered after starting a case branch, execution continues to the end
of the entire switch structure, then on to the commands following. If no case command
matching the evaluated switch expression value exists, program execution will jump to the
default branch, if it exists, or to the program command immediately following the entire
switch structure if a default branch is not present.
set with the program command csetn, and cleared with the buffered program command cclrn.
This element can also be manipulated directly (e.g. Coord[1].Cflags |= $40 performs the
same action as cset6, and more generally, Coord[1].Cflags |= exp2(BitNum) sets
the flag at the specified bit number) .
These structures are mainly intended to implement conditional execution functions in CNC-style
motion programs, especially those using the rotary motion program buffer, in which the single-
line nature of these functions is essential.
Looping Structures
Script programs in Power PMAC are capable of conditional looping structures, with the condition
evaluated either at the beginning or end of the loop.
“While” Loops
In the while({condition}) structure, when the condition evaluates as “true”, the
command(s) immediately following are executed. If this structure is not immediately followed by
a “left curly bracket” (“{”), only the single command following is conditionally executed in this
way. If this structure is immediately followed by a “left curly bracket” (“{”), all the commands
up to the next “right curly bracket” (“}”) are conditionally executed in this way. When the
command or bracketed command set is finished executing, program execution automatically
jumps back to the while command to complete the loop.
If the condition in the while command evaluates as “false”, the command or bracketed
command set immediately following the while command is skipped over, and program
execution jumps to the command immediately following.
“Do/While” Loops
In the do..while({condition}) structure, the command or bracketed command set
immediately following the do command is always executed once. If the condition in the while
command after this command or command set evaluates as true, program execution automatically
jumps back to the do command to complete the loop. If the condition evaluates as false, program
execution continues with the command immediately following.
Nesting of Loops
While and do/while loops can be nested within each other, and there is no inherent limit to the
“depth” of the nesting, as there is no stack that must be kept, so no potential for “stack overflow”.
If program execution encounters a break command inside a loop, execution jumps immediately to
the command following the end of the loop (i.e. it exits the loop), and continues from there.
Subroutine and subprogram calls in the Script environment can be nested 255 levels deep, as
there is a 256-level stack (including the top level). Indefinite recursion should not be used, as it
could overflow the stack. Attempting to go more than 255 levels deep will stop execution of the
program thread, and the low 4 bits of Coord[x].Ldata.Status (for a top-level motion program) or
Plc[i].Ldata.Status (for a top-level PLC program) will contain a value of 5 to indicate this error.
Power PMAC can have a single C function, called CfromScript, that can be called from any
of the Script programs in Power PMAC. This function and its uses are documented in the User’s
Manual chapter on C programs.
These “jump labels” should not be confused with the similar “synchronizing labels”, which do
not end with a colon. Those labels simply cause Power PMAC to set the values of coordinate
system status elements as motion program execution encounters the program line and executes a
move resulting from that line. A program line can have either type of label, both, or neither.
By default, there is an implicit N0: at the beginning of each program buffer. However, if an
explicit N0: is used elsewhere in the buffer, this jump label will override the effect of the default
implicit label (this is not recommended).
“Gosub” Commands
The gosub{data} command causes program execution to transfer to the program line in the
same program whose “jump label” number matches the value of {data}. On the next return
command encountered after this, program execution will transfer back to the command
immediately following the gosub command. This permits the creation of subroutines within the
same program. No argument passing using local stack variables is permitted with the gosub
command.
“Callsub” Commands
The callsub{data} command causes program execution to transfer to the program line in the
same program whose “jump label” number matches the value of {data}. On the next return
command encountered after this, program execution will transfer back to the command
immediately following the callsub command. Like the gosub command, this permits the
creation of subroutines within the same program. However, the callsub command permits the
use of argument passing to the subroutine using local stack variables.
“Call” Commands
The call{data} command causes program execution to transfer to the subprogram whose
number matches the value of the integer part of {data}, and to the line within that program
whose “jump label” number matches the fractional part of {data} multiplied by 1,000,000. For
example, the command call123.456 causes program execution to transfer to subprog123
at jump label N456000:.
On the next return command encountered after this, program execution will transfer back to
the command immediately following the call command. The call command permits the use
of argument passing to the subprogram using local stack variables.
Note that call commands can be used in rotary motion programs, just as in other program types.
To facilitate this implementation, Power PMAC treats several of the letter codes as specialized
subprogram call commands. The G, M, T, and D-codes provide a subprogram call as shown in the
following table.
With the default subprograms used, a G17 command is a call to subprog 1000 at line jump
label N17000:. An M125 command is a call to subprog 1001 at line jump label N125000:.
A T3 or T03 command is a call to subprogram 1002 at line jump label N3000:. A D7.25
command is a call to subprog 1003 at line jump label N7250:.
For more details on the use of these codes, refer to the section Implementing an RS-274 Style
Motion Program, below.
“Return” Commands
When a return command is encountered in the execution of a program, execution is transferred
back to the calling routine or program, immediately after the calling command. If a return
command is encountered in a top-level program, execution is halted, but ready to resume at the
beginning of the program buffer. If the top-level program is a PLC program, execution will
automatically resume on the next scan. If the top-level program is a motion program (fixed or
rotary), a command is required to restart execution of the program.
There is an implicit return command at the end of every Script program buffer. If program
execution reaches the end of the buffer, the action taken is exactly as if there were an explicit
return command at the end. Adding an explicit return command at the end of a subprogram
does not change the execution, but may make its functionality more clear.
These commands are mainly intended to implement “implied” calls in CNC-style motion
programs for functions such as canned cycles. In common use, the canned-cycle G-code is only
explicitly invoked on the first line it is used. On following lines, only the parameters for the
canned cycle are typically used, not the G-code specifying the cycle itself.
Since Power PMAC executes G-codes as subprogram calls, it needs to implement a subprogram
call on each line of the motion program to execute the canned cycle for that program line. Simply
adding a ccalln command to the beginning of each line of the motion program as it is sent to
the Power PMAC can provide this functionality. (This can be easier than detecting when a
particular G-code call needs to be added to individual lines.)
Inside the canned-cycle G-code subroutine, the cdefn command can then be used to cause
subsequent lines of the motion program to call the subroutine again with the ccalln command.
For example, a G87 canned-cycle subroutine could use a cdef1 G87 command so the ccall1
command on the next line of the top-level motion program would call the same subroutine.
In this style of programming, another G-code is typically used to cancel the modal G-code. For
canned cycles in the G81 – G89 range, G80 is often used to cancel any of these cycles. So the
G80 subroutine could use a cundef1 command to “undefine” the subprogram call that was
being used.
Note that if the top-level motion program has a ccalln command before the G80 “cancel”
command, the previously selected canned-cycle subroutine will be called before the G80 cycle
cancel subroutine is called. However, the program line will have no parameters for the cycle, so if
the canned-cycle subroutine will bypass any action if no parameters are passed to it, this will not
be an issue.
Jump commands
The goto{data} command causes program execution to transfer to the program line in the
same program whose “jump label” number matches the value of {data}. Unlike the
gosub{data} command, program execution will not transfer back on encountering a return
command or end of buffer. In general, modern views of good programming practice discourage
the use of goto commands.
Motion Specification
Commands for specifying motion in the Power PMAC Script language are of two types: the
actual move commands, and the modal commands that specify the rules according to which the
move commands are to be interpreted. When a move command is encountered during the
execution of the Script program, Power PMAC generates the equations of commanded motion
that are necessary to implement the move according the specified rules. The coefficients of these
equations are placed in a queue for subsequent execution by other automatic tasks in the Power
PMAC.
The end result of the programmed move specification is a series of commanded positions in a
trajectory for each motor assigned to the coordinate system executing the coordinate system. The
nature of that trajectory for each move mode is explained in detail in the User’s Manual chapter
Power PMAC Move Mode Trajectories. This section explains how the logic of the Script
language is used to command moves.
In a PLC program (or its subprograms) the only type of move that can be commanded is a rapid-
mode move. Commanding the move itself automatically puts the addressed coordinate system in
rapid move mode, even if it has just declared a different mode. For example the program
commands linear X10, when executed in a PLC program or its subprograms, would both
execute a rapid-mode move and leave the addressed coordinate system in rapid move mode.
It is possible, but less common, to have some axes in a coordinate system in absolute mode and
others in incremental mode. The abs and inc commands using axis lists change the mode of
only the specified axes, leaving all other axes in the coordinate system in their present mode. For
example, the command abs(x,y) changes the X and Y axes into absolute mode; other axes
could be left in incremental mode.
For linear and circle-mode moves specified by “feedrate” (F) instead of move time (tm), the user
must specify which axes are involved in the vector feedrate calculations. These axes are known as
the “feedrate axes”. For each move of this type, Power PMAC automatically computes the vector
distance as the vector sum (using the Pythagorean theorem) of the move distances for all of the
feedrate axes, and the move time as this vector distance divided by the feedrate. Any “non-
feedrate” axes complete the move in this same time.
At power-on/reset, the X, Y, and Z axes are the only feedrate axes. The program frax command
can be used to change this. The axes specified in the axis list for the command become feedrate
axes, all axes not in the list become non-feedrate axes. The command frax(XX,YY) makes the
XX and YY axes feedrate axes; all others, including the ZZ, X, Y, and Z axes, become non-
feedrate axes. The program nofrax command makes all of the axes non-feedrate axes.
For more detail on feedrate axes and vector feedrate calculations, refer to the Power PMAC Move
Mode Trajectories chapter of the User’s Manual.
Move Parameters
There are several numerical parameters that govern the moves in each move mode. This section
lists the parameters; details of what the parameters do are explained in the User’s Manual chapter
Power PMAC Move Mode Trajectories.
In the rapid move mode, the parameters are saved setup elements for the motors in the coordinate
system. These parameters are set by assigning values to the elements, often outside the program
itself. Acceleration and deceleration are governed by Motor[x].JogTa and Motor[x].JogTs. Top
speed is governed by Motor[x].MaxSpeed or Motor[x].JogSpeed, depending on the setting of
Motor[x].RapidSpeedSel. Coord[x].RapidVelCtrl governs whether all axes move at their
programmed speed, or only the axis with the greatest distance-to-speed ratio does, with the others
slowed to match this ratio (this gives a closer-to-straight-line path).
In the linear and circle move modes, the parameters are saved setup elements for the coordinate
system. These parameters can be set by assigning values directly to the elements, but they are
often set by matching program commands. The ta{data} program command sets the value of
Coord[x].Ta, specifying the acceleration time for these moves. The ts{data} program
command sets the value of Coord[x].Ts, specifying the “S-curve” portion of the acceleration
time for these moves. The tm{data} and F{data} commands set the value of Coord[x].Tm,
specifying the move time or vector “feedrate” (speed) for these moves. These two commands also
specify whether the moves are specified by time or speed.
In the spline move mode, the spline move times are determined by the value or values specified in
the spline mode command itself. There are no other modal parameters governing the moves. The
times are changed with another spline mode command.
In the PVT move mode, the move time is determined by the value specified in the PVT mode
command itself. There are no other modal parameters governing the moves. The time is changed
with another PVT mode command.
Move Commands
The actual move commands in the Script language simply specify the letter name of each axis to
be moved immediately followed by a quantity specifying the destination of that move. In some
modes, there can be a secondary quantity specified as well, as described below. If multiple axes
are specified on the same program line, these axes will move together in a coordinated fashion.
Moves resulting from commands on separate program lines are executed sequentially.
{axis}{data}[{axis}{data}…]
Here, {axis} is the single-letter or double-letter name for the axis to be moved, and {data} is
the move-end position or distance for the axis, depending on whether the axis is in absolute or
incremental mode.
For example, the command X10 Y20 Z30 tells the X, Y, and Z axes in the coordinate system
running the motion program, or in the coordinate system addressed by the PLC program to start a
move simultaneously according to the modal move rules in place at the time the program line is
encountered.
This basic axis move command is used for standard rapid-mode moves, linear-mode moves, and
spline-mode moves.
Move-Until-Trigger Command
A program move-until-trigger is a variant of the rapid move mode. The move-until-trigger
command has the form:
{axis}{data}^{data}[{axis}{data}^{data}…]
The first {data} after the axis name is the move-end position or distance in the absence of a
trigger. The second {data} is the signed distance from the trigger position to the end of the
post-trigger move.
For example, the command A500^-50 tells the A-axis in the coordinate system to start
execution of a rapid-mode move to a destination of 500 axis units (if in ABS mode) or a length of
+500 axis units (if in INC mode), but if the specified trigger is found, change the destination to a
point a distance of -50 axis units from the position at the trigger.
{axis}{data}[{axis}{data}…][{vector}{data}...]
Here, {vector} is the letter I, J, or K for the vector component along the X, Y, or Z axis,
respectively, or the double letter II, JJ, or KK for the vector component along the XX, YY, or ZZ
axis, respectively. For example, the command X2000 Y3000 Z1000 I500 J300 K500
specifies an arc move in the X/Y/Z Cartesian space.
{axis}{data}[{axis}{data}…] R{data}
The value after the R specifies the radius magnitude. If it is a positive value, the arc move covers
an angle less than 180°; if it is a negative value, the arc move covers an angle greater than 180°.
This command form can only be used with the X/Y/Z axis set.
{axis}{data}:{data}[{axis}{data}:{data}…]
The first value following each axis name is the move-end position or distance for the axis. The
second value, following the colon is the move-end velocity for the axis. Note that this is a signed
velocity value, so if the move is to end going in the negative direction, this must be a negative
number.
These commands are generally just longer versions of the equivalent on-line commands – e.g.
jog for j. They can act on the “listed” motor(s) or coordinate system(s) – e.g. jog+7,
abort1,2 – or if there is no motor or coordinate system list, on the modally addressed motor or
coordinate system, as determined by the present value of Ldata.motor or Ldata.coord.
abort – Stop calculation of motion program from presently selected point, commencing
immediate deceleration of all axes in the coordinate system
begin[:{data}] – Point program counter to beginning of present [or specified] motion
program
ddisable – Delayed disable (kill) of servo control for all motors assigned to coordinate system,
providing time for brakes to engage fully
disable – Disable (kill) of servo control of all motors assigned to coordinate system
enable – Enable servo control of all motors assigned to coordinate system
hold – Execute feed hold by ramping coordinate system time base value to 0, ready to resume
on R or S command
lh\ – (Quick stop) Execute fastest stop in lookahead buffer that does not violate acceleration
constraints
lh< – (Reverse) Start reverse execution in lookahead buffer
lh> – (Forward) Resume forward execution in lookahead buffer
pause – Stop calculation of motion program[s] at presently selected point, ready to resume at
that point
resume – Restart continuous of motion program[s] from paused point
run – Begin continuous of motion program[s] in addressed [or listed] coordinate system[s] from
presently selected point
start[:{data}] – Start running present [or specified] motion program from beginning
step – Execute single command of motion program[s] from presently selected point
stop – Stop calculation of motion program[s] at presently selected point and make the selected
point the beginning of the present program
Motion Programs
A new top-level motion program can be downloaded to the Power PMAC at any time, even while
other motion programs are executing. For a motion program buffer that is already present in
Power PMAC, the buffer can be opened for downloading new contents unless that program (or a
subprogram called from it) is presently executing, or suspended (e.g. with a hold, step, or quit
command) such that it is possible to resume execution at the suspended point. An abort (a)
command can be used to take a program out of either executing or suspended mode so that the
buffer can be opened to download new contents.
When the open prog n command is sent to prepare the motion program buffer for
downloading of new contents, all existing contents of that buffer are automatically erased. There
is no need to use a clear command to do this as in older types of PMAC controllers. As long as
the buffer is open, the motion program cannot be executed; a close command must be sent first.
The define rotary command causes Power PMAC to reserve memory for a rotary motion
program buffer in the addressed coordinate system. The first argument of this command specifies
the number of bytes of memory to be reserved; it has a minimum value of 2048 bytes and is
usually much larger. It is recommended to size this buffer generously, as larger buffers make the
process of downloading contents during execution easier to manage for robust operation. The
optional second argument for this command specifies the size of the “line buffer” each program
line is momentarily held in before being copied to the rotary buffer itself. If no second argument
is specified, this line buffer is 1024 bytes, and this value is satisfactory for virtually all
applications.
The open rotary command causes Power PMAC to open the rotary motion program buffer
for the addressed coordinate system for entry. Unlike other types of buffers, this command does
not cause the existing contents of the buffer to be erased. Subsequent program lines are appended
to the end of the existing contents.
Note that the open rotary command can be issued at any time, including while the rotary
motion program buffer (or a subprogram called from it) is executing or suspended. This
capability for the rotary motion program buffers gives them their unique flexibility to stream new
contents to the Power PMAC while existing contents are being executed.
If it is desired to erase the existing contents of the buffer, the coordinate-system-specific clear
rotary command must be used. This leaves the structure of the buffer itself intact. To erase the
rotary buffers themselves, the global clear all buffers command must be issued. If there
are multiple buffers, it is not possible to erase a single buffer structure.
PLC Programs
A new top-level PLC program can be downloaded to the Power PMAC at any time, even while
other PLC programs are executing. For a PLC program buffer that is already present in Power
PMAC, the buffer can be opened for downloading new contents unless that program (or a
subprogram called from it) is presently executing, or suspended (e.g. with a pause plc
command) such that it is possible to resume execution at the suspended point. A disable plc
command can be used to take a program out of either executing or suspended mode so that the
buffer can be opened to download new contents.
When the open plc n command is sent to prepare the PLC program buffer for downloading of
new contents, all existing contents of that buffer are automatically erased. There is no need to use
a clear command to do this as in older types of PMAC controllers. As long as the buffer is
open, the PLC program cannot be executed; a close command must be sent first.
Subprograms
A new subprogram can be downloaded to the Power PMAC at any time, even while other
programs are executing. For a subprogram buffer that is already present in Power PMAC, the
buffer can be opened for downloading new contents unless that program (or a subprogram called
from it) is presently executing, or suspended (e.g. with a hold, step, quit, or pause command) such
that it is possible to resume execution at the suspended point. An abort (a) command, if the top-
level program is a motion program, or a pause plc command, if the top-level program is a
PLC program can be used to take a program out of either executing or suspended mode so that the
buffer can be opened to download new contents.
When the open subprog n command is sent to prepare the subprogram buffer for
downloading of new contents, all existing contents of that buffer are automatically erased. There
is no need to use a clear command to do this as in older types of PMAC controllers. As long as
the buffer is open, the subprogram cannot be executed; a close command must be sent first. If
another program tries to call this subprogram while its buffer is open, that program will stop with
an error.
Kinematic Subroutines
Forward and inverse kinematic subroutines cannot be downloaded for a coordinate system while
a motion program in that coordinate system or any PLC programs (or subprograms called from
them) are executing, as these programs could attempt to call the kinematic subroutines at any
time, leading to a potentially dangerous failure.
When the open forward or the open inverse command is sent to prepare the subroutine
buffer of the presently addressed coordinate system for downloading of new contents, all existing
contents of that buffer are automatically erased. There is no need to use a clear command to do
this as in older types of PMAC controllers. As long as the buffer is open, motion programs in the
coordinate system, or any PLC programs, cannot be executed; a close command must be sent
first.
If the open forward or the open inverse command is immediately followed by a close
command, with no intervening buffered program commands, the subroutine ceases to exist;
Power PMAC regards the coordinate system as not having the subroutine.
The “Power PMAC Script Language” top-level folder will contain all of the sub-folders and files
for the Script language programs. The sub-folders in this folder are:
The following screen capture shows how the Script programs of a sample project are organized in
the Solution Explorer:
To add a new file under a sub-folder, right-click on the name of the sub-folder, then click on
“Add” on the little sub-menu that comes up. To start a new file, next click on “New”; to import a
file, whether from another project or a separate source, click on “Existing”, then specify the path
and file to import.
Note that the IDE project manager does not support rotary motion programs, as these are
generally sent to the Power PMAC during the actual running of the application, outside of the
IDE project.
The use of the variables themselves is covered in more detail in the Power PMAC Computational
Features chapter of the User’s Manual.
ptr AirSupplyOn->Acc65E[0].DataReg[4].5;
ptr PressureIn->Clipper[0].GpioData[0].0.8;
During the process of downloading the project, the IDE assigns each declared variable name to
one of the matching Power PMAC enumerated variables. For each variable type, a directive in the
project file “pp_proj.ini” specifies the starting variable number for each type to be used in these
auto-assignments. In the default file, these directives are:
PVARSTART=8192
QVARSTART=1024
MVARSTART=8192
With these directives, auto-assignment of “global” variables starts at P8192 and goes up (P0
through P8191 are not used for this); auto-assignment of “csglobal” variables starts at Q1024 and
goes up (Q0 through Q1023 are not used for this); auto-assignment of “ptr” variables starts at
M8192 and goes up (M0 through M8191 are not used for this). These settings will seldom need to
be changed.
Once the project with the declared and/or defined user variable names of these types has been
downloaded to the Power PMAC, these names become part of the project database, and the
names can be used in other parts of the IDE, notably the terminal and watch windows.
Note that it is not possible to view directly the values of local variables (with or without user
names) from outside the program.
The “#define” directive creates an effective text substitution. It can also be used to substitute for
text other than variable names, especially for constants.
Subprograms
The IDE lets you declare subprograms with a list of arguments, making the declaration much like
those in standard high-level programming languages. If you declare a subprogram in the form:
the IDE will create code like the following from that:
Arguments declared in the list without a starting “&” character are intended for passing values to
the subprogram; these can be constants and expressions as well as variables. Arguments declared
in the list with a starting “&” character are intended for returning values to the calling program;
these must be variable names. If you want to use a single variable for both purposes, you must
declare it in both forms.
Up to 16 arguments can be declared in this way. (It is not required to have any arguments.)
If you declare local variables inside the subprogram, these will be automatically assigned to L-
variables starting with the one numbered one greater than the highest number used for the
“argument” variables. These argument variables can be used within the program without any
further declaration or definition. To expand on this example with more meaningful names, if you
wrote the following code for the subprogram in the IDE:
where the arguments are user-declared or defined variables. This would generate code for the
Power PMAC as:
Note that local stack variable Ri of the calling program is the same as Li of the called
subprogram. More detail of how these local stack variables work is given in the Power PMAC
Computational Features chapter of the User’s Manual.
the IDE will create code like the following from that:
#define Arg3 L2
#define Arg4 L3
n10000: …
Arguments declared in the list without a starting “&” character are intended for passing values to
the subroutine; these can be constants and expressions as well as variables. Arguments declared
in the list with a starting “&” character are intended for returning values to the calling routine;
these must be variable names. If you want to use a single variable for both purposes, you must
declare it in both forms.
Up to 16 arguments can be declared in this way. (It is not required to have any arguments.)
To expand on this example with more meaningful names, if you wrote the following code for the
subprogram in the IDE:
A call to this subroutine from a higher-level routine in the same program could be written as:
where the arguments are user-declared or defined variables. This would generate code for the
Power PMAC as:
Note that local stack variable Ri of the calling program is the same as Li of the called
subprogram. More detail of how these local stack variables work is given in the Power PMAC
Computational Features chapter of the User’s Manual.
the IDE will create code like the following from that:
Arguments declared in the list without a starting “&” character are intended for passing values to
the subroutine; these can be variable names, constants or expressions. Arguments declared in the
list with a starting “&” character are intended for returning values to the calling routine; these
must be variable names. Both forms must be declared to use a single variable for both purposes.
Up to 16 arguments can be declared in this way. (It is not required to have any arguments.)
To expand on this example with more meaningful names, if you wrote the following code for
subprogram subroutines in the IDE:
the IDE would create code for the Power PMAC as:
Calls to these subroutines from a higher level program could be written as:
where the arguments are user-declared or defined variables. The IDE would generate code for the
Power PMAC as:
Note that local stack variable Ri of the calling program is the same as Li of the called subroutine.
More detail of how these local stack variables work is given in the Power PMAC Computational
Features chapter of the User’s Manual.
Kinematic Subroutines
The IDE provides several features for making the creation of kinematic subroutines easier and
more understandable. You can declare the subroutines in a form like:
where the number in parentheses is the number of coordinate system that the routine is assigned
to. This is sent to the Power PMAC in the form:
Also, there is a large set of already-defined user variable names for the input and output local
variables for the routines. The user does not need to make these definitions explicitly. With
Sys.MaxMotors at its default value of 32, these include:
#define KinPosMotor0 L0
#define KinPosMotor1 L1
#define KinPosMotor2 L2
...
#define KinPosMotor31 L31 // Up to Sys.MaxMotors-1
#define KinPosAxisA C0
#define KinPosAxisB C1
...
#define KinPosAxisZ C8
#define KinPosAxisAA C9
...
#define KinPosAxisZZ C31
#define KinVelMotor0 R0
#define KinVelMotor1 R1
#define KinVelMotor2 R2
...
#define KinVelMotor31 R31 // Up to Sys.MaxMotors-1
Note that the user will generally not need to know which variables are assigned to which user
name, and can just use the names freely.
More detail on writing forward and inverse kinematic subroutines is provided in the chapter
Setting Up a Coordinate System of the User’s Manual.
Motion Programs
Power PMAC Script motion programs provide for automatic sequenced execution of commanded
moves and the calculations associated with them. Because many of its key actions – moves,
dwells, and delays – “take time”, a standard high-level programming language would require the
user to command the start of such an action and then explicitly monitor for the end.
In addition, if multiple moves need to be executed without an intervening stop, the motion
program must calculate one or more moves ahead to create the proper equations of motion to join
these moves together “on the fly”. Standard programming languages do not have good
mechanisms for allowing the user to program these types of motion sequences easily.
The execution rules for motion programs in the Power PMAC Script language are designed to
facilitate the programming of these types of tasks. Program calculations will automatically
proceed as far ahead as is necessary to ensure that the programmed move sequence can be
properly calculated. When this has happened, program calculations are automatically suspended
at this point. When the actual execution of the resulting commanded moves progresses to the
point where more program calculations are required to ensure that future commands in the
programmed move sequence can be calculated properly, motion program calculations resume
automatically, continue until that condition is met, and then suspend again. Note that the user’s
motion program does not have to contain any of this sequencing logic; the Power PMAC’s Script
execution engine handles this itself.
In the second way, each time the execution of commanded moves resulting from previous
calculations in the motion program advances into the next move in the queue, the execution
engine sets the block-request flag to indicate that it may be necessary to calculate more
programmed moves to keep the move-equation queue full enough.
Simple point-to-point moves that cannot be blended, such as rapid-move moves, do not
require a pre-calculated queue. The move equations are calculated from the program
command, and the move immediately starts executing. Subsequent program calculations
do not start again until the move is finished. A dwell command in the program, even a
dwell 0, always stops blending and pre-calculation as well. The same is true if saved
setup element Coord[x].NoBlend is set to 1 even for blended and splined move types.
Basic blending as in linear and circle-mode moves requires that one move ahead be
calculated. That is, move i+1 must be calculated before move i finishes (or even gets to
the point where the blend would need to start) so the blend between the two moves can be
calculated in time.
The buffered segmented lookahead function can require that many programmed moves
be pre-calculated. The saved setup element Coord[x].LHDistance specifies how many of
the coarse-interpolation “segments” derived from the programmed moves must be stored
in the lookahead buffer at any time. This forces the motion program to pre-calculate
enough programmed moves to keep the segment buffer full. In extreme cases, Power
PMAC may pre-calculate hundreds, or even thousands, of programmed moves ahead of
the execution point.
Commonly, during a continuous sequence of programmed moves, each time move execution
transitions into a new move, one more move from the program is calculated. But as the sequence
starts, multiple moves may be calculated at once to get the queue full, and at the end of the
sequence, the queue will empty.
The following motion program example shows where calculations are suspended (at the
horizontal lines).
The following diagram shows a sample time line for program move calculation and subsequent
move execution “n” move-ahead pre-calculation.
2 3 4
1
Execute "R"
Note that these sequencing rules mean that motion program calculations only occur at move
boundaries. If there are calculations or actions that you wish to occur at other times, those should
be implemented in another type of program, whether a Script PLC program, a C PLC program, or
an independent C application.
In these applications, saved setup element Sys.RtIntPeriod should typically be set to the default
value of 0 so that the real-time interrupt, where motion program calculations are performed,
executes every servo interrupt. This maximizes the chance that move calculations will always be
performed in time to have the equations of motion ready for execution.
In addition, some care may need to be taken with the setting of saved setup element Sys.PreCalc.
Technically, Power PMAC attempts to calculate enough moves ahead so that equations are ready
for at least (Sys.RtIntPeriod + 1) + Sys.PreCalc servo cycles ahead of the presently executing
point. For the large majority of Power PMAC applications, where the programmed move times
are not nearly as small as the servo update time, the default value of 1 for Sys.PreCalc can be
used reliably.
However, when the move times can be as small (or even smaller!) than the servo update time, the
value of Sys.PreCalc may need to be adjusted to optimize the balance between the possibilities of
“too much” pre-calculation, which can overflow a key buffer, and “too little” pre-calculation,
which can mean that equations will not be ready in time for execution, which would result in a
“run-time error”.
Each motor has a buffer of pending move equations in the sub-structures Motor[x].New[i] (i = 0
to 15) that is kept in fast “locked” cache memory for efficient use. This 16-equation buffer queue
should never be emptied during a continuous motion sequence, causing a run-time error, or
overflowed, causing a buffer error. If run-time errors are occurring (Coord[x].ErrorStatus = 16),
Sys.PreCalc should be increased. If buffer overflow errors are occurring (Coord[x].ErrorStatus
= 2), Sys.PreCalc should be decreased.
The status element Coord[x].BufferWarn can be used to optimize the setting of Sys.PreCalc
without actually creating errors. Sys.PreCalc should be set high enough that
Coord[x].BufferWarn is sometimes set to 1, meaning that another move block could not be
loaded into the equation buffer, but set low enough that BufferWarn does not get set to 2, which
would mean that a request for move calculations had to be delayed to keep from overflowing the
buffer.
The reason for this type of calculation suspension is concern for indefinite looping while
searching for the next move or equivalent command. Indefinite looping means that the processor
will not release to other tasks of the same or lower priorities as long as it is in the loop, unduly
delaying those tasks. In addition, if this occurs in the middle of a continuous sequence of moves,
the equations for the next move may not be computed by the time that move needs to start, with
the most recently calculated move ending at a non-zero velocity. When move equations are not
ready in time, a “run-time error” condition occurs, ending program execution and aborting the
resulting motion.
Saved setup element Coord[x].GoBack specifies how many “jumps back” can occur before
program calculations are suspended. If program calculations jump back (Coord[x].GoBack + 2)
times without finding a move or equivalent command, program calculations are suspended at that
point. If the most recently calculated move was set to blend or spline into the next move, a
deceleration to a stop is computed for that move instead. Program calculations will resume when
that deceleration is finished. If there are no moves in progress, program calculations will resume
on the next real-time interrupt.
In general, motion programs that permit indefinite looping without a move command inside the
loop should be avoided. This is especially true when PVT-mode moves, or linear and circle-mode
moves with cutter radius compensation active, are being executed, because the stopping of the
executing moves when calculations are suspended may not be graceful.
However, when the standard variable assignment command is used for something like setting the
value of an external output (analog or digital), the actual output will be set well before the
beginning of execution of the next programmed move, something that many users will find
undesirable. Because it is a common desire to be able to set output values in a program to occur in
proper sequence with the accompanying move execution, Power PMAC has implemented
“synchronous” variable assignments. A synchronous assignment is denoted by using and addition
“=” character in the assignment operator (e.g. M1 == 1 instead of M1 = 1, or M2 +== 32
instead of M2 += 32).
When the program calculation executes a synchronous variable assignment command, it places
the operation in a special assignment queue that is “parallel” to the motion equation queue for the
programmed moves. The actual assignment is not made until the equations for the next
programmed move are pulled from the motion equation queue for execution. This puts the actual
assignment in proper sequence with the move execution.
For more details on synchronous variable assignments, see the section “Synchronous Variable
Value Assignment” in the User’s Manual chapter “Power PMAC Computational Features”.
In addition, execution of a rotary motion program can reach the end of what has already been
downloaded in the Power PMAC. (This condition cannot occur in a fixed motion program.) If this
occurs, calculations are of course suspended at this point, and if the most recently calculated
move was set to blend or spline into the next move, a deceleration to a stop is computed for that
move instead. When additional program lines are downloaded into the Power PMAC, program
calculations will automatically resume.
PLC Programs
Power PMAC Script PLC programs execute much more like standard programming languages
than do motion programs. When a “scan” of a PLC program is started by the Power PMAC
scheduler, it executes until the end of the program, or until it reaches a “jump back” in the
program – the end of a while loop, or a goto command to an earlier line. If it reached the end
of the program, the next scan will start at the beginning of the program; if it stopped on a jump
back, the next scan will start at the point jumped back to.
Power PMAC provides this capability with its buffered PLC-style I/O functionality. (This was
introduced in V2.1 firmware, released 2nd quarter 2016). With this functionality, multiple input
registers can be automatically copied into buffered input registers at the start of a Script PLC scan
cycle. The user can specify registers to be copied at the beginning of a background PLC scan
cycle, at the beginning of a foreground PLC scan cycle, or some of each.
The bits in each input register can be digitally filtered so that up to 4 consecutive scan cycles in
the new state are required before the buffered holding register accepts the change. This is very
useful for electrical noise mitigation and pushbutton debouncing. In addition, any buffered input
bit can be forced on or off, useful for developing and debugging an application.
Multiple output registers can be automatically copied from buffered output registers at the end of
a Script PLC scan cycle. The user can specify registers to be copied at the end of a background
PLC scan cycle, at the end of a foreground PLC scan cycle, or some of each. Any buffered output
bit can be forced on or off, useful for developing and debugging an application.
The buffered PLC-style I/O functionality is described in detail in the User’s Manual chapter
Using General-Purpose Digital I/O with Power PMAC.
at that point as in a motion program, but instead continues on. The move command is simply to
start the move.
This difference in execution rules between motion and PLC programs means that some tasks are
better performed in one type of program or another. For execution of a pre-determined sequence
of moves, it is usually better to use a motion program. (Remember also that PLC programs can
only command rapid-mode axis moves and motor moves such as jogging and homing, so if any
other move types are desired, these must be done from motion programs.)
However, if the application may require decisions after the move starts, for example to change the
destination or speed, or to deal with error conditions, a PLC program will be much better to use
because its calculations stay active after the move starts and even if the move results in an error.
Many applications will check the status of the move each scan until it either reaches the
destination position properly or ends in an error.
Note that a PLC program does not guarantee that the position-match function is executed before a
commanded axis move to ensure that the starting axis position matches the present motor
position. The program must explicitly execute a pmatch command to do this. (If the axis
position already matches the present motor position, the pmatch command will not do anything,
but it will not hurt and will only take a small amount of processor time.)
In a PLC program, it is easy to “break into” an executing axis or motor move with a new move
command. The new move will use the present instantaneous position, velocity, acceleration, and
jerk as its starting point, providing a seamless transition. If the new move command is an
incremental-mode axis move, the end point of this move will be specified distance from the end
point of the presently executing move unless the new move command is preceded by a pmatch
command, in which case the destination is calculated as the distance from the present
instantaneous position.
In execution, each time the while loop is executed with the condition logically true, the PLC scan
ends, and other tasks at the same priority level (e.g. other PLC programs) will be executed before
the next scan of this PLC program, which will start at the beginning of the while loop again.
In addition, Power PMAC provides a set of automatic “countdown timers” that are useful to delay
actions of PLC programs for a specified time. (These timers are new in V2.2 firmware, released
3rd quarter 2016.) There are 256 of these timers.
Each timer has a non-saved setup data structure element Sys.CdTimer[i] (i = 0 to 255) that the
user can write to at any time. This is a non-negative floating-point value, scaled in milliseconds.
The most common method of use is to write a value to a timer element, then have the PLC
program loop until the element value reaches 0.
For example, to delay with no action for a period of 750 milliseconds, the following PLC code
segment could be used:
Sys.CdTimer[5] = 750;
while (Sys.CdTimer[5] > 0) {}
In a Power PMAC project, the user can give a meaningful name to a timer with a #define
directive. Also, it is common to perform some action, often a monitoring action, while looping.
As an example, with the directive:
the following code segment could be used to average measurements taken over a specified
number of seconds:
Subprograms
The execution rules for a subprogram are the same as for the top-level program in the program
stack that calls the subprogram. If the top-level program is a motion program, execution of the
subprogram follows motion program rules. If the top-level program is a PLC program, execution
follows PLC program rules. A subprogram with motion commands would therefore execute
differently when the top-level program is a PLC program compared to how it would execute
when the top-level program is a motion program. For this reason, extreme care is recommended
when writing a subprogram with commanded motion that is to be called by both motion and PLC
programs.
Kinematic Subroutines
Kinematic subroutines are called implicitly from programs as needed. They should not contain
any motion commands themselves. Their primary purpose is to convert between axis and motor
positions, but can contain other calculations as well (e.g. collision avoidance checks).
A kinematic subroutine will generally just run once through its calculations to the end. Looping
constructs may be used, and are often useful for iterative solutions. The number of loop cycles
that can be performed without suspending execution of the routine is determined by local data
structure element Ldata.GoBack. Each time the routine is called, the value of this element is set
to the value of saved setup element Coord[x].GoBack. If you wish a different value for the
kinematic subroutine, a value should be explicitly assigned to the local element at the beginning
of the subroutine (e.g. Ldata.GoBack = 20;).
If a list of multiple coordinate systems immediately precedes the command (e.g. &1..3r,
&2,4,6a), all of the listed coordinate systems are affected by the command, but the modally
addressed coordinate system for the communications thread is not changed.
For buffered program commands that start or stop motion program execution, the program issuing
the command must either list the affected coordinate system in the command (e.g. run1,
abort2), or modally address the coordinate system by setting the value of (non-saved) element
Ldata.Coord for the program. Each PLC program and each coordinate system can have its own
modally addressed coordinate system for these commands. For PLC programs, the power-on
default value for Ldata.Coord is 0. For coordinate systems, which control the modal addressing
of commands issued from motion programs running in the coordinate system, the default value
for Ldata.Coord is the number of the coordinate system itself. Using the modal address, the
coordinate system does not have to be listed in the command itself (e.g. run, abort).
For buffered program commands that take an argument, such as the program number, the
argument value comes after a colon character (e.g. start:500). If there is a value before the
colon, this value specifies the coordinate system to be affected (e.g. start3:500)
For the coordinate system to be able to start execution of a motion program, the following
conditions must be met:
All motors assigned to position axes in the coordinate system must be activated
(Motor[x].ServoCtrl > 0), enabled, and in closed-loop mode.
If axis-definition statements are used, conversion from motor positions to matching axis
positions must be possible (Coord[x].Csolve = 1) so Power PMAC can compute the
starting axis positions from the present commanded motor positions. (If there is a
forward-kinematic subroutine present for the coordinate system, Power PMAC assumes
that it will calculate the starting axis positions correctly.)
No motor assigned to a position axis in the coordinate system may have both overtravel
limits set.
The selected motion program (and any label selected) must be present and valid.
If re-starting from a suspended state, all motors must be in the same commanded position
as they were when initially stopped in the suspended state (but changes in master position
when following is in offset mode are permitted).
It is possible to execute a motion program in a coordinate system in which no motors are assigned
to axes. This provides a type of “dry run” capability for the program.
The s and step commands can be used to start execution of a motion program that has not been
executing, or to resume execution of a motion program that has been stopped in a suspended
state. (They can also be used to halt execution of a program that is currently running in
continuous mode – see the section below under Stopping Script Motion Program Execution.)
The integer part of the numerical argument in the command (e.g. on-line start12, program
start:12) specifies the number of the motion program to be pointed to. The fractional part of
the numerical argument, if any, specifies the number of the “jump label” in the motion program to
be pointed to; the value of the fractional component is multiplied by 1,000,000 to obtain the
number of the jump label. For example, on-line start12.001 or program start:12.001
points to jump label N1000: of motion program 12. There is an implicit N0: jump label at the
beginning of each motion program, so if there is no fractional component to the argument, the
command points the coordinate system to the beginning of the motion program and executes it
from that point.
If the program was in continuous execution mode (as from an r [run] command) when it was
suspended, it will resume in continuous execution mode. If the program was in single-step
execution mode (as from an s [step] command) when it was suspended, it will resume in
single-step mode, which probably means that the already calculated moves will be finished
without the calculation of further moves.
The > [lh>] command can also be used when the coordinate system is retracing moves from the
special lookahead buffer in the reverse direction after a < [lh<] command, without the need to
come to a full stopped state in between.
The < [lh<] command can also be used when the coordinate system is executing moves from the
special lookahead buffer in the forward direction, without the need to come to a full stopped state
in between.
Execution of the motion program can be resumed from this point with an on-line r or s
command, or a program run or step command. Because execution can be resumed from this
point (Coord[x].ProgActive = 1), the motion program buffer cannot be cleared in this state;
usually an a [abort] command is given first to put the coordinate system in a state where the
buffer can be cleared.
Execution of the motion program can be resumed from this point with an on-line r or s
command, or a program run or step command. Because execution can be resumed from this
point (Coord[x].ProgActive = 1), the motion program buffer cannot be cleared in this state;
usually an a [abort] command or a b [begin] command is given first to put the coordinate
system in a state where the buffer can be cleared.
Technically, the program is still running in this state (Coord[x].ProgRunning = 1), but because
commanded motion is not advancing, no further program calculations are being triggered. It is
possible to tell that motion has been stopped because Coord[x].ProgProceeding has been set to
0. Also, Coord[x].FeedHold is set to 3 during the deceleration to stop, to 1 when stopped, and to
2 when accelerating from stop during resumption of motion.
Execution of the motion program can be resumed from this point with an on-line r, s, or >
command, or a program run, step, or lh> command. Because execution can be resumed from
this point (Coord[x].ProgActive = 1), the motion program buffer cannot be cleared in this state;
usually an a [abort] command or a b [begin] command is given first to put the coordinate
system in a state where the buffer can be cleared.
segments from the lookahead buffer, at a rate limited by the maximum acceleration parameter
Motor[x].InvAmax for one of the motors. This is called a “quick stop” command. In general,
motion will not stop at a programmed point, but in a multi-axis application, it will stop along the
programmed path. Motors assigned to axes in the coordinate system are left in closed-loop zero-
velocity position control at this point.
If the program is not presently executing moves from the dynamic lookahead buffer, motion is
stopped as if an h [hold] command had been given, as explained in the preceding section.
Technically, the program is still running in this state (Coord[x].ProgRunning = 1), but because
commanded motion is not advancing, no further program calculations are being triggered. It is
possible to tell that motion has been stopped because Coord[x].ProgProceeding has been set to
0. If stopped during a buffered lookahead move, Coord[x].LookAheadStop is set to 1.
Execution of the motion program can be resumed from this point with an on-line r, s, or >
command, or a program run, step, or lh> command. Because execution can be resumed from
this point (Coord[x].ProgActive = 1), the motion program buffer cannot be cleared in this state;
usually an a [abort] command or a b [begin] command is given first to put the coordinate
system in a state where the buffer can be cleared.
Reverse execution of already executed buffered lookahead move segments can be started from
this point with an on-line < command or a program lh< command.
This state can occur in a variety of different ways. If the coordinate system has its default setting
of responding to command changes in the time-base value (Coord[x].pDesTimeBase =
Coord[x].DesTimeBase.a), this can be one with an on-line %0 command or a program
Coord[x].DesTimeBase=0 command. Often this will come from an operator’s “override
knob” setting of 0. The time-base “%” override value for the coordinate system is ramped down
to zero, starting immediately, at a rate set by the value of saved setup element
Coord[x].TimeBaseSlew for the coordinate system.
If the coordinate system is using “external time base” from a master encoder or external clock
pulse train (Coord[x].pDesTimeBase = EncTable[n].DeltaPos.a), the absence of pulses will
cause the time-base value to become 0. Under external time base, Coord[x].TimeBaseSlew is
usually set to a high enough value that it never limits the rate of change of the time base value;
this is typically limited by the rate of change of frequency of the input signal.
Commanded motion during the deceleration occurs along the programmed path in multi-axis
applications, ending at the point where the % value reaches zero. In general, this will not be at a
programmed point. Motors assigned to axes in the coordinate system are left in closed-loop zero-
velocity position control at this point.
Technically in this mode, the program and moves are still executing (Coord[x].ProgRunning =
1, Coord[x].ProgProceeding = 1). Note that this status is different from that of a “hold”
condition. Execution of motion can be resumed simply by setting the time-base value greater than
zero, by command for internal time base, or by signal for external time base. Because execution
can be resumed from this point (Coord[x].ProgActive = 1), the motion program buffer cannot be
cleared in this state; usually an a [abort] command is given first to put the coordinate system in
a state where the buffer can be cleared.
The program counter is automatically reset to the beginning of the motion program, so it is not
possible to resume execution at the stopped point (Coord[x].ProgActive = 0). Generally, an
abort command is only used to halt execution of a running motion program when there is a fault
or error condition.
However, if program execution has been suspended in a manner that would permit resumption
from the suspended point (hold, quit, step, etc.), and it is desired not to resume the program, an
abort is commonly used to completely terminate program execution. This permits the motion
program buffer to be cleared or reused.
If automatic brake control is enabled for a motor in the coordinate system (Motor[x].pBrakeOut
> 0), the disabling of the motor is not delayed until the brake is engaged.
The program counter is automatically reset to the beginning of the motion program, so it is not
possible to resume execution at the stopped point (Coord[x].ProgActive = 0). All motors
assigned to axes in the coordinate system must be re-enabled in closed-loop mode before the
coordinate system can start a motion program again. Generally, a disable command is only used
to halt execution of a running motion program when there is a fault or error condition so severe
that motors cannot be brought to a closed-loop stop.
at a programmed point, and in a multi-axis application, the (uncontrolled) deceleration will not be
along the programmed path.
If automatic brake control is enabled for a motor in the coordinate system (Motor[x].pBrakeOut
> 0), the disabling of the motor is delayed until the brake is engaged, as set by
Motor[x].BrakeOnDelay. This delay is the only difference from using the disable command.
Because the use of disabling action during motion program execution is generally only needed for
serious fault conditions that could cause an immediate runaway, this delay is usually not
desirable, so the standard disable command is usually used instead.
The program counter is automatically reset to the beginning of the motion program, so it is not
possible to resume execution at the stopped point (Coord[x].ProgActive = 0). All motors
assigned to axes in the coordinate system must be re-enabled in closed-loop mode before the
coordinate system can start a motion program again. Generally, a disable command is only used
to halt execution of a running motion program when there is a fault or error condition so severe
that motors cannot be brought to a closed-loop stop.
The program counter is automatically reset to the beginning of the motion program, so it is not
possible to resume execution at the stopped point (Coord[x].ProgActive = 0). Generally, an
“adisable” command is only used to halt execution of a running motion program when there is a
fault or error condition.
If automatic brake control is enabled for a motor in the coordinate system (Motor[x].pBrakeOut
> 0), the disabling of the motor is not delayed until the brake is engaged.
In all coordinate systems executing a motion program, the execution is immediately halted, and
program counters are automatically reset to the beginning of the motion program, so it is not
possible to resume execution at the stopped point. All motors assigned to axes in a coordinate
system must be re-enabled in closed-loop mode before the coordinate system can start a motion
program again. Generally, a kill command is only used to halt execution of a running motion
program when there is a fault or error condition so severe that motors cannot be brought to a
closed-loop stop.
Note that a kill command for specific motors (e.g. #3k or #1..8k), even if for all of the motors
in the coordinate system, will not act on the motors of a coordinate system that is executing a
motion program.
If automatic brake control is enabled for a motor (Motor[x].pBrakeOut > 0), the disabling of the
motor is delayed until the brake is engaged, as set by Motor[x].BrakeOnDelay. This delay is the
only difference from using the disable command. Because the use of disabling action during
motion program execution is generally only needed for serious fault conditions that could cause
an immediate runaway, this delay is usually not desirable, so the standard kill-all (#*k) command
is usually used instead.
In all coordinate systems executing a motion program, the execution is immediately halted, and
program counters are automatically reset to the beginning of the motion program, so it is not
possible to resume execution at the stopped point. All motors assigned to axes in a coordinate
system must be re-enabled in closed-loop mode before the coordinate system can start a motion
program again. Generally, a kill command is only used to halt execution of a running motion
program when there is a fault or error condition so severe that motors cannot be brought to a
closed-loop stop.
Note that a kill command for specific motors (e.g. #3dkill or #1..8dkill), even if for all of
the motors in the coordinate system, will not act on the motors of a coordinate system that is
executing a motion program.
The enable plc command can act on a PLC program that is disabled, paused, stopped in
single-step mode, or already enabled. In all cases, the next scan will start at the beginning of the
program. This is appropriate if the PLC program is disabled, and is the only way to start or re-
start execution of the PLC program, but may not be appropriate for the other modes, particularly
if the execution has stopped at a point other than the end of the program due to the scan ending at
the end of a while loop or because the program was in single-step mode.
This command sets status bits Plc[i].Active and Plc[i].Running to 1 for the affected PLC
program(s).
This command sets (or leaves) status bit Plc[i].Active to 1, and sets Plc[i].Running to 0 after
completing the step for the affected PLC program(s).
This single-step mode of execution for PLC programs is primarily for debugging purposes.
This command sets status bits Plc[i].Active and Plc[i].Running to 1 for the affected PLC
program(s).
If the disable plc command is issued from within the PLC program itself, the present scan
will finish, even if the command is not the final command for the scan.
This command sets status bits Plc[i].Active and Plc[i].Running to 0 for the affected PLC
program(s).
started at the paused point (beginning of a while loop if the last scan finished at the end of the
loop, or at the beginning of the program if the last scan finished at the end of the program) in
continuous mode with a resume plc command, or in single-step mode with a step plc
command. Execution can be re-started at the beginning of the program (regardless of where the
last scan ended) with an enable plc command
If the pause plc command is issued from within the PLC program itself, the present scan will
finish, even if the command is not the final command for the scan.
This command leaves status bits Plc[i].Active at 1 and sets Plc[i].Running to 0 for the affected
PLC program(s).
In either case, the program is ready to restart operation at the next line either with a resume
plc command (which starts continuous execution) or with a step plc command (which starts
single-step execution).
This command leaves status bits Plc[i].Active at 1 and sets Plc[i].Running to 0 for the affected
PLC program(s).
RS-274 is an old standard, dating back to times when the program parsers had to be very simple.
Its syntax is therefore also very simple, with all commands in letter/number format (e.g. X100
F50). It is also a very “loose” standard, with many different “dialects” of the language. In
addition, there are many different machine-specific implementation issues that must be dealt with
in any application.
Second, Power PMAC interprets the other key commands in the RS-274 standard as subroutine
calls. This permits the machine integrator to write embedded subroutines that implement these
codes, using whatever “dialect” is desired, and covering all machine-specific issues.
G, M, T, and D-Codes
The standard “codes” in RS-274 are G-codes, M-codes, T-codes, and D-codes. Power PMAC
treats these as subroutine calls to dedicated subprograms.
Therefore, to implement the execution of RS-274 programs, the machine integrator must write
subprograms that execute the specific codes of these types in the manner desired. With these
subprograms resident in the Power PMAC, it can execute standard RS-274 “part programs”
directly. Part programmers and machine operators do not need to understand the underlying
mechanism for this execution.
In most implementations, these subprograms will be called only from motion programs running in
a single coordinate system, typically C.S.1. However, it is possible for motion programs running
in multiple coordinate systems to call the same subprograms. Due to the use of variables unique
to each coordinate system (local variables [L and D] or coordinate-system global [Q]), many
tasks can be done in the subprograms for multiple coordinate systems without conflict. However,
it may be easier in many cases to use separate subprograms for separate coordinate systems, even
if many of the code subroutines are identical between coordinate systems. This is particularly true
for M-codes, which will likely use different outputs the same tasks in different coordinate
systems.
Note that if the part program executes a code that causes a call to a non-existent subroutine in an
existing subprogram, it is treated as a “no-op”, and does not cause an error.
If the same subprogram can be called from motion programs running in multiple coordinate
systems, and it is necessary to know which coordinate system is calling it, this can be determined
from the value of local data structure element Ldata.coord. If it is necessary to access a data
structure element for the coordinate system that is executing the subroutine, a local variable
should be given the value of this element, and the local variable then used as the index for the
coordinate system. For example:
local ThisCs;
ThisCs = Ldata.coord;
Coord[ThisCs].NoBlend = 1;
S-Codes
S-codes in RS-274 programs are commonly used to set spindle speeds or equivalent (e.g. laser
intensity, waterjet pressure). Sometimes the S-value is used as an argument in an M-code. For
example M03 S1200 may mean “start spindle clockwise at 1200 rpm”. In this case, the S-value
is passed to the M03 subroutine with a read(S) command and the value is put in local variable
D19 for the coordinate system. The subroutine can then process this value further.
If the S-code is executed in a motion program when it is not an argument in a subroutine call, the
value of the constant or expression following it is assigned to local variable D53 for the
coordinate system, where it can be used by other routines as the user desires.
If Coord[x].Sprog is set to a value greater than 0 when this “independent” S-code is executed,
then after D53 is set to the value of the code, the subprogram specified by Coord[x].Sprog
(suggested 1004) is called. If the subprogram has a numerical jump label matching the code
number (1000 times the code number), subprogram execution will start at that label.
If the subprogram does not have a numerical jump label matching the code number, subprogram
execution will start from the top. In many applications, the execution logic of the subprogram will
be identical for all S-code values (with the S-code value in D53 simply specifying the speed), so
no numeric jump labels will be used.
This subprogram can be used when more complex control is required, such as stopping motion
until the specified speed is reached. The ability to call this subprogram is new in V2.4 firmware,
released 1st quarter 2018.
H-Codes
An H-code (height-offset code) is a call to the subprogram of the number specified by
Coord[x].Hprog (commonly subprog 1005) at the line jump label 1000 times the code
number (e.g. H06 jumps to N6000: of this subprogram).
Standard G-Codes
This section explains implementation issues with the most common, and most standard of the
“preparatory” G-codes in RS-274 programs. These subroutines would be included in the
subprogram whose number is specified by Coord[x].Gprog, which is usually the default
subprog 1000. These examples are intended just as a starting point, as each application will
have unique features depending on the “dialect” used and machine-specific features.
When there is a subprogram call to a non-existent label (but in an existing subprogram), such as
would occur with an unimplemented G-code, Power PMAC jumps to the top of the subprogram.
So whatever action is to be taken on an unimplemented code should be specified at the very
beginning of the G-code subprogram. Note that this should be before any jump label, including
the N0: label used for the G00 code implementation.
If an unimplemented G-code call is desired to be an error that stops execution of the motion
program, there should simply be a stop command at the top of the subprogram. This halts
execution of the program and returns the program counter to the beginning of the top level motion
program. The stop command does not need to be followed by a return command, but using
the return command may make it easier to understand that this is separate action from
subsequent codes.
Some users may want to “clear” the motion program line of possible arguments, as when the call
is for an unimplemented canned cycle. This can be done with a read command that checks the
command line for most possible letter arguments (but probably not G or M). For example:
read(A,B,C,D,E,H,I,J,K,L,P,Q,R,S,T,U,V,W,X,Y,Z);
return;
Of course, with a system variable and branching logic, it is possible to implement the user’s
choice of these options, giving the possibility of one option for development and debugging, and
another for operation.
Under the RS-274 standard, the parameters for G00 moves are not set in the program, but rather
by system constants. In Power PMAC, motor speed for a rapid-mode move is set by
Motor[x].MaxSpeed or Motor[x].JogSpeed, depending on the setting of
Motor[x].RapidSpeedSel. Whether all motors use these speeds, or those with shorter times for a
move are slowed to match the time of the longest motor, is determined by
Coord[x].RapidVelCtrl. Acceleration and deceleration are controlled by Motor[x].JogTa and
Motor[x].JogTs.
Some users will want to implement point-to-point positioning with a “fast” linear mode,
especially if the coordinate system is defined with kinematic subroutines. In this case, a rapid-
mode move may yield an unpredictable path in tool-tip coordinates, because the inverse
kinematics are only calculated for the end-point of a rapid-mode move, and no lookahead
dynamic limiting is possible. In addition, the use of linear mode permits the use of the same
“segmentation override” for feedrate override functions as for G01, G02, and G03 modes, and
provides the possibility of using separate acceleration and deceleration parameters.
There are multiple techniques for making Power PMAC’s linear move mode behave much like
the rapid move mode, but the simplest is to remove all axes from the vector-feedrate axis list with
the nofrax command, then use the value of Coord[x].AltFeedrate to control the speed of the
move(s). This technique is appropriate when there are only Cartesian positioning axes in the
system. The AltFeedrate parameter is used to calculate the move time whenever the time for a
“non-feedrate axis”, calculated as the axis distance divided by this value, is greater than the time
for the “vector feedrate” axes, calculated as the vector distance divided by the vector feedrate.
With no vector feedrate axes, this second time is zero, and the first of these move times will be
used, and it will be the longest time for any of the axes.
To implement point-to-point positioning mode with this technique, the G00 subroutine could be
implemented something like:
N0: linear;
dwell 0;
nofrax;
Coord[1].AltFeedrate = MyRapidSpeed;
Coord[1].NoBlend = 1;
return;
In this example, MyRapidSpeed is a user variable or constant in axis units (as set by the axis
definitions) per coordinate system time unit (as set by Coord[x].FeedTime). Setting
Coord[x].NoBlend to 1 ensures that no moves will be blended together.
If there are rotary axes as well, it is better to specify a very high feedrate value, high enough that
at least one of the motors, linear or rotary, will always be limited by its Motor[x].MaxSpeed
parameter. In this case, the G00 subroutine could be implemented something like:
N0: linear;
if (MyMoveMode != 0) {
dwell 0;
MyLastCuttingFeedrate = -Coord[1].Tm;
}
MyMoveMode == 0;
F(MyRapidFeedrate);
Coord[1].NoBlend = 1;
return;
In this example, the present programmed feedrate is stored in a user variable so it can be restored
when returning to G01, G02, or G03 mode.
If G00 mode is implemented as a “fast linear” mode with the speed controlled by
Coord[x].AltFeedRate, the G01 subroutine could be implemented as:
N1000: linear;
frax(X,Y,Z);
Coord[1].AltFeedrate = MyRotarySpeed;
Coord[1].NoBlend = 0;
return;
In this example, Coord[x].AltFeedRate would control the speed of any moves only involving
non-feedrate axes – usually rotary axes – and only needs to be set if there are non-feedrate axes in
the system. MyRotarySpeed is a user variable or constant in axis units (as set by the axis
definitions) per coordinate system time unit (as set by Coord[x].FeedTime). Setting
Coord[x].NoBlend to 0 enables blending between subsequent linear and circle mode moves.
If G00 mode is implemented as a “fast linear” mode with the speed controlled by a motor’s
Motor[x].MaxSpeed, the G01 subroutine could be implemented as:
N1000: linear;
if (MyMoveMode == 0) {
dwell 0;
F(MyLastCuttingFeedrate);
}
MyMoveMode == 1;
Coord[1].NoBlend = 0;
return;
If G00 mode is implemented as a “fast linear” mode with the speed controlled by
Coord[x].AltFeedRate, the G02 subroutine could be implemented as:
N2000: circle1;
frax(X,Y,Z);
Coord[1].AltFeedrate = MyRotarySpeed;
Coord[1].NoBlend = 0;
return;
In this example, Coord[x].AltFeedRate would control the speed of any moves only involving
non-feedrate axes – usually rotary axes – and only needs to be set if there are non-feedrate axes in
the system. MyRotarySpeed is a user variable or constant in axis units (as set by the axis
definitions) per coordinate system time unit (as set by Coord[x].FeedTime). Setting
Coord[x].NoBlend to 0 enables blending between subsequent linear and circle mode moves.
If G00 mode is implemented as a “fast linear” mode with the speed controlled by a motor’s
Motor[x].MaxSpeed, the G02 subroutine could be implemented as:
N2000: circle1;
if (MyMoveMode == 0) {
dwell 0;
F(MyLastCuttingFeedrate);
}
MyMoveMode == 2;
Coord[1].NoBlend = 0;
return;
If G00 mode is implemented as a “fast linear” mode with the speed controlled by
Coord[x].AltFeedRate, the G03 subroutine could be implemented as:
N3000: circle2;
frax(X,Y,Z);
Coord[1].AltFeedrate = MyRotarySpeed;
Coord[1].NoBlend = 0;
return;
In this example, Coord[x].AltFeedRate would control the speed of any moves only involving
non-feedrate axes – usually rotary axes – and only needs to be set if there are non-feedrate axes in
the system. MyRotarySpeed is a user variable or constant in axis units (as set by the axis
definitions) per coordinate system time unit (as set by Coord[x].FeedTime). Setting
Coord[x].NoBlend to 0 enables blending between subsequent linear and circle mode moves.
If G00 mode is implemented as a “fast linear” mode with the speed controlled by a motor’s
Motor[x].MaxSpeed, the G03 subroutine could be implemented as:
N3000: circle2;
if (MyMoveMode == 0) {
dwell 0;
F(MyLastCuttingFeedrate);
}
MyMoveMode == 3;
Coord[1].NoBlend = 0;
return;
Most Power PMAC implementations will choose a single letter and a specific time unit for the
dwell. For example, to use the letter P with a number specifying the time in seconds, the
subroutine could be:
N4000: read(P);
dwell(D16 * 1000);
return;
The read(P) command places the value after the letter P in the main program into local
variable D16 (as P is the 16th letter of the alphabet). Since Power PMAC’s dwell time is always
specified in milliseconds, the specified time in seconds is multiplied by 1000.
A more robust implementation may want to ensure that a dwell time value has actually been
specified in the command line. In the above subroutine, if no P-value were specified after the G04
in the part program, the subroutine would execute a dwell using whatever value happened to be in
the D16 variable at the time. Bit n-1 of local variable D0 is set to 1 if and only if a value
associated with the nth letter of the alphabet has been successfully read in the most recent read
command. For the letter P, this is bit 15, with a value of 215, or 32,768. A subroutine using this
feature would be like the following:
N4000: read(P);
if (D0 & 32768) dwell(D16 * 1000);
else dwell 0;
return;
Of course, the action to take, if any, if no value is present to be read, is up to the integrator.
Power PMAC’s dwell command always executes at 100%; it does not use the feedrate override
value (whether time base or segmentation override) in force at the time. It also stops any pre-
calculation for blending and lookahead purposes. On the other hand, Power PMAC’s delay
command executes at the override value in effect at the time, and does not disable pre-calculation.
Depending on what features the integrator wants, dwell, delay, or both commands could be
used. For example, to implement a G04 that uses the override value in effect, but disables pre-
calculation, the following subroutine could be used:
N4000: read(P);
if (D0 & 32768) {
dwell 0;
delay(D16 * 1000);
dwell 0;
}
else dwell 0;
return;
The operation described above is for the standard functionality of single-shot exact stop, where
the blending is disabled after the next move commanded in the part program. So if the part
program had the command line G09 X10 Y20, the blending would be disabled at the point
(10,20). If you wish the G09 code to inhibit blending before the next move, the subroutine should
be:
Typically, specification of the cutter radius using the ccr{data} command is not performed
within these G-code routines. More commonly, it is specified in a T-code or D-code routine.
Coord[x].NoBlend is a saved setup element, so the power-on/reset default state can be chosen by
the integrator. The factory default value for this element is 0, so blending is enabled by default.
The modal exact stop operation of G61 is distinct from the single-shot exact stop of G09.
distances (i.e. referenced to the axis starting position for the move). These modes are
implemented in Power PMAC with the abs and inc commands, respectively. This means that
the standard implementation of these codes would be:
In the G93 “inverse-time” mode, the F-code value specifies the reciprocal of the time for the
move, typically with the time in minutes being one divided by the F-code value. This mode is
commonly used when linear and rotary axes are commanded together in the same move block. It
is enabled by setting non-saved setup element Coord[x].InvTimeMode to a non-zero value.
Both feedrate and inverse-time mode use the value of saved setup element Coord[x].FeedTime
in their calculations. This parameter itself has units of milliseconds. In virtually all RS-274
applications, Coord[x].FeedTime should be set to 60,000 so feedrates are specified in
millimeters or inches per minute, and times are specified as minutes divided by the F-code value.
Note that the factor default value of Coord[x].FeedTime is 1,000, specifying seconds, not
minutes.
With Power PMAC’s “external time base” feature, the spindle does not need to be under precise
control of the Power PMAC; instead, its encoder can be used as the time base “master” for the
coordinate system with the linear axes. Refer to the chapter Synchronizing Power PMAC to
External Events for details.
The key actions for this code are to define a “real time” speed for the spindle master (in
revolutions per minute), then calculate the “real time input frequency” from the encoder (in
counts per millisecond) that would be produced at this speed. An encoder conversion table entry
whose scaling EncTable[i].ScaleFactor value uses the RTIF processes the spindle encoder input.
A typical implementation of the G95 code would look like the following:
When using this code, it is necessary to restore settings properly for the G93 and G94 modes.
Typical implementations of those codes would look like the following:
Each move mode can be declared in a motion program, and all following move commands in the
program are executed using the rules of that mode, until a different mode is declared. PLC
programs can only command rapid-mode moves; if a PLC program commands a move, the
addressed coordinate system is automatically placed in rapid mode.
Move Commands
The move commands themselves consist of a set of one-letter (e.g. X) or two-letter (e.g. YY) axis-
specifiers, each followed by one or two values – a constant without parentheses (e.g. X-20) or a
mathematical expression in parentheses (e.g. YY(Target+50) ). The first value specified after
the axis name is always the end destination position if the axis is in abs (absolute) mode, or the
distance from the start point to the end point if the axis is in inc (incremental) mode. The
meaning of the second value, if there is one, depends on the move mode.
All separate axis moves specified on the same command line (e.g. X10.34 Y20) will execute
simultaneously in a coordinated fashion, starting at the same time, and in all modes except
possibly rapid mode, ending at the same time. Axis moves specified on separate lines will execute
sequentially, with or without stops in between, depending on the mode(s) in effect at the time.
Note that if any given axis specifier is found for a second time in one program line, Power PMAC
interprets this point as the beginning of a new command line. This permits multiple moves to be
condensed onto a single command line (e.g. X5 Y10 X7 Y13), possibly improving the
efficiency of the download process.
If an axis in the coordinate system is not explicitly commanded in the move command, it is
implicitly commanded to have the same endpoint as start point for the move. Often this means
that the axis is commanded to hold still during the move.
Rapid-mode moves can be commanded either from motion programs or PLC programs. They are
the only type of move that can be commanded from PLC programs. If a move command is issued
from a PLC program, the coordinate system addressed by the PLC program is automatically put
into rapid mode (even if another move mode has just been declared in the program).
Velocity Specification
The top speed of a rapid-mode move is set either by the value of Motor[x].MaxSpeed or
Motor[x].JogSpeed. If Motor[x].RapidSpeedSel is set to the default value of 1,
Motor[x].MaxSpeed is used; if it is set to 0, Motor[x].JogSpeed is used instead. Note that a
move may not be long enough in distance to reach this top speed, given the acceleration
parameters.
If multiple axes are specified in the same move command, Power PMAC computes the move time
for each motor as the distance divided by the top speed. If Coord[x].RapidVelCtrl is set to its
default value of 0, all motors will use these move times (and therefore their commanded speeds),
and the motors with shorter times will finish first. However, if Coord[x].RapidVelCtrl is set to
1, the lesser move times are extended to equal the longest move time. In a Cartesian system, this
will yield a straight-line or nearly straight-line path, depending on the acceleration specifications
(see below).
No further checking of command velocity against any velocity limits is performed for rapid-mode
moves in any mode.
Acceleration Specification
The acceleration profile for rapid-mode moves is specified on a motor-by-motor basis using the
saved setup elements Motor[x].JogTa and Motor[x].JogTs (the same parameters that govern
acceleration for jogging and homing-search moves.
Specification by Time
If Motor[x].JogTa is greater than zero, it specifies the basic acceleration time in milliseconds.
This time is used regardless of the change in speed, so the rate of acceleration will be different for
different changes in speed.
If Motor[x].JogTs is greater than zero, it specifies the “S-curve” time (the time in each half of
the “S” of the profile) in milliseconds. During the “S-curve” portion of the profile, the
acceleration is increasing or decreasing at a constant rate (so these sections of the profile have a
constant “jerk”). This time is used regardless of the value of the peak acceleration, so the rate of
jerk will be different for different peak accelerations. If it is set to 0, there are no S-curve sections
in the acceleration profiles.
If Motor[x].JogTa is greater than Motor[x].JogTs, the total acceleration time is the sum of the
two element values. (Note that this is different from the PMAC and Turbo PMAC.) If
Motor[x].JogTa is less than Motor[x].JogTs, the total acceleration time is 2 * JogTs, and
JogTa is not used. The profiles for both cases are shown in the figure below.
Vel Acc
JogSpeed
ΔV/JogTa
V0
JogTs JogTs
JogTa
Vel Acc
“Top speed”
ΔV/JogTs
V0
JogTs JogTs
JogTs
Specification of acceleration parameters by time is better for creating true straight-line paths for
multi-axis moves in Cartesian space. If the times are the same for all motors, and
Coord[x].RapidVelCtrl is set to 1, a straight-line path will result.
Specification by Rate
If Motor[x].JogTa is less than zero, it specifies the inverse of the peak acceleration magnitude, in
msec2 / motor unit. This rate is used regardless of the change in speed, so the acceleration time
will be different for different changes in speed.
If Motor[x].JogTs is less than zero, it specifies the inverse of the jerk magnitude during each half
of the “S-curve” portion of the acceleration profile, in msec3 / motor unit. This rate is used
regardless of the value of the peak acceleration, so the S-curve time will be different for different
peak accelerations. If Motor[x].JogTs is less than zero, Motor[x].JogTa must also be less than
zero.
The following figure shows the acceleration profiles for these rate specifications of acceleration
and jerk, both for the case where the specified maximum acceleration is reached, and where this
acceleration is not reached before it must start returning to 0.
Vel Acc
JogSpeed
-1
JogTa
V0
JogTs JogTs
JogTa JogTa
ΔV*JogTa
Vel Acc
“Top speed”
-1
JogTa
√-ΔV/JogTs
V0
√-ΔV*JogTs √-ΔV*JogTs
√-ΔV*JogTs
Specification of acceleration parameters by rate is better for creating minimum-time moves for
short distances. It is also better if you wish to issue new rapid move commands while the moves
from previous commands are still executing, as the transition is seamless, even during
accelerations.
Y
rapid inc x30 y10
A B C
Rapid-Mode Move-Until-Trigger
The “move-until-trigger” function permits a programmed rapid-mode move to be interrupted by a
trigger and terminated by a move relative to the position at the time of the trigger. It is very
similar to a homing-search move, except that the motor zero position is not altered, and there is a
specific destination in the absence of a trigger. Note that the trigger occurs on a motor that has
been assigned to the programmed axis. For this reason, triggered moves are not permitted on axes
defined through kinematic routines.
Speeds and accelerations for both the pre-trigger and post-trigger portions of the move (and the
transition between them) are governed by the same variables as for regular rapid-mode moves.
The “move-until-trigger” function for an axis, and therefore for any motor(s) defined to that axis,
is specified by adding a ^{data} specifier to the move command for the axis, where {data} is
the signed distance from the trigger position to the end of the post-trigger portion of the move.
Motor Action
The move-until-trigger function is technically a motor function, not an axis function. The axis
command simply provides an easy way of commanding the motor(s). With the usual one-to-one
relationship between axes and motors, this relationship is quite transparent to the user. However,
in other cases, there are issues that must be considered. If there are multiple motors defined to the
axis, as in some gantry configurations, each motor performs its own move-until-trigger with
independent trigger conditions. These triggers may not occur at the same time. If multiple axes
are commanded to do moves-until-trigger on the same program line, the associated motors will all
start together, but will find their triggers and execute their post-trigger moves independently.
Example
The following plot shows the velocity and acceleration profiles for a rapid mode triggered move
of -50,000 motor units distance from the trigger position, with MaxSpeed = 50 (50 motor units
per msec), JogTa = -10 (peak acceleration of 0.1 motor units per msec2), and JogTs = -2000
(0.0005 motor units per msec3, for 200 msec to reach the peak acceleration). Note that the rate of
acceleration is the same in each of the three acceleration sections, even though the changes in
speed are different.
The new move command must be issued from a PLC program (or using the on-line cx command,
which creates a one-line one-shot PLC program), because when a motion program commands a
rapid-mode move, it does no further calculations until the move execution is finished. New move
commands can be issued at up to the servo update rate; it is not necessary to wait for the previous
acceleration to finish, as in older PMACs.
For details on implementing this functionality, refer to the section Using Linear Mode for
“Rapid” Moves under Linear Move Mode, below.
Segmentation mode requires more calculations, but it is required if the user wants to utilize any of
the following features:
Circular interpolation
Tool-radius compensation
Special linear contouring mode
Segmentation feedrate override
Inverse-kinematic subroutines
Special lookahead buffer for dynamic limiting
The units of the tm time are milliseconds; the units of the F velocity are the user length (or angle)
units of the vector feedrate axes (see below) divided by the time units as defined by the saved
setup element Coord[x].FeedTime, in milliseconds. If Coord[x].FeedTime is at the default
value of 1000, the F units are length units per second; if Coord[x].FeedTime is set to 60,000, the
F units are length units per minute.
Both the F command and tm command set the value of the data-structure element Coord[x].Tm.
The tm command sets the element to a positive value representing the move time; the F
command sets the element to a negative value, whose magnitude represents the vector federate. It
is possible to bypass the F and tm commands and write to Coord[x].Tm directly. If no F or tm
command is specified after power-up/reset, the saved value of Coord[x].Tm is used for the
moves.
Any feedrate value specified in a program is compared to the value of the saved setup element
Coord[x].MaxFeedrate; if it is greater than this parameter, Coord[x].MaxFeedrate is used
instead.
!
specification will cause the coordinate system to be put in
move-time mode, with the time in milliseconds set as the
magnitude of the specified value. (For example, an F-50
Caution command sets a move time of 50 milliseconds for subsequent
moves.) This could lead to unintended and potentially
dangerous consequences.
Feedrate-Only Mode
In certain applications, particularly NC-style applications, the user may desire that only feedrate
specifications should be valid. For these applications, Coord[x].FProtect can be set to 1 so that a
valid (positive) feedrate command must be specified in a motion program before a linear or circle
mode move can be executed, and moves specified by tm are not permitted. Moves specified by
an F command in “inverse time mode” are still permitted in this case.
each axis’ velocity individually for each different angle of movement. If a simultaneous move is
requested of a non-feedrate axis, that move is completed in the same time as that computed for
the feedrate axes. The default feedrate axes for a coordinate system are the X, Y, and Z-axes.
If there are other axes (“non-feedrate axes”) commanded on the same line, Power PMAC
compares the move time computed for the vector feedrate axes to the move time derived by
taking the greatest distance of a non-feedrate axis divided by the value of the saved setup
element Coord[x].AltFeedRate. Whichever of these move times is the longest is used for all
axes.
tsel{data} command is executed, selecting the matrix. For this method to be useful, the
matrix scaling of the X, Y, and Z axes must always be the same.
The value of Coord[x].TxyzScale can also be set “manually” with the program command
txyzscale{data}, where {data} specifies the value to be placed in the status element.
With either method of setting the value of this element, the feedrate as modified by the scaling of
the transformation matrix is divided by the value of this element (which should contain the matrix
scaling factor). Typically this is used to keep the feedrate at the programmed value regardless of
the scaling of the matrix.
At power-on/reset, there are no axes in this secondary feedrate axis set. When used, the secondary
set usually comes from the XX/YY/ZZ Cartesian axis set, or the U/V/W Cartesian axis set. To
include all three of the former set, the frax2(XX,YY,ZZ) command would be used.
When a secondary feedrate axis set exists and a feedrate-specified move is commanded, Power
PMAC compares the time for the primary feedrate axis set (its vector distance divided by the
feedrate) to the time for the secondary feedrate axis set (its vector distance divided by the same
feedrate), and uses the longer of these two times. Note that these calculations only make sense if
all primary and secondary feedrate axes have the same units.
The secondary feedrate axis set capability is new in V2.1 firmware (released 1st quarter 2016).
Non-Vector-Feedrate Axes
As mentioned above, in many systems, there are a combination of vector feedrate axes and non-
vector-feedrate axes in the same coordinate system. Most commonly, the vector feedrate axes are
linear axes in a Cartesian configuration, and the non-vector-feedrate axes are rotary axes.
In such a system, the time for the vector feedrate axes, calculated as explained above, is
compared to the time for the non-vector-feedrate axes, with the longer of the times being used.
When there are multiple non-vector-feedrate axes, there are two ways of computing the time for
these axes. With Coord[x].AltFeedMode at its default value of 0, the magnitude of the distance
for each of these axes is individually divided by Coord[x].AltFeedRate, and the longest of these
times is used to compare to the time for the vector feedrate axes. This method is typically
appropriate when the non-vector-feedrate axes are rotary, ensuring that no rotary axis will exceed
AltFeedRate.
Inverse time mode in Power PMAC is specified by setting non-saved setup element
Coord[x].InvTimeMode to a value greater than 0. The power-on default for this element is
0, so this mode is always disabled on power-up/reset, and must be enabled explicitly. The
move time for linear-mode moves is calculated identically for any of the valid non-zero
settings for InvTimeMode; the distinction between these settings lies in how the times are
calculated for circle-mode moves. (See the section on circle-mode moves, below, for details.)
When in inverse time mode, the time for a linear-mode move in milliseconds is calculated by
dividing the specified value of the most recent F-code into the value of Coord[x].FeedTime,
which is expressed in milliseconds. For example, with Coord[x].FeedTime set to 60,000,
which is the common setting for CNC applications, an F300 code specifies a move time of
60,000 / 300 = 200 milliseconds (0.2 seconds).
If the request for any motor exceeds the limit, the move time is extended so that motor will not
exceed its limit; this automatically slows the other motors in the coordinate system in proportion
so that the coordination between motors (and the path in space) is maintained.
If segmentation mode is active (Coord[x].SegMoveTime > 0) and the special lookahead buffer is
active (Coord[x].LHDistance > 0, defined lookahead buffer), the velocity limit is also applied
segment by segment, which can be useful for inverse-kinematic axes, where there is a non-linear
relationship between the programmed tool-tip speeds and the underlying motor speeds during
moves.
In this way, the programmed acceleration time acts as the minimum permitted move time for an
individual linear-mode move. This is in part a protection against move times so short that Power
PMAC could not calculate them in real time. If you are working with very short move segments
(particularly programmed by feedrate) and your move sequence is going more slowly than you
want, this acceleration-time limit may be the cause.
If the acceleration-time parameters are set small enough (even to 0), the move times can become
very small. It is even possible for them to be less than a servo cycle in length, although moves
this short are simply skipped over until enough time in the trajectory has accumulated to pass the
next servo cycle. The user should be aware of the potential for overloading the processor in this
case, because each of these programmed moves must be calculated, even if they are actually
skipped over in execution. If the processor cannot compute the required moves before they must
be executed, a “run-time error” will occur, program execution will be halted, and all motors in the
coordinate system aborted (decelerated to a closed-loop stop).
Acceleration Specification
Power PMAC provides multiple parameters for specifying the acceleration and deceleration of
linear-mode moves. The ta{data} command specifies both the “acceleration” and
“deceleration” times for a linear-mode move, in units of milliseconds with floating-point
resolution. It sets the value of data-structure elements Coord[x].Ta, which governs the initial
acceleration from stop of the first move in a continuous sequence and blending between moves in
a sequence, and Coord[x].Td, which governs the final deceleration to a stop.
The td{data} command specifies the final “deceleration” time only, in units of milliseconds
with floating-point resolution, setting the value of data structure element Coord[x].Td alone.
This scheme makes it easy to specify common acceleration and deceleration times, using the
ta{data} command alone, or separate times, using the td{data} command after the
ta{data} command.
The value of Coord[x].Td is used to compute a deceleration to stop for each programmed move
as it is computed, even if that move is then blended on the fly into a subsequent move, with the
deceleration to a stop discarded. If the rate of deceleration exceeds that set by
Coord[x].InvDmax (see next section), this time can be extended, and this could possible cause
the move to be executed at a velocity lower than what was programmed.
It is possible to bypass the ta{data} and td{data} commands and write to Coord[x].Ta and
Coord[x].Td directly. If no ta{data} or td{data} command is specified after power-
up/reset, the saved values of Coord[x].Ta and Coord[x].Td are used for the moves.
The ts{data} command specifies the “S-curve” time for both acceleration and deceleration
(including blends), in units of milliseconds with floating-point resolution, setting the value of data
structure elements Coord[x].Ts (for the initial acceleration and blends) and Coord[x].Tsd (for
the final deceleration. These values are the time in each half of the “S” (so called because the
velocity-versus-time plot looks like the letter S), in which the acceleration or deceleration value is
linearly changing between zero and the peak value. If this S-curve time is zero, the accelerations
and decelerations are constant. If no ts{data} command is specified after power-up/reset, the
saved value of Coord[x].Ts is used for the moves.
The tsd{data} command specifies the final “deceleration” S-curve time only, in units of
milliseconds with floating-point resolution, setting the value of data structure element
Coord[x].Tsd alone. This scheme makes it easy to specify common acceleration and deceleration
S-curve times, using the ts{data} command alone, or separate times, using the tsd{data}
command after the ts{data} command.
If the Ts value is less than the Ta value (or the Tsd value is less than the Td value), the overall
acceleration (or deceleration) time is equal to Ta + Ts (or Td + Tsd). This is “partial S-curve”
acceleration, with a peak constant acceleration time of Ta – Ts (or Td + Tsd). If the Ts value is
greater than or equal to the Ta value (or the Tsd value is greater than or equal to the Td value),
the overall acceleration (or deceleration) time is equal to 2 * Ts (or 2 * Tsd), and there is not
peak constant acceleration time. (Note that these rules are different from those in Turbo PMAC.)
Acceleration Limits
Power PMAC has acceleration-limit saved setup elements Motor[x].InvAmax and
Motor[x].InvDmax for each motor that can be used to automatically limit the commanded
acceleration and final deceleration, respectively, in linear-mode moves even if the motion
program requests a higher rate. The details of how this limiting function operates are dependent
on the mode of operation.
If the acceleration limits are active, Power PMAC compares the motor acceleration magnitudes
requested by the motion program to the Motor[x].InvAmax or Motor[x].InvDmax limit, as
appropriate, for each motor. Note that these elements are in units of inverse acceleration (msec2
per motor unit), which yields quicker calculations by the Power PMAC. If the request for any
motor exceeds the limit, the acceleration-section or segment time is extended so that motor will
not exceed its limit; this automatically slows the other motors in the coordinate system in
proportion so that the coordination between motors (and the path in space) is maintained.
Jerk Limit
Power PMAC also has a “jerk-limit” saved setup element Motor[x].InvJmax for each motor that
can be used to automatically limit the commanded jerk (rate of change of acceleration) in the “S-
curve” portions linear-mode move accelerations and decelerations even if the motion program
requests a higher rate. This jerk limiting is active only if segmentation mode is not active
(Coord[x].SegMoveTime = 0), in which case circular interpolation, special buffered lookahead,
and tool-radius compensation are not permitted.
If the jerk limits are active, Power PMAC compares the motor jerk magnitudes requested by the
motion program to the Motor[x].InvJmax limit for each motor. Note that these elements are in
units of inverse jerk (msec3 per motor unit), which yields quicker calculations by the Power
PMAC. If the request for any motor exceeds the limit, the S-curve time is extended so that motor
will not exceed its limit; this automatically slows the other motors in the coordinate system in
proportion so that the coordination between motors (and the path in space) is maintained.
Each linear move that Power PMAC calculates is considered to be potentially the last move in a
sequence, so Power PMAC checks the required rate to decelerate to a stop at the end of the move
against the acceleration and jerk limits, extending this deceleration time as necessary to see that
the limits are not violated. If this extends the total acceleration time to a value greater than the
move time, the move time is extended, slowing the move. This slowing occurs even if the move
turns out not to be the last move in the sequence and this deceleration is not required.
In another case, if Power PMAC wants to extend an acceleration time in the blending between
two linear-mode moves, because the symmetry of the blending algorithm causes half of the
blending time to be in the incoming move, the extension goes further into the incoming move.
This extension can only go as far as the beginning of the constant-speed portion of this move; it
cannot go into the acceleration/blending into this move, because that would force a recalculation
of the previous move, which will already have been executed. Because of the limits of the
extension of blending time, it is possible that the acceleration limits can be violated. (Those
wishing a robust observance of acceleration limits in this type of case should use the special
lookahead buffer.)
The following plot shows the velocity and acceleration profiles for a linear mode move of 100
axis units (= 100,000 motor units) distance, with a feedrate of 40 axis units per second (= 40
motor units per msec), a Ta time of 400 msec, a Td time of 800 msec, and a Ts time of 0. Three
separate sections are created from a single move command:
The following plot shows the velocity and acceleration profiles for a linear mode move of 40 axis
units (= 40,000 motor units) distance, with a feedrate of 40 axis units per second (= 40 motor
units per msec), a Ta time of 7500 msec, and a Ts time of 750 msec, for a total acceleration time
of 1500 msec. Four separate sections are created from a single move command (there are no
separate sections at constant maximum acceleration, deceleration, or speed):
Linear-mode moves can also blend into and from circle-mode moves and PVT-mode moves.
Details of these blends are discussed in the sections describing those move modes.
If Coord[x].NoBlend is set to 0, these moves are blended together unless some other factor
inhibits blending. In this case, if Coord[x].OnceNoBlend is greater than 0 when the move is
calculated, that move will not be blended into the next move, and the value of OnceNoBlend is
decremented by 1. This permits “single-shot” exact stop specification, as with the G09 NC code.
For multi-axis path-based moves, it is possible to control blending or not based on the corner
angle using Coord[x].CornerBlendBp. This permits “sharp” corners not to be blended, but
“shallow” corners to be blended. This is covered in detail in the section Blended Move Cornering
Control, below.
If motion program calculation is temporarily suspended because the number of “jumps back” in
execution while looking for the next move command exceeds the limit specified by
Coord[x].GoBack, then the most recently calculated move will not be blended into the next
move calculated after execution resumes.
L in e a r M o d e T r a je c t o r ie s
S m a ll a c c e le ra ti o n tim e
P/F
P/F P/F
P/F P/F
L in e a r M o d e T r a je c t o r ie s
A c c e le r a t io n t im e m a tc h e s m o v e t im e
P/F
P/F P/F
P/F P/F
P/F P/F
L in e a r M o d e T r a je c t o r ie s
L a rg e (v e l o c i ty l i m i tin g ) a c c e l e ra ti o n ti m e
P/F
P/F P/F
P/F P/F
Y Y
X X
Vx Vx
t t
Vy Vy
t t
Power PMAC has a new special variant of linear-mode interpolation that avoids these problems.
If the saved setup element Coord[x].SegLinToPvt is set to 1 or 2, then linear-mode move
commands are automatically converted to PVT mode moves for execution.
Coord[x].SegMoveTime must be set greater than zero to enable segmentation in order for this
conversion to occur.
In this mode, Power PMAC takes the basic linear move command for the axis based on the
position/distance specification in the command and the modal feedrate/move-time specification as
the starting point for the conversion. It computes the axis end velocity for the move for a smooth
transition between this move and the next move while passing exactly through the programmed
point, and passes this value to the PVT-mode calculation algorithm. It also computes a move time
value that keeps the speed along the path as constant as possible (or smoothly transitioning from
one speed to another).
For smooth contours, there is essentially no difference between values of 1 and 2 for
Coord[x].SegLinToPvt. The behavior differs if there are sharp corners in the path. If it is set to
1, the velocity is increased at the corner to better preserve the path. If it is set to 2, the
programmed velocity at the corner is preserved better, but the path “bulges” more to the outside
on both sides of the corner.
In this mode, the Ta, Ts, and Td acceleration-time parameters are not used. Acceleration control
is typically accomplished through use of the special lookahead buffer.
This mode is intended for move sequences where the individual points are quite close together
and reasonably evenly spaced. Often, the sequences will be generated automatically from
CAD/CAM programs. Note that CAD/CAM programs often base their point spacing given your
specified error threshold using the errors found in traditional linear interpolation. The contouring
errors in this mode are so much smaller that the points can often be spaced 50 times farther apart
for the same error threshold.
The simplest way of getting linear mode moves to behave like typical rapid mode moves is to
declare a vector feedrate high enough that at least one motor will always limit on its
Motor[x].MaxSpeed parameter. The other motors will be slowed in proportion to maintain a
straight-line path. It will probably be necessary to store the programmed vector feedrate for linear
and circle-mode moves (found in Coord[x].Tm) in a holding variable, to be restored when
returning to linear or circle mode.
If there are only vector feedrate axes in the system (e.g. X, Y, and Z – no rotary axes), it is also
possible to declare nofrax when entering this mode, so that none of the axes are considered
vector feedrate axes. In this case, saved setup element Coord[x].AltFeedrate controls the speed
of the axes, setting the speed of the axis with the longest distance for the move, with the other
axes matching the move time. When returning to linear or circle mode, the axes should be
restored as vector feedrate axes, using a command such as frax(X,Y,Z).
Commanded trajectories (in circle, linear, and PVT modes) are segmented if
Coord[x].SegMoveTime is set greater than 0. The value of Coord[x].SegMoveTime is the
segmentation period in milliseconds, with floating-point resolution. Typically it is set to a value
equivalent to 10 to 20 servo cycles, providing a good trade-off between computational load and
resulting path accuracy.
Standard Planes
The “standard” planes require only a single non-zero component in the normal command. To
specify the X/Y-plane, the usual command is normal K-1. This is the power-on default vector,
and the command is equivalent to G17 in RS-274 “G-code” programming. Similarly, to specify
the Z/X-plane, the usual command is normal J-1 (G18 equivalent); to specify the Y/Z-plane,
the usual command is normal I-1 (G19 equivalent).
The equivalent commands for the standard planes in XX/YY/ZZ space are normal KK-1 for
the XX/YY-plane, normal JJ-1 for the ZZ/XX plane, and normal II-1 for the YY/ZZ-
plane.
The following figure shows the six possibilities for “single-component” normal vectors defining
the three standard planes, each with both possibilities for clockwise sense.
+Z +Z
G17 CW CW
(default)
+X +Y +X +Y
normal K-1 normal K1
+Z +Z
CW
G18
CW
+X +Y +X +Y
normal J-1 normal J1
+Z +Z
CW
CW
+X +Y +X +Y
normal I-1 normal I1
The following list shows what each of the circlen commands does:
The circle1 mode is equivalent to the G02 mode in RS-274 machine-tool code, and circle2
mode is equivalent to the G03 mode.
In circle move mode, it is possible to command a full circle in a single move command when the
end point of all circle axes is the same as the start point. When the end point coordinates are
calculated mathematically, there may be small computational errors that make the end point
slightly different from the start point, which could mean that the intended full-circle command is
instead executed as a tiny arc move, typically too small to detect, so it appears that the move has
been skipped.
The saved setup element Coord[x].MinArcLen provides a tolerance for this type of
computational error. It specifies the minimum arc length (in radians) of a move that will be
executed as a short arc. If the angle subtended by the programmed arc move is smaller than this
value (even if not exactly zero), the move will be executed as a full circle (plus or minus the small
difference from start to end). If Coord[x].MinArcLen is set to its default value of 0.0, the end
point must equal the start point to full floating-point resolution in order for a full-circle move to
be executed.
Center Specification
Power PMAC provides two methods for specifying the arc center in circle-mode move
commands. The first and most commonly used method is to specify a vector from the move start
point to the center. The second method is to specify the magnitude of the radius and let Power
PMAC calculate the coordinates of the arc center point. If neither method is used, the move is
executed as a linear-mode move instead.
It is also possible to use absolute vector mode, implemented with the program command
abs(I,J,K) for X/Y/Z circles, or abs(II,JJ,KK) for XX/YY/ZZ circles. In this mode,
each vector component specifies the distance in the respective axis from the programming origin
to the arc center point.
With the center vector specification, if the end points of all the circle axes are equal to the start
points, whether by explicit command or by not specifying the axis values at all in the move
command, a full circle will be executed. For example, with the X/Y-plane specified for circles the
move command I10 specifies a full circle of radius 10, with the X-axis moving 20 units positive
and back, and the Y-axis moving plus and minus 10 units and back.
To separate the case of minor differences due to effects like mathematical round-off from the case
of programming errors, the user can set the threshold for the maximum change in radius that is
permitted in a circle-mode move. If saved setup element Coord[x].RadiusErrorLimit is set to a
positive value, any circle move with a difference in radius (distance to center) between the start
point and end point whose magnitude is greater than this value will be rejected. Power PMAC
will not execute this move, stopping at the beginning of the move, aborting the motion program,
and setting status element Coord[x].RadiusError to 1 (for a move in X/Y/Z space) or to 3 (for a
move in XX/YY/ZZ space). If Coord[x].RadiusErrorLimit is set to its default value of 0.0, no
checking is performed, and these moves are always executed without error.
Example
Starting from the point (X0, Y0), make a quarter circle clockwise in the XY plane to (X20, Y20),
then a linear move to (X40, Y20), then a three-quarters circle clockwise to (X20, Y0).
Note that if the distance from start point to end point is more than twice the magnitude of the
specified radius, no circular path is possible, and Power PMAC will calculate an exponential
spiral path with continuously changing radius. However, if the magnitude of the difference
between the starting radius and the ending radius is greater than that of saved setup element
Coord[x].RadiusErrorLimit, the move will be rejected. Power PMAC will not execute this
move, stopping at the beginning of the move, aborting the motion program, and setting status
element Coord[x].RadiusError to 1 (for a move in X/Y/Z space) or to 3 (for a move in
XX/YY/ZZ space). If Coord[x].RadiusErrorLimit is set to its default value of 0.0, no checking
is performed, and these moves are always executed without error.
Example
To do the same moves as in the above example, except with radius center specification, the
program would be:
The following figure shows several examples of circle-mode move commands and the paths that
result:
X Z
start/end
YY (15,25) Y normal K-1
normal KK-1
[1] inc
abs circle2
JJ circle3 X-10 Y10 R10
XX15 YY25 JJ-10
or [2] normal K-1
end R
center JJ-10
(15,15)
(0,10) [2] inc
circle2
[1] X-10 Y10 R-10
start
R (10,0)
XX X
The units of the tm time are milliseconds; the units of the F velocity are the user length (or angle)
units of the vector feedrate axes (see below) divided by the time units as defined by the saved
setup element Coord[x].FeedTime, in milliseconds. If Coord[x].FeedTime is at the default
value of 1000, the F units are length units per second; if Coord[x].FeedTime is set to 60,000, the
F units are length units per minute.
More details on this specification are given in the section on linear-mode moves, above.
More details on vector feedrate axes are given in the section on linear-mode moves, above.
Inverse time mode in Power PMAC is specified by setting non-saved setup element
Coord[x].InvTimeMode to a value greater than 0. The power-on default for this element is 0, so
this mode is always disabled on power-up/reset, and must be enabled explicitly. There are three
valid non-zero values; for each one, the exact method of computing circle-mode move times
differs. (The calculation of linear-mode move times is the same in all three – see the above
section for details.)
This means that the programmed acceleration time acts as the minimum permitted move time for
an individual circle-mode move. This is in part a protection against move times so short that
Power PMAC could not calculate them in real time. If you are working with very short move
segments (particularly programmed by feedrate) and your move sequence is going more slowly
than you want, this acceleration-time limit may be the cause.
If the acceleration-time parameters are set small enough (even to 0), the move times can become
very small. It is even possible for them to be less than a servo cycle in length, although moves
this short are simply skipped over until enough time in the trajectory has accumulated to pass the
next servo cycle.
Acceleration Specification
Power PMAC provides multiple parameters for specifying the acceleration and deceleration of
circle-mode moves. These parameters are the same parameters that govern the acceleration and
deceleration of linear-mode moves, and are described in detail in that section, above.
Acceleration Limits
Power PMAC can perform automatic acceleration limiting for circle-mode moves on a segment-
by-segment basis if the special lookahead buffer is enabled (Coord[x].LHDistance > 0, defined
lookahead buffer). If, in any segment generated by a circle-mode move, the magnitude
acceleration requested of a motor exceeds the limit specified by saved setup element
Motor[x].InvAmax, the time for the segment will be extended so the limit is not violated.
Preceding segments may also be extended so that the required deceleration to this point does not
exceed these limits.
Without the special lookahead buffer enabled, Power PMAC does not check for violations of
acceleration limits in circle-mode moves. Power PMAC does not check for violations of jerk
limits in circle-mode moves whether or not the special lookahead buffer is enabled.
The following diagram shows the blend paths between lines and arcs, both when there would be a
corner in the unblended path (“non-tangent”), and when there would not be (“tangent”).
Line/Line
Line/Arc
Arc/Arc
Tangent blends involving arc moves result in a path over the blend that is “flatter” than the
unblended path would be. This feature permits smooth transitions in centripetal acceleration when
the radius/curvature changes, rather than the step change of unblended tangent moves.
Circle-mode moves can also blend into and from PVT-mode moves. Details of these blends are
discussed in the PVT-mode move section, below.
Second, if either (or both) of the moves at the corner is a circle mode move, it is the direction of
the move immediately at the unblended corner that is used, not the direction at the end of any
blending (which would be different).
Finally, it is the angle in the plane defined by the normal command (the XY plane by default)
that is used for these functions. If the corner does not lie in this plane, it is the perpendicular
projection of this corner into the defined plane that determines the angle. For example, with the
XY plane defined, if the incoming move is linear X motion only, and the outgoing move is linear
Y and Z motion only, then the change in directed angle would be calculated as 90°, because the Z
motion is not relevant to the angle calculations in the XY plane.
If either the incoming or outgoing move at the corner has no component in the defined plane, the
corner is treated as having an angle whose cosine is equal to the value of saved setup element
Coord[x].NoCornerBp for the purposes of deciding whether to blend and/or dwell at the corner,
as discussed below.
In this mode of operation, neither the cornering acceleration, the “radius” of curvature, nor the
corner blending path error is fixed as move speeds and corner angles change.
The following plot shows how the corners are executed in this mode. It shows a figure with 45°,
90°, and 135° corners, executed first without blending to show the sharp corners, then at “1x” and
“2x” speeds. It illustrates how the blends vary with speed and angle.
The next plot shows the velocity-vs-time profiles for these three runs of the path, first unblended,
then blended at “1x” speed, and finally blended at “2x” speed. Note how the blending time is
constant over speed and corner angle.
Based on the moves speeds and the change in angle at the corner, it calculates a Ta time to
achieve the specified corner radius, instead of just using the value in Coord[x].Ta (which it does
not change). To get the closest possible approximation to a circular blend, it set the Ts time to 0,
instead of just using the value in Coord[x].Ts (which it does not change).
This mode of operation is generally used to generate a fixed size of corner, regardless of move
speeds and corner angles.
The following plot shows how the corners are executed in this mode. It shows a figure with 45°,
90°, and 135° corners, executed first without blending to show the sharp corners, then at “1x” and
“2x” speeds. It illustrates how the blends vary with speed and angle. Note that the blended paths
are identical at different speeds.
The next plot shows the velocity-vs-time profiles for these three runs of the path, first unblended,
then blended at “1x” speed, and finally blended at “2x” speed.
This mode of operation is generally used to generate the smallest possible corner blends,
regardless of move speeds and corner angles, given an acceleration limit.
The corner blending time is computed to give the cornering acceleration given the programmed
speed at the corner. If buffered lookahead is used to execute the resulting path, the acceleration-
limiting function of the lookahead can be used to further limit motor accelerations by
automatically limiting speed along this path. (The buffered lookahead does not change the path
computed here.)
The following plot shows how the corners are executed in this mode. It shows a figure with 45°,
90°, and 135° corners, executed first without blending to show the sharp corners, then at “1x” and
“2x” speeds. It illustrates how the blends vary with speed and angle.
The next plot shows the velocity-vs-time profiles for these three runs of the path, first unblended,
then blended at “1x” speed, and finally blended at “2x” speed.
If the time calculated this way is less than the value of Coord[x].Td, it will use that value instead,
so Coord[x].Td acts as a minimum time in this mode of operation. This mode does use the value
of Coord[x].Ts in force at the time, resulting in an overall blending time Tb is either Ta + Ts or 2
* Ts, whichever is larger, and the blend starts and stops at a distance V * Tb / 2 from the
programmed corner part.
The following plot shows how the corners are executed in this mode. It shows a figure with 45°,
90°, and 135° corners, executed first without blending to show the sharp corners, then at “1x” and
“2x” speeds. It illustrates how the blends vary with speed and angle. Note that the blended paths
are identical at different speeds.
The next plot shows the velocity-vs-time profiles for these three runs of the path, first unblended,
then blended at “1x” speed, and finally blended at “2x” speed.
If the blending error computed from the acceleration specification is larger than the error limit,
the blending time is recomputed according to the error specification, resulting in a smaller corner
blend. The result of this mode is a corner blend that meets either the acceleration specification or
the error specification, whichever results in a smaller corner.
When the blend time is set by the error specification, the acceleration at the programmed speed
will be higher than that set by CornerAccel. However, if buffered lookahead is used in the
execution of the resulting path, the acceleration-limiting function of the lookahead can be used to
keep the actual motor accelerations in the blend within specifications by automatically reducing
the speed in the vicinity of the corner.
immediately ready to start the next step, regardless of where the actual trajectory is. However, if
Coord[x].InPosTimeout is set to a positive value, Power PMAC will wait until all axes in the
coordinate system have pulled to within their “in-position band” at this target position before
Power PMAC is ready to start the next step.
This dwell period is only added for corners where blending has been disabled because the corner
is sharper than that specified by Corner[x].CornerBlendBp. If Coord[x].InPosTimeout is
greater than 0, requiring that all motors in the coordinate system become “in-position” before the
next step in the process, the added blend period will start after the “in-position” condition occurs.
Power PMAC supports both two-dimensional (2D) and three-dimensional (3D) cutter radius
compensation. In the more common 2D compensation, described immediately below, you first
specify the plane of compensation, the direction of compensation (left or right) relative to the
path, and the radius magnitude. In 3D compensation, described subsequently, you specify the
surface-normal vector and the tool-orientation vector, as well as the tool-tip geometry.
Cutter radius compensation is valid only in linear and circle move modes. The moves must
be specified by F (feedrate), not tm (move time). The coordinate system must be in move
segmentation mode (Coord[x].SegMoveTime > 0) to do this compensation
(Coord[x].SegMoveTime > 0 is required for circle mode moves anyway.)
Each of these features requires that moves be pre-computed and buffered. Saved data structure
element Coord[x].CCSize, by setting the size of this buffer, specifies how many pre-computed
moves can be stored in the buffer for the coordinate system (not necessarily how many will be
stored).
Any type of move that has no component of motion in the plane of compensation must be
buffered. This includes dwells, delays, moves with no distance in any axis, moves perpendicular
to the plane of compensation (e.g. pure Z-axis moves with compensation in the XY-plane), and
rotary-axis moves. For example, if you can have a dwell, a perpendicular move up, a rotary-axis
move, a perpendicular move down, and another dwell between two “in-plane” moves, you must
reserve room to buffer 5 of these “zero-distance” moves.
Interference-Check Buffering
Being able to detect and handle interference conditions that can cause overcutting may require
additional buffering. The most basic interference check just requires a single additional pre-
computed move, as explained above. This is suitable for many applications, as most of the
interference cases encountered just require this single additional buffered move.
However, there are two reasons why additional moves would need to be buffered. First, there are
applications with the possibility of interference between compensated moves that are not adjacent
in a sequence, resulting in overcut (e.g. entry and exit moves for a pocket with a narrow neck). To
catch these cases, the PMAC must be able to buffer enough moves ahead to detect this type of
occurrence and take appropriate action before an overcut occurs.
Second, if it is desired to implement the mode of operation that deletes the move path between the
interfering points and continue operation without that section (sometimes desirable in rough
cutting passes), the number of moves buffered for the purpose of interference checking must be
doubled.
More details on how the interference checking is performed are provided in the section
Interference Checking, below.
to handle, and add this. Finally, add one move for the fundamental compensated intersection
calculation.
Coord[x].CCSize must be set to a value at least as big as this sum (P + Q + 1 or 2P + Q + 1). The
only disadvantage to defining a buffer larger than necessary is that it requires more memory (~1
kbyte per move), making that memory unavailable for other uses.
For example, normal K-1, by describing a vector parallel to the Z-axis in the negative
direction, specifies the XY-plane with the standard right/left sense of the compensation.
(normal K1 would also use the XY-plane, but invert the right/left sense.) The vector normal
K-1 is the power-on/reset default. The compensation plane should not be changed while
compensation is active.
Other common settings are normal J-1, which specifies the ZX-plane for compensation
(common for lathes), and normal I-1, which specifies the YZ-plane. These three settings of
the normal vector correspond to RS-274 “G-codes” G17, G18, and G19, respectively. If you are
implementing G-codes in Power PMAC subprogram 1000 (the default G-code subprogram), you
could incorporate in subprog 1000:
By using more than one vector component in a normal command, a “tilted” plane can be
defined. The ratio of the components determines the orientation of the normal vector, and
therefore of the plane of compensation. For example, the command normal K-0.866 J0.5
defines a plane tilted 30° from the XY-plane.
Negative and zero values for cutter radius are possible, although rarely used. Note that the
behavior in changing between a positive and negative magnitude is different from changing the
direction of compensation. See Changes in Compensation, below. Also, the behavior in changing
between a non-zero magnitude and a zero magnitude is different from turning the compensation
on and off. See the appropriate sections below.
In many applications, this is not desirable, so Power PMAC provides methods for rescaling the
magnitude of radius compensation through the use of status element Coord[x].TxyzScale. Most
users rescale the radius back to the “base” units of the coordinate system, although this is not
required.
The value of Coord[x].TxyzScale can also be set “manually” with the program command
txyzscale{data}, where {data} specifies the value to be placed in the status element.
With either method of setting the value of this element, the compensation radius as modified by
the scaling of the transformation matrix is then divided by the value of this element (which should
contain the matrix scaling factor). Typically this is used to keep the radius magnitude at the
programmed value regardless of the scaling of the matrix.
The user can specify whether the compensated tool-center path moves at the programmed
feedrate, or the tool-edge path along the programmed path does so. If bit 3 (value 8) of saved
setup element Coord[x].CCCtrl is set to its default value of 0, the tool-center path moves at the
programmed feedrate. This means that the tool edge along the programmed path will move at a
different velocity, less if the compensation is to the outside of the arc, greater if to the inside of
the arc.
If bit 3 of Coord[x].CCCtrl is set to 1, the tool-edge path along the programmed path moves at
the programmed feedrate. This means that the compensated tool-center path will move at a
different velocity, greater if the compensation is to the outside of the arc, less if to the inside of
the arc.
The ability to specify the tool-edge path feedrate of a compensated arc move by setting bit 3 of
Coord[x].CCCtrl to 1 is new in V2.1 firmware, released 1st quarter 2016. With the bit at its
default value of 0, operation is compatible with older firmware versions.
Turning On Compensation
The compensation is turned on by buffered motion program command ccmode1 (offset left) or
ccmode2 (offset right). (Note that the equivalent Turbo PMAC commands cc1 and cc2 are
axis motion commands for the “CC” axis in Power PMAC.) These are equivalent to the RS-274
G-codes G41 and G42, respectively. If you are implementing G-code subroutines in Power
PMAC subprogram 1000, you could simply incorporate into subprog 1000:
Tool-Center
Path Tool-Center
Path
From this point, the path is dependent on whether the angle between the lead-in move and the
first fully compensated move is sharp enough that the corner is traversed with an added arc about
the uncompensated intersection point or not. The threshold for this choice is determined by
Coord[x].CCAddedArcBp (as it is for fully compensated intersections). This is explained more
completely in the section Treatment of Compensated Outside Corners, below.
If the angle is sharper than this threshold, Power PMAC will execute an arc move, with radius of
the cutter radius, about the uncompensated intersection point to a point perpendicular to the
starting direction of the fully compensated move.
If the angle is less sharp than this threshold, the compensated lead-in move will extend to the
direct compensated intersection point with the (extended) first fully compensated move. If the
moves are to be blended, the corner will be blended according to the acceleration times in force
(Coord[x].Ta and Coord[x].Ts), just as for uncompensated moves.
Compensated
Arc Move
CCR
CCR CCR
Lead-In Lead-In
Move Move
Programmed
Path
Programmed
Path
No Added Arc
Compensated
Tool-Center Linear Move Tool-Center
Path Path Compensated
Arc Move
Added CCR CCR
Arc
Lead-In Lead-In
Move Move Programmed
With Added Arc Path
Programmed Programmed
Path Linear Move Path
Arc Move
CCR
Linear Move Linear Move CCR
CCR CCR
Tool-Center
Path
Tool-Center
Path
Programmed
Programmed Linear Move Path
Path
Arc Move
CCR Arc Move
CCR CCR
Arc Move CCR
Tool-Center
Path Tool-Center
Path
The purpose of this arc move is to keep the tool-center time from moving too far from the
programmed corner point on sharp corners, which could interfere with other features on the part,
and take more time. The move will be executed at the same vector feedrate as the incoming
move, subject to two limitations. First, the minimum time for this move is the acceleration time in
force (Coord[x].Ta + Coord[x].Ts or 2 * Coord[x].Ts, whichever is greater). Second, the move
speed can be limited by the Coord[x].MaxCircleAccel centripetal acceleration limit.
If the two moves are not blended for whatever reason, Power PMAC can be programmed to stop
either at the beginning of this added arc move (bit 0 – value 1 – of Coord[x].CCCtrl = 1) or at
the end of this added arc move (bit 0 of Coord[x].CCCtrl = 0).
Programmed Programmed
Path CCR Path
CCR
Tool-Center Tool-Center
Path Path
Arc Move
Arc Move
Programmed Programmed
Path Path
Linear Move
CCR CCR
CCR CCR
Arc Move
Tool-Center Tool-Center
Path Linear Move Linear Move
Path
Programmed
Path Programmed
Path
CCR CCR
Arc Move
Tool-Center
Path Tool-Center
Arc Move Path
Arc Move
If the moves are to be blended, the corner will be blended according to the acceleration times in
force (Coord[x].Ta and Coord[x].Ts), just as for uncompensated moves. For the lead-out move,
the compensated tool path will be at a diagonal to the programmed move path, ending at the
programmed point for this move.
Tool-Center
Path Tool-Center
Path
From this point, the path is dependent on whether the angle between the last fully compensated
move and the lead-out move is sharp enough that the corner is traversed with an added arc about
the uncompensated intersection point or not. The threshold for this choice is determined by
Coord[x].CCAddedArcBp (as it is for fully compensated intersections). This is explained more
completely in the section Treatment of Compensated Outside Corners, above.
If the angle is sharper than this threshold, Power PMAC will execute an arc move, with radius of
the cutter radius, about the uncompensated intersection point to a point tangent to a straight-line
move to the programmed point of the lead-out move. It will then execute the straight-line lead-out
move to this point. The path of this move will be diagonal to the path of the uncompensated
move.
If the angle is less sharp than this threshold, the last fully compensated move will extend to the
direct compensated intersection point with the (extended) compensated lead-out move. If the
moves are to be blended, the corner will be blended according to the acceleration times in force
(Coord[x].Ta and Coord[x].Ts), just as for uncompensated moves.
Compensated
Arc Move
CCR
CCR CCR
Lead-Out Lead-Out
Move Move
Programmed
Path
Programmed
Path
No Added Arc
Compensated
Tool-Center Linear Move Tool-Center
Path Path Compensated
Arc Move
Added CCR CCR
Arc
Lead-Out Lead-Out
Move Move Programmed
With Added Arc Path
Interference Checking
Power PMAC has powerful capabilities to detect interference in the compensated tool-center path
that is indicative of “overcut” conditions on the part. Fundamentally, interference can be detected
if a compensated move is in the opposite direction from the uncompensated move, which will
cause a crossover in the compensated path.
In order to detect interference conditions in time to prevent an overcut, Power PMAC must be
pre-computing and buffering at least 2 “in-plane” moves in the compensated move sequence. The
number of pre-computed “in-plane” moves that will be buffered is specified by
Coord[x].CCDistance; the total number of moves – in-plane and not – that can be buffered is
specified by Coord[x].CCSize. The settings for these are discussed in the above sections
Specifying the Pre-Computation Length and Setting Up the Compensation Buffer.
basically assumes that the interference was caused by a programming error, so the program
should not continue.
However, if bit 1 (value 2) of Coord[x].CCCtrl is set to 1, Power PMAC will compute the
intersection point of the interfering compensated move paths, discard the trajectory between the
first arrival at this intersection point and the second arrival, and directly blend the first incoming
path to point to the second outgoing path. This mode is useful for rough cutting with a large tool
that may not be able to get into small features in the part, before a final path with a small tool that
can. Note that this removal is only possible for linear mode moves in the compensated path, and
that it is not always possible to compute a non-interfering path in this algorithm. If the Power
PMAC cannot compute a non-interfering path in this mode, it will stop the program when
interference is detected.
For debugging purposes, bit 2 (value 4) of Coord[x].CCCtrl can be set to 1. With this setting,
Power PMAC will permit interference to occur. This setting is suggested mainly for dry-run
modes, to be able to detect more clearly what the source of the problem is.
Examples
This XY path plot shows what can happen with interference checking disabled. The bottom path
shows the uncompensated path; this path has a “pocket” that is deep and narrow relative to the
radius of the tool. Without interference checking, the top compensated path goes too deep into the
pocket. One of the compensated moves is reversed in direction and the compensated path
intersects itself. The result is that the tool would “overcut” past the edge of the uncompensated
path.
The next XY path plot shows the same uncompensated and compensated paths, but this time with
interference checking enabled for the compensated moves. Note that the reversed move at the
bottom of the pocket of the compensated path is eliminated, and the moves entering and leaving
the pocket are shortened to the point where they intersected without interference checking. This
action prevents any overcutting by the tool.
In this next case, the XY path plot shows a case of interference that involves several moves. The
bottom path shows the uncompensated path with a small shallow pocket. Without interference
checking active, the top compensated path goes too deep into the pocket, causing overcut. Note
that the compensated path has several points of intersection with itself.
The following XY path plot shows the same uncompensated and compensated paths, but this time
with interference checking enabled for the compensated moves. Notice that everything between
the first and last crossover point has been removed, so that the added outside arc going into the
pocket directly blends into the added outside arc leaving the pocket.
However, when 2D compensation is active, in order to be able to execute the next move (which is
the operator’s intention), the program must calculate far enough ahead to compute the intersection
with the next in-plane move, and to check for possible interference conditions. At the end of a
compensated move sequence, no more moves must be calculated.
The 3D compensation algorithm automatically uses this data to offset the described path of
motion, compensating for the size and shape of the tool. This permits the user to program the path
along the surface of the part, letting Power PMAC calculate the path of the center of the end of
the tool.
3D compensation is valid only in linear and circle move modes, and is really intended only
for linear moves.
Most users will define a very simple table for either a “flat-end” tool or a spherical “ball-nose”
tool. These cases are given as specific examples below. However, this table gives the capability
for using other tool-tip shapes, and also for compensating for tool wear in very high-accuracy
applications.
The table is defined within the data structure Coord[x].CC3Data[i], where x is the
coordinate system number, and i is the index (i = 0 to 16) of the arc section of the tool tip.
(Index i = 16 only contains data for the end of section 15.) Each tool-tip section structure
has multiple elements, as explained below. Note that each coordinate system only has one
table of tool-tip geometry, so if the tool is changed, the table must be re-entered using (on-
line or program) commands. The table contents cannot be saved to non-volatile memory, so
the table must be created after power-on/reset using (on-line or program) commands.
User sets:
Coord[x].CC3Data[0].ToolRadius = TR0
Coord[x].CC3Data[0].ToolOffset = TO0
Coord[x].CC3Data[i].CutRadius = Ri
Coord[x].CC3Data[i].NdotT = cos Θi
The user defines the table’s initial reference point by setting two table elements.
Coord[x].CC3Data[0].ToolRadius is set to the radial distance of this point from the tool
center-line, in the linear length units of the coordinate system (typically millimeters or
inches). This must be a positive value, and is usually considered to be the “shaft radius”.
Coord[x].CC3Data[0].ToolOffset is set to the (signed) axial distance of the this point from
the tool-center reference point, in the linear length units of the coordinate system. If this is a
positive value, the initial reference point for the table is “above” (away from the tool tip) the
tool-center reference point; if it is a negative value, the initial reference point for the table is
“below” (toward the tool tip) from the tool-center reference point.
Note that the ToolRadius and ToolOffset elements exist and are used for higher section
index values (i = 1 to 16). However, these are automatically calculated by the Power PMAC
as arc-piece data is entered using Script commands. Note that the user should not enter
values for these elements using the Script language, and should not enter the arc-piece
section data using C-language commands.
The element Coord[x].CC3Data[i].NdotT is set to the cosine of the starting angle for the arc
piece with index i. The angle is defined as the angle between the tool axis of rotation (“vertical”)
and the radial line on the end of the arc away from the tool tip (the “top” end of the arc). This
cosine value is equivalent to the dot product of the surface-normal vector N and the tool-direction
vector T for this point on the tool, hence the element name NdotT. Of course, this value must be
within the range -1.0 to +1.0; an attempt to enter a value outside of this range will be rejected
with an error.
The value of NdotT for each arc piece must be greater than the value for the previous piece (so
the starting angle is less than for the previous piece) – this requires that the full tool-end cross-
section be convex. When a value for NdotT is entered for an arc piece with a Script command,
the values of NdotT for all subsequent (higher-numbered) arc pieces are checked against this
value, and if less, are set equal to this value. If a command attempts to set a value for NdotT that
is less than the value for a previous (lower-numbered) arc piece, the command will be rejected
with an error.
The element Coord[x].CC3Data[i].CutRadius is set to the length of the radius for the arc piece
with index i, in the linear length units of the coordinate system. This must be a non-negative
value. It can be larger or smaller than the tool radius. A zero value can be used to specify a sharp
corner in the cross-section.
The tool-tip cross section can be defined using up to 16 arc pieces (i = 0 to 15). A table of n arc
pieces is ended with a setting for Coord[x].CC3Data[n].NdotT of 1.0, which defines a zero-
degree angle from the “vertical” for the radial line at the end of the last arc piece (with index n-1),
specifying a “smooth” tool-center tip. Coord[x].CC3Data[16].NdotT is automatically set to 1.0,
so if the full set of 16 arc pieces is used, this will be the ending value for the last arc. In the
unusual event that a pointed tool-center tip is desired, a last arc piece of zero radius must be
specified to bring the final angle to zero degrees. No value of Coord[x].CC3Data[n].CutRadius
must be entered; this value will not be used in any case. A value for
Coord[x].CC3Data[16].CutRadius cannot be entered and will never be used.
Examples
A semi-circular (“ball-nose”) tool-end cross section whose radius is specified in the variable
BallRad and whose tool-center reference point is at the center of the hemisphere can be defined
with the following settings:
Coord[x].CC3Data[0].ToolRadius = BallRad
Coord[x].CC3Data[0].ToolOffset = 0.0
Coord[x].CC3Data[0].NdotT = 0.0
Coord[x].CC3Data[0].CutRadius = BallRad
Coord[x].CC3Data[1].NdotT = 1.0
A tool-end cross section that is square with an overall size set by variable ShaftRad and a
circular corner of radius CornerRad, and whose tool-center reference point is ShaftRad in from
the tool tip, can be defined with the following settings:
Coord[x].CC3Data[0].ToolRadius = ShaftRad
Coord[x].CC3Data[0].ToolOffset = ShaftRad - CornerRad
Coord[x].CC3Data[0].NdotT = 0.0
Coord[x].CC3Data[0].CutRadius = CornerRad
Coord[x].CC3Data[1].NdotT = 1.0
Turning On 3D Compensation
3D cutter compensation is turned on by the buffered motion program command ccmode3. (Note
that the equivalent Turbo PMAC command cc3 is an axis motion command for the “CC” axis in
Power PMAC.) Since the offset vector is specified explicitly, there is no “left” or “right”
The direction of the surface-normal vector is determined by the nxyz I{data}, J{data},
and K{data} components declared in a motion program line, specifying the X, Y, and Z-axis
components, respectively. The absolute magnitude of these components does not matter, but the
relative magnitudes define the direction. The direction must be from the surface into the tool.
If a component is not declared in an nxyz command, that component is automatically set to 0.0.
For example the command nxyz I1 automatically sets the J and K components to 0, defining a
surface-normal vector parallel to the X-axis.
Note that the coordinates of the surface-normal vector must be expressed in the machine
coordinates. If the part is on a rotating table, these coordinates will not in general be the same as
the original part coordinates from the part design – the vector must be rotated into machine
coordinates before sending to Power PMAC.
The surface-normal vector affects the compensation for the move on the same line of the motion
program, and all subsequent moves until another surface-normal vector is declared. In usual
practice, a surface-normal vector is declared for each move, affecting that move alone.
The direction of the tool-orientation vector is determined by the txyz I{data}, J{data},
and K{data} components declared in a motion program line, specifying the X, Y, and Z-axis
components, respectively. The absolute magnitude of these components does not matter, but the
relative magnitudes define the direction. The direction sense of the tool-orientation vector is not
important; it can be from base to tip, or from tip to base.
If a component is not declared in a txyz command, that component is automatically set to 0.0.
For example the command txyz K1 automatically sets the I and J components to 0, defining a
surface normal vector parallel to the Z-axis.
The tool-orientation vector affects the compensation for the move on the same line of the motion
program, and all subsequent moves until another tool-orientation vector is declared. In usual
practice, a tool-orientation vector is declared for each move, affecting that move alone.
X37.32Y-1.64Z39.45A-17.23C27.33nxyzI0.73J-0.26K0.55txyzI0.51J0.72K-0.35
The following diagram shows how the programmed point, surface-normal vector, tool-orientation
vector, and tool-nose shape are used to compute the offset point.
Move command:
X.. Y.. Z.. A.. B.. nxyz I.. J.. K.. txyz I.. J.. K..
P: Programmed Point
(from X.. Y.. Z.. A.. B..)
N: Surface Normal Vector
(from nxyz I.. J.. K..)
T: Tool Orientation Vector T
(from txyz I.. J.. K..)
R: Tool-Nose Radius C
(from tool-tip table)
C: Tool Center Point N
R
(automatically computed)
P
If Power PMAC cannot compute a proper solution for a move, it will stop the motion program
with an error. It will set Coord[x].ErrorStatus to 12 (“CCNdotTError”) to denote this particular
error. If the command backup Coord[x].Status is used, the text name of the error will be
reported for ErrorStatus.
Once the modified end-point is calculated, the move to that end-point is calculated just as it
would be without compensation. If the program is in linear mode, it will be linearly
interpolated. If the program is in circle mode (not advised), arc interpolation will be applied.
Because the offset to the end-point is directly specified for each move, there are no intersection
points for Power PMAC to compute using the equations for the next move. This means there are
no special lookahead or single-step execution considerations, as there are in 2D compensation.
No interference checking is performed.
All moves in 3D compensation are directly blended together. There are no special considerations
for outside corners, as there are in 2D compensation. Also, there are no special considerations for
the lead-in and lead-out moves. The lead-in move is simply an interpolated move from the last
uncompensated position to the first compensated position. The lead-out move is simply an
interpolated move from the last compensated position to the first uncompensated position.
Velocity Specification
The ending velocity for an axis move is specified as a signed quantity following the “:” (colon)
character immediately after the position/distance value. This makes the axis mode command of
the form X100:-25. The value can be specified either as a numerical constant without
parentheses or as a mathematical expression inside parentheses. The velocity units are determined
by the user axis units and the coordinate-system time units. The user axis units are determined by
the axis definition; the coordinate-system time units are determined by the value of
Coord[x].FeedTime, in milliseconds. At the default value of 1000, the coordinate-system time
units are seconds, so the velocity units are the user axis units per second.
of time that satisfies these constraints. This results in a linearly changing acceleration, a parabolic
velocity profile, and a cubic position profile for the move.
PMAC Transition Point Moves
Position, Velocity, and Time (PVT mode) [Parabolic Velocity]
VEL
dA
= constant (calculated)
dt
A (specified)
P
(calculated)
V (specified)
P ,V
(from A (calculated)
before)
PVT200
P P P ...
X 9000:150
...
TA TIME
The PVT mode is the most useful for creating arbitrary trajectory profiles. It provides a “building
block” approach to putting together linear and parabolic velocity profile sections to create
whatever overall profile is desired. The following diagram gives an example of such an arbitrary
PVT-mode sequence.
Velocity
(Units/sec)
Move Program
inc
1000
900
pvt200
1 Y133.333:1000
pvt100
2 Y100:1000
3 Y96.667:900
500 pvt200
4 Y140:500
pvt500
5 Y83.333:0
The next diagram shows the relationship between distance, velocity, and time for common PVT-
mode sections:
P V T S e g m e n t S h a p e s
Vel Vel
V V
P=1/2 Vt
P=1/3 Vt
t T ime t T ime
Vel Vel
V V
P=2/3 Vt P=Vt
t T ime t T ime
Vel Vel
V2 V
V1
P =1/ 6 Vt
1
V/2
P =5/6 Vt
P=1/2(V +V ) t 2
1 2
t T ime t 2t T ime
The following drawing shows one technique for computing the the axis velocities at each
programmed point of a contour. Each point in the sequence can be considered as being on a circle
with the point before and point after. The line from the center of this circle to the programmed
point (the radius vector) is perpendicular to the velocity vector at the point. Using the desired
vector velocity magnitude and the direction of the vector, the individual axis velocities can be
computed.
Vi+2
PVT Mode Contouring
(Hermite Spline)
Pi+2 Ri+2
Vi+1 Ci+2
Ci
To compute axis velocities at point Pi:
Ci+1 Pi+1 1. Find common center of Pi-1, Pi, and Pi+1
Ri+1
Vi 2. Compute velocity vector as normal
Ri
VYi to radius vector
Pi VXi
3. Resolve velocity vector into components
Pi-1
The automatic conversion of linear-mode moves to PVT format that is performed when
Coord[x].SegLinToPvt is greater than 0 uses an algorithm similar to this to compute the internal
PVT move commands from the programmed points and vector feedrate.
acceleration times at the blend (regardless of the present settings of the acceleration-time
parameters), and these are directly concatenated with the PVT-mode moves before or after. Note
that the coordinate system must be in “segmentation mode” (Coord[x].SegMoveTime > 0) to
perform this blending.
Probably the most common use of this capability is to create “custom” acceleration and
deceleration profiles for linear and circle-mode moves that cannot be created by the standard
profiles for those modes.
In the case of a linear or circle-mode move blending into a PVT-mode move, the ending velocity
of each axis in the linear or circle-mode move is automatically used as the starting velocity for
that axis in the PVT-mode move, guaranteeing continuity of velocity. The ending (programmed)
position for each axis in the linear or circle-mode move (not where it would have started to
decelerate to a stop in the absence of blending) is the starting position for the PVT-mode move.
In the case of a PVT-mode move blending into a linear or circle-mode move, each axis starts the
linear or circle-mode move at the (unblended) programmed speed. Each axis ends the PVT-mode
move at the speed programmed in the PVT-mode move command. If these two speeds are not the
same, there will be a sudden step-change in the axis velocity. It is the user’s responsibility to
ensure that these two velocities are the same in order to achieve a smooth transition.
The following plot shows the velocity and acceleration profiles for a linear-mode move with
PVT-mode acceleration and deceleration moves. The parabolic acceleration and deceleration
profiles in this example can optimize the use of a typical motor’s torque/speed envelope. The
sequence of commands is:
The bstart (block-start) and bstop (block-stop) program commands can be used to “bracket”
a set of PVT-mode moves in a motion program that start and end at zero velocity. Since single-
step execution progresses all the way from the bstart to the bstop (block-stop) command, the
entire move sequence can be safely executed as a single-step.
Note that if the PVT-mode move is executed in single-step mode with segmentation and the
special lookahead buffer active, the lookahead acceleration control will keep the profile within
the acceleration limits, but the profile will look nothing like that for continuous execution.
In this mode, commanded axis position, velocity, and acceleration are guaranteed to be
continuous, even at programmed move boundaries. Jerk (rate of change of acceleration) and
“snap” (rate of change of jerk) are continuous within each programmed move.
(When Coord[x].PvatEnable is set to its default value of 0, Power PMAC computes a 3rd-order
position profile between the programmed points for each axis, with position and velocity
guaranteed to be continuous, even at programmed move boundaries. Acceleration is continuous
within each programmed move.)
The time for a move is still specified by the most recent pvt{data} command, with the value
of {data} setting the move time in milliseconds.
{axis}{data}:{data}:{data}
The first {data} value specifies the ending position or distance for the axis, depending on
whether the axis is in absolute or incremental mode, respectively. The second {data} value
specifies the ending signed velocity for the axis. These two terms are exactly the same as for
standard PVT moves with Coord[x].PvatEnable = 0.
The third {data} value specifies the ending signed acceleration for the axis. If no third value is
specified for the axis, Power PMAC will use a value of 0.0 for the end acceleration.
Power PMAC uses the constraints at the beginning of the move – from the previous move or a
stopped condition – and these constraints to compute the unique 5th-order position profile that
meets all of these constraints.
To execute moves in this mode, the coordinate system must be in segmentation mode, with
Coord[x].SegMoveTime set greater than zero, specifying the segmentation time in milliseconds.
In executing these moves, Power PMAC will solve the exact 5th-order equations each segment.
As with other segmented moves, the fine interpolation executing at the servo update rate is a 3rd-
order interpolation between the segmentation points.
Internally, Power PMAC uses this mode to perform the “fine interpolation” between coarse
segment points when executing linear, circle, and PVT mode moves in segmentation mode. When
moves are programmed directly in spline mode, the spline equations are generated directly from
the programmed points and interpolated at the servo update rate. Programmed spline-mode moves
are never segmented, even if the coordinate system is in “segmentation mode” with
Coord[x].SegMoveTime > 0.
The most common use of the spline mode utilizes the declaration of a single spline segment time
with the simplest form of this command: spline{data}. In this form, all of the spline
segments use the same time value. This case creates a “uniform” B-spline, and is explained in the
“Uniform-Time Calculations” section below.
If multiple spline-segment time values are declared using the optional forms of the spline
command, “non-uniform” B-spline trajectories can be created. In this form, the spline segments
use different time values. This case is explained in the “Non-Uniform Time Calculations” section
below.
Uniform-Time Calculations
A single spline-mode programmed move with all segments of the same time creates a “bell-
shaped” velocity-versus-time profile with three separate parabolic sections. In the figure “Spline-
Mode Uniform-Time Profiles” below, this case is shown in the “One Programmed Move” plot. A
constant-velocity move profile (“unsplined”) of the programmed time is shown in the rectangular
profile. The splined profile has equivalent times added before and after. The total distance for the
spline move (visualized as the area under the curve) is the same for the splined move as the
unsplined move. Note that the splined profile is continuous in both velocity and acceleration,
even at the section boundaries (including beginning and end). A single spline-mode move with
uniform times for all three sections will always have this profile.
If there are multiple spline-mode moves in a continuous sequence, the resulting profile can be
thought of as a superposition of individual moves, each offset by one programmed move time.
This concept is illustrated by subsequent drawings in the figure.
The following figure shows the profile for a typical spline sequence with uniform-time moves of
varying distances.
T T T T T T TIME
(added) (added)
Non-Uniform-Time Calculations
When the spline mode declaration command specifies multiple separate section times, the
resulting profiles are somewhat different, and not so symmetrical. For instance, with the
declaration command spline 50 spline 100 spline 150, then for a single
programmed move, the first parabolic section would be 50 msec long, the second section would
be 100 msec long, and the third section would be 150 msec long. The total distance (area under
the velocity profile curve) is still the programmed distance, and both velocity and acceleration are
always continuous, including at all section boundaries.
Power PMAC stores the times for the three sections of a programmed spline move in the data
structure elements Coord[x].T0Spline (for the incoming section), Coord[x].T1Spline (for the
center section), and Coord[x].T2Spline (for the outgoing section). If only a single time is
specified in the mode declaration command (e.g. spline 50), all three elements will be set to
the specified value. If two times are specified in the command (e.g. spline 50 spline
100), Coord[x].T0Spline and Coord[x].T1Spline are set to the first value, and
Coord[x].T2Spline is set to the second value. If three times are specified in the command (e.g.
spline 50 spline 100 spline 150), each element is set to a unique value.
When a spline move is calculated from a motion program command, all three sections are
calculated according to the times in effect at that point, but only the first section is committed to
execution. If there is another move in the same continuous sequence, it will use as its starting
state the position, velocity, and acceleration of the end of the first section of the previous move,
and calculate the equations for its three sections, using the three section times in effect at that
point, “overwriting” the last two sections calculated from the previous move. Note that if the
section times have not been changed between the two move commands, the new command will
use Coord[x].T0Spline for its incoming section, overwriting the possibly different
Coord[x].T1Spline used for the matching section of the previous move. Also, the new command
will use Coord[x].T1Spline for its incoming section, overwriting the possibly different
Coord[x].T2Spline used for the matching section of the previous move.
However, the commanded path in spline mode does not pass exactly through the programmed
points in general. Instead, the path passes slightly to the inside of the programmed points. The
“way points” WPi through which the commanded path actually passes (for a uniform-time path)
can be calculated from the programmed point Pi and the points on either side of it as:
Pi 1 4 Pi Pi 1
WPi
6
For a given radius of curvature R in a path, the error introduced in the commanded path by the
splining algorithm can be approximated as:
V 2T 2
E
6R
where V is the velocity and T is the programmed move time.
Some users will want to reduce this error in their contours. A simple algorithm that can
dramatically reduce this error pre-compensates for these errors. For each point Pi in the spline,
replace with a point P’i with the following formula before sending to Power PMAC:
Pi 1 8Pi Pi 1
P'i
6
These new points are to the outside of the desired curve (technically, they are “control points” for
the spline curve) and the fact that the spline algorithm will cause the commanded curve to pass to
the inside of these points means that the curve will pass very close to the original points. The
contouring error for a given radius of curvature R in a path using this technique can be
approximated as:
V 4T 4
E
36R 3
Lookahead calculations are appropriate for any execution of a programmed path where
throughput has been limited by the need to keep execution slow throughout the path because of
the inability to anticipate the few sections where slow execution is required. The lookahead
function’s ability to anticipate these problem areas permits much faster execution through most of
the path, dramatically increasing throughput.
Because of the nature of the lookahead calculations – trajectory calculations are done well in
advance of the actual move execution, and moves are kept within machine limits by the automatic
adjustment of move speeds and times – they are not appropriate for some applications. Any
application requiring quick reaction to external conditions should not use lookahead. Also, any
application requiring precise synchronization to external motion, such as those using PMAC’s
“external time base” feature, should not use lookahead.
Principle of Operation
When the lookahead function is enabled, Power PMAC will scan ahead in the programmed
trajectories, looking for potential violations of its position, velocity, and acceleration limits. If it
sees a violation, it will slow the trajectory at that point just enough so that no limit is violated. It
will then work backward through the pre-computed buffered trajectories, slowing down the parts
of these trajectories going into this point so that the deceleration to this point does not violate any
motor limits. These calculations are completed before these sections of the trajectory are actually
executed.
Power PMAC can perform these lookahead calculations on linear, circle, and PVT-mode moves.
The coordinate system must be put in segmentation mode (Coord[x].SegMoveTime > 0) to
enable lookahead calculations. In segmentation mode, Power PMAC automatically splits the
moves into small segments, which are executed as a series of smooth splines to re-create the
programmed moves.
Power PMAC stores data on these segments in a specially defined lookahead buffer for the
coordinate system. Each segment takes Coord[x].SegMoveTime milliseconds when it is put into
the buffer, but this time can be extended if it or some other segment in the buffer violates a
velocity or acceleration limit.
This technique permits Power PMAC to create deceleration slopes in the middle of programmed
moves, at the boundaries of programmed move, or over multiple programmed moves, whichever
is required to create the fastest possible move that does not violate constraints. All of this is done
automatically and invisibly inside the Power PMAC; the part programmer and operator do not
need to understand the workings of the algorithm.
Before Lookahead
F100
X1
X2
1 2 3 4 5 6 7 8 9 10 X3
X4
t X5
X6
X7
V X8
X9
X10
DWELL50
After Lookahead
ACCEL & DECEL ARE CONTROLLED BY
SPECIFIED ACCEL LIMIT (G’s)
1 2 3 4 5 6 7 8 9 10
t
The next diagram shows how the lookahead function can automatically create a deceleration into
a tight corner, permitting the corner to be taken slowly to keep it within acceleration constraints,
and then to accelerate back up to the programmed speed coming out of the corner. This permits
the user to command high speeds, and to have Power PMAC slow down the path only where
needed. Note that the post-lookahead profile in this diagram is not time-extended as it would
really be; this was done to show the correspondence of points on the profiles.
3
1 2 3 4 5
2 VY
1
F50
Y X10 Y10 VX
7
X0 Y20 Time
6
5 ACCEL & DECEL
CONTROLLED BY
4 SPECIFIED G’s 1 2 3 4 5 6 7
AT CORNER
3
2
VY
1
Time
X Note how ‘Y” decelerates
After Lookahead to make the corner
If it is desired that the lookahead algorithm limit tool-tip position, velocity, and/or acceleration as
well as joint (motor) dynamics, additional virtual motors (with active computation) should be
assigned to tool-tip axes in the kinematics subroutines with a direct 1-to-1 relationship.
Transparent Operation
Once the lookahead function has been set up, the lookahead function operates transparently to the
programmer and the operator. No changes need to be made to a motion program to use the
lookahead function, although the programmer may choose to make some changes to take
advantage of the increased performance capabilities that lookahead provides.
1. Assign all desired motors to the coordinate system with axis definition statements.
2. Set Motor[x].MaxPos and Motor[x].MinPos positive and negative position limits, in motor
units for each motor in coordinate system, relative to the home position.
4. Set Motor[x].InvAmax inverse maximum acceleration in msec2/motor unit for each motor in
coordinate system.
8. Compute number of segments needed to look ahead as this “stopping time” divided by (2 *
Coord[x].SegMoveTime).
9. Multiply the “segments needed” by 4/3 (round up if necessary) and set the
Coord[x].LHDistance lookahead length parameter to this value.
10. If the application involves high block rates, set the Coord[x].Ta default acceleration time to
the minimum block time in msec; the Coord[x].Ts default S-curve time to 0.
11. If the application does not involve high block rates, set the Coord[x].Ta default acceleration
time and the Coord[x].Ts default S-curve time parameters to values that give the desired
blending corner size and shape at the programmed speeds.
12. Store these parameters to non-volatile memory with the save command if you want them to
be an automatic part of the machine state.
13. After each power-up/reset, send the card a define lookahead {# of segments}
command for the coordinate system, where {# of segments} is equal to
Coord[x].LHDistance plus any segments for which backup capability is desired.
14. Load your motion program into the Power PMAC. Nothing special needs to be done to the
motion program. The motion program defines the path to be followed; the lookahead
algorithm may reduce the speed along the path, but it will not change the path.
15. Run the motion program, and let the lookahead algorithm do its work!
Lookahead Constraints
Power PMAC’s lookahead algorithm forces the coordinate system to observe four constraints for
each motor. These constraints are defined in saved setup elements for each motor representing
maximum position extents, velocities, and accelerations. These setup elements must have valid
values in order for the lookahead algorithm to work properly.
Position Limits
Variables Motor[x].MaxPos and Motor[x].MinPos for each motor define the maximum and
minimum position values, respectively, that are permitted for the motor (“software overtravel
limits”). These variables are defined in motor units, and are referenced to the motor zero, or
home, position (often called “machine zero”). Even if the origin of the axis for programming
purposes has been offset (often called “program zero”), the physical position of these position
limits does not change; they maintain their reference to the machine zero point. Power PMAC
checks the actual position for each motor as the trajectory is being executed against these limits;
if a limit is exceeded, the program is aborted and the motors are decelerated at the time or rate set
by Motor[x].AbortTa and Motor[x].AbortTs.
In lookahead, if the algorithm, while scanning ahead in the programmed trajectory, determines
that any motor in the coordinate system would exceed one of its desired position limits, it will
suspend the program and force a stop right at that limit. It will then work backwards through the
buffered trajectory segments to bring the motors to a stop along the path at that point in the
minimum time that does not violate any motor’s Motor[x].InvAmax acceleration constraint.
(However, if Coord[x].SoftLimitStopDis is set to 1, the program does not stop at the limit.
Instead, it will continue, with the offending motor saturating at the limit value. If operating in this
mode, Motor[x].SoftLimitOffset should be set less than 0.0 for all involved motors to put the
execution-time limits outside of the calculation-time limits, preventing the program from being
stopped due to possible violation of execution-time limits.)
When stopped on a soft position limit within lookahead, the program is only suspended, not
aborted. The action is effectively equivalent to issuing a \ quick-stop command. It is possible to
“retrace” the path coming into the limit, or even to resume forward execution after changing the
limit value. An “abort” command must be issued before another program can be started.
Velocity Limits
Motor[x].MaxSpeed defines the magnitude of the maximum velocity permitted for each motor.
These variables are defined in motor units per millisecond, so a quick conversion must be
calculated from the axis user units (e.g. millimeters per minute).
If the algorithm, while looking ahead in the programmed trajectory, determines that any motor in
the coordinate system is being asked to violate its velocity limit during a segment, it will slow
down the trajectory at that point just enough so that no limit is violated. It will then work
backwards through the buffered trajectory segments to create a controlled deceleration along the
path to this limited speed in the minimum time that does not violate any motor’s
Motor[x].InvAmax acceleration constraint.
During the initial move-block calculations, before move data is sent to the lookahead function, a
couple of factors can result in commanded velocities lower than what is programmed:
If the vector feedrate commanded in the motion program with the F command exceeds
the maximum feedrate parameter Coord[x].MaxFeedrate, then Coord[x].MaxFeedrate
is used instead.
If the programmed feedrate and radius for a circle-mode move would result in a
centripetal acceleration greater than the limit specified by Coord[x].MaxCirAccel, the
speed of the move will be reduced so that this limit is not violated
If the move-block time, either specified directly with the TM command, or calculated as
vector-distance divided by vector-feedrate, is less than the programmed acceleration time
(the larger of Ta + Ts or 2 * Ts), the programmed acceleration time is used instead. This
results in a speed less than what was programmed.
The lookahead function can further slow these moves, but it cannot speed them up.
Acceleration Limits
Motor[x].InvAmax defines the magnitude of the maximum acceleration permitted for each
motor (as the inverse of this magnitude). These variables are defined in the raw PMAC units of
milliseconds-squared per motor unit, so a quick conversion (and inversion) must be calculated
from the user units (e.g. in/sec2, or g’s).
If the algorithm, while looking ahead in the programmed trajectory, determines that any motor in
the coordinate system is being asked to violate its acceleration limit for a segment, it will slow
down the trajectory at that point just enough so that no limit is violated. It will then work
backwards through the buffered trajectory segments to create a controlled deceleration along the
path to this limited speed in the minimum time that does not violate any motor’s
Motor[x].InvAmax acceleration constraint.
Saved setup element Coord[x].SegMoveTime for each coordinate system defines the time for
each intermediate segment in the programmed trajectory (before it is possibly extended by the
lookahead function). Coord[x].SegMoveTime is a floating-point value, with units of
milliseconds. If Coord[x].SegMoveTime is set to 0, the coordinate system is not in
“segmentation mode”; no intermediate segments are calculated, and the lookahead function
cannot be enabled.
Several issues must be addressed in setting the segmentation time. These include its relationship
to the maximum block rate, the small interpolation errors it introduces, and its effect on the
calculation load of the Power PMAC. Each of these is addressed in turn, below.
This relationship holds because blocks of a smaller time than the segmentation time are skipped
over as Power PMAC looks for the next segment point. While this does not cause any errors,
there is no real point in putting these programmed points in the motion program if the controller
is going to skip over them. However, some people “inherit” old motion programs with points
closer together than is actually required; these users may have reason to set their segmentation
time larger than their minimum block time.
Note that the programmed acceleration time sets a limit on the maximum block rate. The move
time for a programmed block, even before lookahead, is not permitted to be less than the
programmed acceleration time. The programmed acceleration time is the larger of the sum of the
Ta and Ts times and twice the Ts time. In high-block-rate contouring lookahead applications, the
Ta time is typically set equal to the minimum desired block time, and the Ts time is typically set
to 0 (because it squares up corners).
Interpolation errors
The cubic-spline interpolation technique that Power PMAC uses to connect the intermediate
segment points is very accurate, but it does create small errors. These errors can be calculated as:
V 2T 2
Error
6R
where V is the vector velocity along the path, T is the segmentation time (watch the units!), and R
is the local radius of curvature of the path. For example, if the speed is 100 mm/sec (~4 in/sec),
the segmentation time is 0.01 sec (Coord[x].SegMoveTime = 10 msec), and the minimum radius
at this speed is 50 mm (~2 in), then the worst-case interpolation error can be calculated as:
mm 2
100 2 2
* 0.012 sec 2
Error sec 0.003mm 3m
6 * 50mm
If the programmed path itself introduces path error, such as the “chordal error” of linear
interpolation, this must be added to the error budget as well. In addition, if the servo-loop
execution adds servo errors, these must also be included.
Because the lookahead buffer stores motion segments, this lookahead length must be expressed in
segments.
To calculate this value, first compute the worst-case time required to stop for each motor in the
coordinate system. This value can be obtained by dividing the maximum motor velocity by the
maximum motor acceleration. In terms of Power PMAC parameters:
Note that if the motor speed is limited to less than Motor[x].MaxSpeed in the segmented path
moves that used the lookahead buffer, through the use of Coord[x].MaxFeedrate or other
limiting methods, this lower speed can be used instead in these calculations.
Now take the motor with the longest stop time, and divide this time by 2 (because the segments
will come in at maximum speed, which takes half the time of ramping down to zero speed). Next,
convert this value to a number of segments by dividing by the coordinate system segmentation
time:
This is the number of segments in the lookahead buffer that must always be properly computed
ahead of time. Because the Power PMAC does not fully recalculate the lookahead buffer every
segment, it must actually look further ahead than this number of required segments.
4 2 * MaxSpeed * InvAmax
Coord [ x].LHDistance * SegmentsNeeded
3 3 * SegMoveTim e
Setting Coord[x].LHDistance to a value larger than needed does not increase the computational
load (although it does increase the time of heaviest computational load while the buffer is filling).
However, it does require more memory storage, and it does increase the delay in having the
program react to any external conditions, including changes in the “segmentation override” value
commonly used for interactive feedrate override.
Some users will want to vary Coord[x].LHDistance dynamically during operation, making it
proportional to the present programmed speed, the present segmentation override, or both. This
can minimize “excessive” lookahead, making the system more responsive to external conditions
and commanded override changes.
Setting Coord[x].LHDistance to a value smaller than needed does not cause the limits to be
violated. However, it may cause Power PMAC to limit speeds more severely than the velocity
limits require in order to ensure that acceleration limits are not violated. Also, a “saw-tooth”
velocity profile may be observed.
The value associated with the define lookahead command determines the number of
motion segments for each motor in the coordinate system that can be stored in the lookahead
buffer. At a minimum, this must be set equal to Coord[x].LHDistance (and it must be greater
than or equal to 1024).
If this value is set greater than Coord[x].LHDistance, the lookahead buffer stores “historical”
data. This data can be used to reverse through the already executed trajectory. If reversal is
desired, the buffer should be sized to store enough “back segments” to cover the desired backup
distance. There is no penalty for reserving more memory for this history than is needed, other
than the loss of this memory for other uses.
The room reserved for the segment data in the lookahead buffer is dependent on the number of
motors assigned to axes in the coordinate system at the time of the define lookahead
command (motors with a null definition in the coordinate system do not count). If the number of
motors assigned to axes in the coordinate system then changes, the organization of the lookahead
buffer will be wrong, and the program will abort with a run-time error on the next move after the
coordinate system is changed.
The most common reason to alter the configuration of a coordinate system during an application
is to change a motor between a rotary positioning axis and a spindle (velocity) axis. Power
PMAC can support this change without the necessity to redefine the lookahead buffer. When the
lookahead buffer is defined, the motor should either be assigned to a position axis (e.g. #4->C)
or a spindle axis (e.g. #4->S0) in the coordinate system. After this time, the definition can be
changed between the two types without the need to reconfigure the lookahead buffer. When the
motor is assigned to a position axis, it is involved in the lookahead calculations; when it is
assigned to a spindle axis, it is not.
If a motor must be added to or removed from a coordinate system during an application that uses
lookahead, the lookahead buffer must first be deleted, then defined again after the change. The
following motion program code shows how this could be done:
Memory Requirements
The act of defining a lookahead buffer reserves space in active memory for the buffer. The longer
the buffer defined, and the more motors assigned to axes in the coordinate system, the more
memory will be reserved. The equation for the amount of memory required for a lookahead buffer
is:
B S * 16 * N 40
where B is the number of bytes of memory required, S is the length of the buffer in segments, and
N is the number of motors assigned to axes in the coordinate system. For example, defining a
lookahead buffer with a length of 20,000 segments in a coordinate system with 6 motors assigned
to axes requires 20,000 * (16*6 + 40) = 2,720,000 bytes (2.6 MB) of memory.
By default, Power PMAC reserves 16 MB of RAM for all lookahead and reversal buffers (plus
target-position and cutter-compensation buffers, which are typically very small). This is sufficient
memory for virtually all applications. The amount of memory still available in the buffer can be
determined using the on-line free query command. This amount can be changed as part of the
project management.
3. A lookahead buffer has been defined for the coordinate system since the last board power-
up/reset.
The lookahead function is active under these conditions even when Power PMAC is performing
inverse-kinematic calculations every segment to convert tip positions to joint positions. This
permits the user to write a motion program in convenient tip coordinates, yet still automatically
observe all joint-motor limits. This is particularly important if the tip path passes near a
singularity, requesting very high joint velocities and accelerations.
Other move modes – rapid and spline– can be executed with the lookahead buffer defined, but the
lookahead function is not active when these moves are being executed.
It is important to realize the implications of the lookahead function on several aspects of the
motion program. Each of these areas is covered below.
Vector Feedrate
Without lookahead, the vector feedrate value (Fxxx) is a command for each programmed move
block in the motion program. That is, each move is calculated so that it is traversed at the
programmed vector feedrate (speed). With lookahead active, the feedrate value is only a
constraint. The move will never be executed at a higher speed, but it may be executed at slower
speeds during some or all of the move as necessary to meet the motor constraints.
If the move is programmed by move time instead of feedrate, the programmed move time
becomes a (minimum) constraint; the move will never be executed in less time, but it may be
executed in greater time.
Acceleration Time
The programmed acceleration times Coord[x].Ta and Coord[x].Ts, whether using the saved
values or setting with the ta and ts commands in the motion program, are the times before
lookahead. The lookahead function will control the actual acceleration times that are executed,
but the programmed acceleration times are still important for two reasons.
First, the programmed acceleration time Tacc, which is the larger of Ta + Ts and 2 * Ts, is the
minimum move-block time. If Power PMAC initially computes a smaller move time, typically as
(vector-distance divided by vector-feedrate), it will increase the time to be equal to the
acceleration time, slowing the move. This check occurs even before lookahead (which can only
slow the move further), and it is an important protection against computational overload. The
acceleration time must be set low enough not to limit valid moves.
Second, as longer moves are blended together, the programmed acceleration time and feedrate
control the corner size for the blending. The blended corner begins a distance of F * Tacc / 2
before the programmed corner point, where F is the programmed feedrate, and Tacc is the larger of
Ta + Ts and 2 * Ts. The blended corner ends an equal distance past the programmed corner
point.
If the lookahead algorithm determines that the blended corner violates the acceleration limit on
one or more motors, it will automatically slow the speed of the path in the corner. This will make
the time for the blended corner bigger than what was specified in the program. The lookahead
will also automatically create a controlled deceleration ramp going into the blended corner, and a
controlled acceleration ramp coming out of the corner. In this manner, the size of the rounding at
a corner can be kept small without violating acceleration constraints, and without limiting speeds
far away from the corners.
In general, the acceleration time should be set as large as it can be without either making the
minimum move time too large, or the corners too large. In high block-rate applications, the Ta
time is generally set to the minimum block time, and the Ts time is set to 0. In low block-rate
applications, the Ta and Ts times are generally set to get the desired corner size and shape.
Quick Stop
The \ [lh\ buffered program command] “quick-stop” command causes Power PMAC to
immediately calculate and execute the quickest stop within the lookahead buffer that does not
exceed Motor[x].InvAmax acceleration limits for motors in the coordinate system. Motion
continues along the programmed path to a controlled stop, which is not necessarily at a
programmed point (and probably will not be). This command is the effective equivalent of a
“feed hold” within lookahead (even though the internal mechanism is quite different), and it
should be the command issued when an operator presses a “Hold” button during lookahead.
Outside of lookahead, this command causes an actual feed hold, as if the h [hold] command had
been given.
The \ command is the best command to use to stop interactively within lookahead operation with
the intention of resuming operation. Any synchronous M-variable assignments set to happen
within the deceleration will execute.
Motors may be jogged away from this stop point, if desired. Also, motion can be reversed along
the path with the < command (see “Reversal”, below).
Normal programmed motion can subsequently be resumed with the > [lh>]“resume-forward”, r
[run], or s [step] command, provided all motors are commanded to be at the same position at
which they originally stopped with the / command. If any motors have been jogged away from
this point, they must first be returned with the j= [jog=] command. Acceleration limits are
observed during the ramp up from a stop here. The > “resume-forward” command puts the
coordinate system in either continuous run mode, or single-step mode, whichever mode it was in
before the “quick-stop”.
Quit/Step
The q “quit” command simply tells the motion program not to calculate any further motion
program blocks. (The s “single-step” command will do the same thing if given while the program
is running.) Motion segments up to the end of the latest calculated motion program move block
are still added to the lookahead buffer, and all segments and synchronous M-variable assignments
in the lookahead buffer are completed.
Motion will come to a controlled stop at the end of the latest calculated move block without
violating constraints. However, there can be a significant delay – over (Coord[x].LHDistance *
Coord[x].SegMoveTime) milliseconds if the lookahead buffer is full – from the time the q or s
command is given and the time the axes stop.
Motors may be jogged away from this stop point, if desired. Motion can subsequently be resumed
with the r or s command. Motors do not have to be at the same position at which they were
originally stopped with the q or s command. However, if it is desired to return them to this
position, the j= command should be used.
Feed Hold
The h “feed hold” command brings the feedrate override value to zero, starting immediately, and
ramping down at a rate controlled by coordinate system variable Coord[x].FeedHoldSlew.
Motion continues along the programmed path to a controlled stop, which is not necessarily at a
programmed point (and probably will not be). Acceleration limits are not necessarily observed
during the ramp down to a stop. Any synchronous M-variable assignments set to happen within
the deceleration will execute.
Abort
The a “abort” command breaks into the executing trajectory immediately, and brings all motors
in the coordinate system to a controlled stop, each at its own deceleration time or rate as set by
Motor[x].AbortTa and Motor[x].AbortTs for the motor. The stop is not necessarily at a
programmed point (and probably will not be), and it is not necessarily even along the
programmed path (and probably will not be).
Segments and synchronous M-variable assignments already in the lookahead buffer are
discarded; they cannot be recovered. The program counter is automatically reset to the beginning
of the (top-level) motion program, so the abort command is not recommended except for stopping
quickly under error conditions.
Back-up Command
If the < command is given while the coordinate system is in normal forward execution in the
lookahead buffer, Power PMAC will internally generate a \ “quick-stop” command to halt the
forward execution, then immediately start reverse execution.
The < command can also be given after execution of the program has been halted with a \ quick-
stop command. It cannot be given after stopping with a q “quit”, s “single-step”, or a “abort”
command, or an automatic error termination.
Reverse Execution
Execution in the reverse direction will observe the position, velocity, and acceleration limits, just
as in the forward direction. If not stopped by another command, reverse execution will continue
until it reaches the beginning (oldest stored point) of the lookahead buffer. It will automatically
stop at this point with a controlled deceleration within the acceleration constraints.
Reversal cannot proceed through any non-segmented move (spline, rapid, homing), so will
automatically stop at the end point of the latest of this type of move. If the program had been
stopped with a q or s command, the lookahead buffer is cleared on restarting, so reversal can
only go back to that point.
It is possible for reversal to continue through a stop due to a dwell command or similar break,
but the time for such a stop is not retained; it is just a momentary stop in reversal (and subsequent
forward execution). Note that a delay command is part of the continuous motion sequence, so
its time at zero velocity is maintained during reversal.
programmed move block being executed during all aspects of this procedure if synchronizing line
labels have been used in the program.
Forward execution over the reversed part of the path will blend seamlessly into previously
unexecuted parts of the path. At this point, standard execution of the lookahead buffer will
resume, with new points being added to the end of the lookahead buffer, and execution of
buffered synchronous M-variable assignments starting again.
Reversal with negative time base is generally better for “proportional” changes, as with operator
pot or handwheel rotation, or with a continuously varying process value that controls movement
along the programmed path.
However, this override function occurs after the lookahead calculations, so it can override the
limits imposed by the lookahead algorithm. The velocity of the resulting trajectory varies linearly
with the override value, and the acceleration varies with the square of the override value. At an
override value of 150%, the velocities will be 150% of those programmed (or limited), and the
accelerations will be 225% of those programmed (or limited).
Because the lookahead algorithm occurs after this override function, the limits imposed by
lookahead are not changed by the override value. This factor makes the segmentation override the
preferred method in most applications. It should be noted that changes in the override value are
delayed by the length of the lookahead buffer. This delay is necessary to ensure that acceleration
limits are always observed.
Both override techniques are discussed in detail in the “Setting Up Coordinate Systems” chapter
of the User’s Manual.
Master
Desired
Action
Slaving
Master Algorithm Slave
Actual Desired
Action Action
Feedback
Desired Algorithm
Relationship
Slave
Actual
Action
A master/slave algorithm is one strategy for tying together the motion of two or more devices.
Another strategy is generally known as “coordination”. In a coordination strategy, the desired
motion of multiple axes is tied together through a mathematical relationship, and the physical
coordination is achieved through the action of the feedback loops for each motor causing the
actual motion to track the desired motion. In Power PMAC, this is achieved by means of
assigning the relevant motors to axes in the same coordinate system, and commanding the axes
together in a motion program.
Coordination
Axis #1 Algorithm Axis #2
Desired Desired
Action Action
Feedback Feedback
Algorithm Algorithm
Axis #1 Axis #2
Actual Actual
Desired
Action Action
Relationship
In general, if the desired physical relationship can be achieved through a coordination strategy,
such a strategy should be used. A mathematically generated trajectory is superior to a signal-
generated trajectory, reducing quantization noise, measurement noise, and delay. However, the
use of a coordination strategy requires a sufficiently high-quality feedback algorithm on all axes
to keep the relationship within the required tolerance, and the ability to generate all of the
trajectories in a single controller.
If these conditions do not apply, it is necessary to use one axis without tight feedback or
commanded from a separate controller as the “master”, employing a sensor on this device to
generate the master signal for the other axes operating as “slaves”. This signal is used in the
generation of the trajectories for the slave axes. Note that the imperfections (noise) in the master
signal may limit the aggressiveness of the tuning of the slave axes, particularly of the feedforward
terms.
When the signal is used for feedback or position-following master, the output scale factor of the
ECT entry is usually set to scale the result in the “counts” or “LSBs” of the encoder or other
sensor. When the signal is used for external time-base master, the output scale factor of the ECT
entry is usually set based on a user-selected “real-time input frequency” (RTIF), so the result is
scaled in the “milliseconds” elapsed if the input signal were running at this RTIF. Refer to the
section “What is External Time-Base Control?” below for details on understanding and setting
the RTIF. The motion program running under external time base is written as if the master device
were always producing the RTIF, with the time base functionality automatically adjusting the
speed in proportion to the actual frequency.
If the same signal is used both for feedback and for external time-base master, it should be
processed through two separate ECT entries, one for the feedback function, and one for the time-
base master function. These two entries can be identical except for the output scale factor. The
scale factor for the time-base master entry should be smaller than the scale factor for the feedback
entry by a factor of the RTIF (in counts per millisecond). That is, to get the scale factor for the
time-base master entry, divide the scale factor for the feedback entry by the RTIF value.
This software sub-count interpolation computes 9 bits of fractional count information. When used
for feedback or position-following master, this type of entry usually has an output scale factor
EncTable[n].ScaleFactor of 1/29 (1/512) so the output is scaled in counts of the encoder. When
used for an external time-base master, the output scale factor should be set to 1/(512*RTIF), with
the RTIF expressed in counts per millisecond, so the output is in units of the fictitious
“milliseconds” required for external time-base. It is recommended that the value be entered as an
expression so Power PMAC can compute the result precisely.
From this point on, the signal is treated just as a quadrature encoder would be (see directly
above). The RTIF is usually selected as the nominal frequency of this input signal.
This sub-count interpolation computes 10 bits of fractional count information (12 bits per line for
“4096x” interpolation). When used for feedback or position-following master, this type of entry
usually has an output scale factor EncTable[n].ScaleFactor of 1/210 (1/1024) so the output is
scaled in (quadrature) counts of the encoder. When used for an external time-base master, the
output scale factor should be set to 1/(1024*RTIF), with the RTIF expressed in counts per
millisecond, so the output is in units of the fictitious “milliseconds” required for external time-
base. It is recommended that the value be entered as an expression so Power PMAC can compute
the result precisely.
From this point on, the signal is treated just as a quadrature encoder would be (see directly
above). The RTIF is usually selected as the nominal frequency of this input signal.
required for external time-base. It is recommended that the value be entered as an expression so
Power PMAC can compute the result precisely.
When used for feedback or position-following master, this type of entry usually has an output
scale factor EncTable[n].ScaleFactor of 1.0 so the output is scaled in counts (LSBs) of the
encoder. When used for an external time-base master, the output scale factor should be set to
1/RTIF, with the RTIF expressed in counts per millisecond, so the output is in units of the
fictitious “milliseconds” required for external time-base. It is recommended that the value be
entered as an expression so Power PMAC can compute the result precisely.
The functionality can be envisioned through its mechanical analogy as shown in the following
figure:
ΔPm ΔPs
Rm Rs
Master
MasterPosSf = Rm / Rs
Slave
Use of the position-following feature does not require the use of any motion or PLC programs. It
simply requires setting values for a few setup elements. These values can be saved to non-volatile
flash memory, but also can be changed at any time.
Motor[x].pMasterEnc = EncTable[n].a
This command can be either an on-line or buffered-program command. The assignment can also
be made interactively through the motor-setup program associated with the IDE. Note that the
only valid settings for Motor[x].pMasterEnc are addresses of ECT entries.
The default value of pMasterEnc for all motors is EncTable[0].a. ECT entry 0 is by default a
“dummy” entry, processing a null register. Many Power PMAC users who have a single master
encoder for position following will process it through ECT entry 0. However, if the encoder
channel used for the master encoder is already processed through a different entry (auto-
assignment of ECT entries to existing hardware interface channels at system re-initialization start
with ECT entry 1), it is usually best just to use that entry. Because all ECT entries are processed
first in each servo cycle, before any of the following or feedback algorithms, there is no delay
from using a higher-numbered ECT entry.
Motor[x].MasterPosSf can be changed at any time to any floating-point value, whether or not
following is enabled. If saved setup element Motor[x].SlewMasterPosSf is set to its default
value of 0.0 (or in older firmware revisions where Motor[x].SlewMasterPosSf does not exist),
the ratio used is changed immediately to the new value; there is no slew-rate control. Care should
therefore be taken in this mode when changing this value while the motor is actually moving in
tracking the master position, as large instantaneous changes will cause significant step changes in
the commanded velocity of the slaved motor.
When following is disabled, the actual ratio in Motor[x].ActiveMasterPosSf is set to 0.0. When
following is enabled, this actual ratio is incremented by the magnitude of
Motor[x].SlewMasterPosSf each servo cycle until the desired ratio is reached. When following
is disabled the actual ratio is incremented in the other direction by Motor[x].SlewMasterPosSf
each servo cycle until a value of 0.0 is reached. When the desired ratio is changed, the actual ratio
is incremented by the magnitude of Motor[x].SlewMasterPosSf each servo cycle until the new
desired ratio is reached.
If the application may enable or disable following, or change the desired ratio, while the master is
“moving”, it is strongly recommended to use slew-rate control to prevent step changes in the
commanded velocity of the slaved motor. However, the use of slew-rate control means that the
“position lock” between master and slave is not just dependent on the desired following ratio.
However, if bit 1 is set to 1, thus adding 2 to the value of Motor[x].MasterCtrl, “offset” mode is
specified, the reference position for programmed moves using the motor does change along with
the following motion. Subsequent absolute-mode moves are added on top of the position changes
from the following function. This permits the user to superimpose programmed and following
motion, as on a moving web, so the motion program can be written as if the web were not
moving, but resulting in an identical path relative to the moving web.
calculations would be done for subsequent moves, creating a “mismatch” between axis and motor
position, which could cause a sudden jump in the motor motion on the next programmed move if
not corrected. This is true regardless of whether following is enabled or not. To eliminate this
mismatch, a pmatch position-matching command must be executed before the next programmed
move command is executed.
Power PMAC automatically executes a pmatch command any time an r (run) or s (step)
command is issued to start a motion program; however, if the mode is changed in the middle of a
motion program, or if the next axis move is commanded from a PLC program, the pmatch
buffered program command must be issued explicitly in the program before the next move
command. It should be preceded by a dwell command in a motion program to ensure that any
pre-calculation is halted.
When the following is speed-limited, the motor “falls behind” the master, losing position
synchronization with it. In some applications, the desire is to “catch up” with the master when the
speed is no longer limited and re-establish “position lock” with the master. In other applications,
the desire is just to re-establish “velocity lock” with the master when the speed is no longer
limited, letting the motor “stay behind” the master.
The following plot demonstrates the case that is speed limited but not acceleration limited, and
which therefore only re-establishes velocity lock when no longer limited. The slave motor (Motor
2) does not catch up to the master position when it comes out of speed limiting.
The “excess” accumulated at any time can be seen in the difference between the status elements
Motor[x].MasterPos (the unlimited position from the master) and Motor[x].ActiveMasterPos
(the limited position). Position lock is re-established when these two elements have the same
value. Note that acceleration limiting can only be enabled if velocity limiting is also enabled
(Motor[x].MasterMaxSpeed > 0).
The next plot demonstrates the case that is both speed limited and acceleration limited, and which
therefore “catches up” with the master once it is no longer limited. The slave motor (Motor 2)
continues at the speed set by Motor[x].MasterMaxSpeed, even when the master is no longer
commanding a speed this high, until it is almost caught up, at which time it decelerates at the rate
set by Motor[x].MasterMaxAccel.
Note that the initial slave-motor acceleration is kept well below the specified limit (at which the
final slave-motor deceleration occurs). This is due to the fact the Power PMAC is limiting the
speed so that a deceleration to zero velocity could occur within the specified acceleration limit,
even if there were no further change in master position.
When following is disabled when the master is in motion, the slave motor will first decelerate at
the rate specified by Motor[x].MasterMaxAccel until it is traveling in the opposite direction. It
will continue to move in the opposite direction until it has returned to the position where it was
when following was disabled, by which time it will have decelerated to zero velocity.
The following plot shows the response to enabling and disabling following while the master is in
motion. In this case, the master is moving at approximately constant velocity throughout the
process.
If, during the initial acceleration after enabling, continued acceleration would cause the following
motor to exceed its following speed limit, the following is clamped at this maximum speed even
while it is attempting to re-attain position lock with the master. This is shown in the following
plot:
It is suggested that custom following algorithms that directly to the Motor[x].MasterPos register
be implemented in a foreground PLC program executing at servo rate, or a user-written servo for
an unused motor (especially Motor 0). These algorithms can implement special features not
present in the standard algorithm.
This is fine for a great number of applications. However, in some applications, we wish to slave
the Power PMAC axes to an external axis not under Power PMAC control. In these applications,
we really want to specify the trajectories as functions of master position, not of time. Most
controllers force the user to use a completely different method for specifying the trajectories for
this type of trajectory, often table-based, as common terms involved in position-vs-time
trajectories, such as velocity and acceleration, are no longer really valid.
Power PMAC’s method for specifying trajectories in this mode leaves the language expressing
position as a function of “time”, but makes this now-fictitious “time” proportional to the distance
covered by the master. This is done by defining a “real-time input frequency” (RTIF) from the
master’s position sensor, usually in units of counts per millisecond. For example, we define an
RTIF of 32 cts/msec. Then, in external time-base mode, when the motion program refers to a
millisecond (directly or indirectly), it is really referring to a distance elapsed on the master
corresponding to 32 counts of the master encoder. If the motion program commands a move to
take 2 seconds (2000 msec) to complete, it is really commanding the move to complete in 64,000
counts of the master encoder, however long of a time that takes.
The selected RTIF is used to compute a scale factor in the encoder conversion table (ECT) entry
that processes the master signal, as explained in the section “Processing the Master Position
Signal”, above. The motion program then specifies a trajectory assuming that the master always
provides this frequency.
The selection of the RTIF is quite arbitrary. In many applications, the frequency produced at the
“nominal” speed of the master is used. It can be desirable to select a value that is a power of 2
(such as 32) so that the scale factor in the ECT has an exact floating-point representation, if this
does not result in difficulties in writing the motion sequence. (The scale factor is inversely
proportional to the RTIF.) However, because the scale factor is a double-precision floating-point
value, in the vast majority of applications, a non-exact representation will not cause any
noticeable errors. (This is a substantial improvement over the PMAC and Turbo PMAC integer
algorithms, in which any inexactness would cause a quickly noticeable error. In Power PMAC, an
inexact representation would require continuous high-speed motion of the master for multiple
hours before any noticeable error could accumulate.)
One of the advantages of this method is that is possible to develop and debug the slave
trajectories without the need for a master signal, executing them as true functions of time (i.e.
with “internal time base”). This is often a very useful development strategy, especially employing
the data gathering and plotting features provided. Once satisfied with the results at this stage,
changing the value of a single variable (as explained below) converts execution to external time
base.
The key advantage of the cam table approach is that the master can be fully bi-directional,
whereas the time-base master must be fundamentally uni-directional. Also, many users are more
familiar with the table-based approach, since it is more common in industry.
However, the external time-base approach is more flexible in that it can use the full capabilities of
Power PMAC’s motion program math, logic, and trajectory generation. It is not limited to cyclic
motions, and in many cyclic motions, the cycle can be described in a small number of
programmed moves, not necessarily evenly spaced, rather than a large number of evenly spaced
table points.
where CPn-1 is the previous cycle’s command position, CVn is the cycle’s command velocity, and
Δt is the time elapsed in the servo cycle.
In most operation, the value of Δt corresponds to the true physical time elapsed in one servo
cycle. This true time should be specified by the user in saved global setup element
Sys.ServoPeriod, in units of milliseconds. However, the numerical value used does not need to
match this physical time interval. If we instead use a value for Δt each servo cycle that is
proportional to the change in master position (ΔMP) during that servo cycle, we have made the
trajectory a function of elapsed master position, not of elapsed time.
Note that the physical time between servo cycles does not change, which means the dynamics of
the servo loop feedback and feedforward terms do not change either. It is only the rate of
execution of commanded trajectories that change, and since they change together for all motors in
the coordinate system, any path through space does not change, and full coordination is
maintained.
External time base is designed to work only in the positive direction (ΔMP > 0). The algorithm
can handle very brief moments of negative direction from the master without losing
synchronicity, as the motion is reversible within a single motion segment with given equations of
motion. This permits the master to come to a stop and to dither about a stopping point without the
slave axes losing their “lock” to the master. However, if the accumulated negative signal from the
master would require a transition into a previous segment with different motion equations, this
transition will not be made. Applications that require tracking of a fully bi-directional master
position signal may use position “compensation” tables with the master signal assigned to the
“source” motor and the slaved motor as the table’s “target” motor.
The details for processing each common type of signal in an ECT entry are given in the section
Processing the Master Position Signal earlier in this chapter. The key difference in using the
signal for time-base master instead of servo feedback is that the output scale factor for the entry
for time-base master should be a factor of the RTIF (in cts/msec) smaller than it would be for
servo feedback. If the signal is used for both purposes, two separate entries with different scale
factors should be used.
Coord[x].pDesTimeBase = EncTable[n].DeltaPos.a
This will cause the coordinate system to use the computed scaled ΔMP value from the entry as its
Δt value in the motion interpolation equations. If the master encoder is outputting the real-time
input frequency, this value will match the real time elapsed in a servo cycle.
The saved setup element Coord[x].TimeBaseSlew, which limits how much the time-base value
actually used in the interpolation equations can change each servo cycle, even if there are big
changes in the desired time-base value, is by default set to a very low value (0.00001) to prevent
sudden velocity changes when commanded time-base has a step change. When external time-base
is used, the inertia of the physical master prevents large instant changes, but there can be cycle-to-
cycle “noise” requiring significant changes to maintain full synchronization. Therefore
Coord[x].TimeBaseSlew should be set much larger (e.g. to 1.0) so it will not limit the changes
due to noise, which would cause a loss of synchronization.
Maintaining Synchronicity
Synchronicity to the master signal is only maintained during a continuous (blended or splined)
motion sequence. If there is a break in the sequence for whatever reason, even if only for a
moment, synchronicity to the master cannot be fully maintained between the motion sections
before and after the break. Conditions that will cause a break in the continuous sequence include
disabling of blending from setting Coord[x].NoBlend to 1 or from having a corner sharper than
that set by Coord[x].CornerBlendBp, using a rapid-mode move (which is never blended at
beginning or end), and using a dwell command (even a dwell 0).
Note that a dwell command always executes in “real time”, regardless of the input frequency. It
also disables pre-computation, so there is a brief but not fully deterministic break afterward to
compute the next move. If you want to command zero motion of the slave axes for a period
proportional to the frequency of the master, either explicitly command a zero-distance move of a
specified “time”, or use the delay command for this “time”. Unlike a dwell command, a
delay command executes in “variable time”, and it is part of a blended move sequence, with
calculations done during the continuous sequence.
In some applications, the commanded motion is started with the master signal at rest, and so will
not actually begin until the master signal actually starts. If the master signal comes from a
position sensor on a physical device, the inertia of the device will limit the acceleration of the
signal. Sometimes, the user desires that the actual motion of the commanded trajectory be directly
proportional to the master signal frequency, without any lag (much like in electronic gearing). To
accomplish this, the acceleration times for the programmed trajectory should be set to 0, and if
there could be any acceleration rate limiting, the InvAmax parameters should be set to 0.0 to
permit “infinite” acceleration at 100%.
For simplicity, we will define our RTIF as the count frequency produced by the web encoder at
the nominal speed. We get:
EncTable[4].ScaleFactor = 1/(512*64)
Many time-base applications do not require the master and slave cycles to be in phase with each
other (for example, cutting blank sheets of paper to length rather than printed pages), and others
have to be continually re-registered due to stretching, slippage, or uneven spacing. These types of
applications can use the standard time-base functionality, with any necessary adjustments made in
the application program on the fly.
However, applications that simply need to start off in proper phase with the master cycle can use
the automatic “triggered time base” feature of the conversion table. This technique permits
perfect synchronization to the position of the master that is captured by a trigger, by freezing the
time base until the capture trigger is received, then starting the time base referenced precisely to
the position that was captured by the trigger. The trigger is commonly the index pulse of a spindle
encoder, or a registration mark on a moving web wired to one of the channel’s flags. The
“hardware capture” feature of PMAC ASICs is used to get the exact master position at the instant
of the capture, without any software reaction delays.
Then, EncTable[n].pEnc1, which specifies the address of the secondary source for the entry,
must be changed to Gaten[i].Chan[j].Status.a for the IC and channel used, so the trigger-capture
bit can be monitored. At this point, the time base is still frozen.
(In the older Turbo PMAC, this arming step needed to be done in a separate PLC program to
ensure that the arming occurred after the first move was fully calculated. That separate function is
not required in the Power PMAC as long as the first move command line in the motion program
immediately follows the arming command.)
While the time base is in its frozen state, the initial programmed move that is to start on the
trigger must be fully calculated and completely read to start execution. This way, there will be no
possibility of a calculation delay hurting the accuracy of the relationship of the motion to the
master trigger position.
It also reads the position captured at the instant of the trigger, and subtracts this from the position
captured at the start of the servo cycle to get the change in master position since the trigger
(which will be a fraction – between 0.0 and 1.0 – of the position elapsed since the previous servo
cycle), multiplies this difference by EncTable[n].ScaleFactor, and puts the result into
EncTable[n].DeltaPos.a, where it will be used by the slaved coordinate system.
In subsequent servo cycles, the change in master position will be calculated over the entire servo
cycle, but by using the hardware-captured position at the trigger, the motion will be referenced
exactly to this position.
Next, the time base must be frozen by setting EncTable[n].type to 10 and prepared to read the
trigger by setting EncTable[n].pEnc1 to Gaten[i].Chan[j].Status.a.
If there are any extensive calculations required to prepare for the first move command, these
should be done next in the motion program.
(This arming can also be done, as in Turbo PMAC, in a single statement in a PLC program, e.g.:
if (EncTable[n].type == 10) EncTable[n].index1 = 2 ).
The actual move command for the first move to start on the trigger must immediately follow in
the motion program. Power PMAC will calculate the equations of motion for this move and place
them in the execution queue, but actual move execution (interpolation) will not begin because the
time base (Δt value) is frozen at zero. This move execution will not begin until the specified
trigger is detected.
Each thread cut pass is triggered by the index pulse of the spindle encoder, permitting a precisely
referenced start to the cut. This permits the different threads to be perfectly spaced relative to
each other, while still permitting the fastest possible return after each thread cut (which causes a
loss of synchronicity).
The spindle has a quadrature encoder with 1024 lines per revolution, which provides 4096 counts
per revolution with the standard “times-4” decode, connected into the last channel of our single
ACC-24E2A board at the default address. The spindle has a nominal speed of 1200 rpm (20
revolutions per second), which we will use as the real-time speed. The resulting real-time input
frequency is 81.92 cts/msec (81.92 kHz).
The spindle encoder channel is assigned by default to the ECT entry 4 as a Type 3 “software 1/T
extension” conversion, and we will not change that. However, the default scale factor is 1/512, so
we will change that to specify our selected RTIF with the command:
EncTable[4].ScaleFactor = 1 / (512*81.92)
The program sequence is to cut three equally spaced threads of a pitch of 4 mm and a depth of 0.5
mm on a cylinder of 10 mm radius from Z = 1 mm to Z = 25 mm. The programmed speed of the
cutting move is calculated as 4 (mm/rev) * 20 (rev/sec) = 80 mm/sec.Each thread is delayed one-
third of a revolution from the previous thread by the time of the “plunge” move; at the real-time
speed of 20 rps, this delay is 50/3 msec. The motion program code to implement this is:
Power PMAC has high-level “move-until-trigger” constructs that can utilize the hardware
position-capture function to end a commanded move automatically at a precise distance from the
captured feedback position at the trigger. The “triggered time base” slaving function uses the
hardware-capture function on the master position data to provide a precise staring reference point
for the following. It is also possible to create your own “low-level” algorithms to use the
hardware capture functions for other purposes.
Both PMAC2-style and PMAC3-style interface ICs support the hardware position-capture
function. Both also support capture of timer-based estimated sub-count position as well, although
this is much easier and more direct in the PMAC3-style IC.
The following diagram shows the capture trigger specification circuitry for a channel of a
PMAC2-style IC as part of the encoder processing circuitry. The same basic circuitry is present in
each channel of a PMAC3-style IC.
Servo
Clock
TimeBetweenCts
Timers
TimeSinceCts
A
B Decoder Counter ServoCapt
EncCtrl Phase
Clock
C PhaseCapt
HOME
PLIM Trigger Trigger
Flag Select
MLIM
Select
USER
CaptCtrl HomeCapt
CaptFlagSel
Address Data
In the PMAC3-style IC, however, it is possible to use a flag from any channel on the IC in the
trigger for a given channel’s position capture. Gate3[i].Chan[j].CaptFlagChan specifies the
channel index (0 to 3) for the flag that will be used in this (i) channel’s position capture. The
default value for each channel’s capture is the same channel’s flag. Whether the same or different
channel’s flag set is selected, Gate3[i].Chan[j].CaptFlagSel specifies which flag in the set is
used.
All of these create basically the same type of motion. All of them end their “post-trigger” move at
a pre-defined distance from the position at the trigger. These moves are described in detail in the
chapter Executing Individual Motor Moves.
The input trigger is most commonly from a capture flag in one of the Servo ICs (“gates”) for the
Power PMAC. In this case Gaten[i].Chan[j].CaptCtrl and Gaten[i].CaptFlagSel determine
which states of which inputs contribute to the trigger event.
Once the captured motor position is calculated, it is stored in Motor[x].CapturedPos and the
control element Motor[x].CapturePos is set back to 0 to indicate that the function is complete.
An example of how to use this function is shown in the following PLC program code:
Bit 1 (value 2) of the status flag is set to 1 by the IC’s capture logic when the trigger condition
occurs and the position is latched into the capture register(s). It is set to 0 when the captured-
position register Gaten[i].Chan[j].HomeCapt is read by the processor. The act of reading this
register automatically resets and re-arms the capture logic.
Bit 0 (value 1) of the status flag is set to 1 by the IC’s capture when a trigger condition occurs
that uses the “gated index” as at least part of the trigger condition (Gaten[i].Chan[j].CaptCtrl bit
0 = 1 to specify use of the index, and Gaten[i].Chan[j].GatedIndexSel = 1 to specify “gating” of
the index pulse to a single quadrature-state width). Bit 1 is always set as well when this bit is set.
This bit is set to 0 when the captured-position register is read by the processor This bit is mainly
used by routines that check for position loss by comparing the difference in successive capture
values against the nominal counts per revolution.
PMAC3-style ICs use “edge-triggered” capture logic, so after a trigger and read of the captured-
position register, the specified input signal(s) must leave the specified trigger level(s) and then re-
enter these level(s) to create another trigger.
Note that the relationship of these “hardware count” units to any resulting motor position units
depend on the values for EncTable[n].ScaleFactor and Motor[x].PosSf used in processing the
position data for the motor.
The value in this register is referenced to the power-up/reset position of the sensor. That is, the
counter is set to zero at power-up/reset, and it counts from there. It does not get reset to zero if the
motor using it for feedback is homed. If the value in the register passes 0 in the negative
direction, or 16,777,215 (224 – 1) in the positive direction, it simply rolls over to the other end of
its range. See the section “Handling Rollover of the IC Position Registers”, below, for
instructions on how to deal with this effect.
This “hardware 1/T” extension in the IC is not compatible with the standard “software 1/T”
extension performed in the encoder conversion table for servo use. For this reason, it is most
often used with sinusoidal encoders, as on the ACC-51E interpolator board. In this case, the servo
uses analog arctangent extension in the ECT, but the capture (and compare) circuits use the
“hardware 1/T” in the IC.
When “hardware 1/T” extension is enabled for an IC channel, the contents of the two timer
registers for the channel change (which is why “software 1/T” extension in the conversion table
cannot be supported). The 24-bit element Gate1[i].Chan[j].TimeBetweenCts is split into 2 12-
bit components; the high 12 bits form the (unsigned) fractional count portion for HomeCapt (for
C users, these are the high 12 bits of a 32-bit element).
This component can take a value of 0 to 4095, in units of 1/4096 of a count. Higher values of
fractional count are closer to the more positive whole count, regardless of the direction of motion.
When reading the value in the component, it is best to mask out the low 12 bits (although some
will consider that data too insignificant to care about), then shift the data right by 24 bits to get it
into the fractional components of a count. (First, shift 12 bits to move the data to the LSBs of the
element, then 12 more bits to make it fractional. In C, this would be 20 + 12 = 32 bits of shift.)
Note carefully what a “count” means here. Because we are dealing with the hardware counter in
the Servo IC, these are “hardware counts” – one unit of the hardware counter. With the “times-4”
decode that is almost universally used (and must be used with ACC-51E boards), there are 4
hardware counts per line (signal cycle) of the encoder. The units of the output of an encoder
conversion table entry processing the sinusoidal encoder for motor servo feedback depend on the
scale factor used there (if the suggested value 1/1024 is used, it will have the same units).
Because the act of reading the whole-count position in the HomeCapt register re-arms the trigger
circuitry, the fractional-count position should be read first in any operation to read both and
combine into a single position value. For example:
In C, which must work with 32-bit I/O elements, the mask value would be $FFF00000 and the
shift-right operation would be by 32 bits.
The following diagram shows how the fractional count position is generated for the positions
latched on the capture trigger, servo clock, and phase clock. Even if the “arctangent extension” is
used for the fractional count extension for servo and phase data (as enabled by setting saved setup
element Gate3[i].Chan[j].AtanEna to 1), the timer-based extension will can still be used for the
trigger-captured position.
Trigger
Count
Timer Home Capture Home
Extension Whole Count Fraction
Trigger
Servo
Clock
A
Servo Capture Servo
B Decoder Counter
Whole Count Fraction
Dir
Servo
Clock
AtanEna
Phase
Clock
SinData
ADC Shift Arctangent Phase Capture Phase
CosData
Registers Extension Whole Count Fraction
Phase
Clock Address Data
Note that the relationship of these “hardware count” units to any resulting motor position units
depend on the values for EncTable[n].ScaleFactor and Motor[x].PosSf used in processing the
position data for the motor.
The value in this register is referenced to the power-up/reset position of the sensor. That is, the
counter is set to zero at power-up/reset, and it counts from there. It does not get reset to zero if the
motor using it for feedback is homed. If the value in the register passes 0 in the negative
direction, or 232 - 1 in the positive direction, it simply rolls over to the other end of its range. See
the section “Handling Rollover of the IC Position Registers”, below, for instructions on how to
deal with this effect.
For simplicity, this analysis assumes that EncTable[n].ScaleFactor for the ECT entry processing
the encoder for motor position feedback results in the entry’s output being scaled in the same
counts as the compare circuit uses. (There can be fractional resolution from 1/T timer extension
or analog arctangent extension, but each unit increment is a count.) If the application uses a
different scaling, this must be accounted for in subsequent calculations.
If the user is accessing the captured position registers directly in an application where rollover is a
possibility, the application code must explicitly account for the rollover, calculating the number
of times the counter has rolled over, and in which direction, so a correction can be applied. In an
application where the motor is scaled in encoder counts and a PMAC2-style IC is used, the
following script algorithm (with declared user variables) can be used to account for rollover:
Note that EncCaptPos and Motor[x].ActPos are in units of full counts of the encoder in this
example. Use of other units for either will require rescaling.
A Power PMAC motor takes the feedback position output from its selected ECT entry and
multiplies it by saved setup element Motor[x].PosSf to use as motor position. At the default
value of 1.0, the motor has the same units as the ECT output – counts in our case. However, if the
motor is scaled in engineering units, the value will be different from 1.0 – often much smaller. To
convert from motor units to encoder units, the calculation must divide by this motor scale factor.
The calculation combining the offset and scaling to convert from encoder units to motor units is:
If the capture position register has fractional resolution, you will need to include that scaling in
the calculations. For example, the PMAC3-style ICs have 8 bits of fractional resolution, so you
will need to divide the read value in counts by 28 (256) (even if you will have a value of 0 in the
fractional component).
where Motor[x].CoordSf[i] is the axis scale factor for the axis with index “i” (e.g. 0 for A, 1 for
B, etc.) and Motor[x].CoordSf[32] is the axis offset value.
If the axis definitions are more complex than this, either involving multiple axes in a single
definition, or using kinematic subroutines, then this simple relationship cannot be used, and
application-specific algorithms must be employed.
This interrupt has a higher priority than even the phase and servo interrupts that control the
motors. This means that capture events can be processed at a higher frequency than even the
phase and servo interrupts. However, it also means that the interrupt service routine must be kept
very short so that phase and servo tasks can always complete in the correct update cycle. The
intent of this routine is to update a list of positions in memory quickly from the captured position
register and prepare the capture circuitry for the next trigger.
Power PMAC permits the user to install a dedicated interrupt service routine written in C to react
to capture and/or compare events from a PMAC3-style IC. Refer to the chapter Writing C
Functions and Programs for more details.
The individual hardware used determines where the position-compare outputs are brought out,
and the nature of the driver circuit. Consult the Hardware Reference manual for your product.
These outputs, typically labeled “EQUn”, can be used to driver external hardware, such as the
triggers for scanning and measurement equipment.
Setup on a PMAC2-Style IC
Each encoder channel in a PMAC2-style servo IC has a position-compare circuit. Furthermore,
the position value of the 1st channel (index j = 0) on the IC can use any or all of the 4 compare
circuits on the IC. The action of the compare function for a channel is controlled by 3 24-bit
position registers and 2 control elements.
Compare Registers
The position-compare circuitry for each channel is based on three (non-saved) setup data
structure elements:
Gate1[i].Chan[j].CompA
Gate1[i].Chan[j].CompB
Gate1[i].Chan[j].CompAdd
All 3 elements are unsigned 24-bit integer values, in units of counts of the encoder. Even though
they are unsigned values, you can assign negative values to them and get the same effect as
though they were signed registers. For example, if you wrote a value of -100 to one of the
registers, the value would report back as 16,777,116 (224 - 100).
The encoder counter value associated with the compare position registers is automatically set to 0
at power-on/reset, and counts from there. It is not reset on the homing of an associated motor or
transformation of an associated axis. The present value of the encoder counter can be read in the
element Gate1[i].Chan[j].PhaseCapt (in units of counts).
Each SCLK (encoder sample clock) cycle, the encoder counter value is compared to the values in
CompA and CompB. If it matches either value, the compare output is toggled from the existing
state. Technically, the transition occurs on the transition from “equal” to “not equal” in either
direction. For instance, if the compare register has a value of 100, the toggling of the output
would occur on the counter transition from 100 to 101 counts in the positive direction, or on the
transition from 100 to 99 counts in the negative direction.
Auto-Increment Function
In addition, when the output is toggled by the count matching one of the compare registers, the
other compare register is incremented immediately by the amount in the CompAdd element. If
the output is toggled by movement in the positive direction, the value in CompAdd is added to
the other compare register. If the output is toggled by movement in the negative direction, the
value in CompAdd is subtracted from the other compare register. Of course, if the value of
CompAdd is 0 (the power-on default value), there is no change to the value of the compare
registers.
If the value of CompAdd is non-zero, all of the compare edges should be at least two counts
apart. This means that the values of CompA and CompB should not be less than two counts
apart, and the minimum non-zero value for CompAdd should be 4.
Because every compare event that toggles the output causes the other compare value to be
incremented, to start a series of pulses with auto-increment, it is necessary to set CompA and
CompB initially to “bracket” the present position counter value. In the figure below, we want the
first pulse to turn on at the CompA position represented by A0 and turn off at the CompB
position represented by B1. However, when the counter reaches the A0 position and the output
turns on, the value of CompB will be incremented automatically. This means that the initial value
B0 that we write to CompB must be equal to B1 minus the auto-increment value.
Starting Position
B0 A0 B1 A1
Auto-Increment
(If a 50% duty cycle in the compare-output waveform is acceptable, and it is known which
direction from the starting position to the first transition will be, it is possible to set up for a
repeated compare output of even intervals without bracketing the starting position. To do this,
both CompA and CompB should be set to the value of the position where the first transition is
desired. CompAdd should be set to half the value of a full on/off cycle. In this case, each time a
compare position is reached, the output is toggled once, and both elements are automatically
incremented to the position where the output will be toggled in the opposite direction.
Gate1[i].Chan[j].Equ1Ena: This single-bit saved setup element determines whether the compare
circuitry for the channel uses the encoder counter for the same channel, or for the first channel
(index j = 0) of the IC. Of course, this element for the first channel on the IC has no effect. Note
that when multiple compare circuits have been assigned to the first channel’s counter, the
compare output for the first channel is the logical OR of all the compare logical states of circuits
assigned to this counter.
Gate1[i].Chan[j].EquWrite: This two-bit (non-saved) element allows you to force the state of
the output directly, either as an initial state for a compare sequence, or to use the output for
general-purpose use. Bit 1 (value 2) is the output value to be forced; a “1” in this bit forces a high
state on the output of the IC (this may be inverted by the output driver); a “0” forces a low state
of the IC output. Bit 0 (value 1) is the “forcing” bit. Writing a value of 1 in this bit causes the
value of bit 1 to be forced onto the IC output, and once this is done, the IC resets this bit to 0.
Setting EquWrite to 3 forces the IC output value (which can be read in status bit
Gate1[i].Chan[j].Equ) to 1 (high); setting EquWrite to 1 forces the IC output value to 0 (low).
This “hardware 1/T” extension in the IC is not compatible with the standard “software 1/T”
extension performed in the encoder conversion table for servo use. For this reason, it is most
often used with sinusoidal encoders, as on the ACC-51E interpolator board. In this case, the servo
uses analog arctangent extension in the ECT, but the compare (and capture) circuits use the
“hardware 1/T” in the IC.
When “hardware 1/T” extension is enabled for an IC channel, the contents of the two timer
registers for the channel change (which is why “software 1/T” extension in the conversion table
cannot be supported). The 24-bit element Gate1[i].Chan[j].TimeBetweenCts is split into 2 12-
bit components; the low 12 bits form the (unsigned) fractional count portion for CompA. The 24-
bit element Gate1[i].Chan[j].TimeSinceCts is also split into 2 12-bit components; the low 12
bits form the (unsigned) fractional count portion for CompB.
These components can take a value of 0 to 4095, in units of 1/4096 of a count. Higher values of
fractional count are closer to the more positive whole count, regardless of the direction of motion.
When writing to one of these 24-bit elements, you can simply assign as value of 0 to 4095, as the
high 12 bits are read-only and will not be affected. However, to read the value in the component,
it is necessary to mask out the value in the high 12-bits of the 24-bit element (e.g.
Gate1[i].Chan[j].TimeBetweenCts & $FFF).
Note carefully what a “count” means here. Because we are dealing with the hardware counter in
the Servo IC, these are “hardware counts” – one unit of the hardware counter. With the “times-4”
decode that is almost universally used (and must be used with ACC-51E boards), there are 4
hardware counts per line (signal cycle) of the encoder. The units of the output of an encoder
conversion table entry processing the sinusoidal encoder for motor servo feedback depend on the
scale factor used there (if the suggested value 1/1024 is used, it will have the same units).
The auto-increment function is still available in extended-count mode, but the auto-increment
value is limited to integer numbers of counts.
In operation in this mode, the user writes to both the whole-count compare element and the
fractional-count compare element. In this mode, the integer value written to the whole-count
compare register is offset by one count from the count value at which the compare output will
toggle. The direction of this offset is dependent on the direction of motion. If a value of n counts
is written to the integer compare register, the compare output will toggle at n+1 counts when
moving in the positive direction, or n-1 counts when moving in the negative direction. To
compensate for this, simply add or subtract 1 count depending on the direction of motion. For
instance, to get a compare edge at 743.25 counts when moving in the positive direction, write 742
(= 743 - 1) to the integer compare register, and write 1024 (= 0.25 * 4096) to the fractional
compare register.
Setup on a PMAC3-Style IC
Each encoder channel in a PMAC3-style IC has a position-compare circuit. Furthermore, the
position value of the 1st channel (index j = 0) on the IC can use any or all of the 4 compare
circuits on the IC. Also, the compare output for each channel can be a user-specified logical
combination of the 4 internal compare states in the IC. The action of the compare function for a
channel is controlled by 3 32-bit position registers and 4 control elements.
Compare Registers
The position-compare circuitry for each channel is based on three (non-saved) setup data
structure elements:
Gate3[i].Chan[j].CompA
Gate3[i].Chan[j].CompB
Gate3[i].Chan[j].CompAdd
All 3 elements are unsigned 32-bit integer values, in units of 1/4096 of a count of the encoder.
That is, they have 20 bits of full-count information, and 12 bits of fractional-count information.
Even though they are unsigned values, you can assign negative values to them and get the same
effect as though they were signed registers. For example, if you wrote a value of -1000 to one of
the registers, the value would report back as 4,294,966,296 (= 232 - 1000).
whole-count and fractional-count value against the values in the compare registers, which have 20
bits of whole-count data and 12 bits of fractional data. If TimerMode is set to a different value,
the fractional count value is fixed at ½.
The encoder counter value associated with the compare position registers is automatically set to 0
at power-on/reset, and counts from there. It is not reset on the homing of an associated motor or
transformation of an associated axis. If saved setup element Gate3[i].Chan[j].AtanEna is set to
its default value of 0, the present value of the encoder position, latched on the most recent servo
interrupt, which can be read in the element Gate3[i].Chan[j].ServoCapt, has 8 bits of fraction,
so has units of 1/256 of a count. Note that the units of the ServoCapt register is different from
that of the compare registers, and the numerical value in ServoCapt will be 16 times that of the
compare registers for the same position (before rollover).
If Gate3[i].Chan[j].AtanEna is set to 1, the present value of the encoder position, latched on the
most recent servo interrupt, which can be read in the element Gate3[i].Chan[j].ServoCapt, has
12 bits of fraction derived from the A/D converters through a hardware arctangent calculation in
the ASIC. In this mode, the ServoCapt register has the same units as the compare registers.
However, the converters cannot be sampled often enough to be useful for the compare function,
so the sub-count data in the instantaneous position value to be checked against the compare
positions is still timer-based (provided TimerMode is set to its default value of 0).
Each SCLK (encoder sample clock) cycle, the encoder position value, potentially with timer-
estimated sub-count resolution, is compared to the values in CompA and CompB. If it has
matched or passed either value, the compare output is toggled from the existing state.
(Note that if the value of CompA is equal to the value of CompB in a PMAC3-style IC, as is the
case when both have their power-on default value of 0, the output will not toggle when the value
of the encoder counter matches this value.)
Auto-Increment Function
In addition, when the output is toggled by the count reaching the value of one of the compare
registers, the other compare register is incremented immediately by the amount in the CompAdd
element. If the output is toggled by movement in the positive direction, the value in CompAdd is
added to the other compare register. If the output is toggled by movement in the negative
direction, the value in CompAdd is subtracted from the other compare register. Of course, if the
value of CompAdd is 0 (the power-on default value), there is no change to the value of the
compare registers. Note that it is possible to suppress the first auto-increment operation of a
sequence, making the initial setup easier in many applications. See the instructions for the
EquWrite element, below.
=? Compare A
A
Decoder/
B Counter/ Σ
Timer Extension
Present Compare
Position Increment
Compare
T
Out
Q Σ
T
=? Compare B
To
CPU
In theory, compare edges can be as close as 1/128 of a count (32 LSBs of the register) apart, so
CompAdd could be as small as 1/64 of a count (64 LSBs of the register). However, for this to
operate correctly, the count edges must be perfectly evenly spaced in time, requiring both
completely constant speed and perfect spacing of encoder edges (or zero-crossings) to eliminate
any possible discontinuities in the timer-estimated sub-count data. In addition, each compare
event must occur in a separate SCLK cycle. If sub-count spacing of edges is desired, particularly
with auto-increment active, careful characterization is required to ensure reliable operation.
The following diagram shows the waveform possibilities for the compare function, first with
auto-increment disabled, then with auto-increment enabled in both the mode where the first
increment is not inhibited, and where it is.
1
EQUn
EQUn
CompAdd CompAdd
CompAdd
Auto-Increment Enabled
(1st Increment Disabled – Gate3 only)
(Start) CompA0 CompB0 CompA1 CompB1
1
EQUn
CompAdd
CompAdd
Position
Gate3[i].Chan[j].Equ1Ena: This single-bit saved setup element determines whether the compare
circuitry for the channel uses the encoder counter for the same channel, or for the first channel
(index j = 0) of the IC. The default value of 0 specifies the use of the same channel’s counter. Of
course, this element for the first channel on the IC has no effect.
The internal compare state for a channel can be read in the single-bit status element
Gate3[i].Chan[j].Equ; the compare output state for a channel can be read in the single-bit status
element Gate3[i].Chan[j].EquOut.
The following diagram illustrates the relationship between the channel internal compare states
and the channel compare outputs.
The next diagram shows how the logical combination of the internal Equ signals, along with the
ability to apply multiple compare circuits to the first encoder channel of the ASIC, produces a
“windowing” function, providing high-frequency output signals only within a pre-defined range.
Gate3[i].Chan[0].Equ
(Gate3[i].Chan[0].CompAdd > 0)
Internal States
Gate3[i].Chan[1].Equ
(Gate3[i].Chan[1].Equ1Ena = 1)
(Gate3[i].Chan[1].CompAdd = 0)
Gate3[i].Chan[0].EquOut
(Gate3[i].Chan[0].EquOutMask = 3)
(Gate3[i].Chan[0].EquOutPol = 0)
External Signals
Gate3[i].Chan[1].EquOut
(Gate3[i].Chan[1].EquOutMask = 3)
(Gate3[i].Chan[1].EquOutPol = 1)
Gate3[i].Chan[j].EquWrite: This two-bit (non-saved) element allows you to force the state of
the channel’s internal compare state directly, either as an initial state for a compare sequence, or
for general-purpose use. Bit 1 (value 2) is the state value to be forced. Bit 0 (value 1) is the
“forcing” bit. Writing a value of 1 in this bit causes the value of bit 1 to be forced into the
channel’s internal compare state, and once this is done, the IC resets this bit to 0.
Setting EquWrite to 3 forces the channel’s internal compare state (which can be read in status bit
Gate3[i].Chan[j].Equ) to 1; setting EquWrite to 1 forces the channel’s internal compare state to
0. This can immediately affect one or more of the IC’s compare outputs if the compare state is
used in the generation of those outputs.
The act of forcing a value into the channel’s internal compare state, whether it changes the state
or not, will disable the auto-increment operation on the first subsequent compare event for the
channel. This permits the user to specify the first two compare positions directly in an auto-
incrementing sequence; without this, the second compare position must initially be specified one
increment interval away from where the desired position would be (as is required with PMAC2-
style ICs – see above). Writing to either CompA or CompB (re-)enables the first auto-increment
operation.
In most applications, it is desirable to specify the first two compare edge positions directly, both
in the same direction from the present position. This makes it easier to specify the sequence when
the position is changing, and provides more flexibility as to where the sequence will start, as it
can be more than one increment interval away. In these applications, the initial values of CompA
and CompB should be assigned before forcing the initial value with EquWrite.
Gate1[i].Chan[j].CompB = rint(MyDesiredCompPos);
In a PMAC2-style IC, if you wish to retain the fractional count component for use with the
“hardware 1/T extension”, you must explicitly split the value into whole-count and fractional-
count components so these can be written to separate registers. For example:
MyWholeCountCompPos = int(MyDesiredCompPos);
Gate1[i].Chan[j].CompB = MyWholeCountCompPos;
Gate1[i].Chan[j].TimeSinceCts = (MyDesiredCompPos -
MyWholeCountCompPos) * 4096;
In a PMAC3-style IC, where the compare position registers are single 32-bit elements with 12
bits of fraction, simply multiply the desired value in encoder counts by 4096, regardless of
whether you are using the fractional count value or not. For example:
For simplicity, this analysis assumes that EncTable[n].ScaleFactor for the ECT entry processing
the encoder for motor position feedback results in the entry’s output being scaled in the same
counts as the compare circuit uses. (There can be fractional resolution from 1/T timer extension
or analog arctangent extension, but each unit increment is a count.) If the application uses a
different scaling, this must be accounted for in subsequent calculations.
When writing a value to a compare register, if there is a possibility that the total position value
could be outside of this range, it is important to ensure that the value written is kept within this
range. This is usually done with a “modulo” or “remainder” operation. Power PMAC’s script
language provides two methods of implementing this functionality: the “%” modulo operator, and
the rem remainder function.
In a PMAC3-style IC, where the units of the compare position registers are in 1/4096 of a count,
typical program commands would be:
A Power PMAC motor takes the feedback position output from its selected ECT entry and
multiplies it by saved setup element Motor[x].PosSf to use as motor position. At the default
value of 1.0, the motor has the same units as the ECT output – counts in our case. However, if the
motor is scaled in engineering units, the value will be different from 1.0 – often much smaller. To
convert from motor units to encoder units, the calculation must divide by this motor scale factor.
The calculation combining the offset and scaling to convert from motor units to encoder units is:
If the compare position register has fractional resolution, you will need to include that scaling in
the calculations. For example, the PMAC3-style ICs have 12 bits of fractional resolution, so you
will need to multiply the desired value in counts by 212 (= 4096) before writing to the register
(even if you will have a value of 0 in the fractional component).
where Motor[x].CoordSf[i] is the axis scale factor for the axis with index “i” (e.g. 0 for A, 1 for
B, etc.) and Motor[x].CoordSf[32] is the axis offset value.
If the axis definitions are more complex than this, either involving multiple axes in a single
definition, or using kinematic subroutines, then this simple relationship cannot be used, and
application-specific algorithms must be employed.
This interrupt has a higher priority than even the phase and servo interrupts that control the
motors. This means that compare events can be processed at a higher frequency than even the
phase and servo interrupts. However, it also means that the interrupt service routine must be kept
very short so that phase and servo tasks can always complete in the correct update cycle. The
intent of this routine is to update the compare registers quickly from a list of positions already in
Power PMAC memory.
Power PMAC permits the user to install a dedicated interrupt service routine written in C to react
to capture and/or compare events from a PMAC3-style IC. Refer to the chapter Writing C
Functions and Programs for more details.
2. Phase interrupt: “User-written phase” functions: The most common use for these
functions is to execute specialized motor phase commutation and/or current-loop-closure
algorithms, but these can also be used for other tasks (e.g. fast I/O) at this highest priority
level. Each motor with an active phase task can select its own phase function (built-in or
user-written) to be called each phase interrupt.
3. Servo interrupt: “User-written servo” functions: The most common use for these
functions is to execute specialized motor feedback and feedforward algorithms, but these
can also be used for other tasks (e.g. fast I/O) at this second-highest priority level. Each
motor with an active servo task can select its own servo function (built-in or user-written)
to be called each servo interrupt.
4. Real-time interrupt: “Real-time C PLC” function: This function is most commonly used
for non-motion operations that must occur at a predictably repeatable interval. This
(single) function is called each real-time interrupt.
5. Each background scan: “Background C PLC” functions: These functions are most
commonly used for non-motion operations that do not need to be run as an interrupt task.
These 32 separately enabled functions are called between each scan of a single
background Script PLC program.
The IDE also provides a sophisticated text editor, shown in the center of the screen capture, for
both Script and C programs with color coding and syntax checking. Most users will write their
code directly in this text editor, but others may simply paste in their code from another editor that
they prefer.
The IDE includes a built-in GNU C/C++ cross-compiler that automatically compiles your C/C++
code on the PC for the Power PMAC’s processor. This public-domain and open-source compiler
is very popular and well supported in the software community. To compile your C software and
load the resulting executable code to the Power PMAC, simply right-click on the project name in
the Solution Explorer, then click on “Build and Download All Programs”.
All files with C code that want to access anything in shared memory must start with the directive:
#include <RtGpShm.h>
This will give the software in the file access to the provided header file “RtGpShm.h”, which
contains the definitions for the accessible variables, data structures, and buffers in shared memory
(Shm), for both real-time (Rt) – that is, interrupt-driven – and general-purpose (Gp) – that is,
background – routines and programs.
For C routines automatically called by Power PMAC (user-written phase and servo, C PLCs), the
code automatically has access to several pre-defined pointer variables, “inherited” from the
calling software:
Independent background C application programs must explicitly declare a pointer variable for the
shared-memory data structure. For example:
Data-structure element names are fundamentally the same as in the Script environment. Of
course, in C, the element name must be preceded with “phsm->”. (Other names could be used in
independent programs.)
Keep in mind that the data structure and element names are case-sensitive in C, whereas they are
not in the Script environment. Furthermore, in the Script environment, many elements are write-
protected so user code cannot change their values, but these elements can be read at any time. In
the C environment, any element for which you are provided access (that is, whose name is
provided in the RtGpShm.h header file) can be written to. However, many of the elements that
are write-protected in the Script environment are not provided at all in the C environment.
Accessing these registers can be done using the pre-defined data structure elements for the
registers, or directly with pointer variables. Both methods are discussed below.
In both cases, the variables should be declared as “volatile” so that each use of the variable results
in a full 32-bit access of the hardware register. This keeps optimizing compilers such as GNU
from attempting shortcuts that can have unpredictable results.
Note that the actual read or write access to a hardware register takes approximately 100
instruction cycles, so the number of such accesses should be carefully limited. If you want to use
the value read from a hardware register in multiple instructions, it should first be copied into a
software variable. If you have several operations setting different bits in the same hardware
output register (as with discrete outputs), you should manipulate bits in an “image” variable in
software, then copy this variable to the output register in a single operation.
These declared variables can then be assigned to particular ICs with function calls in program
statements like the following. These must be executed every time the Power PMAC is started up.
MyFirstGate1IC = GetGate1MemPtr(4);
MySecondGate1IC = GetGate1MemPtr(6);
MyFirstGate2IC = GetGate2MemPtr(0);
MySecondGate2IC = GetGate2MemPtr(1);
MyFirstGate3IC = GetGate3MemPtr(0);
MySecondGate3IC = GetGate3MemPtr(1);
MyFirstGateIoIC = GetGateIoMemPtr(0);
MySecondGateIoIC = GetGateIoMemPtr(1);
Note that functions will return a NULL value if the corresponding IC was not auto-detected by
Power PMAC at power-on/reset. It will always be valid numerical value if the IC was detected.
This can be used to check for the expected configuration of the system.
Then, “whole-word” elements in these structures can be used in program statements like:
The IC pointer variables are then assigned to the ICs using Power PMAC’s address auto-detection
elements. This can be done with program statements like the following. For global variables,
these must be executed once every time the Power PMAC is started up. For local variables, these
must be executed each time the routine is entered.
MyFirstGate1Ptr = pshm->OffsetGate1[4];
MySecondGate1Ptr = pshm->OffsetGate1[6];
MyFirstGate2Ptr = pshm->OffsetGate2[0];
MySecondGate2Ptr = pshm->OffsetGate2[1];
MyFirstGate3Ptr = pshm->OffsetGate3[0];
MySecondGate3Ptr = pshm->OffsetGate3[1];
MyFirstGateIoPtr = pshm->OffsetCardIo[0];
MySecondGateIoPtr = pshm->OffsetCardIo[0];
Note that the value of one of these elements will be 0 if the corresponding IC was not auto-
detected by Power PMAC at power-on/reset. It will always be non-zero if the IC was detected.
This can be used to check for the expected configuration of the system.
The next step is to compute the address offset of the IC register in question from the IC’s base
address offset. To do this, the user must refer to the Software Reference Manual chapter “Power
PMAC ASIC Register Element Addresses”. These give the offset of the register address from the
IC base address offset. The net address of the register element can then be computed as the sum
of piom, the IC’s base address offset, and the register’s offset from IC base. Note that for
channel-specific registers in the Servo ICs, one must use the sum of the channel offset from the
IC base, and the register offset from the channel base.
The register pointer variables can be computed with program statements like the following. For
global variables, these must be executed once every time the Power PMAC is started up. For local
variables, these must be executed each time the routine is entered.
The “shift-right 2” (>> 2) operation converts the “byte addressing” of the offset values into the
“word addressing” that the program requires. This effective division by 4 reflects the fact that
there are 4 bytes per 32-bit word.
The user-written ISR permits extremely fast software response to these hardware events. This
allows the user to set up the circuits very quickly for the next event, facilitating very high update
rates on these events. Typically, the ISR will simply log the latest captured-position value to a
memory array, or seed the next compare-position value from a memory array. Update rates to 60
kHz and above can be supported with this technique.
The high byte (bits 16 – 23) is the “interrupt enable” byte. It allows the user to control which of
the possible 4 capture and 4 compare events will create an interrupt.
The middle byte (bits 8 – 15) is the “interrupt source” byte. This read-only byte permits the ISR
to check which signal(s) have triggered the interrupt.
The low byte (bits 0 – 7) is the “interrupt status” byte. Writing a 1 to a bit in this byte clears the
corresponding interrupt and re-arms it for the next interrupt. When a 1 is written to any bit in this
low byte, no changes will be made to the “interrupt source” byte, whatever is written to that byte.
Within each byte, the bits for each of the 8 signals that can create an interrupt are arranged as
follows:
There can only be a single routine of this type in a Power PMAC, and it must have this exact
name and declaration. The starting “void” indicates that no value is returned to the calling
program (the Power PMAC real-time scheduler). The final “void” in parentheses indicates that
the function takes no arguments.
automatically re-arms the capturing circuitry for the next trigger edge. Writing a 1 to the IntCtrl
register clears the interrupt to prepare it for the next capture trigger on this channel.
In the header file “usrcode.h” in the same directory, the following declarations must be made:
The compare position values in Gate3[i].Chan[j].CompA and CompB are 32-bit integers in
units of 1/4096 of a count (i.e. the low 12 bits are fractional counts, estimated by timer-based
extension if Gate3[i].Chan[j].TimerMode is set to its default value of 0). These values are 16
times bigger than those of Gate3[i].Chan[j].PhaseCapt, which holds the present counter position
(latched in the most recent phase cycle) in units of 1/256 of a count (8 fractional bits).
Gate3[i].Chan[j].CompA is set by copying the value from the presently reference 32-bit integer
Sys.Idata element in the user buffer. In this example, the 0-to-1 transition of the channel’s
internal compare state triggers the interrupt. The example routine sets Gate3[i].Chan[j].CompB
to a value 10 counts more positive than that of CompA, and the compare state would be forced
back to 0 on reaching the CompB position. Note that CompB is not really required in this
example, because the routine forces the compare state back to 0 in software, which could happen
before the CompB position is reached. But setting CompB does enforce a maximum pulse width.
After each compare interrupt (caused by the channel’s internal Equ state going to 1), the routine
forces the Equ state back to 0 by setting bit 7 of the channel’s 32-bit OutCtrl register to 0, and
bit 6 to 1. This is done by reading the hardware register into a software variable, masking the bits
in question, and writing back the modified full 32-bit value. (This operation is equivalent to
setting 2-bit element Gate3[i].Chan[j].EquWrite to 1 in the Script environment.) Note that this
is done after setting new compare positions. Writing a 10 (hex) to the IC’s IntCtrl register clears
the interrupt to prepare it for the next capture trigger on this channel.
void CaptCompISR(void)
{
volatile GateArray3 *MyGate3; // DSPGATE3 IC structure variable
int *CompCounter; // Pointer to compare event index
int *CompPosStore; // Pointer to next compare position
int Temp;
In the header file “usrcode.h” in the same directory, the following declarations must be made:
Most people who write user-written phase routines will use them to execute a custom algorithm
for motor phase commutation and/or current-loop closure, providing capabilities that the built-in
algorithm does not have. However, the routines can be used to perform actions that have nothing
to do with these tasks. Use of these routines for very fast I/O operations is common.
To create a user-written phase routine in the IDE, go into the Project Manager’s “Solution
Explorer”, expand the “C language” branch, and then expand the “Realtime Routines” branch. In
this branch, select the file “usrcode.c” for editing. Remember that this file can contain multiple
routines, for both phase and servo.
Declaration
A user-written phase routine must be declared in the form:
The “void” indicates that no value is returned to the calling program. “MyPhaseAlg” is the
user’s name for the routine. “MotorData *Mptr” must be included as an argument (even if it
is not used in the routine). “Mptr” is a pointer to the motor data structure for the present motor.
This permits a single routine to be used for multiple motors, providing access to all of the data
structure elements for the calling motor.
This automatic preparation does not add any “slip” or other offsets to this value, and it does not
make sure it is rolled over into the required range of (0.0 <= PhasePos < 2048.0) that would be
required to use Power PMAC’s built-in 2048-unit sine table.
Input/Output Access
Unlike the user-written servo algorithm, a user-written phase algorithm that is actually
performing motor functions must write its resulting command values directly to the output
registers. To use the motor’s command output addressing element for this (which is
recommended, but not required), the routine would have code something like:
Mptr->pDac[0]=PhaseACmd;
Mptr->pDac[1]=PhaseBCmd;
Mptr->pDac[2]=PhaseCCmd;
To compile and download this code to the Power PMAC, right-click on the project name in the
Solution Explorer, then select “Build and Download All Programs”.
To instruct the Power PMAC to use a compiled and downloaded user-written phase routine, right-
click on “Realtime Routines” in the “C Language” branch. Select “User Servo Setup” to get the
window permitting you to assign user routines to motors. If you have not added your routine’s
name to the list of selectable routines, click on “Add New Function”, type your routine name into
the dialog box, and click on “Apply”.
Then to select this routine for Motor “x”, click on the down arrow associated with “User Phasex”
and select the routine name from the pick list. When you have done this for all of the motors you
desire, click on “Apply” for the large window.
Most people who write user-written servo routines will use them to execute a custom algorithm
for motor feedback and feedforward, providing capabilities that the built-in algorithm does not
have. However, the routines can be used to perform actions that have nothing to do with these
tasks. Use of these routines for fast I/O operations is common.
To create a user-written servo routine in the IDE, go into the Project Manager’s “Solution
Explorer”, expand the “C language” branch, and then expand the “Realtime Routines” branch. In
this branch, select the file “usrcode.c” for editing. Remember that this file can contain multiple
routines, for both phase and servo.
Declaration
A user-written servo routine must be declared in the form:
The “double” indicates that a double-precision floating-point value (the servo output command)
is returned to the calling program. “MyServoAlg” is the user’s name for the routine.
“MotorData *Mptr” must be included as an argument (even if it is not used in the routine).
“Mptr” is a pointer to the motor data structure for the present motor. This permits a single
routine to be used for multiple motors, providing access to all of the data structure elements for
the calling motor.
The following automatically computed elements are of particular use. All are “double” format
floating-point values.
if (Mptr->ClosedLoop) {
// Compute PD terms
ctrl_out=Mptr->Servo.Kp*Mptr->PosError-Mptr->Servo.Kvfb*Mptr->ActVel;
Mptr->Servo.Integrator+=Mptr->PosError*Mptr->Servo.Ki; // I term
ctrl_out+=Mptr->Servo.Integrator; // Combine
return ctrl_out;
}
else {
Mptr->Servo.Integrator=0.0;
return 0.0;
}
Multi-Motor Routines
It is possible to write servo routines for coupled control of multiple motors. In fact, this is one of
the key reasons that custom servo algorithms are employed. (Power PMAC has one built-in
multi-motor servo algorithm – the two-motor cross-coupled gantry algorithm.)
The motors affected by this coupled algorithm must be consecutively numbered, and the servo
algorithm actually executed by the lowest-numbered of these motors. The saved setup element
Motor[x].ExtraMotors for this motor must be set to the additional number of motors controlled
by this algorithm. For example, if Motors 3 through 7 are controlled in a single servo algorithm,
this algorithm will be executed by Motor 3 and Motor[3].ExtraMotors would be set to 4. Motors
4 through 7 would then not execute any servo algorithms.
The Mptr structure passed to the custom algorithm refers to the structure of this lowest numbered
motor. There are a couple of methods of accessing the structure(s) of the other motor(s)
controlled.
In “relative addressing”, you can declare new structure variables like Mptr2 and Mptr3 and
reference them in the routine with:
Mptr2 = Mptr + 1;
Mptr3 = Mptr + 2;
In “absolute addressing”, you can simply use the full structure name for these motors, such as:
pshm->Motor[4].ActPos…
pshm->Motor[5].ActPos…
The servo command for the motor actually executing the routine is the returned value. For the
other motors, the routine should write directly to the ServoOut element (a “double” variable) for
that motor, such as:
Mptr2->ServoOut
or
pshm->Motor[4].ServoOut
To compile and download this code to the Power PMAC, right-click on the project name in the
Solution Explorer, then select “Build and Download All Programs”.
To instruct the Power PMAC to use a compiled and downloaded user-written phase routine, right-
click on “Realtime Routines” in the “C Language” branch. Select “User Servo Setup” to get the
window permitting you to assign user routines to motors. If you have not added your routine’s
name to the list of selectable routines, click on “Add New Function”, type your routine name into
the dialog box, and click on “Apply”.
Then to select this routine for Motor “x”, click on the down arrow associated with “User Servox”
and select the routine name from the pick list. When you have done this for all of the motors you
desire, click on “Apply” for the large window.
To create an RTI C PLC in the IDE, go into the Project Manager’s “Solution Explorer”, expand
the “C language” branch, and then expand the “CPLCs” branch, followed by the “rticplc” branch.
In this branch, select the file “rtiplcc.c” for editing.
void realtimeinterrupt_plcc()
The “void” indicates that no value is returned to the calling program. Unlike user-written phase
and servo algorithms, the user cannot select his own name for this routine.
The following code implements a simple example of writing to banks of discrete outputs in
alternating on/off patterns.
#include <RtGpShm.h>
#include <stdio.h>
#include <dlfcn.h>
To compile and download this code to the Power PMAC, right-click on the project name in the
Solution Explorer, then select “Build and Download All Programs”.
To enable the execution of this routine, simply set the data structure element UserAlgo.RtiCplc
to 1. To disable the execution, set UserAlgo.RtiCplc to 0.
To create a background C PLC in the IDE, go into the Project Manager’s “Solution Explorer”,
expand the “C language” branch, and right click on the “CPLCs” folder. In the window that pops
up select a C PLC number (0 to 31) from the pick list. The Solution explorer will create a sub-
folder “bgcplcnn”, and a file in that folder “bgplcnn.c”, where nn is the selected C PLC number
(always two digits). Select this file for editing.
The routine for all background CPLC programs must be named as “user_plcc” and must be
declared as:
void user_plcc()
The “void” indicates that no value is returned to the calling program. Unlike user-written phase
and servo algorithms, the user cannot select his own name for this routine. Note that the routine
itself contains no information as to what number the CPLC has – that is determined by the file
and folder names.
To compile and download this code to the Power PMAC, right-click on the project name in the
Solution Explorer, then select “Build and Download All Programs”.
To enable the execution of routine C PLC n, simply set the data structure element
UserAlgo.BgCplc[n] to 1. To disable the execution, set UserAlgo.BgCplc[n] to 0.
The next background Script PLC program will not run until all of the enabled background C PLC
programs have finished executing a scan, or 100 microseconds after the start of execution of these
C PLC programs, whichever is less.
CfromScript Function
CfromScript is a C-language function that the user can call from Power PMAC Script
programs. This function permits users to access their C subroutines directly from the PMAC
Script language. It is expected to be used primarily for kinematics calculations, but is flexible
enough that the user can use it for many different purposes. This function is useful especially for
kinematics calculations (which are known to be generally quite computationally intensive)
because this C function executes calculations much faster than if the calculations had been written
in the Script-based subroutines directly.
Power PMAC can have only a single CfromScript function. However, it is possible using passed
arguments and internal logic to call this single function from multiple Script programs, even at
overlapping times. Techniques to do this are explained below.
Declaring CfromScript()
The CfromScript function must be written in the “usrcode.c” file in the “Realtime Routines”
folder of the Project Manager. The declaration must be of the form:
double CfromScript(double arg1, double arg2, double arg3, double arg4, double arg5,double
arg6, double arg7, LocalData *Ldata)
While the user can give whatever names are desired to the eight arguments, there must be seven
arguments of type “double”, and one final argument of the structure type “LocalData”.
There must be exact matching prototype and symbol exportation declarations in the “usrcode.h”
file in the same folder:
The calling program must pass to CfromScript() all seven arguments of type double, even
if CfromScript() does not use all of the arguments internally. If CfromScript() does not
use one of the arguments, it is recommmended just to pass a zero to CfromScript() for that
argument. All general-purpose user variables in Power PMAC (P, Q, L, R, C, D) are of type
double. Some data structure elements are of type double, but the value in an element of a
different type can be converted to double simply by copying the value into a general-purpose
variable.
Power PMAC automatically passes to CfromScript() into the 8th argument a pointer to the
local data structure of the program from which the user is calling the function. The user should
not include this argument explicitly in the function call.
The calling program must store the result of CfromScript() in a variable (R, L, C, D, P, Q, or
M variable) even if the result is not needed. Otherwise, the command will be flagged with a
syntax error.
Note that the execution of the calling program will halt until the CfromScript() function call
has completed – there is no need to write additional code to force PMAC to wait for
CfromScript() to finish.
open plc 0
P1000 = CfromScript(0,0,0,0,0,0,0);
close
double CfromScript(double arg1, double arg2, double arg3 double arg4, double arg5, double
arg6, double arg7, LocalData *Ldata)
{
double *R;
double *L;
double *C;
double *D;
Once these pointers have been assigned, R, L, C, and D variables can be used with array notation.
For example, R[0] will be equivalent to accessing R0 in the script program that calls
CfromScript(), L[0] will be just like L0, C[0] like C0, and D[0] like D0, R[1] equivalent to
R1, and so on for other indices.
In the kinematics routines, the variables L[n] are the Motor n positions – inputs for the forward
kinematics, and results for the inverse kinematics. The variables C[n] are the Axis α positions –
inputs for the inverse kinematics and results for the forward kinematics.
// Prototypes
int ForwardKinematics(int CS_Number,int Kinematics_Type, LocalData *Ldata);
int InverseKinematics(int CS_Number,int Kinematics_Type, LocalData *Ldata);
int ForwardKinematicsSubroutine1(int CS_Number,LocalData *Ldata);
int InverseKinematicsSubroutine1(int CS_Number,LocalData *Ldata);
int ForwardKinematicsSubroutine2(int CS_Number,LocalData *Ldata);
int InverseKinematicsSubroutine2(int CS_Number,LocalData *Ldata);
{
// CfromScript() functions as a State Machine handler.
// Inputs:
// CS_Number_double: Coordinate System number of the coordinate system
// program that called this instance of CfromScript().
// State_double: State number. Pass in the state corresponding to
// what the user wants CfromScript() to do; e.g., design CfromScript() such
// that Forward_Kinematics_State ( = 0) will make CfromScript() run the
// forward kinematics routine.
// KinematicsType_double: Type of kinematics to use. Only need to use this
// argument if using kinematics; otherwise, set to 0.
// arg4 - arg7: unused in this example.
// Output: ErrCode – error code of function calls.
// Will return -11 if invalid state entered.
switch(State)
{
case Forward_Kinematics_State:
{
ErrCode = ForwardKinematics(CS_Number,KinematicsType,Ldata);
break;
}
case Inverse_Kinematics_State:
{
ErrCode = InverseKinematics(CS_Number,KinematicsType,Ldata);
break;
}
default:
{
ErrCode = -11; // InvalidState Entered
break;
}
}
return (double)ErrCode;
}
L = GetLVarPtr(Ldata);//Ldata->L + Ldata->Lindex;
C = GetCVarPtr(Ldata);//Ldata->L + Ldata->Lindex + MAX_MOTORS;
D = GetDVarPtr(Ldata);// Ldata->D;
//** Put forward kinematics calculations here **//
return ErrCode;
}
// Add any to usrcode.c other functions one might need for other
// kinematics calculations or anything else CfromScript() might need
// to call
This CfromScript() function can then be called from Script kinematics routines such as
the following:
// Define the same state values as defined in usrcode.c
#define Forward_Kinematics_State 0
#define Inverse_Kinematics_State 1
#define KinematicsType1 1
#define KinematicsType2 2
#define CS_Number_1 1
#define CS_Number_2 2
These programs can be completely independent of the Power PMAC control tasks, or they can
interact with these control tasks through the Power PMAC shared-memory structures.
Each program must be compiled with the #include <RtGpShm.h> directive to access the
pre-defined header file with the structure definitions. Since these are independent programs, they
must explicitly declare variables to access the structures, as noted above.
The motion program does not belong to any specific coordinate system, nor does it
directly specify which motor(s) it will move. One or more coordinate systems can point
to the program and run it (even simultaneously!). Which motor or motors move is
dependent on which have already been assigned to the X-axis in the executing coordinate
system.
The program explicitly declares all of the factors affecting the moves. It is possible to
rely on defaults for much of this, but it is better where possible to declare explicitly, both
because the defaults can change, and because it makes it easier to understand what the
program is intended to do. Note that these factors are modal; they do not have to be
declared for each move.
The setup assigns a motor to an axis with 1000 motor units (usually encoder counts) per
axis unit. Therefore, each axis unit commanded corresponds to 1000 units of the assigned
motor.
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 847
Power PMAC User’s Manual
The following diagram shows the commanded trajectory generated by execution of this program,
gathered from Power PMAC’s actual execution of the program:
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 848
Power PMAC User’s Manual
// To run this program with C.S. 1, issue the following on-line commands:
// &1 b2r
The following diagram shows the commanded trajectory generated by the first two loops of
execution of this program, gathered from Power PMAC’s actual execution of the program:
// Variable declarations
ptr LoopCtrlInput->u.io:$A00000.8.1; // IO Card 0 Point 00
ptr DirCtrlInput->u.io:$A00000.9.1; // IO Card 0 Point 01
ptr LaserOn->u.io:$A0000C.8.1; // IO Card 0 Point 24
csglobal MoveLength; // Externally settable variable
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 849
Power PMAC User’s Manual
The following plot shows the commanded velocity profile along with the direction-control input
and the laser-control output.
open prog 4
abs; // Absolute end-point specification
normal k-1; // XY-plane specification for circles
Gather.Enable = 2; // Start data gathering
rapid x1 y4; // Rapid mode move to (1,4)
dwell 20; // Hold position for 20 msec
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 850
Power PMAC User’s Manual
The following plot shows the XY commanded path generated by this program.
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 851
Power PMAC User’s Manual
The most common move modes used for generating paths are linear and circle modes, so called
because of the paths they create in a Cartesian system. This example uses linear and circle modes
to generate the following oval shape in a Cartesian system.
(-60,20) (60,20)
(-60,0) (0,0) (60,0)
For circular interpolation it is necessary to define the “segmentation time” for the coordinate
system – the period at which the exact circle calculations are done. In between these precisely
calculated points, a simpler cubic-spline interpolation is done to create new commanded positions
every servo cycle. Typically the exact calculations are done every 10 to 20 servo cycles, yielding
a very accurate path without overloading the processor from too many trigonometric calculations.
Here we set the segmentation time for C.S. 1 to 5 msec with Coord[1].SegMoveTime = 5.
Note that the circular arc moves are programmed here by specifying the radius of the arc. It is
also possible to program them by specifying a vector to the center of the arc with I, J, and K
components.
The following diagram shows the commanded path generated by execution of this program,
gathered from Power PMAC’s actual execution of the program:
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 852
Power PMAC User’s Manual
The next diagram shows the commanded acceleration profiles for the same move sequence:
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 853
Power PMAC User’s Manual
However, Power PMAC’s buffered lookahead feature permits the controller to automatically
identify problem areas in the path, compute the highest speed at these areas that do not violate
constraints, and to compute the optimum deceleration into these areas and acceleration out of
them. The user simply needs to tell Power PMAC what the constraints are and to enable the
feature. The problem areas do not need to be identified in the motion program. (While the
lookahead algorithm also checks for violations of position and velocity constraints, it is usually
the acceleration constraints that are key.)
In this example, the X and Y-axes are limited to an acceleration of 1000 mm/sec2. To execute the
arc moves, which have a radius of 10 mm, at the programmed speed of 200 mm/sec would
require a centripetal acceleration of 200*200/10 = 4000 mm/sec2. Note that simply programming
a lower speed for these moves would not necessarily solve the problem, because it does not
ensure that the deceleration into the arc and the acceleration out of it are handled properly.
For robust acceleration control, the algorithm must look ahead at least the worst case stopping
time, which is the maximum velocity divided by the maximum acceleration. In this example, we
have a maximum velocity of 500 mm/sec (even though the program only asks for 200), so our
worst case stopping time is 500/1000 = 0.5 sec, or 500 msec to decelerate from full speed.
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 854
Power PMAC User’s Manual
The following commands can be used to set up the buffered lookahead for this example:
These next two diagrams show the profiles when lookahead has been applied. First we see the
commanded velocities. Note that the acceleration ramps to and from a stop have been
significantly stretched out compared to the above velocity profiles. Note also that the arc moves
have been slowed down, not because their programmed velocities exceeded the lookahead
velocity limits, but because their centripetal acceleration at the programmed speed is above the
lookahead acceleration limit. Furthermore, the linear moves going into the arcs start slowing
down well before the beginning of the arc, and the linear moves out of the arc accelerate for some
distance from the end of the arcs.
Finally we see the commanded accelerations with lookahead applied. We see that the magnitude
of acceleration has been dramatically reduced compared to the plot without limits, above. Note
that the acceleration-limiting calculations are approximations, permitting very momentary slight
excursions past the specified limits (+/-1,000,000 counts/sec2) to preserve smoothness in the
trajectories.
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 855
Power PMAC User’s Manual
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 856
Power PMAC User’s Manual
/****************************************/
open prog 1 // Open buffer for entry
linear; // Linear interpolation move mode
abs; // Absolute move specification mode
ta500; // 0.5 second acceleration time
td800; // 0.8 second deceleration time
ts100; // 0.1 second S-curve accel/decel time
F5; // Speed of 5 axis units per time unit
Gather.Enable = 2; // Turn on data gathering
X10; // Move X-axis to position of 10 units
dwell 500; // Sit here for 0.5 seconds
X0; // Move X-axis to position of 0 units
dwell 500; // Sit here for 0.5 seconds
Gather.Enable = 0; // Turn off data gathering
close
/****************************************/
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 857
Power PMAC User’s Manual
/****************************************/
// Variable declarations
ptr LoopCtrlInput->u.io:$A00000.8.1; // IO Card 0 Point 00
ptr DirCtrlInput->u.io:$A00000.9.1; // IO Card 0 Point 01
ptr LaserOn->u.io:$A0000C.8.1; // IO Card 0 Point 24
csglobal MoveLength; // Externally set variable
MoveLength = 40; // Set value for this example
open prog 3
local ThisCs; // Local var for # of CS
ThisCs = Ldata.Coord; // Set to # of CS running program
rapid; abs; // Rapid move mode, end-point spec
while (LoopCtrlInput) { // Loop until control input false
if (DirCtrlInput) Z(MoveLength); // Move in positive direction
else Z(-1.0*MoveLength); // Move in negative direction
while (!(Coord[ThisCs].InPos)) {} // Wait for settled
LaserOn = 1; // Turn on laser control output
dwell100; // Hold for 100 msec
LaserOn = 0; // Turn off laser control output
Z0; // Return to home position
dwell50; // Hold for 50 msec
}
close
/****************************************/
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 858
Power PMAC User’s Manual
/*****************************************/
// Interactive motor jog PLC program
// A single motor selected out of #1-#8 can be jogged in "continuous"
// mode, in either the positive or negative direction.
// In continuous mode, the motor will be commanded to jog its
// "deceleration distance" from the present position each scan as long
// as the button is pressed.
// This distance is calculated as V^2/A/2 or V^2xTa/2.
// With S-curve accel specified (JogTs != 0), this distance is
// increased somewhat.
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 859
Power PMAC User’s Manual
This next example shows a more sophisticated version of a jogging control PLC program
/******************************************************************************/
// Interactive motor jog PLC program
// A single motor selected out of #1-#8 can be jogged in either "incremental"
// or "continuous" mode, in either the positive or negative direction.
//
// In incremental mode, each time a jog button is pressed, the motor will move
// the distance specified by saved element Motor[x].ProgJogPos (the equivalent
// of the on-line incremental jog command). The button must be released before
// another jog increment can be commanded.
/****************************************/
open plc 2
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 860
Power PMAC User’s Manual
JogMotorStatus = 1;
}
else {
if (!(JogMinusButton) && !(JogPlusButton)) JogMotorStatus = 0;
} // if (JogPlusButton...) else
} // if (JogMinusButton...) else
} // if (JogMode == 1)
else { // Continuous jog mode
if (JogMinusButton && JogMotorStatus <= 0) {
jog:(-JogDecelDist);
JogMotorStatus = -1;
}
else {
if (JogPlusButton && JogMotorStatus >= 0) {
jog:(JogDecelDist);
JogMotorStatus = 1;
}
else {
JogMotorStatus = 0;
} // if (JogPlusButton...) else
} // if (JogMinusButton...) else
} // if (JogMode == 1) else
close
/****************************************/
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 861
Power PMAC User’s Manual
//====================================================================
// SCARA robot forward kinematic subroutine
// Global variable declarations and values
global Len1 = 400; // Shoulder-to-elbow length 400 mm
global Len2 = 300; // Elbow-to-wrist length 300 mm
global Zofs = 250; // Vertical axis offset 250 mm
global SumLenSqrd; // L1^2 + L2^2
global ProdOfLens; // 2 * L1 * L2
global DifLenSqrd; // L1^2 - L2^2
//====================================================================
open forward (1) // Forward kinematics for C.S.1
local SplusE; // Sum of shoulder and elbow angles
if (Coord[1].HomeComplete) { // All motors referenced?
SplusE = KinPosMotor1 + KinPosMotor2;
KinPosAxisX = Len1 * cosd(KinPosMotor1) + Len2 * cosd(SplusE);
KinPosAxisY = Len1 * sind(KinPosMotor1) + Len2 * sind(SplusE);
KinPosAxisC = SplusE + KinPosMotor3;
KinPosAxisZ = KinPosMotor4 + Zofs;
KinAxisUsed = $1C4; // Mask for C,X,Y,Z values returned
// Compute intermediate constants for inverse kinematics
SumLenSqrd = Len1 * Len1 + Len2 * Len2;
ProdOfLens = 2 * Len1 * Len2;
DifLenSqrd = Len1 * Len1 - Len2 * Len2;
}
else Coord[1].ErrorStatus = 255; // Not referenced; stop
close
//====================================================================
// SCARA robot inverse kinematic subroutine
open inverse (1) // Inverse kinematics for C.S.1
local X2Y2, Ecos, SplusQ, Qangle; // Intermediate variables
X2Y2 = KinPosAxisX * KinPosAxisX + KinPosAxisY * KinPosAxisY;
Ecos = (X2Y2 - SumLenSqrd) / ProdOfLens;
if (abs(Ecos) < 0.996) { // Valid solution w/ 5-deg margin?
KinPosMotor2 = cosd(Ecos);
SplusQ = atan2d(KinPosAxisY, KinPosAxisX);
Qangle = acosd(X2Y2 + DifLenSqrd) / (2 * Len1 * sqrt(SumLenSqrd));
KinPosMotor1 = SplusQ - Qangle;
KinPosMotor3 = KinPosAxisC - KinPosMotor1 - KinPosMotor1;
KinPosMotor4 = KinPosAxisZ - Zofs;
}
else Coord[1].ErrorStatus = 255; // No valid solution; stop
close
//====================================================================
Power PMAC Example SCRIPT ProgramsPower PMAC Example SCRIPT Programs 862