APIs, concepts, guides, and more
IO: Input & Output

Learn how to work with Input/Output operations in C#.

Warning
This is a sample program to assist in the integration of the RMP motion controller with your application. It may not contain all of the logic and safety features that your application requires. We recommend that you wire an external hardware emergency stop (e-stop) button for safety when using our code sample apps. Doing so will help ensure the safety of you and those around you and will prevent potential injury or damage.

The sample apps assume that the system (network, axes, I/O) are configured prior to running the code featured in the sample app. See the Configuration page for more information.


In this page:


📜 IO: General Purpose

Learn how to access General Purpose IO 📖 on EtherCAT network nodes. Shows how to read and write digital and analog inputs/outputs using NetworkNode methods.

// get node
var node = controller.NetworkNodeGet(nodeNumber: 0);
// digital io
bool dIn = node.DigitalInGet(digitalInNumber: 0);
bool dOut = node.DigitalOutGet(digitalOutNumber: 0);
node.DigitalOutSet(digitalOutNumber: 0, state: dOut);
// analog io
int aIn = node.AnalogInGet(analogChannel: 0);
int aOut = node.AnalogOutGet(analogChannel: 0);
node.AnalogOutSet(analogChannel: 0, analogValue: aOut);

Source: io-general-purpose.cs


📜 IO: Dedicated

Learn how to access Dedicated IO 📖 on an axis. Shows how to read hardware limits, home switch, amp fault, and amp enable signals using both generic and specific methods.

