<!-- Source: https://docs.captron.com/de/application-notes/CaneoSeries5x-allen-bradley-aoi -->

# CANEO series5x + Allen-Bradley — Add-On Instruction Guide

This guide walks through integrating a **CANEO series5x Duo-Touch Display** with an **Allen-Bradley** ControlLogix or CompactLogix controller in **Studio 5000 Logix Designer**. By the end you'll be reading touch zones from the button and writing text, numbers, text color, and LED scenes to it from ladder logic — all through a single CAPTRON **Add-On Instruction (AOI)** that hides the byte-level plumbing.

Most IO-Link masters on EtherNet/IP hand the controller its process data as one flat `SINT` array covering every port on the block. Several CANEO series5x fields — the active scenes, the displayed number, and the text string — are **larger than one byte**, and some masters also **swap the byte order**. The AOI takes care of both: you point it at the master's raw arrays and tell it where your port starts, and it gives you back two clean, named structures to read and write.

## Prerequisites

Before starting, make sure:

- **Studio 5000 Logix Designer** is installed and you have a project open for your controller. This example uses a **5069-L306ER** CompactLogix on firmware **v38**.
- An **IO-Link master** is configured under **I/O Configuration** and its input and output data are visible as controller tags. This example uses a **MURR IMPACT67 Pro E DIO8 IOL8 M12L 5P** (54631).
- The **CANEO series5x Duo-Touch Display** is wired to an IO-Link port on the master (this example uses **port 0**).
- You have downloaded **`CANEOseries5x_V34_AOI.zip`** and unzipped it to get the AOI file **`CANEOseries5x_V34_AOI.L5X`** (see [Download](#download) at the end of this guide).
- You have the CANEO series5x **IO-Link process data layout** handy for the meaning of each value: [series5x IO-Link Process Data](https://docs.captron.com/trms/series5x/io-link-process-data).

---

## 1. Import the Add-On Instruction {/* #import-aoi */}

In the **Controller Organizer**, expand **Assets**, then right-click **Add-On Instructions** and choose **Import Add-On Instruction…**.

![Right-click menu on Add-On Instructions with Import Add-On Instruction highlighted](./images/caneo50-ab-aoi-image1.png)

Browse to the downloaded file, select **`CANEOseries5x_V34_AOI.L5X`**, and click **Open**. Confirm the import dialog that follows.

![Import Add-On Instruction dialog with CANEOseries5x_V34_AOI.L5X selected](./images/caneo50-ab-aoi-image2.png)

After the import, **`AOI_CANEOseries5x_V34`** appears under **Add-On Instructions**, and two user-defined data types (UDTs) appear under **Data Types → User-Defined**:

- **`CaneoSeries5x_PDIN`** — the process data coming *from* the display (touch zones).
- **`CaneoSeries5x_PDOUT`** — the process data going *to* the display (text, number, color, scenes).

---

## 2. AOI parameters

Open the AOI definition and switch to the **Parameters** tab to see what the instruction expects.

![Add-On Instruction Definition showing the AOI_CANEOseries5x_V34 parameters](./images/caneo50-ab-aoi-image3.png)

<table>
  <thead>
    <tr>
      <th>Parameter</th>
      <th>Data type</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr><td><code>IOL_PD_IN</code></td><td><code>CaneoSeries5x_PDIN</code></td><td>Structure the AOI fills with the CANEO series5x input process data. <b>Read</b> the touch zones from here. See <a href="#iol-pd-in">Reading the touch zones</a>.</td></tr>
    <tr><td><code>IOL_PD_OUT</code></td><td><code>CaneoSeries5x_PDOUT</code></td><td>Structure you <b>write</b> to. The AOI packs it into the output process data. See <a href="#iol-pd-out">Writing to the display</a>.</td></tr>
    <tr><td><code>IOL_PD_IN_RAW</code></td><td><code>SINT[8]</code></td><td>The raw IO-Link input process data array from the IO-Link master (as defined by the master's EDS file).</td></tr>
    <tr><td><code>IOL_PD_OUT_RAW</code></td><td><code>SINT[16]</code></td><td>The raw IO-Link output process data array from the IO-Link master (as defined by the master's EDS file).</td></tr>
    <tr><td><code>IOL_PD_IN_RAW_START_INDEX</code></td><td><code>DINT</code></td><td>Index of the first input byte of the port the CANEO series5x is connected to. Consult your IO-Link master's manual for the byte layout.</td></tr>
    <tr><td><code>IOL_PD_OUT_RAW_START_INDEX</code></td><td><code>DINT</code></td><td>Index of the first output byte of the port the CANEO series5x is connected to. Consult your IO-Link master's manual for the byte layout.</td></tr>
    <tr><td><code>byteswap</code></td><td><code>BOOL</code></td><td>Set to <code>1</code> if your IO-Link master swaps the byte order of the process data. Default is <code>0</code> (no swap).</td></tr>
  </tbody>
</table>

> **Do I need byte swapping?** IO-Link masters don't all format process data the same way. Some present each 16-bit word with its two bytes swapped. Masters from **Turck**, **IFM**, and **Comtrol** commonly do this. If text appears with pairs of characters swapped (e.g. `BADCE` instead of `ABCDE`), or touch zones show up on the wrong zone, set `byteswap` to `1`.

---

## 3. Add the AOI to your routine {/* #add-aoi */}

Open your routine (here **MainProgram → MainRoutine**) and add **`AOI_CANEOseries5x_V34`** to a rung — you'll find it in the **Toolbox** under **Add-On**. Every operand starts as a question mark.

![AOI_CANEOseries5x_V34 placed on rung 0 with all operands unassigned](./images/caneo50-ab-aoi-image4.png)

Fill in the operands one by one. For the tags that don't exist yet, right-click the question mark and choose **New Tag**:

1. **AOI instance** — create a new tag of type `AOI_CANEOseries5x_V34` (e.g. `AOI_port0_MURR`). Use one instance per display.
2. **`IOL_PD_IN`** — create a new tag of type `CaneoSeries5x_PDIN` (e.g. `CD50_PDIN_port0`).
3. **`IOL_PD_OUT`** — create a new tag of type `CaneoSeries5x_PDOUT` (e.g. `CD50_PDOUT_port0`).
4. **`IOL_PD_IN_RAW`** / **`IOL_PD_OUT_RAW`** — select the IO-Link master's input and output data arrays from the **Controller Tags**.
5. **`IOL_PD_IN_RAW_START_INDEX`** / **`IOL_PD_OUT_RAW_START_INDEX`** — enter the index of the first input and output byte of the port the CANEO series5x is connected to. These values are specific to your IO-Link master. If your master (or the master manufacturer's own AOI) already gives you a separate array per port, the start index is most likely `0`.
6. **`byteswap`** — `0` or `1`, depending on your master (see above).

### Example: MURR IMPACT67 (54631), port 0

![AOI configured for a MURR 54631 IO-Link master, port 0](./images/caneo50-ab-aoi-image5.png)

<table>
  <thead>
    <tr>
      <th>Operand</th>
      <th>Value</th>
      <th>Why</th>
    </tr>
  </thead>
  <tbody>
    <tr><td>AOI instance</td><td><code>AOI_port0_MURR</code></td><td>Named after the port and the master it serves.</td></tr>
    <tr><td><code>IOL_PD_IN</code></td><td><code>CD50_PDIN_port0</code></td><td>Named after the part number (CD50), the type of process data, and the port.</td></tr>
    <tr><td><code>IOL_PD_OUT</code></td><td><code>CD50_PDOUT_port0</code></td><td>Same naming scheme for the output side.</td></tr>
    <tr><td><code>IOL_PD_IN_RAW</code></td><td><code>Murr54631:I1.Data</code></td><td>The MURR block's complete input data array, stored under Controller Tags.</td></tr>
    <tr><td><code>IOL_PD_OUT_RAW</code></td><td><code>Murr54631:O1.Data</code></td><td>The MURR block's complete output data array.</td></tr>
    <tr><td><code>IOL_PD_IN_RAW_START_INDEX</code></td><td><code>10</code></td><td>First input byte of port 0 in the MURR input array.</td></tr>
    <tr><td><code>IOL_PD_OUT_RAW_START_INDEX</code></td><td><code>2</code></td><td>First output byte of port 0 in the MURR output array.</td></tr>
    <tr><td><code>byteswap</code></td><td><code>0</code></td><td>The MURR block does not swap bytes.</td></tr>
  </tbody>
</table>

In this example the entire MURR data array is passed in, and the start indexes tell the AOI where port 0's data begins inside it. To connect a display on another port, add a second AOI instance with its own `PDIN`/`PDOUT` tags and that port's start indexes.

---

## 4. `IOL_PD_IN` — reading the touch zones {/* #iol-pd-in */}

`CaneoSeries5x_PDIN` holds one `BOOL` per touch zone. Each one goes high when its zone is actuated, according to the **Touch Input** parameters configured in the IODD.

![CD50_PDIN_port0 expanded showing Zone_1_Actuated to Zone_4_Actuated](./images/caneo50-ab-aoi-image6.png)

<table>
  <thead>
    <tr>
      <th>Member</th>
      <th>Data type</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr><td><code>Zone_1_Actuated</code></td><td><code>BOOL</code></td><td>Touch zone 1 is actuated</td></tr>
    <tr><td><code>Zone_2_Actuated</code></td><td><code>BOOL</code></td><td>Touch zone 2 is actuated</td></tr>
    <tr><td><code>Zone_3_Actuated</code></td><td><code>BOOL</code></td><td>Touch zone 3 is actuated</td></tr>
    <tr><td><code>Zone_4_Actuated</code></td><td><code>BOOL</code></td><td>Touch zone 4 is actuated</td></tr>
  </tbody>
</table>

For more on how the touch zones are laid out and configured, see [series5x Touch Zones](https://docs.captron.com/trms/series5x/touch-zones).

---

## 5. `IOL_PD_OUT` — writing to the display {/* #iol-pd-out */}

`CaneoSeries5x_PDOUT` holds everything you send to the display. Write to these members from your logic; the AOI copies them into the correct output bytes on every scan.

![CD50_PDOUT_port0 expanded showing the process data output members](./images/caneo50-ab-aoi-image7.png)

<table>
  <thead>
    <tr>
      <th>Member</th>
      <th>Data type</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr><td><code>Text_To_Display</code></td><td><code>STRING</code></td><td>Text shown on the display — up to 5 characters.</td></tr>
    <tr><td><code>Text_Color</code></td><td><code>SINT</code></td><td>Color of the text, selected by number (e.g. <code>1</code> = <code>Red</code>, <code>2</code> = <code>Green</code>, <code>3</code> = <code>Blue</code>).</td></tr>
    <tr><td><code>Text_Select</code></td><td><code>SINT</code></td><td>What the display shows: <code>0</code> = text from the active scene (IODD), <code>1</code> = the number from <code>Number_To_Display</code>, <code>2</code> = the text from <code>Text_To_Display</code>.</td></tr>
    <tr><td><code>Number_To_Display</code></td><td><code>ULINT</code></td><td>Number shown on the display — up to 5 digits.</td></tr>
    <tr><td><code>Active_Scenes</code></td><td><code>UINT</code></td><td>Bitmask of the active scenes, up to 16 scenes. Bit 0 = scene 1, bit 1 = scene 2, and so on — write <code>1</code> for scene 1, <code>2</code> for scene 2, <code>4</code> for scene 3, <code>8</code> for scene 4.</td></tr>
    <tr><td><code>Scene_Selection_Mode</code></td><td><code>SINT</code></td><td><code>0</code> = Local Data (scenes are activated by the configured triggers in the IODD), <code>1</code> = Process Data (scenes follow the bits in <code>Active_Scenes</code>).</td></tr>
  </tbody>
</table>

> **`Active_Scenes` only takes effect in Process Data mode.** Set `Scene_Selection_Mode` to `1` before you expect the display to follow the scenes you write.

For the full list of color codes and the details of each field, see [series5x IO-Link Process Data](https://docs.captron.com/trms/series5x/io-link-process-data).

---

## 6. Usage example

The ladder logic below switches scenes based on touch zone 1 and writes a text string to the button.

![Ladder logic switching scenes on Zone_1_Actuated and writing text to the display](./images/caneo50-ab-aoi-image8.png)

- **Rung 0** — calls the AOI. It must be scanned on every cycle, so leave it unconditional.
- **Rung 1** — while zone 1 is **not** actuated (`XIO`), `MOVE 3` into `Active_Scenes` — scenes 1 and 2 are active.
- **Rung 2** — while zone 1 **is** actuated (`XIC`), `MOVE 4` into `Active_Scenes` — scene 3 is active.
- **Rung 3** — sets `Scene_Selection_Mode` to `1` (Process Data) so the display follows `Active_Scenes`, `Text_Color` to `1` (`Red`), `Text_Select` to `2` (show the text from process data), and `Text_To_Display` to `'ABCDE'`.

To show a number instead, set `Text_Select` to `1` and write the value to `Number_To_Display`.

---

## 7. Using integer arrays and an IO-Link master AOI (IFM AL1322) {/* #ifm-int-arrays */}

Not every IO-Link master hands you its process data as a `SINT` array. The **IFM AL1322** imports its data as an **`INT` array**. IFM also provides its own generic AOI, **`Generic_8PORT_IOL`**, which pulls a single port's process data out of the master's data and gives it to you as a separate array for that port.

The CAPTRON AOI expects `SINT` arrays for `IOL_PD_IN_RAW` and `IOL_PD_OUT_RAW`. So when your master works in `INT`s, you need to convert to `SINT` on the way into the CAPTRON AOI and back to `INT` on the way out. The **`CPS`** (Synchronous Copy File) instruction does this. It copies the raw bytes from one array into another, whatever the data type of each array.

![IFM Generic_8PORT_IOL AOI feeding the CANEO series5x AOI through CPS instructions](./images/caneo50-ab-aoi-image9.png)

The rung runs in four stages:

1. **`Generic_8PORT_IOL`** (IFM's AOI) reads the master's data (`IFM:I1.Data` / `IFM:O1.Data`) for **port 1**. It places that port's process data in `caneoseries5x_port1_input_data_array` and takes the port's output data from `caneoseries5x_port1_output_data_array`. Both are `INT` arrays. For the `Vendor_ID` and `Device_ID` settings and the status outputs, see IFM's documentation for the AOI.
2. **`CPS`** copies the `INT` input array into a `SINT` array, `int_to_sint_input_array_port1_IFM`.
3. **`AOI_CANEOseries5x_V34`** reads `int_to_sint_input_array_port1_IFM` as `IOL_PD_IN_RAW` and writes to `int_to_sint_output_array_port1_IFM` as `IOL_PD_OUT_RAW`, exactly as in [step 3](#add-aoi).
4. **`CPS`** copies the `SINT` output array back into the `INT` array `caneoseries5x_port1_output_data_array`. IFM's AOI then sends it to the master.

<table>
  <thead>
    <tr>
      <th>CAPTRON AOI operand</th>
      <th>Value</th>
      <th>Why</th>
    </tr>
  </thead>
  <tbody>
    <tr><td><code>IOL_PD_IN</code></td><td><code>caneoseries5x_PDIN_port1_IFM</code></td><td>Touch zones for the display on port 1.</td></tr>
    <tr><td><code>IOL_PD_OUT</code></td><td><code>caneoseries5x_PDOUT_port1_IFM</code></td><td>Values you write to the display on port 1.</td></tr>
    <tr><td><code>IOL_PD_IN_RAW</code></td><td><code>int_to_sint_input_array_port1_IFM</code></td><td>The <code>SINT</code> copy of the port's input data.</td></tr>
    <tr><td><code>IOL_PD_OUT_RAW</code></td><td><code>int_to_sint_output_array_port1_IFM</code></td><td>The <code>SINT</code> array that is copied back to the port's output data.</td></tr>
    <tr><td><code>IOL_PD_IN_RAW_START_INDEX</code></td><td><code>ifm_start_index</code> = <code>0</code></td><td>IFM's AOI already returns only port 1's data, so it starts at index 0.</td></tr>
    <tr><td><code>IOL_PD_OUT_RAW_START_INDEX</code></td><td><code>ifm_start_index</code> = <code>0</code></td><td>Same as above, for the output side.</td></tr>
    <tr><td><code>byteswap</code></td><td><code>byteswap_IFM</code> = <code>1</code></td><td>The IFM master swaps the byte order, so byte swapping <b>must be enabled</b>.</td></tr>
  </tbody>
</table>

> **Keep the order: IFM AOI → `CPS` in → CAPTRON AOI → `CPS` out.** If the input copy runs after the CAPTRON AOI, the touch zones are one scan late. If the output copy runs before it, the display gets the values from the previous scan.

You can use the same pattern with any IO-Link master that delivers `INT` or `DINT` data, or that comes with its own port-parsing AOI. Convert to `SINT` with `CPS`, set the start index to the first byte of the port, and set `byteswap` to whatever that master needs.

---

## Tested IO-Link masters

The AOI was created and tested with the following IO-Link masters:

- **MURR** IMPACT67 Pro E DIO8 IOL8 M12L 5P (54631)
- **IFM** AL1322 (byte swap enabled — see [step 7](#ifm-int-arrays))
- **SICK** SIG300

Other IO-Link masters on EtherNet/IP should work as long as you set the correct start indexes and `byteswap` value for that master.

---

## Reference

- **CANEO series5x IO-Link process data:** [https://docs.captron.com/trms/series5x/io-link-process-data](https://docs.captron.com/trms/series5x/io-link-process-data)
- **CANEO series5x touch zones:** [https://docs.captron.com/trms/series5x/touch-zones](https://docs.captron.com/trms/series5x/touch-zones)

---

## Download: Add-On Instruction {/* #download */}

Download the CAPTRON Add-On Instruction used in this guide. It includes the `CaneoSeries5x_PDIN` and `CaneoSeries5x_PDOUT` data types. Unzip it and import the `.L5X` file as described in [step 1](#import-aoi).

<a href="/downloads/CANEOseries5x_V34_AOI.zip" target="_blank">CANEOseries5x_V34_AOI.zip</a>
