I/O Functions

Physical I/O

The Analog and Digital I/O APIs give you access to analog inputs and outputs on physical and virtual drives.

Table: I/O Available Per Drive Type

Drive Type Analog Inputs Analog Outputs Digital Inputs Digital Outputs
FLEX Standard 0 0 0 0
FLEX -EB1 option 3 3 16 16
GI4 4 2 9 8
GL4 1 2 4 4
SI4 Standard 0 0 8 8
iXA4, XA4 (1 axis) -EB0 option 1 0 0 0
iXA4, XA4 (1 axis) -EB1 option 3 2 16 16
iXA4, XA4 (1 axis) -EB2 option 4 6 32 32
iXA4, XA4 (2 axis) -EB0 option 2 0 0 0
iXA4, XA4 (2 axis) -EB1 option 4 2 16 16
iXA4, XA4 (2 axis) -EB2 option 5 6 32 32
iXA4, XA4 (4 axis) -EB0 option 4 0 0 0
iXA4, XA4 (4 axis) -EB1 option 6 2 16 16
iXA4, XA4 (4 axis) -EB2 option 7 6 32 32
iXC2, XC2 Standard 0 0 0 0
iXC2, XC2 -EB1 option 1 1 8 8
iXC2e, XC2e Standard 0 0 0 0
iXC2e, XC2e -EB1 option 1 1 8 8
iXC4, XC4 Standard 1 1 4 4
iXC4, XC4 -EB1 option 4 4 20 20
iXC4e, XC4e Standard 1 1 4 4
iXC4e, iXC4e -EB1 option 4 4 20 20
iXC6e, XC6e Standard 1 1 4 4
iXC6e, XC6e -EB1 option 4 4 20 20
iXI4, XI4 4 2 9 8
iXL2e, XL2e Standard 0 0 0 0
iXL2e, XL2e -EB1 option 1 1 8 8
XL4s 1 2 4 4
iXL5e, XL5e Standard 1 1 4 4
iXL5e, XL5e -EB1 option 4 4 20 20
iXR3, XR3 2 per axis 2 per axis 16 28

Analog I/O

The Analog I/O API gives you access to analog inputs and outputs on physical and virtual drives. Typically, analog inputs and outputs have a range of -10 to +10 volts. To get exact information about analog I/O ranges, refer to the hardware manual for your drive.

The controller updates the value of an analog I/O each millisecond. If you set an analog output on virtual axes, the controller automatically sets the corresponding analog input to the same value. When you set the analog I/O, this process is synchronized with motion. But when the controller reads the analog I/O, this process is not synchronized with motion.

WARNING: Signals that are out of the input range can cause damage to the controller.

In AeroScript programs, you can control Analog I/O by using the AnalogInputGet(), AnalogOutputGet(), and AnalogOutputSet() functions.

Standard Functions

function AnalogInputGet($axis as axis, $inputNum as integer) as real

Gets the value of a specified analog input.

Arguments

$axis  The axis on which to retrieve the value of the analog input.

$inputNum  The number of the analog input to get.

Returns

The value of the specified analog input.

function AnalogOutputSet($axis as axis, $outputNum as integer, $value as real)

Sets the value of a specified analog output.

Arguments

$axis  The axis on which to set the value of the analog output.

$outputNum  The number of the analog output to set.

$value  The value to set to the specified analog output.

function AnalogOutputGet($axis as axis, $outputNum as integer) as real

Gets the value of a specified analog output.

Arguments

$axis  The axis on which to retrieve the value of the analog output.

$outputNum  The number of the analog output to get.

Returns

The value of the specified analog output.

Status

To get values of analog inputs and outputs, you can use the axis status items that follow.

  • AnalogInput0

  • AnalogInput1

  • AnalogInput2

  • AnalogInput3

  • AnalogOutput0

  • AnalogOutput1

  • AnalogOutput2

  • AnalogOutput3

  • AnalogOutput4

  • AnalogOutput5

Program Example

// Get the value of analog input 0 on axis X.
var $myAnalogInput as real
$myAnalogInput = AnalogInputGet(X, 0)

// Get the value of analog input 0 on axis Y.
$myAnalogInput = StatusGetAxisItem(Y, AxisStatusItem.AnalogInput0)
								
// Get the value of analog output 0 on axis X.
var $myAnalogOutput as real
$myAnalogOutput = AnalogOutputGet(X, 0)

// Get the value of analog output 1 on axis X.
$myAnalogOutput = StatusGetAxisItem(X, AxisStatusItem.AnalogOutput1)
				
// Set analog output 0 on axis X to 1.2345.
AnalogOutputSet(X, 0, 1.234)

Advanced Functions and Enumerations

You can configure the analog outputs of an axis to operate in one of the advanced modes that follow.

function AnalogOutputConfigureDefaultMode($axis as axis, $outputNum as integer)

Restores the analog output configuration to the default operating mode.

Arguments

$axis  The axis on which to apply the configuration.

$outputNum  The number of the analog output to configure.

function AnalogOutputConfigureArrayMode($axis as axis, $outputNum as integer, $updateEvent as AnalogOutputUpdateEvent, $driveArrayStartAddress as integer, $numberOfPoints as integer, $divisor as integer, $enableRepeat as integer)

Configures the specified analog output to use values from the drive array.

Arguments

$axis  The axis on which to apply the configuration.

$outputNum  The number of the analog output to configure.

$updateEvent  The event which causes a new analog output value to be read from the drive array.

$driveArrayStartAddress  The byte-addressable index of the drive array where the first analog output value is stored.

$numberOfPoints  The number of analog output values to read from the drive array.

$divisor  Divides the default update event rate by the specified integer if $updateEvent is set to Time.

$enableRepeat  Configures the specified analog output to start over at the first analog output value after the last value in the drive array is used.

function AnalogOutputConfigureAxisTrackingMode($outputAxis as axis, $outputNum as integer, $trackingItem as AnalogOutputAxisTrackingItem, $scaleFactor as real, $offset as real, $minVoltage as real, $maxVoltage as real)

Configures an analog output to be dependent on a specified real-time internal servo loop value of a single axis.

Arguments

$outputAxis  The axis of the servo loop value that $trackingItem is tracking.

$outputNum  The index of the analog output to update.

$trackingItem  A servo loop value, such as position command, to track.

$scaleFactor  The scale factor applied to the analog output.

$offset  This value is applied with the tracking value to the analog output. Use this argument if you want to track position on a stage where the position can never be negative. The units are volts.

$minVoltage  The minimum voltage that the analog output will be set to.

$maxVoltage  The maximum voltage that the analog output will be set to.

function AnalogOutputConfigureVectorTrackingMode($outputAxis as axis, $outputNum as integer, $inputAxes[] as axis, $trackingItem as AnalogOutputVectorTrackingItem, $scaleFactor as real, $offset as real, $minVoltage as real, $maxVoltage as real)

Configures an analog output to be dependent on the square root of the sum of squares of a specified real-time internal servo loop value of multiple axes. The tracked value is always positive or zero.

Arguments

$outputAxis  The axis of the servo loop value that $trackingItem is tracking.

$outputNum  The index of the analog output to update.

$inputAxes  An array of axes from which to read the $trackingItem from, vectorizing the result, in order to update the analog output.

$trackingItem  A servo loop value, such as position command, to track.

$scaleFactor  The scale factor applied to the analog output.

$offset  This value is applied with the tracking value to the analog output. Use this argument if you want to track position on a stage where the position can never be negative. The units are volts.

$minVoltage  The minimum voltage that the analog output will be set to.

$maxVoltage  The maximum voltage that the analog output will be set to.

Setting Analog Outputs Directly

Use the AnalogOutputConfigureDefaultMode() function to allow the analog output to be set using AnalogOutputSet() function.

Setting Analog Outputs Using the Drive Array

The Analog I/O API lets you set analog outputs by using an array of analog output values from the drive array. To specify an array of analog output values, use the AnalogOutputConfigureArrayMode() function. Before you use this function, make sure that you write the necessary analog output values, in volts, to the drive array locations that you specify with the $driveArrayStartIndex and $numberOfPoints arguments. For more information about how to write values to the drive array, refer to the DriveArrayWrite() function in Device Functions. When the first update event occurs, the analog output is set to the first specified drive array value. On the next update event, the analog output is set to the next drive array value. The analog output continues to use values in the drive array in this sequence until it completes the specified number of values.

You can also use the $enableRepeat argument to specify an infinite number of drive array values to the analog output. To enable this mode, set this argument to 1. To disable this mode, set this argument to 0. In this mode, the analog output uses all the configured values in the drive array. Then it goes back to the value at the $driveArrayStartIndex and uses the same set of values again.

You can update an analog output to the next value in the drive array by using a PSO event, the active edge of the PSO Output, or a specified rate. To configure the update, use the $updateEvent argument of the AnalogOutputConfigureArrayMode() function. You can set this argument with the AnalogOutputUpdateEvent enumeration.

If you are using a PSO event, you must configure an analog output from the same axis on which PSO is configured. For more information about PSO, refer to PSO Output Functions.

If you are using the Time update event, the default update rate is 200 kHz on the GL4 and XL4s. It is 100 kHz on all other drives. You can set a slower update rate by using the $divisor argument. You must set this argument to an integer that is greater than 0. The controller calculates the update rate as the default update rate divided by the $divisor argument.

For example, your drive has a 100 kHz default update rate. You set the $updateEvent argument to AnalogOutputUpdateEvent.Time and the $divisor argument to 50. As a result, the analog output updates to the next value in the drive array at a rate of 2 kHz.

When analog output is configured for the array mode, you cannot use the AnalogOutputSet() function. But you can use all the other standard functions. To return control of the analog output to the AnalogOutputSet() function, use the AnalogOutputConfigureDefaultMode() function.

Setting Analog Outputs Based on Servo Loop Values From a Single Axis

To set analog outputs based on a real-time internal servo loop value from a single axis, use the AnalogOutputConfigureAxisTrackingMode() function. Use the enumeration that follows to select which internal servo loop value to track:

When you use the AnalogOutputConfigureAxisTrackingMode() function, the analog output is updated at the servo rate of the specified axis. The drive converts the tracked value to a voltage using the following formula:

Voltage = $offset + $scaleFactor * (Tracked Value)

The drive then clamps the voltage so that it stays between the provided values of $minVoltage and $maxVoltage.

When analog output is configured for axis tracking mode, you cannot use the AnalogOutputSet() function. But you can use all the other standard functions. To return control of the analog output to the AnalogOutputSet() function, use the AnalogOutputConfigureDefaultMode() function.

Setting Analog Outputs Based on the Position or Velocity of Multiple Axes

To set analog outputs based on a real-time internal servo loop value from multiple axes, use the AnalogOutputConfigureVectorTrackingMode() function. Use the enumeration that follows to select which internal servo loop value to track:

Specify which axes’ servo loop values will be used by supplying an array of axes to $inputAxes. The controller vectorizes the values read from these axes by taking the square root of the sum of squares of the component values of each axis. The resulting value is always positive or zero. When you track positions, the distance is relative to the axis position at which the AnalogOutputConfigureVectorTrackingMode() function was called. When you track velocities, the velocity is always relative to zero. The controller converts the vectorized value to a voltage using this formula:

Voltage = $offset + $scaleFactor * (Vectorized Tracked Value)

The controller then clamps the voltage so that it stays between the provided values of $minVoltage and $maxVoltage.

When you use the AnalogOutputConfigureVectorTrackingMode() function, the analog output is updated at 1 kHz.

When analog output is configured for vector tracking mode, you cannot use the AnalogOutputSet() function. But you can use all the other standard functions. To return control of the analog output to the AnalogOutputSet() function, use the AnalogOutputConfigureDefaultMode() function.

IMPORTANT: The analog output configuration modes set by the functions that follow cannot be active at the same time:

  • AnalogOutputConfigureDefaultMode()
  • AnalogOutputConfigureArrayMode()
  • AnalogOutputConfigureAxisTrackingMode()
  • AnalogOutputConfigureVectorTrackingMode()

Input Offset

You can apply an offset to each analog input by using the Axis parameters that follow:

IMPORTANT: Aerotech does offset calibration of all analog inputs at the factory. In most conditions, it is not necessary for you to set these parameters to a nonzero value.

The controller adds the configured parameter values to their corresponding analog inputs after the analog input values are read from the hardware. When you read the analog input values from Aerotech Automation1 Studio, Data Collection, or the StatusGetAxisItem() function, this offset is applied to the values.

Filters

All drives have two second-order digital filters on each analog input. To configure each of these filters, open Aerotech Automation1 Studio. Select the Configure tab. Then go to AxesI/OAnalog Input Filters. Select the axis that you are using and specify the values that follow:

IMPORTANT: Configure these filters for each axis that you are using.

  • Filter (Input 0 Filter 0, Input 0 Filter 1, Input 1 Filter 0, Input1 Filter1)
  • Filter Type (LowPass, LeadLag, Notch, Resonant, or None)
  • Cutoff Frequency

To specify values for the coefficients, configure the Axis parameters that follow:

On the first filter of each input, the coefficients default to a low-pass filter with a 250 Hz bandwidth. On the second filter of each input, the coefficients default to no filtering.

Analog inputs are sampled at a rate of 10 kHz on FLEX, iXA4, and XA4 and 20 kHz on all other drives.

HARDWARE: The GI4, iXA4, XA4, iXC4, XC4, iXC4e, XC4e, iXI4, and XI4 have two more analog inputs (Input 2 and Input 3). FLEX has one more analog input (Input 2). These inputs are programmed with a 250 Hz low-pass filter that you cannot change. You can enable or disable the filter on these inputs by using the AnalogFilterSetup Parameter.

MFO

You can use analog inputs to change the MFO setting. For more information, refer to Manual Feedrate Override (MFO).

External Fault Trigger

You can use analog inputs to trigger faults by setting the ExternalFaultAnalogInput Parameter. When the value of the analog input that you specify in this parameter is greater than the value specified in the ExternalFaultThreshold Parameter, the controller generates an external fault.

The controller generates an axis fault only if you set the corresponding bit in the FaultMask Parameter. When an axis fault is generated, you can configure what the axis does by changing the state of the corresponding bit in the FaultMaskDecel Parameter and FaultMaskDisable Parameter.

For more information about faults, refer to Fault and Error Functions.

Drive Command Delay

To compensate for the delay that is caused by motion filters, set the DriveOutputCommandDelay Parameter to the value of the expected motion delay in milliseconds. This parameter delays, by the specified value, all digital output, analog output, PSO commands, and the DriveArrayWrite() function.

Joystick

You can use analog inputs for Joystick control. For more information, refer to Joystick Functions.

Digital I/O

HARDWARE: On the iXR3 and XR3, you can use the DigitalInputGet(), DigitalOutputGet(), and DigitalOutputSet() functions only on the first axis because all digital inputs and outputs are connected only to the first axis.

The Digital I/O API gives you access to digital inputs and outputs on physical and virtual drives. Digital inputs and outputs are numbered from 0-31.

The controller updates the value of the digital I/O each millisecond. If you set a digital output on virtual axes, the controller automatically sets the corresponding digital input to the same value. When you set digital I/O, this process is synchronized with motion. But when the controller reads digital I/O, this process is not synchronized with motion.

You can control digital I/O through AeroScript by using the DigitalInputGet(), DigitalOutputGet(), and DigitalOutputSet() functions.

Functions

function DigitalInputGet($axis as axis, $inputNum as integer) as integer

Gets the value of the specified digital input bit.

Arguments

$axis  The axis from which to get the digital input bit.

$inputNum  The digital input bit to get.

Returns

The value of the specified digital input bit.

function DigitalOutputSet($axis as axis, $outputNum as integer, $value as integer)

Sets the value of the specified digital output bit.

Arguments

$axis  The axis on which to set the digital output bit.

$outputNum  The digital output bit to set.

$value  The value of the specified digital output bit.

function DigitalOutputGet($axis as axis, $outputNum as integer) as integer

Gets the value of the specified digital output bit.

Arguments

$axis  The axis from which to get the digital output bit.

$outputNum  The digital output bit to get.

Returns

The value of the specified digital output bit.

Status

To get values of digital inputs and outputs, you can use the axis status items that follow.

  • DigitalInput

  • DigitalOuput

Both items return a 32-bit word where each bit corresponds to a specific digital input or output.

Program Example

// Get the value of digital input 0 on axis X.
var $myDigitalInput as integer
$myDigitalInput = DigitalInputGet(X, 0)
				
// Get the values of all digital inputs on axis Y.
var $myDigitalInputs as integer
$myDigitalInputs = StatusGetAxisItem(Y, AxisStatusItem.DigitalInput)

// Get the value of digital output 4 on axis X.
var $myDigitalOutput as integer
$myDigitalOutput = DigitalOutputGet(X, 4)