// retrieve dedicated inputs with generic and specific function.
Console.WriteLine("RSIMotorDedicatedInLIMIT_HW_NEG: {0} and {1}",
axis.DedicatedInGet(RSIMotorDedicatedIn.RSIMotorDedicatedInLIMIT_HW_NEG),
Console.WriteLine("RSIMotorDedicatedInLIMIT_HW_POS: {0} and {1}",
axis.DedicatedInGet(RSIMotorDedicatedIn.RSIMotorDedicatedInLIMIT_HW_POS),
Console.WriteLine("RSIMotorDedicatedInHOME: {0} and {1}",
axis.DedicatedInGet(RSIMotorDedicatedIn.RSIMotorDedicatedInHOME),
axis.HomeSwitchGet());
Console.WriteLine("RSIMotorDedicatedInAMP_FAULT: {0} and {1}",
axis.DedicatedInGet(RSIMotorDedicatedIn.RSIMotorDedicatedInAMP_FAULT),
axis.AmpFaultGet());
Console.WriteLine("RSIMotorDedicatedInAMP_ACTIVE: {0} and {1}",
axis.DedicatedInGet(RSIMotorDedicatedIn.RSIMotorDedicatedInAMP_ACTIVE),
axis.AmpEnableGet());

Source: io-dedicated.cs


📜 IO: Network PDOs and SDOs

Learn how to read network inputs and outputs PDO vs. SDO 📖 . Shows how to enumerate through all network inputs/outputs and read their properties including size, offset, name, and value.

// get Input values
int inputCount = controller.NetworkInputCountGet(); // get number of Network Inputs (PDOs)
Console.WriteLine($"Network Input Count: {inputCount}");
for (int i = 0; i < inputCount; i++)
{
int size = controller.NetworkInputBitSizeGet(i); // read Input BitSize
int offset = controller.NetworkInputBitOffsetGet(i); // read Input BitOffset
string name = controller.NetworkInputNameGet(i); // read Input Name
UInt64 value = controller.NetworkInputValueGet(i); // read Input Value
Console.WriteLine($"Input {i}: {name}, Size: {size}, Offset: {offset}, Value: {value}");
}
// get Output values
int outputCount = controller.NetworkOutputCountGet(); // get number of Network Outputs (SDOs)
Console.WriteLine($"Network Output Count: {outputCount}");
for (int i = 0; i < outputCount; i++)
{
int size = controller.NetworkOutputBitSizeGet(i); // read Output BitSize
int offset = controller.NetworkOutputBitOffsetGet(i); // read Output BitOffset
string name = controller.NetworkOutputNameGet(i); // read Output Name
UInt64 value = controller.NetworkOutputSentValueGet(i); // read Output Value
Console.WriteLine($"Output {i}: {name}, Size: {size}, Offset: {offset}, Value: {value}");
controller.NetworkOutputOverrideValueSet(i, value);
}

Source: io-network-pdo-sdo.cs


📜 IO: IOPoint Objects

Learn how to use IOPoint 📖 objects to read and write network data. Shows how to create IOPoint objects for digital outputs and use them to control IO.

const int NODE_INDEX = 0; // the EtherCAT Node we will be communicating with
const int OUTPUT_INDEX = 0; // the PDO Index in that Node
// create IOPoint for digital output - automatically gets memory index of specified node and output index
IOPoint output0 = IOPoint.CreateDigitalOutput(controller.NetworkNodeGet(NODE_INDEX), OUTPUT_INDEX);
// set the output to false
output0.Set(false);
Console.WriteLine($"Output {OUTPUT_INDEX} set to: false");
// wait one sample for the change to take effect
controller.SampleWait(1);
// read back the value
bool outputValue = output0.Get();
Console.WriteLine($"Output {OUTPUT_INDEX} value: {outputValue}");
// set the output to true
output0.Set(true);
Console.WriteLine($"Output {OUTPUT_INDEX} set to: true");
controller.SampleWait(1);
outputValue = output0.Get();
Console.WriteLine($"Output {OUTPUT_INDEX} value: {outputValue}");

Source: io-iopoint.cs


📜 IO: IOPoint User Buffer

Learn how to create simulated IOPoint 📖 objects using user buffer memory. Shows how to create IOPoint objects from base memory addresses and test their functionality without actual hardware.

const int INPUT_INDEX = 0;
const int OUTPUT_INDEX = 1; // the PDO Index in the user buffer
// get user buffer address for simulated IO point storage
UInt64 userBufferAddress = controller.AddressGet(RSIControllerAddressType.RSIControllerAddressTypeUSER_BUFFER, 0);
// create simulated IOPoints based on memory address and index
IOPoint input0 = IOPoint.CreateDigitalInput(controller, userBufferAddress, INPUT_INDEX);
IOPoint output0 = IOPoint.CreateDigitalOutput(controller, userBufferAddress, OUTPUT_INDEX);
// get & set an output
bool outVal = output0.Get();
output0.Set(outVal);
Console.WriteLine($"Output 0 value: {outVal}");
// test input operations by directly writing to memory
controller.MemorySet(input0.AddressGet(), 1);
bool inVal = input0.Get();
Console.WriteLine($"Input 0 memory set to 1, value: {inVal}");
controller.MemorySet(input0.AddressGet(), 0);
inVal = input0.Get();
Console.WriteLine($"Input 0 memory set to 0, value: {inVal}");

Source: io-iopoint-user-buffer.cs


📜 IO: Sync Outputs

Learn how to set up Sync Outputs for Streaming Motion Sync Outputs 📖 . Shows how to configure outputs to trigger at specific motion element IDs during streaming motion.

const int TOTAL_POINTS = 4; // total number of points
const int EMPTY_CT = -1; // number of points that remains in buffer before e-stop
const int OUTPUT_INDEX = 0; // digital output index that will be controlled
const int NODE_INDEX = 0; // the EtherCAT Node index
double[] positions = [1.0, 2.0, 3.0, 4.0]; // streaming motion positions
double[] times = [0.5, 0.1, 0.2, 0.4]; // streaming motion times
int outputEnableID = 2; // motion element ID at which to set output HIGH
int outputDisableID = 3; // motion element ID at which to set output LOW
// create IOPoint for digital output
IOPoint output0 = IOPoint.CreateDigitalOutput(controller.NetworkNodeGet(NODE_INDEX), OUTPUT_INDEX);
output0.Set(false); // set output low initially
// enable streaming/sync outputs
// configure sync outputs - turn output HIGH at motion element 2, LOW at motion element 3
axis.StreamingOutputAdd(output0, true, outputEnableID); // turn output HIGH at element ID 2
axis.StreamingOutputAdd(output0, false, outputDisableID); // turn output LOW at element ID 3
Console.WriteLine($"Starting streaming motion with {TOTAL_POINTS} points");
Console.WriteLine($"Output will go HIGH at element ID {outputEnableID}");
Console.WriteLine($"Output will go LOW at element ID {outputDisableID}");
// start streaming motion
axis.MovePT(RSIMotionType.RSIMotionTypePT, positions, times, TOTAL_POINTS, EMPTY_CT, false, true);
// monitor motion and output state
while (!axis.MotionDoneGet())
{
int currentElement = axis.MotionIdExecutingGet();
bool outputState = output0.Get();
Console.WriteLine($"Motion Element: {currentElement}, Output State: {outputState}");
Thread.Sleep(50); // small delay to avoid overwhelming console
}

Source: io-sync-outputs.cs