leJOS NXJ supports communications using Bluetooth and USB. The NXJ communications classes are designed so that most of your code is independent of whether you are using Bluetooth or USB – you can write applications that work with both (see the example below). And you can use Java streams, which are a very flexible and easy to use.
USB has the advantage of speed, but the cable can be used only to connect a NXT to a PC. Bluetooth is slower, but much flexible. It supports a multitude of methods of communicating NXT to NXT, PC to NXT, Mobile phone to NXT, NXT to remote Bluetooth device, etc.
The first step in communicating is to establish a connection. A connection has an initiator and a receiver. The receiver waits for a connection from the initiator. The initiator connects to a specific device that must be waiting for a connection. When the connection has been established, both ends of the connection can use it to open input and output streams and read and write data. In this tutorial we do not deal with the case where the NXT is an initiator and the PC is a receiver, although this is possible for Bluetooth connections. In most cases of PC to NXT or mobile phone to NXT communications, it is more convenient for the NXT to be the receiver and the PC the initiator.
The initiator program may run on a PC (always for USB), another NXT, a mobile phone or another device that supports the Bluetooth Serial Port Profile (SPP). Some external devices, such as GPS Bluetooth devices only act as a receiver, so when communicating with these devices, the NXT must act as the initiator. Note that such external devices must implement SPP - this is the only profile that the NXT supports.
A receiver program on the NXT waits for a connection by calling the waitForConnection() method in the Bluetooth or USB class. These are:-
Even though the Bluetooth class returns a BTconnection object, and the USB class returns a USBConnection object, both of classes implement the NXTConnectiion interface. So an object of either class can be assigned to an reference variable that implements that interface.
You need to ensure that Bluetooth power and visibility are on before calling this method. The leJOS NXJ start-up menu can be used to do this.
You need to ensure that the USB cable is connected before calling this method.
Here is an example program that selects between USB and Bluetooth at run time:
Once a connection has been established, streams can then be opened by calling any of the following methods in the NXTConnection interface:
Data items can then be read from the DataInputStream by:
Be aware: The stream read methods are blocking – that is, they do not return until data is read. If your program has other tasks that need attending to while waiting for data, calls to the read methods should be made in a separate thread.
Data can be written to the DataOutputStream by:
Example of reading and writing integers using data streams (
Be aware: you must flush the output stream to be sure the data is actually transmitted. Furthermore, it is possible for transmission to fail without throwing an exception.
The DataInputStream, DataOutputstream and NXTConnection can then be closed using the close() method.
The full example using Bluetooth is:
To modify this example to work with USB, you only have to change Bluetooth.waitForConnection() to USB.waitForconnection()
To initiate a Bluetooth connection from one NXT to another NXT, you first need to add the receiver NXT to the initiator NXT’s Bluetooth devices.
To do this, you go to the Bluetooth menu in the leJOS NXJ start-up menu and select “Search”. Providing the Bluetooth power is on and visibility is on for the receiving NXT, it will be found and you can select “Add” to add it to the initiator’s Bluetooth devices.
To check it is in the Devices list, you can select “Devices” from the Bluetooth menu of the initiator NXT.
You can then create a RemoteDevice class on the initiator NXT:
You can connect to the remote device by its address, which you can get by:
You can then connect to the remote device by calling one of the connect() methods in the Bluetooth class:
Having got a BTconnection object you can open the data input and output streams and read data as in the receiver example above.
The complete BTConnectTest example, which works as the initiator program for the BTReceive receiver program, is:
A PC program can initiate a connection to a NXT and open a Java data stream.
The API on the PC is different to the NXT API. See pcapidocs. and how to compile and run PC API Programs
To connect to the NXT, you need a NXTComm object that can be obtained using the NXTCommFactory class:
A NXTComm object to connect via Bluetooth can be obtained by:
The reason for using a factory method is that there are several implementations of comms drivers for Bluetooth and USB on the PC and the one that is used depends on what operating system you are using and the contents of he nxj.properties file.
You can connect to the NXT by address or by do a Bluetooth inquiry:
To connect by address, you create a NXTInfo object using the constructor:
To find the available NXTs doing a Bluetooth inquiry, you do:
The initiator sequence using USB is almost the same as for Bluetooth; You just have to use USB instead of Bluetooth.in your code. While USB cannot use a device address , but you can use the NXT name.
To find the available NXT , you do:
If there is only one NXT connected, you can use a null name parameter in the search() method.
Using the NXTInfo object
Once you have a NXTInfo object,you can call the open() method of the NXTComm object to connect to the NXT:
Once the NXT is open, you can obtain an InputStream and an OutputSttream, by calling the getInputStream() anf getOutputStream() methods of the NXTComm object:
From these you can construct a DataInputStream and a DataOutputStream and send data to the receiving NXT.
The complete BTSend sample is in the samples folder.
In this section you will learn how to:
Controlling a remote NXT
The RemoteNXT class allows one NXT running leJOS NXJ to control another, remote NXT, running NXJ or the standard LEGO firmware. It uses the LEGO Communications Protocol (LCP) over Bluetooth to control the remote NXT.
Currently, the class is limited and I2C and RCX sensors are not supported, and the motors must be used in a simple way as the regulation thread is not used.
To access a remote NXT, you use the constructor:
The name of the remote NXT must have already been added to the known devices of the initiating NXT by do a Bluetooth search followed by “Add” fron the leJOS NXJ Bluetooth menu.
The constructor opens the connection and creates instances of the remote motor and sensor ports.
It is then possible to get access to information about the remote NXT by using the methods:
There are also methods that act on the remote NXT:
A remote Battery object is created that can be used to get the voltage of the remote battery using the normal Battery methods.
Objects are also created for the sensor ports of the remote NXT. These are accessed as S1, S2, S3 and S4.
Local sensor objects can then be created using these ports and use exactly as if they were connected to a local sensor port.
Motor objects are created for the remote motors. They are named A, B and C.
These can be used in the normal way, e.g:
External Bluetooth devices
The NXT can connect to external Bluetooth devices that implement the Serial Port Profile (SPP).
Such devices can be searched for on the Bluetooth menu and added to the known devices.
An example of such a device is an external Bluetooth GPS receiver. These can be used to obtain to obtain the geographic location of a robot
leJOS supports external Bluetooth GPS receivers that support the NMEA protocol via the GPS and NMEASentence classes. NMEASentence is a utility class used by GPS, and is not directly accessed.
One such device that has been tested with leJOS NXJ is the Holux M-1200.
Most such devices have a PIN that is required to connect to them, but it may have a default value such as “0000”.
To connect to a GPS device, you do:
As you see from this example, the GPS constructor takes the input stream from the Bluetooth connection as a parameter:
The GPS class starts thread and uses the NMEASentence class to process messages (known as sentences) from the Bluetooth device. Messages such as the $GPGGA sentence that gives the current latitude, longitude and altitude, are processed.
To read the current values of latitude, longitude and altitude, you use the methods:
You can also get the time stamp corresponding to these values by:
Communicating with the RCX
IR communication with the RCX can be done using the Mindsensors NRLink RCX IR adapter. The software abstraction of this device is the RCXLink class. The constructor is:
The NRLink-Nx supports a set of macros in ROM and EEPROM that can be used to send messages to the RCX using the LEGO RCX IR protocol. The EEPROM macos can be overwritten allowing the user to define their own macros.
Macros can be run by:
There are convenience methods for running the ROM macros:
A new macro in the EEPROM address range can be defined by:
There is a convenience method to define and run a macro: