Universal Robots Forum

Accessing General Purpose I/O from Java

In my latest project I wanted to access the general purpose integer register, specifically read a few values. I know how to do that in URScript, but I wanted to have them available in Java, to use them while putting together some strings.

Anyway, I am a bit confused by this. In the API Reference, I found the IO Interface, which has the IntegerRegister subinterface. I figured out how to get the Collection of all my IntegerRegisters, and I’m able to iterate through them and get their names (all the registers I want to use have names assigned to them in the Installation), check whether they are resolvable, and so on.

However, I cannot get their values.
The API Reference for the IO Interface lists a mehtod:

String getValueStr()
Returns: get current reading of the I/O as a string.

The IntegerRegister Interface is a Subinterface of the IO Interface, and the API Reference says it inherits this method from its Superinterface. The compiler is perfectly fine with me calling this method as well. The only problem is, it always returns an empty string.
I have a robot, with software version 5.6, connected to a PLC, and they exchange some data over Profinet - I know the Fieldbus is working, because I can get all the values via URScript. When I run my URCap, however, the getValueStr() method always returns an empty string.

I would like to know if this is me, misinterpreting what the API Reference says, or maybe a mistake in the Reference, or maybe I’m doing something wrong in my code (I’ll list it below). The latter of which I would find very surprising, given the fact that the other inherited methods - getName(), isResolvable() - work fine.

Here’s my code:

public String getIntRegisterValue(String regName) {
	Collection<IntegerRegister> intRegisters = ioModel.getIOs(IntegerRegister.class);
	Iterator<IntegerRegister> itr = intRegisters.iterator();
	String ret = "";
	while (itr.hasNext()) {
		if (regName.equals(itr.next().getName())) {
			ret = itr.next().getValueStr();
			if (ret == null) {
				return "NULL";
			} else if (ret == "") {
				return "EMPTY";
			} else {
				return ret;
	// if the register is not found
	return "NO_READ";

Whichever integer register I try, the function returns “EMPTY”.
I have also read somewhere else on the forum that people access these registers via the RTDE server, and while there are plenty hacks like this, it just looks janky, and the issue really should have an elegant, easy solution implemented in the SDK (especially that the method is right there, listed in black and white).