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

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

This guide walks through integrating a **CANEO series4x** button with an **Allen-Bradley** ControlLogix or CompactLogix controller in **Studio 5000 Logix Designer**. By the end you'll be reading the button's state from ladder logic and writing LED scenes, colors, numbers, and display text to it — all through a 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 series4x fields — the actuation count, the displayed number, and the active LEDs — 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 series4x** is wired to an IO-Link port on the master (this example uses **port 2**).
- You have downloaded **`CANEOseries4x_V34_AOI.zip`** and unzipped it to get the two AOI files (see [Download](#download) at the end of this guide).
- You have the CANEO series4x **process data layout** handy for the meaning of each value: [series4x Process Data](/trms/series4x/process-data).

### Choose the LED control mode

The series4x only uses the output process data you send it if the button is set to accept it. This is the IO-Link parameter **LED Control Mode**, which you'll find in the IODD under **LEDs → LED Control Mode**:

<table>
  <thead>
    <tr>
      <th>LED Control Mode</th>
      <th>What the button shows</th>
      <th>AOI to use</th>
    </tr>
  </thead>
  <tbody>
    <tr><td><code>Automatic Scene selection</code></td><td>Scenes are selected by the button's own triggers. The output process data is <b>unused</b>.</td><td>—</td></tr>
    <tr><td><code>Scene controlled by IO-Link Process Data</code></td><td>The LED ring and display show one of the eight scenes configured in the IODD. You pick the scene, and optionally the number or text, from the PLC.</td><td><code>AOI_CANEOseries4x_Scene_Control_v34</code></td></tr>
    <tr><td><code>Advanced control by IO-Link Process Data</code></td><td>The PLC sets everything directly: which LEDs are on, their RGB color, effect, brightness, and each display digit.</td><td><code>AOI_CANEOseries4x_Advanced_Control_V34</code></td></tr>
  </tbody>
</table>

Scene control covers most applications. Use Advanced control when eight scenes aren't enough — for example to light individual LEDs or build a scrolling text. For details on each mode, see [series4x LED (and Display) Control](/trms/series4x/led-control).

> **Pick one AOI per button.** The two AOIs share the same input structure, but their output structures are different and match only their own LED Control Mode. Set the LED Control Mode on the button first, then use the matching AOI.

---

## 1. Import the Add-On Instructions {/* #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/caneo40-ab-aoi-image1.png)

Browse to the unzipped files and import **`CANEOseries4x_Scene_Control_v34_AOI.L5X`**, **`CANEOseries4x_Advanced_Control_V34_AOI.L5X`**, or both. Confirm the import dialog that follows.

![Import Add-On Instruction dialog showing the CANEO series4x AOI files](./images/caneo40-ab-aoi-image2.png)

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

- **`CANEOseries4x_PDIN`** — the process data coming *from* the button. Used by both AOIs.
- **`CANEOseries4x_PDOUT_Scene_Controlled`** — the process data going *to* the button in Scene control mode.
- **`CANEOseries4x_PDOUT_Advanced_Control`** — the process data going *to* the button in Advanced control mode.

---

## 2. AOI parameters

Open the AOI definition and switch to the **Parameters** tab to see what the instruction expects. Both AOIs have the same parameters — only the data type of `IOL_PD_OUT` differs.

![Add-On Instruction Definition showing the AOI_CANEOseries4x_Advanced_Control_V34 parameters](./images/caneo40-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>CANEOseries4x_PDIN</code></td><td>Structure the AOI fills with the CANEO series4x input process data. <b>Read</b> the button's state from here. See <a href="#iol-pd-in">Reading the button</a>.</td></tr>
    <tr><td><code>IOL_PD_OUT</code></td><td><code>CANEOseries4x_PDOUT_Scene_Controlled</code> or <code>CANEOseries4x_PDOUT_Advanced_Control</code></td><td>Structure you <b>write</b> to. The AOI packs it into the output process data. See <a href="#iol-pd-out-scene">Scene control</a> and <a href="#iol-pd-out-advanced">Advanced control</a>.</td></tr>
    <tr><td><code>IOL_PD_IN_RAW</code></td><td><code>SINT[16]</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 series4x 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 series4x 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 display digits appear in swapped pairs, or values like the actuation count look wrong, set `byteswap` to `1`.

---

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

Open your routine (here **MainProgram → series4x**) and add the AOI that matches your LED Control Mode to a rung — you'll find both in the **Toolbox** under **Add-On**. Every operand starts as a question mark.

![AOI_CANEOseries4x_Scene_Control_v34 placed on rung 0 with all operands unassigned](./images/caneo40-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 the AOI's type (e.g. `AOI_port2_MURR`). Use one instance per button.
2. **`IOL_PD_IN`** — create a new tag of type `CANEOseries4x_PDIN` (e.g. `CD40_PDIN_port2`).
3. **`IOL_PD_OUT`** — create a new tag of the matching output type (e.g. `CD40_PDOUT_port2` of type `CANEOseries4x_PDOUT_Scene_Controlled`).
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 series4x 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` — see [Using integer arrays](#int-arrays).
6. **`byteswap`** — `0` or `1`, depending on your master (see above).

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

![AOI configured for a MURR 54631 IO-Link master, port 2](./images/caneo40-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_port2_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>CD40_PDIN_port2</code></td><td>Named after the part number (CD40), the type of process data, and the port.</td></tr>
    <tr><td><code>IOL_PD_OUT</code></td><td><code>CD40_PDOUT_port2</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>90</code></td><td>First input byte of port 2 in the MURR input array.</td></tr>
    <tr><td><code>IOL_PD_OUT_RAW_START_INDEX</code></td><td><code>66</code></td><td>First output byte of port 2 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 2's data begins inside it. To connect a button 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 button {/* #iol-pd-in */}

`CANEOseries4x_PDIN` is the same for both AOIs. It holds the button's actuation state, its pin states, and its sensor readings.

![CD40_PDIN_port2 expanded showing the process data input members](./images/caneo40-ab-aoi-image6.png)

<table>
  <thead>
    <tr>
      <th>Member</th>
      <th>Data type</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr><td><code>Surronding_Brightness</code></td><td><code>SINT</code></td><td>Ambient brightness measured by the button's light sensor, in percent (<code>0</code>…<code>100</code>).</td></tr>
    <tr><td><code>Actuation_Strength</code></td><td><code>SINT</code></td><td>Damping of the sensor, in percent (<code>0</code>…<code>100</code>).</td></tr>
    <tr><td><code>Actuation_Count</code></td><td><code>INT</code></td><td>Number of actuations since the button was powered on. Resets on restart and after <code>65535</code>.</td></tr>
    <tr><td><code>Actuation_Flag</code></td><td><code>SINT</code></td><td>Sensor actuation state: <code>0</code> = idle, <code>1</code> = actuated.</td></tr>
    <tr><td><code>Pin_5</code></td><td><code>SINT</code></td><td>Input 2 (E2) pin state: <code>4</code> = input off, <code>5</code> = input on, <code>8</code> = pin unused.</td></tr>
    <tr><td><code>Pin_4</code></td><td><code>BOOL</code></td><td>OUT pin state: <code>0</code> = output off, <code>1</code> = output on.</td></tr>
    <tr><td><code>Pin_2</code></td><td><code>SINT</code></td><td>Input 1 (E1) pin state: <code>4</code> = input off, <code>5</code> = input on, <code>8</code> = pin unused.</td></tr>
  </tbody>
</table>

> **`Actuation_Count` above 32767 shows as negative.** The button counts up to `65535`, but `INT` in Logix is signed. Past `32767` the tag rolls over to negative values. If you need the full range, copy it into a `DINT` and add `65536` when it's negative.

For the full input layout, see [series4x Process Data](/trms/series4x/process-data).

---

## 5. `IOL_PD_OUT` — Scene control mode {/* #iol-pd-out-scene */}

Use `CANEOseries4x_PDOUT_Scene_Controlled` with **`AOI_CANEOseries4x_Scene_Control_v34`** when the LED Control Mode is `Scene controlled by IO-Link Process Data`.

![CD40_PDOUT_port2 expanded showing the Scene control output members](./images/caneo40-ab-aoi-image7.png)

<table>
  <thead>
    <tr>
      <th>Member</th>
      <th>Data type</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr><td><code>Text</code></td><td><code>STRING</code></td><td>Text shown on the 4-digit, 7-segment display — up to 4 characters. Shown when <code>Display_Mode</code> = <code>2</code>.</td></tr>
    <tr><td><code>Displayed_Number</code></td><td><code>INT</code></td><td>Number shown on the display, <code>0</code>…<code>9999</code>. Shown when <code>Display_Mode</code> = <code>1</code>.</td></tr>
    <tr><td><code>Display_Mode</code></td><td><code>SINT</code></td><td>What the display shows: <code>0</code> = the text defined in the active scene (IODD), <code>1</code> = the number from <code>Displayed_Number</code>, <code>2</code> = the characters from <code>Text</code>.</td></tr>
    <tr><td><code>LED_Scene</code></td><td><code>SINT</code></td><td>Active LED scene, <code>0</code>…<code>7</code>. Write <code>-1</code> (<code>255</code>) to let the button select the scene from its actuation and input pins instead.</td></tr>
  </tbody>
</table>

The scenes themselves — color, effect, and display text for each of the eight — are configured in the IODD. See [series4x LED Scenes](/trms/series4x/led-scenes).

> **Display fields apply to Display variants only.** On a series4x without a display, `Text`, `Displayed_Number`, and `Display_Mode` have no effect.

---

## 6. `IOL_PD_OUT` — Advanced control mode {/* #iol-pd-out-advanced */}

Use `CANEOseries4x_PDOUT_Advanced_Control` with **`AOI_CANEOseries4x_Advanced_Control_V34`** when the LED Control Mode is `Advanced control by IO-Link Process Data`.

![CD40_PDOUT_port2_ADVANCED expanded showing the Advanced control output members](./images/caneo40-ab-aoi-image8.png)

<table>
  <thead>
    <tr>
      <th>Member</th>
      <th>Data type</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr><td><code>Display_Brightness</code></td><td><code>SINT</code></td><td>Brightness of the 7-segment display in percent (<code>0</code>…<code>100</code>). Write <code>-1</code> (<code>255</code>) for automatic brightness.</td></tr>
    <tr><td><code>Display_Digit_4</code></td><td><code>SINT</code></td><td>Character for digit 4, as an ASCII code.</td></tr>
    <tr><td><code>Display_Digit_3</code></td><td><code>SINT</code></td><td>Character for digit 3, as an ASCII code.</td></tr>
    <tr><td><code>Display_Digit_2</code></td><td><code>SINT</code></td><td>Character for digit 2, as an ASCII code.</td></tr>
    <tr><td><code>Display_Digit_1</code></td><td><code>SINT</code></td><td>Character for digit 1, as an ASCII code.</td></tr>
    <tr><td><code>Effect_Frequency</code></td><td><code>SINT</code></td><td>Frequency of the LED effect in 1/10 Hz, <code>1</code>…<code>60</code> (0.1…6 Hz). <code>0</code> = default frequency.</td></tr>
    <tr><td><code>LED_Effect</code></td><td><code>SINT</code></td><td>LED effect number. See the <a href="/trms/series4x/led-scenes#led-effects">LED Effects reference</a>.</td></tr>
    <tr><td><code>LED_Color_B</code></td><td><code>SINT</code></td><td>Blue component of the LED color, <code>0</code>…<code>255</code>.</td></tr>
    <tr><td><code>LED_Color_G</code></td><td><code>SINT</code></td><td>Green component of the LED color, <code>0</code>…<code>255</code>.</td></tr>
    <tr><td><code>LED_Color_R</code></td><td><code>SINT</code></td><td>Red component of the LED color, <code>0</code>…<code>255</code>.</td></tr>
    <tr><td><code>LED_Brightness</code></td><td><code>SINT</code></td><td>Brightness of the LED ring in percent (<code>0</code>…<code>100</code>). Write <code>-1</code> (<code>255</code>) for automatic brightness.</td></tr>
    <tr><td><code>Active_Leds</code></td><td><code>INT</code></td><td>Bitmask of the LEDs that are on. Bit 0 = LED 1 (top left), increasing clockwise. A <code>1</code> bit turns that LED on; <code>-1</code> turns all 16 on.</td></tr>
  </tbody>
</table>

> **Values above 127 are written as negatives.** `SINT` in Logix is signed (`-128`…`127`), but most of these fields take `0`…`255`. To send a value above 127, write it minus 256 — for example `-1` for `255` (full color or automatic brightness) or `-128` for `128`. The same applies to `Active_Leds`: `-1` sets all 16 bits.

> **The display digits take ASCII codes, not characters.** Write the number of the character, not the character itself — for example `65` for `A`, `48` for `0`, or `64` for `@`. The full list of characters the 7-segment display can show, and how to build custom segment patterns, is in [series4x Display Content](/trms/series4x/display-content).

---

## 7. Usage example — Scene control {/* #usage-scene */}

The ladder logic below switches LED scenes based on the button's OUT pin and shows a number on the display.

![Ladder logic switching LED scenes on Pin_4 and writing a number to the display](./images/caneo40-ab-aoi-image9.png)

- **Rung 0** — calls `AOI_CANEOseries4x_Scene_Control_v34`. It must be scanned on every cycle, so leave it unconditional.
- **Rung 1** — while the OUT pin is **off** (`XIO CD40_PDIN_port2.Pin_4`), `MOVE 1` into `LED_Scene` — scene 1 is active.
- **Rung 2** — while the OUT pin is **on** (`XIC CD40_PDIN_port2.Pin_4`), `MOVE 2` into `LED_Scene` — scene 2 is active.
- **Rung 3** — sets `Display_Mode` to `1` (show the number) and `Displayed_Number` to `123`.

To show text instead, set `Display_Mode` to `2` and write up to 4 characters to `Text`.

---

## 8. Usage example — Advanced control {/* #usage-advanced */}

The ladder logic below lights the whole LED ring green, turns it red while the OUT pin is on, and writes `AAAA` to the display.

![Ladder logic setting LED colors on Pin_4 and writing ASCII codes to the display digits](./images/caneo40-ab-aoi-image10.png)

- **Rung 0** — calls `AOI_CANEOseries4x_Advanced_Control_V34` with its own output tag, `CD40_PDOUT_port2_ADVANCED`. Leave it unconditional.
- **Rung 1** — sets `Display_Brightness` to `100`, `Active_Leds` to `-1` (all 16 LEDs on), and `LED_Brightness` to `100`.
- **Rung 2** — while the OUT pin is **on** (`XIC CD40_PDIN_port2.Pin_4`), sets `LED_Color_G` to `0` and `LED_Color_R` to `-1` (`255`) — the ring is red.
- **Rung 3** — while the OUT pin is **off** (`XIO CD40_PDIN_port2.Pin_4`), sets `LED_Color_R` to `0` and `LED_Color_G` to `-1` (`255`) — the ring is green.
- **Rung 4** — writes `65` (the ASCII code for `A`) to `Display_Digit_1` through `Display_Digit_4`, so the display shows `AAAA`.

To blink or animate the ring, write an effect number to `LED_Effect` and a speed to `Effect_Frequency`.

---

## 9. Using integer arrays and an IO-Link master AOI {/* #int-arrays */}

Some IO-Link masters, such as the **IFM AL1322**, import their data as an **`INT` array** instead of a `SINT` array, and some come with their own AOI that pulls one port's data into a separate array. The CANEO series4x AOIs expect `SINT` arrays, so convert with a **`CPS`** instruction on the way in and back on the way out:

1. The master manufacturer's AOI (if any) extracts the port's data into its own array.
2. **`CPS`** copies the input array into a `SINT` array for `IOL_PD_IN_RAW`.
3. The CANEO series4x AOI runs, with both start indexes set to `0` because the arrays already hold only that port's data.
4. **`CPS`** copies the `SINT` array from `IOL_PD_OUT_RAW` back into the master's output array.

Set `byteswap` to `1` for masters that swap bytes, such as IFM. For a full walkthrough with screenshots, see step 7 of the [CANEO series5x + Allen-Bradley guide](./CaneoSeries5x-allen-bradley-aoi.md#ifm-int-arrays). The same steps apply to the series4x.

---

## Tested IO-Link masters

The AOIs were 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 9](#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 series4x Process Data:** [series4x Process Data](/trms/series4x/process-data)
- **CANEO series4x LED (and Display) Control:** [series4x LED Control](/trms/series4x/led-control)
- **CANEO series4x LED Scenes and Effects:** [series4x LED Scenes](/trms/series4x/led-scenes)
- **CANEO series4x Display Content:** [series4x Display Content](/trms/series4x/display-content)

---

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

Download the CAPTRON Add-On Instructions used in this guide. The zip contains both AOIs — `CANEOseries4x_Scene_Control_v34_AOI.L5X` and `CANEOseries4x_Advanced_Control_V34_AOI.L5X` — and each one includes its data types. Unzip it and import the `.L5X` file you need as described in [step 1](#import-aoi).

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