This page shows how to read and write the variables and the I/O of a Yaskawa Motoman controller through the Ethernet Server: B, I, D, R and S variables, I/O groups and network inputs. It covers the YRC1000 and YRC1000micro controllers.

## Variables

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

public class EServerVariables
{
    static void Main()
    {
        var parameters = new ConnectParameters("192.168.0.1");
        parameters.EServer.Enable = true;
        var robot = new YaskawaRobot();
        robot.Connect(parameters);

        /**/
        // Read 4 variables from index 0: B000 to B003, I000 to I003...
        byte[] b = robot.EServer.ReadByte(0, 4);
        short[] i = robot.EServer.ReadInteger(0, 4);
        int[] d = robot.EServer.ReadDoubleInteger(0, 4);
        float[] r = robot.EServer.ReadReal(0, 4);
        string[] s = robot.EServer.Read16BytesChar(0, 4);

        // Write from index 10: B010 = 1, B011 = 2
        robot.EServer.WriteByte(10, new byte[] { 1, 2 });
        robot.EServer.WriteInteger(10, new short[] { -100 });
        robot.EServer.WriteDoubleInteger(10, new[] { 123456 });
        robot.EServer.WriteReal(10, new[] { 1.5f });
        robot.EServer.Write16BytesChar(10, new[] { "PART-42" });
        /**/

        robot.Disconnect();
    }
}
```

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

parameters = ConnectParameters("192.168.0.1")
parameters.e_server.enable = True
robot = YaskawaRobot()
robot.connect(parameters)

##
# Read 4 variables from index 0: B000 to B003, I000 to I003...
b = robot.e_server.read_byte(0, 4)
i = robot.e_server.read_integer(0, 4)
d = robot.e_server.read_double_integer(0, 4)
r = robot.e_server.read_real(0, 4)
s = robot.e_server.read16_bytes_char(0, 4)

# Write from index 10: B010 = 1, B011 = 2
robot.e_server.write_byte(10, [1, 2])
robot.e_server.write_integer(10, [-100])
robot.e_server.write_double_integer(10, [123456])
robot.e_server.write_real(10, [1.5])
robot.e_server.write16_bytes_char(10, ["PART-42"])
##

robot.disconnect()
```

| Variable | Read                    | Write                         | .NET type  | Range of a value                |
| -------- | ----------------------- | ----------------------------- | ---------- | ------------------------------- |
| `B`      | `ReadByte`              | `WriteByte`                   | `byte`     | 0 to 255                        |
| `I`      | `ReadInteger`           | `WriteInteger`                | `short`    | -32768 to 32767                 |
| `D`      | `ReadDoubleInteger`     | `WriteDoubleInteger`          | `int`      | -2147483648 to 2147483647       |
| `R`      | `ReadReal`              | `WriteReal`                   | `float`    | 32 bit floating point           |
| `S`      | `Read16BytesChar`       | `Write16BytesChar`            | `string`   | 16 characters                   |

Reads take `(firstIndex, count)` and return one value per variable. Writes take `(firstIndex, values)` and write the variables from `firstIndex`. The number of variables depends on the settings of the controller. An index that does not exist throws a `HostControlException`.

The position variables (P, BP, EX) are not available through the Ethernet Server: read them with the [High Speed Ethernet Server](/yaskawa/documentation/hses-variables).

## Inputs and outputs

### Read the signals

`ReadIO(startAddress, count)` reads `count` bytes of signals. Each byte holds 8 signals. `startAddress` is the number of the first signal, as shown on the pendant: `10010` for `#10010`. Use a number that ends with 0, so that each byte is one group of 8 signals.

**C# : EServerIo**
```csharp
using UnderAutomation.Yaskawa;
using UnderAutomation.Yaskawa.HostControl;

public class EServerIo
{
    static void Main()
    {
        var parameters = new ConnectParameters("192.168.0.1");
        parameters.EServer.Enable = true;
        var robot = new YaskawaRobot();
        robot.Connect(parameters);

        /**/
        // 2 bytes from the signal #10010: #10010 to #10017, then #10020 to #10027
        HostControlIOData outputs = robot.EServer.ReadIO(10010, 2);
        Console.WriteLine($"#10010: {outputs.GetBit(0)}, #10011: {outputs.GetBit(1)}");
        Console.WriteLine($"#10020 to #10027: {outputs.Data[1]}");

        // Network inputs #27010 to #27017: bits 0 and 2 on (value 5)
        robot.EServer.WriteIO(27010, new byte[] { 5 });
        /**/

        robot.Disconnect();
    }
}
```

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

