Codesys Ros2 |best| Jun 2026
CODESYS and ROS 2 Integration: Bridging Industrial Automation and Advanced Robotics
FUNCTION_BLOCK FB_ROS2_Publisher VAR_INPUT execute : BOOL; topic_name : STRING(64); qos_depth : INT := 10; data : VARIANT; // Points to PLC memory END_VAR VAR_OUTPUT busy : BOOL; error : BOOL; error_id : DWORD; END_VAR
While highly effective, bridging these two systems presents unique challenges:
Lightweight, incredibly fast, easy to implement for basic data exchange. codesys ros2
Bridging the Industrial-Robotic Divide: CODESYS and ROS2 Integration
ROS 2 is the industry standard for robot development, featuring a distributed architecture built on the Data Distribution Service (DDS) that enhances its fault tolerance and real-time performance.
Bridging Industrial Automation and Robotics: The Ultimate Guide to CODESYS and ROS2 Integration CODESYS, which has a built‑in CANopen protocol stack,
For systems that already use CAN‑based fieldbuses, the ros_canopen package provides a ROS 2 interface to CANopen devices. CODESYS, which has a built‑in CANopen protocol stack, can be configured as a CANopen master. The two systems then communicate directly over the CAN bus. This method avoids any additional middleware but requires careful configuration of PDO mapping and node IDs.
Integrating CODESYS with ROS 2 allows you to use high-level robotics algorithms (Navigation, SLAM, Computer Vision) running in ROS 2 nodes while maintaining hard real-time control of motors and sensors using IEC 61131-3 logic in CODESYS.
3. Implementing the CODESYS ROS2 Bridge: A Step-by-Step Overview Integrating CODESYS with ROS 2 allows you to
import rclpy from rclpy.node import Node from std_msgs.msg import Float64 from asyncua import Client import asyncio class CodesysBridge(Node): def __init__(self): super().__init__('codesys_bridge') self.publisher_ = self.create_publisher(Float64, 'plc_sensor_data', 10) self.loop = asyncio.get_event_loop() self.loop.create_task(self.connect_to_plc()) async join connect_to_plc(self): url = "opc.tcp:// :4840" async with Client(url=url) as client: self.get_logger().info(f"Connected to CODESYS OPC UA at url") # Locate the node ID based on your CODESYS Symbol Configuration path var_node = await client.nodes.root.get_child(["0:Objects", "2:Device", "4:PLC Logic", "4:Application", "4:PLC_PRG", "4:lrSensorValue"]) while rclpy.ok(): value = await var_node.read_value() msg = Float64() msg.data = float(value) self.publisher_.publish(msg) await asyncio.sleep(0.05) # 20 Hz sample rate def main(args=None): rclpy.init(args=args) node = CodesysBridge() try: asyncio.run(node.loop.run_forever()) except KeyboardInterrupt: pass finally: node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() Use code with caution. Step 4: Run and Verify
// Example Data rVelocity : REAL := 0.0; rPosition : REAL := 0.0;