Advanced Motors, Sensors and Third Party Hardware
Advanced Motors, Sensors and Third Party Hardware

Motor interfaces

leJOS supports a variety of motors, including the NXT motors, RCX motors, PF motors, and a variety of servos. It supports them directly attached to a NXT motor port, or connected by a multiplexer, or via RCX or PF converter cables, or connected to a remote NXT via Bluetooth or RS485, or connected to a remote RCX via an infrared link.

To help classify the types of motor, there are a set of motor interfaces in the lejos.robotics packages. These interfaces allow you to write programs that are essentially independent of the specific type of motor used and the way it is connected. It is only the constructor for the a specific motor and its connection that needs to change to use another type of motor or connection.


The simplest interface that all motors implement is BaseMotor. It supports the methods:

  • public void forward()
  • public void backward()
  • public boolean isMoving()
  • public void flt()
  • public void stop()

All leJOS NXJ motors implement this interface. However, servo motors are not currently supported as they do not normally support these methods.


The DCMotor interface extends BaseMotor and adds methods for setting the power and getting the current power setting. It is used for unregulated motors.

  • public void setPower(int power)
  • public int getPower()

Unregulated motors without encoders, such as the RCX motor, support this interface.


Some motors, such as the NXT motors, have built in encoders. The Encoder interfaces defines the methods that these support.

  • public int getTachoCount();
  • public void resetTachoCount();

The EncoderMotor interface extends DCMotor and Encoder and adds no new methods. It is used for unregulated motors with encoders. The NXTMotor class implements this interface.


Tachometers are more sophisticated encoders that not only give a tachometer count, but also continuously monitor the tachometer readings to give a rotation speed. They are implemented in software for NXT motors. The tachometer interface extends Encoder and adds:

  • public int getRotationSpeed();

The RegulatedMotor interface is used for motors that implement speed regulation and stopping at a defined encoder count, such as the NXTRegulatedMotor class that implements the interface for NXT motors.

The RegulatedMotor interface extends BaseMotor and Tachometer and adds the following methods:

  • public void addListener(RegulatedMotorListener listener);
  • public int getLimitAngle(;)
  • public float getMaxSpeed();
  • public int getSpeed();
  • public boolean isStalled();
  • public void rotate(int angle);
  • public void rotate(int angle, boolean immediateReturn);
  • public void rotateTo(int limitAngle);
  • public void rotateTo(int limitAngle, boolean immediateReturn);
  • public void setAcceleration(int acceleration);
  • public void setSpeed(int speed);
  • public void stop(boolean immediateReturn);
  • public void waitComplete();

NXTRegulatedMotor (which is the class of Motor.A, Motor.B, and Motor.C) support this interface. RemoteMotor also supports it but with some restrictions.


Regulated motors must generate events when the motor starts and stops. Classes that listen for these events implement the RegulatedMotorListener interface, which has the methods:

  • public void rotationStarted(RegulatedMotor motor, int tachoCount, boolean stalled, long timeStamp);
  • public void rotationStopped(RegulatedMotor motor, int tachoCount, boolean stalled, long timeStamp);

DifferentialPilot is an example of a class that supports this interface.

Back to top

Unregulated Motor classes


As well as the interface defined above, leJOS has an abstract motor class that simplify the implementation of the unregulated motor classes.

BasicMotor is an abstract class which implements the DCMotor interface, and provide methods common to all implementations of unregulated motors.


NXTMotor is a very simple implementation of an unregulated motor for NXT motors. It extends BasicMotor and implements the Encoder interface method, and therefore implements the EncoderMotor interface.

It is used for applications such as Segway robots that need to directly control the power supplied to the NXT motors, and do not need speed regulation or rotation to a limit point.

To use an NXTMotor you create an instance of the NXTMotor class using one of the constructors:

  • public NXTMotor(TachoMotorPort port);
  • public NXTMotor(TachoMotorPort port, int PWMMode);


NXTMotor m1 = new NXTMotor(MotorPort.A);

The RCX motors do not have an in-built tachometer and so cannot support the advanced functions of the NXT motors such as the rotate and rotateTo methods and the speed regulation.

A simpler class is used to support the RCX motors. It has similar methods to the Motor class in the RCX version of leJOS (which are the same as those supported by the BasicMotor class).

To use an RCX motor you create an instance of the RCXMotor class using the constructor:

  • public RCXMotor(BasicMotorPort port)


RCXMotor rcxMotor = new RCXMotor(MotorPort.A);

You can use RCX Motors with leJOS NXJ by connecting them with the conversion cables that can be purchased from LEGO (and are bundled with the LEGO MINDSTORMS NXT educational kits). You can also use the RCXMotor class to control RCX motors connected to a remote RCX - see the "Communications" tutorial.

