This page explains how to connect the SDK to a Yaskawa Motoman controller: the settings of the controller, the connection parameters, the errors and the disconnection. The SDK uses the High Speed Ethernet Server of the controller, over UDP. Nothing is installed on the controller.

## Prerequisites

- The PC reaches the controller on the network. Its address is shown in the network settings of the controller, on the pendant.
- The High Speed Ethernet Server function is enabled on the controller. It answers on the UDP ports 10040 (data) and 10041 (files). A firewall between the PC and the controller must let these ports through.
- The controller is one of: YRC1000 (micro), MOTOMAN NEXT, DX100 / DX200, FS100, ERC / XRC / MRC.

The read methods work in any mode. The commands (servo, motion, job start, file write) need the settings below.

## Prepare the controller

Each setting is made once, on the programming pendant, with the management mode set to Security mode.

### Enable the remote commands

- Select `IN/OUT` > `PSEUDO INPUT SIGNAL`.
- Move the cursor to `#82015 CMD REMOTE SEL` and press `INTER LOCK` + `SELECT`.

![Enable remote command](https://raw.githubusercontent.com/underautomation/Yaskawa.NET/refs/heads/main/.github/assets/cmd-remote-sel.png)

### Put the key in the remote position

The commands need the key of the pendant in the remote position.

![Pendant remote key](https://raw.githubusercontent.com/underautomation/Yaskawa.NET/refs/heads/main/.github/assets/pendant-remote.png)

To use the key for the remote control, copy `#80011` (key in the remote position) to `#40042` (remote control enabled) with the ladder editor:

- Select `IN/OUT` > `LADDER EDITOR`.
- Check that no other rung writes `#40042`, then add this rung:

![Ladder remote key](https://raw.githubusercontent.com/underautomation/Yaskawa.NET/refs/heads/main/.github/assets/ladder-remote.png)

`GetStatusInformation().CommandRemote` is `true` when the controller accepts the remote commands.

### Allow the job selection

- Select `SETUP` > `FUNCTION ENABLE`.
- Set `JOB SELECT WHEN REMOTE AND PLAY` to `PERMIT`. On the Smart Pendant, set the parameter `SC2 224` to `0`.

![Job select when remote and play](https://raw.githubusercontent.com/underautomation/Yaskawa.NET/refs/heads/main/.github/assets/job-select-when-remote-and-play.png)

### Allow the file overwrite

To send a file that already exists on the controller:

- Select `PARAMETER` > `RS`.
- Set `RS029` to `1` and `RS214` to `1`.

## Quick connection

Pass the address of the controller. The other parameters keep their default values.

**C# : ConnectQuick**
```csharp
using UnderAutomation.Yaskawa;

public class ConnectQuick
{
    static void Main()
    {
        /**/
        var robot = new YaskawaRobot();

        // IP address of the controller, default ports and timeouts
        robot.Connect("192.168.0.1");

        // Every function of the SDK is a method of robot.HighSpeedEServer
        var status = robot.HighSpeedEServer.GetStatusInformation();
        Console.WriteLine($"Servo on: {status.ServoOn}, play mode: {status.Play}");

        robot.Disconnect();
        /**/
    }
}
```

**Python : ConnectQuick**
```python
from underautomation.yaskawa.yaskawa_robot import YaskawaRobot
from underautomation.yaskawa.connect_parameters import ConnectParameters

##
robot = YaskawaRobot()

# IP address of the controller, default ports and timeouts
robot.connect(ConnectParameters("192.168.0.1"))

# Every function of the SDK is a method of robot.high_speed_e_server
status = robot.high_speed_e_server.get_status_information()
print(f"Servo on: {status.servo_on}, play mode: {status.play}")

robot.disconnect()
##
```

**Matlab : ConnectQuick**
```matlab
NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.Yaskawa.dll'));
import UnderAutomation.Yaskawa.*

%%
robot = YaskawaRobot();

% IP address of the controller, default ports and timeouts
robot.Connect('192.168.0.1');

status = robot.HighSpeedEServer.GetStatusInformation();
fprintf('Servo on: %d, play mode: %d
', status.ServoOn, status.Play);

robot.Disconnect();
%%
```

`YaskawaRobot` gives access to every function of the SDK, through its `HighSpeedEServer` property.

## Connection parameters

`ConnectParameters` holds every option. Use it when the controller has other ports, or when the network needs longer timeouts.

**C# : Connect**
```csharp
using UnderAutomation.Yaskawa;

public class Connect
{
    static void Main()
    {
        /**/
        var parameters = new ConnectParameters("192.168.0.1");

        // Ping the controller first (default: true)
        parameters.PingBeforeConnect = true;

        // UDP ports of the High Speed Ethernet Server (defaults: 10040 and 10041)
        parameters.HighSpeedEServer.DataPort = 10040;
        parameters.HighSpeedEServer.FilePort = 10041;

        // Time to wait for an answer, in milliseconds
        parameters.HighSpeedEServer.DataTimeoutMilliseconds = 1500;
        parameters.HighSpeedEServer.PowerOnTimeoutMilliseconds = 8000;
        parameters.HighSpeedEServer.FileTimeoutMilliseconds = 4000;

        var robot = new YaskawaRobot();
        robot.Connect(parameters);
        /**/

        robot.Disconnect();
    }
}
```

**Python : Connect**
```python
from underautomation.yaskawa.yaskawa_robot import YaskawaRobot
from underautomation.yaskawa.connect_parameters import ConnectParameters

##
parameters = ConnectParameters("192.168.0.1")

# Ping the controller first (default: True)
parameters.ping_before_connect = True

# UDP ports of the High Speed Ethernet Server (defaults: 10040 and 10041)
parameters.high_speed_e_server.data_port = 10040
parameters.high_speed_e_server.file_port = 10041

# Time to wait for an answer, in milliseconds
parameters.high_speed_e_server.data_timeout_milliseconds = 1500
parameters.high_speed_e_server.power_on_timeout_milliseconds = 8000
parameters.high_speed_e_server.file_timeout_milliseconds = 4000

robot = YaskawaRobot()
robot.connect(parameters)
##

robot.disconnect()
```

**Matlab : Connect**
```matlab
NET.addAssembly(fullfile(pwd, 'net48', 'UnderAutomation.Yaskawa.dll'));
import UnderAutomation.Yaskawa.*

%%
parameters = ConnectParameters('192.168.0.1');
parameters.PingBeforeConnect = true;

% UDP ports and timeouts of the High Speed Ethernet Server
parameters.HighSpeedEServer.DataPort = 10040;
parameters.HighSpeedEServer.FilePort = 10041;
parameters.HighSpeedEServer.DataTimeoutMilliseconds = 1500;

robot = YaskawaRobot();
robot.Connect(parameters);
%%

robot.Disconnect();
```

| Parameter                                     | Default | Meaning                                                                 |
| --------------------------------------------- | ------- | ----------------------------------------------------------------------- |
| `IP`                                          | none    | IP address or host name of the controller                               |
| `PingBeforeConnect`                           | `true`  | Send a ping first. The connection fails if there is no answer in 200 ms |
| `HighSpeedEServer.Enable`                     | `true`  | Open the High Speed Ethernet Server client                              |
| `HighSpeedEServer.DataPort`                   | `10040` | UDP port of the data commands                                           |
| `HighSpeedEServer.FilePort`                   | `10041` | UDP port of the file transfers                                          |
| `HighSpeedEServer.DataTimeoutMilliseconds`    | `1500`  | Time to wait for the answer of a data command                           |
| `HighSpeedEServer.PowerOnTimeoutMilliseconds` | `8000`  | Time to wait for the answer of `ServoCommand(Servo, true)`              |
| `HighSpeedEServer.FileTimeoutMilliseconds`    | `4000`  | Time to wait for the answer of a file transfer                          |

The ping also protects the controller: a request sent while the controller starts can raise an error on it. Set `PingBeforeConnect` to `false` only when a firewall blocks ICMP between the PC and the controller.

## UDP: what "connected" means

UDP has no connection. `Connect` checks the license, sends the ping and opens the socket: it does not exchange a message with the controller. The first method call is the first exchange. If the controller does not answer, this call fails after `DataTimeoutMilliseconds`.

To check the link at startup, call a read method, for example `GetStatusInformation()`, right after `Connect`.

`Connected` is `true` while the socket is open.

## Standalone client

`HighSpeedEServerClient` opens a High Speed Ethernet Server client without `YaskawaRobot`. The methods are then directly on the client: `client.GetStatusInformation()` instead of `robot.HighSpeedEServer.GetStatusInformation()`.

**C# : ConnectStandalone**
```csharp
using UnderAutomation.Yaskawa.HighSpeedEServer;

public class ConnectStandalone
{
    static void Main()
    {
        /**/
        // A High Speed Ethernet Server client without YaskawaRobot
        var client = new HighSpeedEServerClient();
        client.Connect("192.168.0.1", new HighSpeedEServerConnectParameters());

        // The methods are directly on the client
        RobotStatusData status = client.GetStatusInformation();
        Console.WriteLine($"Running: {status.Running}");

        client.Close();
        /**/
    }
}
```

**Python : ConnectStandalone**
```python
from underautomation.yaskawa.high_speed_e_server.high_speed_e_server_client import HighSpeedEServerClient
from underautomation.yaskawa.high_speed_e_server.high_speed_e_server_connect_parameters import HighSpeedEServerConnectParameters

##
# A High Speed Ethernet Server client without YaskawaRobot
client = HighSpeedEServerClient()
client.connect("192.168.0.1", HighSpeedEServerConnectParameters())

# The methods are directly on the client
status = client.get_status_information()
print(f"Running: {status.running}")

client.close()
##
```

## Errors

**C# : ConnectErrors**
```csharp
using System.Net.Sockets;
using UnderAutomation.Yaskawa;
using UnderAutomation.Yaskawa.Common;
using UnderAutomation.Yaskawa.HighSpeedEServer;
using UnderAutomation.Yaskawa.License;

public class ConnectErrors
{
    static void Main()
    {
        var robot = new YaskawaRobot();

        /**/
        try
        {
            robot.Connect("192.168.0.1");
            robot.HighSpeedEServer.StartJob();
        }
        catch (InvalidLicenseException ex)
        {
            // No valid license: the trial is over, or the key is wrong
            Console.WriteLine(ex.LicenseInfo);
        }
        catch (ConnectException ex)
        {
            // The UDP socket could not be opened
            Console.WriteLine($"{ex.Address}: {ex.Message}");
        }
        catch (InvalidDataAnswerException ex)
        {
            // The controller refused the command, for example "Servo OFF" or "Command remote not set"
            Console.WriteLine($"{ex.Message} ({ex.Status}, {ex.AddedStatus})");
        }
        catch (SocketException ex)
        {
            // No answer before the timeout
            Console.WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            // For example, no answer to the ping
            Console.WriteLine(ex.Message);
        }
        /**/
    }
}
```

**Python : ConnectErrors**
```python
from underautomation.yaskawa.yaskawa_robot import YaskawaRobot
from underautomation.yaskawa.connect_parameters import ConnectParameters
from UnderAutomation.Yaskawa.License import InvalidLicenseException
from UnderAutomation.Yaskawa.Common import ConnectException
from UnderAutomation.Yaskawa.HighSpeedEServer import InvalidDataAnswerException
from System.Net.Sockets import SocketException

robot = YaskawaRobot()

##
# The exceptions come from the .NET runtime, so their members keep their original names
try:
    robot.connect(ConnectParameters("192.168.0.1"))
    robot.high_speed_e_server.start_job()
except InvalidLicenseException as ex:
    # No valid license: the trial is over, or the key is wrong
    print(ex.LicenseInfo)
except ConnectException as ex:
    # The UDP socket could not be opened
    print(f"{ex.Address}: {ex.Message}")
except InvalidDataAnswerException as ex:
    # The controller refused the command, for example "Servo OFF" or "Command remote not set"
    print(f"{ex.Message} ({ex.Status}, {ex.AddedStatus})")
except SocketException as ex:
    # No answer before the timeout
    print(ex.Message)
except Exception as ex:
    # For example, no answer to the ping
    print(ex)
##
```

| Exception                    | When                                                                                                 |
| ---------------------------- | ---------------------------------------------------------------------------------------------------- |
| `InvalidLicenseException`    | `Connect` is called without a valid license. See [Licensing](/yaskawa/documentation/license)         |
| `Exception`                  | No answer to the ping, or a method is called before `Connect`                                        |
| `ConnectException`           | The UDP socket could not be opened. `Address` gives the address and the port                         |
| `SocketException`            | No answer before the timeout, or the port is closed                                                  |
| `InvalidDataAnswerException` | The controller refused the command. `Message` gives the reason, `Status` and `AddedStatus` the codes |

Frequent messages of `InvalidDataAnswerException`, and what to check:

| Message                                        | Check                                                                          |
| ---------------------------------------------- | ------------------------------------------------------------------------------ |
| `Command remote not set`                       | The remote mode, see [Prepare the controller](#prepare_the_controller)         |
| `Incorrect mode`                               | The mode of the controller: play mode to start a job                           |
| `Servo OFF`                                    | Switch the servo on first                                                      |
| `Error/alarm occurring`                        | Reset the alarm, see [Alarms](/yaskawa/documentation/hses-alarms)              |
| `Hold by programming pendant`, `External hold` | Release the hold on the pendant or on the external signal                      |
| `Cannot over write the target file`            | `RS029` and `RS214`, see [Allow the file overwrite](#allow_the_file_overwrite) |

## Disconnect

`Disconnect` closes the sockets. Call it when your application ends, or when it no longer needs the controller.

**C# : ConnectDisconnect**
```csharp
using UnderAutomation.Yaskawa;

public class ConnectDisconnect
{
    static void Main()
    {
        var robot = new YaskawaRobot();
        robot.Connect("192.168.0.1");

        /**/
        // True while the UDP socket is open
        Console.WriteLine(robot.Connected);

        // Close the sockets when the application no longer needs the controller
        robot.Disconnect();
        /**/
    }
}
```

**Python : ConnectDisconnect**
```python
from underautomation.yaskawa.yaskawa_robot import YaskawaRobot
from underautomation.yaskawa.connect_parameters import ConnectParameters

robot = YaskawaRobot()
robot.connect(ConnectParameters("192.168.0.1"))

##
# True while the UDP socket is open
print(robot.connected)

# Close the sockets when the application no longer needs the controller
robot.disconnect()
##
```

## Try it in the demo application

Everything on this page can be tried without writing code, in the **Connection** page of the [demo application](/yaskawa/documentation/demo-app).

![Connection page of the Yaskawa SDK demo application](/yaskawa/WinformsScreenshots/Connect.jpg)

Its C# source is [ConnectControl.cs](https://github.com/underautomation/Yaskawa.NET/blob/main/UnderAutomation.Yaskawa.Showcase.Forms/Components/ConnectControl.cs).

## Reference

**Members of ConnectParameters**
```csharp
public class ConnectParameters {
    // Creates a new set of connect parameters
    public ConnectParameters()

    // Creates a new set of connect parameters and defines IP property
    public ConnectParameters(string ip)

    // High Speed Ethernet Server connect parameters
    public HighSpeedEServerConnectParametersInternal HighSpeedEServer { get; set; }

    // IP Adress or robot host name
    public string IP { get; set; }

    // Send a ping command before connecting
    public bool PingBeforeConnect { get; set; }
}
```

**Members of HighSpeedEServer.Internal.HighSpeedEServerConnectParametersInternal**
```csharp
public class HighSpeedEServerConnectParametersInternal : HighSpeedEServerConnectParameters {
    public HighSpeedEServerConnectParametersInternal()

    // Gets or sets a value indicating whether to enable the High Speed Ethernet Server connection (default: true).
    public bool Enable { get; set; }
}
```

**Members of HighSpeedEServer.HighSpeedEServerConnectParameters**
```csharp
public class HighSpeedEServerConnectParameters {
    // Initializes a new instance of the connection parameters class.
    public HighSpeedEServerConnectParameters()

    // Default UDP port for data communication (10040).
    public const int DEFAULT_DATA_PORT = 10040

    // Default timeout in milliseconds for data commands (1500ms).
    public const int DEFAULT_DATA_TIMEOUT_MILLISECONDS = 1500

    // Default UDP port for file transfer operations (10041).
    public const int DEFAULT_FILE_PORT = 10041

    // Default timeout in milliseconds for file operations (4000ms).
    public const int DEFAULT_FILE_TIMEOUT_MILLISECONDS = 4000

    // Default timeout in milliseconds for servo power on operations (8000ms).
    public const int DEFAULT_POWER_ON_TIMEOUT_MILLISECONDS = 8000

    // Gets or sets the UDP port number for data communication.
    // Must match the robot controller's High Speed Ethernet Server data port configuration.
    // Default: 10040.
    public int DataPort { get; set; }

    // Gets or sets the maximum time in milliseconds to wait for a response to data commands.
    // Applies to most read/write operations like position reading, variable access, etc.
    // Default: 1500ms.
    public int DataTimeoutMilliseconds { get; set; }

    // Gets or sets the UDP port number for file transfer operations.
    // Must match the robot controller's High Speed Ethernet Server file port configuration.
    // Default: 10041.
    public int FilePort { get; set; }

    // Gets or sets the maximum time in milliseconds to wait for file operation responses.
    // File operations may be slower due to larger data transfers and disk I/O on the controller.
    // Default: 4000ms.
    public int FileTimeoutMilliseconds { get; set; }

    // Gets or sets the maximum time in milliseconds to wait for servo power on to complete.
    // Servo power on may take longer due to brake release and motor initialization.
    // Default: 8000ms.
    public int PowerOnTimeoutMilliseconds { get; set; }
}
```

**Members of Common.ConnectException**
```csharp
public class ConnectException : Exception, ISerializable {
    // Address of the robot (IP:port or serial port name)
    public string Address { get; }

    // Name of the protocol that failed to connect
    public string Service { get; }
}
```

**Members of HighSpeedEServer.InvalidDataAnswerException**
```csharp
public class InvalidDataAnswerException : Exception, ISerializable {
    // Gets the additional status code providing more detailed error information.
    // The interpretation of this value depends on the primary Status code.
    public int AddedStatus { get; }

    // Gets the primary status code returned by the robot controller.
    // A value of 0 indicates success; any other value indicates an error condition.
    public int Status { get; }
}
```