top of page

Codesys Ros2 [PROVEN • 2024]

Integrating CODESYS with ROS 2 allows you to combine the deterministic hardware control of industrial PLCs with the advanced motion planning and perception capabilities of the Robot Operating System. 🚀 Direct Integration Methods

Shared Memory Bridge (Recommended for High Speed): Use the ROBIN project (ScalABLE40/robin) for high-performance data exchange on the same hardware (e.g., Raspberry Pi, Beaglebone).

OPC UA Bridge: Set up an OPC UA Server in CODESYS and use a ROS 2 node as an OPC UA Client with libraries like asyncua (Python) or open62541 (C++). codesys ros2

MQTT Messaging: Use the CODESYS MQTT library to publish PLC variables to a broker and subscribe to them via a ros2_mqtt bridge for non-real-time tasks.

Micro-ROS Agent: For microcontrollers or lightweight PLCs, run a micro-ROS node directly on the target hardware to communicate with the ROS 2 Global Data Space. 🛠️ Strategic Setup: Why use both? Integrating CODESYS with ROS 2 allows you to


5.3 Determinism Impact

Inserting the CODESYS→ROS2 publisher at 1kHz increased the maximum PLC cycle time from 1.02ms to 1.19ms (17% increase). The worst-case occurred during DDS discovery heartbeats (every 3s). Using rclcpp::Publisher::publish() with pre-allocated messages eliminated dynamic memory inside the RT task.

Example Code

Here's an example code snippet in C++ that demonstrates how to integrate a CoDeSys controller with ROS 2: Option C: ROS 2 + EtherCAT (SoEM, IgH)

#include <ros2/ros2.hpp>
#include <industrial_ros2/industrial_ros2.hpp>
int main(int argc, char* argv[]) 
  // Initialize ROS 2
  rclcpp::init(argc, argv);
// Create a ROS 2 node
  auto node = rclcpp::Node::create_node("co_de_sys_node");
// Create a CoDeSys controller object
  industrial_ros2::CoDeSysController controller;
// Configure the CoDeSys controller
  controller.configure("co_de_sys_controller");
// Start the CoDeSys controller
  controller.start();
// Create a ROS 2 publisher
  auto publisher = node->create_publisher<std_msgs::msg::String>("co_de_sys_topic", 10);
// Publish data from the CoDeSys controller
  while (rclcpp::ok()) 
    std_msgs::msg::String msg;
    msg.data = controller.read_data();
    publisher->publish(msg);
// Shutdown ROS 2
  rclcpp::shutdown();
return 0;

Option C: ROS 2 + EtherCAT (SoEM, IgH)

  • Bypass CODESYS entirely and make ROS 2 an EtherCAT master.
  • Pros: Very tight integration (e.g., ros2_control with ethercat_hardware interface).
  • Cons: You lose IEC 61131-3 environment. Hard real-time from Linux only.

The Synergy

By integrating the two, you build a hybrid system:

| Feature | Handled by CODESYS (PLC side) | Handled by ROS 2 (Edge/PC side) | | :--- | :--- | :--- | | Real-time control | Servo drives, hydraulic valves, temperature loops (<1ms) | High-level trajectory following (>10ms) | | Safety | Safety-rated PLC (ISO 13849) | Monitoring, but not SIL-rated logic | | I/O Handling | 24V digital, 4-20mA analog, EtherCAT slaves | Cameras, LiDARs, 3D sensors, microphones | | Algorithms | PID, motion control (CNC/Robotics) | SLAM, A*, MoveIt motion planning, YOLO vision | | Communication | Modbus TCP, Profinet, OPC UA | DDS (Fast-DDS, CycloneDDS), MQTT, WebSockets | | Deployment | Flash to non-volatile PLC memory | Docker containers, Kubernetes, snap packages |

Step 2: Write CODESYS PLC Logic

In your CODESYS project:

  1. Add the ROS2 Core and ROS2 std_msgs libraries.
  2. Declare variables:
    PROGRAM Main
    VAR
        ros2_core : ROS2_CORE;
        sub_cmd_vel : ROS2_SUBSCRIBE;
        twist_msg : geometry_msgs__Twist;
        motor_speed_left : REAL;
        motor_speed_right : REAL;
    END_VAR
    
  3. In the PLC cycle:
    • Call ros2_core() to initialize the DDS node (once).
    • Call sub_cmd_vel(Execute:=TRUE, TopicName:= "/cmd_vel", Message:= twist_msg)
    • Map twist_msg.linear.x (forward speed) and twist_msg.angular.z (rotation) to your motor outputs.

1. One‑Click ROS 2 Interface Generation

  • In CODESYS, right‑click any global variable or POU (Program Organization Unit) and select “Publish to ROS 2 Topic” or “Subscribe to ROS 2 Topic”.
  • Automatically generates required ROS 2 .msg definitions (including complex data types like arrays, structs, enums).
  • Supports ROS 2 QoS settings (reliability, durability, history) configurable per variable.

Email us:

Find us:

2825 50th Street, Sacramento, CA  95817

© 2026 Cameron Vault

Proudly created with Wix.com

bottom of page