RCXMotor extends BasicMotor and therefore implements the DCMotor interface.

RCX motors can be connected to a sensor port via the RCXMotorMultiplxer device. This allows up to 4 RCX motors to be connected and thus entends the number of motors that a NXT can support.

RCX Motors can be attached to RCX bricks and controlled remotely via the Mindsensors NRLink device using the RCXRemoteMotorPort class.

Back to top

Regulated motor classes

The NXTRegulatedMotor class controls the NXT motors, and is described in Controlling the Motors. It implements speed regulation and rotation by a specified number of degrees. Motor.A, Motor.B and Motor.C are instances of NXTRegulatedMotor.

RemoteMotor also implements the RegulatedMotor class but with restrictions. It sends LCP commands to a remote NXT, which uses an instance of NXTRegulatedMotor to implement them. RemoteMotor is available on the NXT and on the PC (via the pccomms API). On the PC, Motor.A, Motor.B and Motor.C are instances of RemoteMotor.

On the NXT, RemoteMotor can be used to control motors on another NXT either over Bluetooth, or using RS485, by connecting port 4 of the two NXTs via a NXT cable. RS485 has lower latency than Bluetooth, so the motors will be more responsive over RS485.

Back to top

MotorPort classes

To use the NXT motors it is not necessary to explicitly use the MotorPort class: you can just use the variables Motor.A, Motor.B and Motor.C. So if you are only using NXT motors, you can skip this section.

However it is useful to understand how motor ports work as they are used by:

  • The NXTRegulatedMotor class
  • The RCXMotor class
  • The RemoteNXT class
  • The RCXMotorMultiplexer class
  • Remote RCX motors accessed via the RCXLink class

There is a hierarchy of interfaces defined for motor ports:

  • BasicMotorPort
  • Tachometer
  • TachoMotorPort

All motor ports support the BasicMotorPort interface which allows control of a motors power and mode (forward, backward, stop, float).

Ports that supports this include:

  • NXT ports connected to NXT motors
  • NXT ports connected via the RCX conversion cable to RCX motors
  • Ports on the RCXMotorMultiplexer adapter
  • Ports on remote NXTs accessed via the RemoteNXT class
  • Ports on remote RCXs accessed via the RCXLink class

The implementations of BasicMotorPort include:

  • MotorPort
  • PFMotorPort
  • RemoteMotorPort
  • RCXPlexedMotorPort
  • RCXRemoteMotorPort

The tachometers that are built in to the NXT motors support the Tachometer interface.

NXT motor ports support the TachoMotorPort interface which includes the BasicMotorPort and Tachometer interfaces.

Implementations of TachoMotorPort include:

  • MotorPort
  • RemoteMotorPort

All this sounds rather complicated, but is simple to use:

  • For NXT motors, you use Motor.A, Motor.B and Motor.C
  • For RCX motors connected by the conversion cable you use RCXMotor(MotorPort.A), RCXMotor(MotorPort.B) or RCXMotor(MotorPort.C)
  • For NXT motors on a remote NXT, you use remoteNXT.Motor.A, remoteNXT.Motor.B or remoteNXT.Motor.C where remoteNXT is an instance of RemoteNXT.
  • For RCX motors connected by the RCX Motor Multiplexer, you use rcxMotorMultiplexer.A, rcxMotorMultiplexer.B, rcxMotorMultiPlexer.C or rcxMotorMultiplexer.D, where rcxMotorMultiplexer is an instance of RCXMotorMultiPlexer.
  • For RCX motors connected t remote RCXs via the RCXLink class you use rcxLink.A, rcxLink.B or rcxLink.C where rcxLink is an instance of the RCXLink class.

Back to top

LEGO Power Function motors

LEGO PF motors can be controlled by leJOS NXJ in a variety of ways. They can be directly connected to the NXT via converter cables, or they can be controlled remotely using their IR receivers use several different third party devices.

If you use converter cables, then PF motors are best driven using the RCXMotor class.

To drive PF Motors remotely, via the IR Receiver, three different devices can be used.

The Mindsensors PFMate device is designed to drive PF motors directly. This device is supported by the PFMate and PFMateMotor classes. PFMate implements the DCMotor interface, and therefore provides similar methods to RCXMotor.

Using the HiTechnic IRLink device, one way to drive PF motors is to use the PFMotorPort class. This provides a BasicMotorPort interface and so can be used as the BasicMotorPort parameter for the RCXMotor constructor. This allows RCXMotor to drive remotely connected PF motors. Another option is to use the methods of the PFLink class directly. This gives greater control but the methods are specific to this device.

A third device that can be used to drive PF motors is the Mindsensors NRLink. The PFLink class can be used to drive this device and send commands to the PF motors. The methods are specific to this device and none of the motor or motor port interfaces are supported.

Back to top

Servos and Linear Actuators

