UnderAutomation
질문이요?

[email protected]

문의하기
UnderAutomation
⌘Q
Universal Robots SDK documentation
Reading & Writing Global Variables
Documentation home

Reading & Writing Registers

Learn how to use Boolean, Float, and Integer registers on UR Cobots to communicate with Fieldbus or RTDE systems. Includes code examples, usage tips, and interface methods like Primary Interface and RTDE.

🚀 Introduction

Let’s dive into how you can use registers to communicate with external systems like Fieldbus or RTDE clients — it's simpler than it sounds, promise! 😉


🧠 What Are Registers?

UR Cobots offer access to several types of registers you can use to send and receive data between your robot and external systems. Think of them as little data mailboxes 📬 with three types of content:

  • Boolean: true or false
  • Float: 32-bit floating-point numbers
  • Integer: 32-bit signed integers

Each data type comes in two flavors:

  • Input Registers: Read-only 🔍 — used to receive data from external systems like Fieldbus or RTDE.
  • Output Registers: Read/write ✍️ — used to send data to those systems.

⚠️ Note: You can only write to output registers using script. Input registers are strictly read-only from scripts!

🔍 Reading Registers with URScript

Data TypeFunctionAddress RangeNotes
Boolean (Input)read_input_boolean_register(address: int) -> bool0–1270–63: Fieldbus/PLC
64–127: RTDE
Boolean (Output)read_output_boolean_register(address: int) -> bool0–127Same ranges as input
Float (Input)read_input_float_register(address: int) -> float0–470–23: Fieldbus/PLC
24–47: RTDE
Float (Output)read_output_float_register(address: int) -> float0–47Same ranges as input
Integer (Input)read_input_integer_register(address: int) -> int0–470–23: Fieldbus/PLC
24–47: RTDE
Range: [-2,147,483,648, 2,147,483,647]
Integer (Output)read_output_integer_register(address: int) -> int0–47Same as above

✍️ Writing Registers with URScript

Data TypeFunctionAddress RangeValue
Boolean (Output)write_output_boolean_register(address: int, value: bool)0–127True / False
Float (Output)write_output_float_register(address: int, value: float)0–4732-bit float (e.g. 1.5)
Integer (Output)write_output_integer_register(address: int, value: int)0–47Signed 32-bit int

🧪 Handling Registers with the Primary Interface

✍️ Writing Output Registers

The Primary Interface allows remote script execution with two key behaviors:

  • If you send a raw script line, it will stop the current program and execute your line. ⛔➡️▶️
  • If the script is sent within a secondary program (a sec block), it will run in parallel without stopping the main program. 🧵✨

Example: Writing the float register 0 with the value 1.5:

using UnderAutomation.UniversalRobots;
class PrimaryInterfaceWriteRegisters
{
static void Main(string[] args)
{
var robot = new UR();
robot.Connect("192.168.0.1");
/**/
// Pause main program and execute script
robot.PrimaryInterface.Script.Send("write_output_float_register(0, 1.5)");
// Send Secondary program that does not stop the main program
robot.PrimaryInterface.Script.Send(@"
sec secondaryProgram():
write_output_float_register(0, 1.5)
end
");
/**/
}
}

🕵️ Reading Registers

Technically, you can read registers via the Primary Interface... but it's a bit tricky 😅.

You’d need to execute something like:

global myRegister0 = read_input_float_register(0)

Then read myRegister0 via Primary Interface functions. The catch? You can’t write to a global variable from a secondary program. So this requires stopping the current program, which isn't ideal.

🚫 Not recommended — use RTDE instead for smoother operation.


⚡ Handling Registers with RTDE

RTDE (Real-Time Data Exchange) is the go-to method for reading and writing registers up to 500Hz 🔥⚡

To use it:

  • Set up registers when configuring the RTDE connection
  • Use OutputSetup for the data you want to read 📤
  • Use InputSetup for the data you want to write 📥

💡 Boolean trick: Booleans from 0–63 are accessed via two 32-bit unsigned integer packets. From 64–127, access them bit-by-bit.

✍️ Writing Input Registers

Only input-type registers (bool, int, float) can be written via RTDE. To write output-type registers, use Primary Interface. Here’s an example:

using UnderAutomation.UniversalRobots;
using UnderAutomation.UniversalRobots.Common;
using UnderAutomation.UniversalRobots.Rtde;
using UnderAutomation.UniversalRobots.Rtde.Internal;
class RtdeWriteRegisters
{
static void Main()
{
/**/
var robot = new UR();
var param = new ConnectParameters("192.168.0.1");
// Enable RTDE
param.Rtde.Enable = true;
// Exchange data at 500Hz
param.Rtde.Frequency = 500;
// Select data you want to write in robot controller
param.Rtde.InputSetup.Add(RtdeInputData.InputBtRegisters0To31);
param.Rtde.InputSetup.Add(RtdeInputData.InputBtRegisters32To63);
param.Rtde.InputSetup.Add(RtdeInputData.InputBitRegisters,64);
param.Rtde.InputSetup.Add(RtdeInputData.InputIntRegisters, 0);
param.Rtde.InputSetup.Add(RtdeInputData.InputDoubleRegisters, 0);
// Connect to robot
robot.Connect(param);
//...
// Write input values in robot
var inputValues = new RtdeInputValues();
inputValues.InputBtRegisters0To31 = 0xff;
inputValues.InputBtRegisters32To63 = 0xCA;
inputValues.InputBitRegisters.X64 = true;
inputValues.InputIntRegisters.X0 = 2;
inputValues.InputDoubleRegisters.X0 = 3.14;
robot.Rtde.WriteInputs(inputValues);
}
}

🔍 Reading Registers

All registers are available for reading! Here’s how you can do it:

using UnderAutomation.UniversalRobots;
using UnderAutomation.UniversalRobots.Rtde;
class RtdeReadRegisters
{
static void Main()
{
/**/
var robot = new UR();
var param = new ConnectParameters("192.168.0.1");
// Enable RTDE
param.Rtde.Enable = true;
// Exchange data at 500Hz
param.Rtde.Frequency = 500;
// Select data you want the robot to send
// Read input registers
param.Rtde.OutputSetup.Add(RtdeOutputData.InputBitRegisters0To31); // 32 bits integer
param.Rtde.OutputSetup.Add(RtdeOutputData.InputBitRegisters32To63);// 32 bits integer
param.Rtde.OutputSetup.Add(RtdeOutputData.InputBitRegisters, 64); // one by one access of registers 64-127 from FW 3.9.0 / 5.3.0
param.Rtde.OutputSetup.Add(RtdeOutputData.InputDoubleRegisters, 0); // floating point
param.Rtde.OutputSetup.Add(RtdeOutputData.InputIntRegisters, 0); // integer
// Read output registers
param.Rtde.OutputSetup.Add(RtdeOutputData.OutputBitRegisters0To31);
param.Rtde.OutputSetup.Add(RtdeOutputData.OutputBitRegisters32To63);
param.Rtde.OutputSetup.Add(RtdeOutputData.OutputBitRegisters, 64);
param.Rtde.OutputSetup.Add(RtdeOutputData.OutputDoubleRegisters, 0);
param.Rtde.OutputSetup.Add(RtdeOutputData.OutputIntRegisters, 0);
// Connect to robot
robot.Connect(param);
// Be notified at 500Hz when data is received
robot.Rtde.OutputDataReceived += Rtde_OutputDataReceived;
/**/
}
/**/
private static void Rtde_OutputDataReceived(object sender, RtdeDataPackageEventArgs e)
{
// Read input registers
bool bit0 = e.OutputDataValues.InputBitRegisters.X64;
uint bit0To31 = e.OutputDataValues.InputBitRegisters0To31;
uint bit32To63 = e.OutputDataValues.InputBitRegisters32To63;
int int0 = e.OutputDataValues.InputIntRegisters.X0;
double double0 = e.OutputDataValues.InputDoubleRegisters.X0;
// Read output registers
bool outputBit0 = e.OutputDataValues.OutputBitRegisters.X64;
uint outputBit0To31 = e.OutputDataValues.OutputBitRegisters0To31;
uint outputBit32To63 = e.OutputDataValues.OutputBitRegisters32To63;
int outputInt0 = e.OutputDataValues.OutputIntRegisters.X0;
double outputDouble0 = e.OutputDataValues.OutputDoubleRegisters.X0;
}
/**/
}

Universal Robots, Fanuc, Yaskawa 또는 Staubli 로봇을 .NET, Python, LabVIEW 또는 Matlab 애플리케이션에 쉽게 통합

UnderAutomation
문의하기가격 • 대리점견적 • 주문Legal

© All rights reserved.