parameters = ConnectParameters("192.168.0.1")
parameters.e_server.enable = True
robot = YaskawaRobot()
robot.connect(parameters)

##
# 2 bytes from the signal #10010: #10010 to #10017, then #10020 to #10027
outputs = robot.e_server.read_io(10010, 2)
print(f"#10010: {outputs.get_bit(0)}, #10011: {outputs.get_bit(1)}")
print(f"#10020 to #10027: {outputs.data[1]}")

# Network inputs #27010 to #27017: bits 0 and 2 on (value 5)
robot.e_server.write_io(27010, [5])
##

robot.disconnect()
```

`Data[0]` holds `#10010` to `#10017`: bit 0 is `#10010`, bit 7 is `#10017`. `GetBit(n)` reads bit `n` of the result, from 0 for the first signal of the first byte.

| Signals            | Example number |
| ------------------ | -------------- |
| General inputs     | `#00010`       |
| General outputs    | `#10010`       |
| External inputs    | `#20010`       |
| Network inputs     | `#27010`       |
| Network outputs    | `#37010`       |
| Specific outputs   | `#50010`       |
| Auxiliary relays   | `#70010`       |

The numbers are the same as with the High Speed Ethernet Server: the full table is in [Inputs and outputs](/yaskawa/documentation/hses-io#signals_groups_and_bits). The signals that exist depend on the I/O boards of the controller.

### Write the network inputs

`WriteIO(startAddress, values)` writes bytes of signals. By default, the controller accepts only the network inputs (`#27010` to `#29567`). They are the signals to use to send an order or a state to a job. A write to another signal throws a `HostControlException`.

## Reference

**Methods of HostControlClientBase**
```csharp
// Reads 16-byte string (S) variables starting at the specified index.
string[] Read16BytesChar(int firstIndex, int count);

// Reads byte (B) variables starting at the specified index.
byte[] ReadByte(int firstIndex, int count);

// Reads double integer (D) variables starting at the specified index.
int[] ReadDoubleInteger(int firstIndex, int count);

// Reads I/O signals from the robot controller. Each byte holds 8 signals.
HostControlIOData ReadIO(int startAddress, int count);

// Reads integer (I) variables starting at the specified index.
short[] ReadInteger(int firstIndex, int count);

// Reads real (R) variables starting at the specified index.
float[] ReadReal(int firstIndex, int count);

// Writes 16-byte string (S) variables starting at the specified index.
void Write16BytesChar(int firstIndex, string[] data);

// Writes byte (B) variables starting at the specified index.
void WriteByte(int firstIndex, byte[] data);

// Writes double integer (D) variables starting at the specified index.
void WriteDoubleInteger(int firstIndex, int[] data);

// Writes I/O signals to the robot controller. Each byte holds 8 signals. By default, the controller accepts only the network input signals (#27010 to #29567).
HostControlResponse WriteIO(int startAddress, byte[] data);

// Writes integer (I) variables starting at the specified index.
void WriteInteger(int firstIndex, short[] data);

// Writes real (R) variables starting at the specified index.
void WriteReal(int firstIndex, float[] data);
```

Every method also exists in an asynchronous version, with the same name followed by `Async` and an optional `CancellationToken`.

**Members of HostControl.HostControlIOData**
```csharp
public class HostControlIOData : HostControlResponse {
    // Gets or sets the number of I/O bytes read.
    public int Count { get; }

    // Gets or sets the I/O data bytes.
    public byte[] Data { get; }

    // Gets the bit value at the specified offset from the start address.
    public bool GetBit(int bitOffset)

    // Gets or sets the starting I/O contact number.
    public int StartAddress { get; }
}
```

## What to read next

- [Read and write variables](/yaskawa/documentation/how-to-read-write-variables): which protocol and which variable type to choose.
- [Read and write I/O](/yaskawa/documentation/how-to-read-write-io): switch a network input and wait for an output.