leJOS NXJ has several classes in lejos.nxt.addon to support Servo motors.

The Mindsensors MSC8 device is supported by the MSC and MServo classes. MSC represents the controller, which allows up to 8 servo motors to be connected. MServo represents each servo. the main methods are setSpeed and setAngle. None of the motor interfaces are supported.

The Lattebox range of products is supported by the NXTe, LSC and LServo classes.

Firgelli L12-NXT-50 and L12-NXT-100 Linear Actuators are supported by the LnrActuator class.

Back to top

Motor multiplexers

The motor multiplexors supported by leJOS NXJ are:

  • Mindsensors RCX multiplexer
  • Mindsensors NXT multiplexer

The RCX multiplexor is supported by the RCXMotorMultiplexor and RCXPlexdMotorPort classes.

Back to top

Sensor Ports

If you are using a sensor connected directly to a NXT sensor port, you can use the SensorPort class and you can probably skip this section.

But if you are using a port splitter, or a remote NXT or RCX, it may be of interest.

The NXT sensor ports support three different types of sensor:

  • NXT Analog/Digital Sensors
  • I2C Sensors
  • Legacy RCX sensors

Corresponding to each of the different types of sensor, there is a corresponding interface:

  • ADSensorPort which extends BasicSensorPort
  • I2CPort extends BasicSensorPort
  • LegacySensorPort extends ADSensorPort

At the top of the interface hierarchy is the BasicSensorPort. All sensor port classes implement this interface. This interface allows the type and mode of a sensor to be set. These type and mode constants are defined by the interface SensorConstants, which is inherited by the BasicSensorPort interface.

The types of sensors are:


and the modes are:

MODE_RAW = 0x00

The BasicSensorPort interface defines the methods:

  • public int getmode();
  • public int gettype();
  • public void setmode(int mode);
  • public void settype(int type);
  • public void settypeandmode(int type, int mode);

Most of the time, with leJOS NXJ, these types and modes do not need to be set explicitly as it is done by the constructor for the sensor class being used, e.g. TouchSensor, LightSensor and UltrasonicSensor.

The implementation of the NXT sensor port – SensorPort – supports all these interfaces. The reason for separating out the different interfaces is that there are other implementations of sensor ports that only support a subset of these interfaces, and different types of sensors only require particular interfaces to be implemented:

  • I2C Sensors just require I2CPort
  • NXT Analog/Digital sensors just require ADSensorPort
  • RCX sensors such as the RCX Light sensor require LegacySensorPort

Port splitters like the Mindsensors Split-Nx only support I2C sensors and thus, effectively, only support the I2CPort interface.

There are other implementations that only support the other interfaces. For example the current implementation of remote sensor ports – RemoteSensorPort – currently only supports the ADSensorPort interface.

The classes for RCX Sensors multiplexers – such as the forthcoming Mindsensors version – will only support the LegacySensorPort interface.

Back to top


Each sensor supported by leJOS NXJ has a specific class that is used to access the sensor. Each of these sensor classes has, as a parameter, a sensor port that supports the required interface. Any sensor port class that implements the interface can be specified as the parameter. As the SensorPort class supports all the interfaces, if the sensor being accessed is directly connected to the NXT, the parameter should be one of SensorPort.S1, SensorPort.S2, SensorPort.S3 or SensorPort.S4.

If a port splitter is used the parameter again should be one of SensorPort.S1, SensorPort.S2, SensorPort.S3 or SensorPort.S4. This specifies the port that the splitter is connected to. If multiple sensors are connected to the splitter they must each have different I2C addresses. Most I2C sensors can have their address changed – see the manufacturers instructions. To specify the address that a sensor uses, if it is not the default, then you may need to use an alternate constructor for the sensor class to allow you to specify the address. If such a constructor does not exist please report this to us and use the setAddress method of I2CSensor.

The sensor ports supported by leJOS NXJ together with the class that supports them and the type of sensor port they require is given in the following table:

Hardware Device


SensorPort interface

LEGO NXT Touch Sensor



LEGO NXT Light Sensor



LEGO NXT Sound Sensor



LEGO NXT Color Sensor



LEGO NXT Ultrasonic Sensor



RCX Light Sensor



RCX Temperature Sensor



RCX Rotation Sensor



HiTechnic Compass Sensor



HiTechnic Color Sensor



HiTechnic Acceleration Sensor



HiTechnic Gyro Sensor



HiTechnic IR Seeker



HiTechnic IRSeeker v2



HiTechnic IRLink



HiTechnic EOPD Sensor



HiTechnic Sensor Multiplexer



HiTechnic Angle Sensor



Mindsensors Compass Sensor



Mindsensors Acceleration Sensor



Mindsensors NXTCam



Mindsensors LineLeader



Mindsenors NXTMMX