// Get the values of all digital outputs on axis Y.
var $myDigitalOutputs as integer
$myDigitalOutputs = StatusGetAxisItem(Y, AxisStatusItem.DigitalOutput)
				
// Set digital output 7 on axis X to 1.
DigitalOutputSet(X, 7, 1)

Emergency Stop

You can use digital inputs to trigger the Emergency Stop (ESTOP). The EmergencyStopFaultInput Parameter selects the digital input that the controller uses as the Emergency Stop sense input. You can connect an ESTOP switch or circuit to a dedicated ESTOP input or to one of the standard digital inputs. The ESTOP input is always fail-safe, which means that the ESTOP condition occurs if the optocoupler is not driven or when the digital input is not connected.

External Fault Trigger

You can use digital inputs to trigger faults. The input polarity that causes a fault is specified by the External Fault Polarity setting of the FaultSetup Parameter.

IMPORTANT: The controller generates an axis fault only if you set the corresponding bit in the FaultMask Parameter. When an axis fault is generated, you can configure what the axis does by changing the state of the corresponding bit in the FaultMaskDecel Parameter and FaultMaskDisable Parameter.

Drive Command Delay

To compensate for the delay that is caused by motion filters, set the DriveOutputCommandDelay Parameter to the value of the expected motion delay in milliseconds. This parameter delays, by the specified value, all digital output, analog output, PSO commands, and the DriveArrayWrite() function.

Joystick

You can use digital inputs for Joystick control. For more information, refer to Joystick Functions.

Virtual I/O

Virtual I/O is a globally accessible memory that is not directly connected to the hardware. You can use virtual I/O to communicate between tasks or communicate between processes on other PCs. Use this feature to do motion synchronized communication.

Virtual Binary I/O

Virtual binary I/O is a globally accessible one-bit memory that is not connected to the hardware. Each input or output can have a value of 0 or 1. Virtual binary inputs and outputs are numbered from 0 - 2047. When you set virtual binary I/O, this process is synchronized with motion. But when the controller reads virtual binary I/O, this process is not synchronized with motion.

Functions

function VirtualBinaryInputGet($inputNum as integer) as integer

Gets the value of the specified virtual binary input bit.

Arguments

$inputNum  The virtual binary input bit to get.

Returns

The value of the specified virtual binary input bit.

function VirtualBinaryInputSet($inputNum as integer, $value as integer)

Sets the value of the specified virtual binary input bit.

Arguments

$inputNum  The virtual binary input bit to set.

$value  The value to which you set the virtual binary input bit.

function VirtualBinaryOutputGet($outputNum as integer) as integer

Gets the value of the specified virtual binary output bit.

Arguments

$outputNum  The virtual binary output bit to get.

Returns

The value of the specified virtual binary output bit.

function VirtualBinaryOutputSet($outputNum as integer, $value as integer)

Sets the value of the specified virtual binary output bit.

Arguments

$outputNum  The virtual binary output bit to set.

$value  The value to which you set the virtual binary output bit.

Status

To get the value of one virtual binary input bit or one virtual binary output bit, use the system status items that follow:

  • VirtualBinaryInputBit
  • VirtualBinaryOutputBit

Use the VirtualBinaryInputBit and VirtualBinaryOutputBit system status items unless you are collecting many signals and it is necessary to save memory. To get more than one bit at a time, use the status items that follow to access the full 16-bit input or output words:

  • VirtualBinaryInput
  • VirtualBinaryOutput

Each item returns a 16-bit word where each bit corresponds to a specific virtual binary input or output bit. The status items must have one more data field to specify the index of the 16-bit word. Use the formula that follows to calculate the correct additional data value:

The example program that follows shows different methods that you can use to get and set virtual binary inputs.

Program Example

// Get and set virtual binary inputs.

program
// Get the value of virtual binary input bit 0.
var $myVirtualBinaryInput as integer
$myVirtualBinaryInput = VirtualBinaryInputGet(0)

// Get the value of only virtual binary input bit 33.
var $myVirtualBinaryInput33 as integer
$myVirtualBinaryInput33 = StatusGetSystemItem(SystemStatusItem.VirtualBinaryInputBit, 33)