Mindsensors Dist-Nx



RCX Touch Sensor



Mindsenors NRLink-Nx



Mindsensors PFMate



Mindsensors PSP-Nx



Mindsensors NRLink



Mindsensors RCX Multiplexer



Mindsensors RTC



Mindsensors Touch Multiplexer



Mindsensors Servo Multiplexer



Codatext RFID Sensor



Dexter Industries DSwitch



Dexter Industries dGPS sensor



Linear Actuator



Lattebox LSC



Lattebox NXTe



Micro Infinity Cruizcore Gyro



Back to top

RCX Sensors

RCX sensors, other than the touch sensor, are active sensors that have voltage applied for all but the short period every three milliseconds when the measurement is taken.

RCX Light Sensor

The RCX light sensor is supported by the RCXLightSensor class.

The constructor is:

  • public RCXLightSensor(LegacySensorPort port)

For example:

RCXLightSensor light = new RCXLightSensor(SensorPort.S1);

The RCX light sensor is automatically activated, so current is applied to it and the LED comes on. It can be passivated and activated explicitly.

The methods are:

  • public int readValue()
  • public void activate()
  • public void passivate()
RCX Touch Sensor

As the RCX touch sensor is a passive sensor similar to the NXT version, it is supported by the standard TouchSensor class.

RCX Rotation Sensor

The RCX rotation sensor is not currently supported by leJOS NXJ.

RCX Temperature Sensor

The constructor is:

  • public RCXTemperatureSensor(LegacySensorPort port)
  • The methods are:
  • int readValue() - returns raw value
  • float getCelcius() - return the temperature in degrees Celcius
  • float getFarenheit() - return the temperature in degrees Farenheit

Back to top

Third party sensors and other devices

leJOS NXJ supports many third party sensors. The two main vendors of third party sensors are Mindsensors and HiTechnic.

Most of the third party sensors and I2C sensors and extend the I2CSensor class but there are also Analog/Digital sensors such as the HiTechnic Gyro sensor and the IR Seeker.

There are also other I2C devices supplied by the third parties, that are not sensors, but are multiplexers or adapters.

The RCX Motor Multiplexer from Mindsensors is an example of a multiplexer. It allows up to 4 RCX motors to be connected to a NXT sensor port and to be independently controlled.

The Mindstorms NRLink-Nx infra-red communications adapter is an example of an adapter. It allows two-way communication between the NXT and RCXs. It also allows control of Power Function motors.

Back to top


The I2CSensor class implements the basic methods for accessing I2C sensors including getData and SendData.

It also includes methods that are implemented by all the I2C sensors, including getVersion, getProductID and getSensorType.

The method signatures are:

  • public int getData(int register, byte [] buf, int len)
  • public int sendData(int register, byte [] buf, int len)
  • public int sendData(int register, byte value)
  • public String getVersion()
  • public String getProductID()
  • public String getSensorType()

Individual I2C devices have registers that can be read and written and registers that can be used to execute commands. Each I2C device has a class that extends I2CSensor and has methods to access the registers and execute the commands specific to that sensor.

The I2CSensor class can be used to implement an I2C device explorer that reports what devices are connected to which sensor using which address – see the I2CDevices sample. This is possible as all the NXT I2C sensors and other devices support the getVersion, getProductID and getSensorType methods.

See the table above for the complete list of sensors and other third party devices.

Back to top


The I2CPort provides low level access to a port being used for I2C communications. In many cases these operations are not required and the higher level I2CSensor class is used. However some advanced applications (like those scanning ports to identify sensors) may require access at this level.

The method signatures are:

  • public void i2cEnable(int mode)
  • public void i2cDisable()
  • public int i2cStatus()
  • public int i2cTransaction(int deviceAddress, byte[]writeBuf, int writeOffset, int writeLen, byte[] readBuf, int readOffset, int readLen)

To use a port with I2C it must be enabled. When I2C operation is no longer required it should be disabled. The enable method also sets the operating mode of the port. The available operating modes are:


The mode normally used is LEGO_MODE. This offers compatibility with the standard Lego firmware. The bus will operate at 9.6Kbps and will add delays to be compatible with the Lego Ultrasonic sensor. This mode will normally work with all NXT compatible devices. STANDARD_MODE operates the port in a more I2C standard compliant way. You may wish to try using this if you are having problems with a device. HIGH_SPEED mode operates the bus at a much higher speed (125Kbps), to function at this speed the device will typically need to be using a hardware implementation of I2C (many of the HiTechnics and Mindsensors devices can be used at this speed). It should be noted that these modes operate at the port level not for an individual sensor so if more than one sensor is attached to the same port they will all share the same operating mode. To set the operating mode of a port a call to enable(mode) should be made prior to creating any instances of sensors to be associated with the port.

Back to top