// Get the value of virtual binary inputs 64 and 79.
// Use the Virtual Binary Input bit item to get the value of one input bit unless you are
// collecting many signals and it is necessary to save memory.
var $myVirtualBinaryInputs64to79 as integer
$myVirtualBinaryInputs64to79 = StatusGetSystemItem(SystemStatusItem.VirtualBinaryInput, 64 / 16)

var $myVirtualBinaryInput64 as integer
$myVirtualBinaryInput64 = ($myVirtualBinaryInputs64to79 >> 0) & 0x1

var $myVirtualBinaryInput79 as integer
$myVirtualBinaryInput79 = ($myVirtualBinaryInputs64to79 >> 15) & 0x1

// Set virtual binary input 7 to 0.
VirtualBinaryInputSet(7, 0)
end

The example program that follows shows different methods that you can use to get and set virtual binary outputs.

Program Example

// Get and set virtual binary outputs.

program
// Get the value of virtual binary output bit 4.
var $myVirtualBinaryOutput as integer
$myVirtualBinaryOutput = VirtualBinaryOutputGet(4)

// Get the value of only virtual binary output bit 63.
var $myVirtualBinaryOutput63 as integer
$myVirtualBinaryOutput63 = StatusGetSystemItem(SystemStatusItem.VirtualBinaryOutputBit, 63)

// Get the value of virtual binary output bits 64 and 79.
// Use the Virtual Binary Output bit item to get the value of one output bit unless you are
// collecting many signals and it is necessary to save memory.
var $myVirtualBinaryOutputs64to79 as integer
$myVirtualBinaryOutputs64to79 = StatusGetSystemItem(SystemStatusItem.VirtualBinaryOutput, 64 / 16)

var $myVirtualBinaryOutput64 as integer
$myVirtualBinaryOutput64 = ($myVirtualBinaryOutputs64to79 >> 0) & 0x1

var $myVirtualBinaryOutput79 as integer
$myVirtualBinaryOutput79 = ($myVirtualBinaryOutputs64to79 >> 15) & 0x1

// Set virtual binary output 100 to 1.
VirtualBinaryOutputSet(100, 1)
end

Virtual Register I/O

Virtual register I/O is a globally accessible memory that is not connected to the hardware. Virtual register inputs and outputs are numbered from 0 - 895. When you set virtual register I/O, this process is synchronized with motion. But when the controller reads virtual register I/O, this process is not synchronized with motion.

Functions

function VirtualRegisterInputGet($inputNum as integer) as real

Gets the value of a specified virtual register input.

Arguments

$inputNum  The number of the virtual register input to get.

Returns

The value of the specified virtual register input.

function VirtualRegisterInputSet($inputNum as integer, $value as real)

Sets the value of a specified virtual register input.

Arguments

$inputNum  The number of the virtual register input to set.

$value  The value to set to the virtual register input.

function VirtualRegisterOutputGet($outputNum as integer) as real

Gets the value of a specified virtual register output.

Arguments

$outputNum  The number of the virtual register output to get.

Returns

The value of the specified virtual register output.

function VirtualRegisterOutputSet($outputNum as integer, $value as real)

Sets the value of a specified virtual register output.

Arguments

$outputNum  The number of the virtual register output to set.

$value  The value to set to the virtual register output.

Status

To get the values of virtual register inputs and outputs, you can use the system status items that follow:

  • VirtualRegisterInput
  • VirtualRegisterOutput

The status items must have one more data field to specify the index of the virtual register input or output.

Program Example

// Get the value of virtual register input 0.
var $myVirtualRegisterInput as real
$myVirtualRegisterInput = VirtualRegisterInputGet(0)

// Get the value of virtual register input 3.
$myVirtualRegisterInput = StatusGetSystemItem(SystemStatusItem.VirtualRegisterInput, 3)

// Get the value of virtual register output 4.
var $myVirtualRegisterOutput as real
$myVirtualRegisterOutput = VirtualRegisterOutputGet(4)

// Get the value of virtual register output 6.
$myVirtualRegisterOutput = StatusGetSystemItem(SystemStatusItem.VirtualRegisterOutput, 6)

// Set virtual register input 7 to 55.
VirtualRegisterInputSet(7, 55) // Set virtual register output 100 to -76.
VirtualRegisterOutputSet(100, -76)

Joystick

You can use virtual register inputs for Joystick control. For more information, refer to Joystick Functions.