Information

Bluetooth (BT) is an industry standard short-distance (up to 10 meters) wireless communications protocol operating at 2.4 GHz. It can optionally use a higher power transmission to achieve distances up to 100 meters. The NXT utilizes the 10 meter option.

BT includes not only the low-level radio transmission (at 2.5 GHz) but also several higher layer message protocols (or profiles) designed for different applications. There are over 25 different BT profiles currently defined. Some of the more popular profiles include:

The Serial Port Profile (SPP) is used to provide wireless emulation of a conventional RS-232 serial communications cable. This is the only protocol supported on the NXT.

The Human Interface Device (HID) protocol is used for communication on wireless keyboards and mice. It is also used on some game controllers like the Nintendo Wii or SONY Playstation 3.

The Headset Profile (HSP) is used to connect wireless headsets to devices like cellphones.

In order to connect two devices via BT, the devices must not only support BT but also support the type of profile that will be used for the connection. The NXT only supports the SPP so that it cannot, for example, directly connect to a Nintendo or Sony game controller.

The NXT has a very powerful communication capability between two NXTs using the wireless Bluetooth functionality built into every NXT. The Messaging functions described here provide an easy approach for using this communication. It limits the communication to messages containing three 16-bit parameters.

It is very easy to set up Bluetooth communications between two NXTs.

Use the NXT’s on-brick user interface to make a connection between two NXTs.

It is also possible to set up the connections within a user’s program but that is for advanced users.

Use the variables message and messageParms to retrieve the contents of a message. When you’ve finished processing a message, use the ClearMessage() function to “zero out” the message so that your program can process subsequent messages. The next time your program references the message variable, it will be for the next message that has arrived.

The ROBOTC BT messaging has been optimized for a single slave connection on the master. This allows for significantly less latency on the BT message link. Slaves can immediately transmit messages without having to wait for a polling request from the master. ROBOTC also allows for multiple slave support, but a description of this is beyond the scope of this tutorial. This optimization gives a performance improvement of three to 20 times over other architecture that support – at a significantly reduced performance level – multiple simultaneous slaves.

ROBOTC measured performance to send a BT message, receive it at far end, process it, generate a reply and receive it at original device is about 36 such transactions per second. Other implementations (e.g. NXT-G) typically support about 13 transactions per second.

ROBOTC allows full duplex operation over a single BT stream. Measured performance indicates that each end of the stream can autonomously send 250 messages per second. The half-duplex implementation is limited to 13.

Bluetooth Messaging is Incompatible with Debugging Over BT Link

NOTE: The ROBOTC IDE debugger can operate over either USB or Bluetooth connection to the NXT. When an application program uses the Bluetooth connection to send messages to another NXT then you cannot use the Bluetooth debugger connection. They are incompatible.

Differences Between NXT Messaging and the RCX Infrared Messaging

This functionality is similar to that found on the LEGO Mindstorms RCX with a few notable exceptions:

There was no queuing of received messages on the RCX. When a new message arrives at the RCX it overwrites previously unhandled messages or it is discarded if the current message is not finished processing.

Connecting Two NXT Bricks

1. Use the NXT user interface to select Bluetooth commands.

2. The top left of the NXT LCD status display shows the Bluetooth status. The leftmost icon is the BT symbol and indicates that BT is enabled on the NXT. The icon indicates that the NXT BT visibility is enabled -- if visibility is disabled, then the NXT will not respond to search commands from other BT devices. "ROBOTC2" is the friendly name for the NXT.

3. Then select "Search" command and run the command.

4. Once search has been performed, you'll be presented with a menu of the NXTs that were found via Bluetooth. In this case, only a single item -- the device "ROBOTC1" was found.

5. Select the target device for the connection from the search results -- i.e. "ROBOTC1" -- and then select "Connect"

6. The NXT supports connections to up to three "slave" devices. You need to select the appropriate "slot" (1, 2, or 3) for the connection. Select an empty slot -- all three slots are empty in the following picture -- and hit the orange button.

7. The NXT screen will show "Connecting" as the connection is attempted. Depending on the settings on your NXT, you may be prompted for a password.

8. Once the connection is made, the status ICON will change to "<>". The ">" indicates that the NXT is connected to another BT device.

Disconnecting Two NXT Bricks

1. Use the NXT user interface to select Bluetooth commands.

2. Select the "Connections" Menu item.

3. You now get a list of the devices connected via Bluetooth. In this case, there is a single connection to the "ROBOTC1" Bluetooth device.

4. Select this item. Then select the "Disconnect" command.

5. The connection will be removed and the NXT GUI will return to the Bluetooth commands menu. Note that the Bluetooth status icon in the top-left of the screen has changed from "<>" (visible + connected) to "<" (visible + not connected).

PC/NXT Pairing with ROBOTC

To pair your NXT with your Bluetooth adapter to use ROBOTC, follow these steps.

Note: You cannot download firmware to an NXT over Bluetooth. Please download ROBOTC's firmware before trying to connect via Bluetooth.

1. Go to the "Robot" menu, and under the "NXT Brick" submenu, select "Link Setup."

2. In the NXT Brick Link Selection screen, we want to enable Bluetooth seaching. Click the checkbox labeled "Include Bluetooth in Brick Search" and then click the "Refresh Lists" button.

3. ROBOTC will use the bluetooth adapter to search for NXT bricks. This may take 30 seconds.

4. When ROBOTC is competed searching for Bricks, you can select which brick you would like to connect to. Click the name of the brick under the "NXT Bricks Reachable via Bluetooth Wireless" menu and then click the "Select" button on the right.

5. ROBOTC will remind you to press the orange button on the NXT when the NXT make a sound. Click "OK" to continue.

This is the NXT requiring input for the Bluetooth passcode. The default passcode will automatically be entered, so just press the orange button.

6. ROBOTC will start to pair with the NXT. This may take 15-30 seconds and you will have to press the orange button once during this time.

7. Once the brick has connected via Bluetooth, you will see the brick's name appear under the "NXT Brick Connection History". Your NXT is now connected via Bluetooth! You can continue to use ROBOTC as if your brick was connected via USB... everything will work, including the debugger and program downloading. Click "Close" to exit this screen.

Connecting via Bluetooth - Pairing

Each BT device is identified by a unique 12 hexadecimal digit address. It's a little awkward to refer to devices with this address so the BT protocols include a "friendly name" that is a more conventional 15-character string. The default friendly name for a NXT brick is "NXT" but you can modify this using the NXT's on-brick user interface, or from the ROBOTC IDE, or directly from within a ROBOTC program.

Before you can connect two devices via BT they must be "paired". The pairing process exchanges messages between the two devices where they share their BT address, their friendly names and their supported profiles. The devices confirm that they support the same profiles and that the (optional) password matches. Once two devices have been paired, you can make subsequent connections using just the friendly names. The devices remember the passwords so that they don’t have to be re-entered each time

There's a lot of low-level messages used in establishing a paired connection. Fortunately, this is hidden from the user on the NXT with a simple user interface via the user interface on the NXT.

From the BT menu on the NXT, a search is performed to build a internal list in the NXT of all the devices that are currently available via BT. The NXT simply broadcasts a "who's available" message over BT and collects a list of all the devices that replied.

To learn how to connect two NXTs together, please see the "Connecting NXTs" page here.

Once connected, the "slave" device will be added to the NXT's internal table of paired devices, i.e. the "My Contacts" list on the NXT. Next time you want to make a connection you can select the device from the "My Contacts" and avoid the 30-second search.

NOTE: Sometimes you'll find that you cannot get two previously paired devices to connect. One cause of this is that one device is no longer powered on. Another cause is that somehow the devices have got out of sync on the pairing status where one device has "lost" the paired status. If this happens, try removing both devices from the "My Contacts" list on each NXT and restart the connection using the "Search" function.

Sending Messages via Bluetooth

Once you have two NXTs connected via BT, it is very easy to send messages between them. There are only three functions that are needed:

cCmdMessageWriteToBluetooth writes a message.

cCmdMessageGetSize get the size of the first message in a mailbox containing a queue of received messages.

cCmdMessageRead removes the first message from a mailbox queue and copies it to a user buffer.

After calling each of the above functions you should check the returned value to determine the success/failure of the function.
Use the function cCmdMessageWriteToBluetooth(nQueueID, nXmitBuffer, nSizeOfMessage) to send a BT message to the far end NXT. Check the error code to make sure message was transmitted successfully. This sends the message (up to 58 bytes in length) in the variable nXmitBuffer to queue or mailbox number nQueueID on the far end NXT. nSizeOfMessage is the length of the message.

When messages are received over BT by a NXT they are automatically added to the end of one of the 10 message or mailbox queues. Use the function cCmdMessageGetSize(nQueueID) to determine whether any messages have been received. A positive return value indicates that a message was received and is the number of bytes in the message.

Use the function cCmdMessageRead(nQueueID, nRcvBuffer, nSizeOfMessage) to retrieve the first message from the specified mailbox and copy it to a user’s buffer at nRcvBuffer. Only the first nSizeOfMessage bytes of the message are copied. nQueueID is the mailbox number to obtain the message from.

The sample program "NXT BT Messaging No Error Checking.c" is a simple program to show how to use all three of the functions.

Sending Messages

There are two functions for easily sending messages. One sends a single 16-bit value and the other sends three 16-bit values. Either of the two NXTs can send messages at either time. It is the responsibility of the user program to not send messages too frequently as they may cause congestion on either the Bluetooth link or overflow of the NXT’s transmit and receive queues.

sendMessage(nMessageID)

Sends a single 16-bit word message. nMessageID should range in value form -32767 to +32767. Message value 0 is invalid and should not be used. It is a special value to indicate "no message" received when using the message variable.

sendMessageWithParm(nMessageID, nParm1, nParm2)

This function is identical to the sendMessage function except that the message contains three 16-bit values. This is useful in easily sending separate items of information in a single message. Do not use a value of zero for nMessageID.

Receiving Messages

The NXT firmware automatically receives messages and adds them to a queue of incoming messages. The application program takes the messages from this queue and processes them one at a time. The variables message and messageParm contain the contents of the current message being processed. The function ClearMessage discards the current message and sets up to process the next message.

message

This variable contains the 16-bit value of message received over the Bluetooth channel. It has a range of -32767 to 32767. A value of zero is special and indicates that there is “no message”. Whenever the value is zero and the message variable is accessed, the firmware will check to see if it has any received messages in its queue; if so, it will take the first message and transfer its contents to the message and messageParms variables. These two variables will continue to contain the message contents until the user’s program indicates it has finished processing the message by calling the ClearMessage() function.

messageParm[]

Array containing optional message parameters (up to 3 16-bit words) for messages received over the RCX infrared channel. messageParm[0] is the same as message. messageParm[1] and messageParm[2] are additional 16-bit values.

bQueuedMsgAvailable()

Boolean function that indicates whether a unprocessed message is available in the NXT's received message queue. This is useful when multiple messages have been queued and your program wants to skip to the last message received. Your program can simply read and discard messages as long as a message is available in the queue.

ClearMessage()

Clears the current message. The next time the message variable is accessed, the firmware will attempt to obtain the first message from the queue of messages received by the NXT.
Do not send messages faster than about one message per 30 milliseconds or it is possible for some messages to be lost.

Skipping Queued Messages

A typical application might have one NXT send a message to the NXT on a periodic basis. For example, it might send a message containing the current values of sensors S1 and S2 every 100 milliseconds. Due to processing delays in the receiving NXT, several messages may have been queued and your program may want to rapidly skip to the last message received. The following are two code snippets that show how this might be accomplished.

while(true){//// Skip to the last message received//while(bQueuedMsgAvailable()){word temp;
ClearMessage(); // We’re ready to process the next message
temp = message; // Obtain the next message}if(message == 0){// No message is available to processwait1Msec(5);
continue;
}// A message is ready to be processed
remoteSensor1 = message; // the value of ‘S1’ from the remote NXT
remoteSensor2 = messageParm[1]; /* the value of ‘S2’ from the remote NXT . . . *//* user code to process the message. It may have many delays. */}

Master vs Slave Device

One end of a BT connection is the master device and the other end is the slave device. The master device generates the clocking signal used for the BT connection and the slave device derives its clock from the received radio signal. This results in the following restrictions:

A device can be either a slave or a master, but not both.

A single master can (optionally) make connections to multiple slaves.

A slave can only connect to a single master. It cannot have connections to other masters as it would then need to support multiple clock sources!

The BT protocol is asymmetric. At its lowest level, A master can transmit over radio at any time.

A slave only transmits in response to a request from a master.

During the initial connection setup, the two devices negotiate the maximum bandwidth that they will use and how often they are listening for traffic. This allows the devices to use a low-power mode (i.e. the radios are only enabled part of the time) at the expense of lower bandwidth.

Bluecore Bluetooth Information

BT implementation on the NXT uses a "Bluecore" chip from CSR. Bluecore is a self-contained implementation of BT that manages the BT hardware and protocols. It has a few limitations that are common to many other BT hardware implementations:

The "search" function requires 100% of the BT resources. When a search is in progress no other BT activity can take place on the NXT.

The module can be in either "command" or "data" mode. They are mutually exclusive states.

In command mode, housekeeping functions related to the BT protocol are being performed -- this includes things like searching, pairing, making connections and disconnection.

Data mode is used to transfer data between two devices over the BTX wireless link.

Bluecore supports a single "master" device connecting to up to three 'slave' devices at one time. However, it can only communicate data with one device at a time; it could not simultaneously receive data from all three slaves!

On the radio side, Bluecore can have three connections (or "streams") to different slave devices. However, on the other side -- i.e. the connection from Bluecore to the NXT CPU, only a single connection is possible. It is this implementation that leads to the above restrictions. So, for example:

If you wanted to add a second slave connection to a NXT, the Bluecore module would be switched into "command" mode. This would interrupt "data" traffic from the original connection. The appropriate commands would be performed to set up the connection and then Bluecore would be switched back to "data" mode.

In data mode, Bluecore is only connection to one of the two streams/connections at a time. If data from the disconnected stream is received, it is discarded.

Bluecore can be switched from "data mode on stream 1" to "data mode on stream 2". This is done by switching to "command" mode, sending the "switch stream" command and then switching back to "data" mode; this takes over 100 milliseconds.

NXT-G Bluetooth Messaging Compatibility

The NXT-G firmware has built a message passing system on top of the NXT Bluecore implementation. It works as follows:

Messages can contain up to 58 bytes of data. The restriction is that firmware has a fixed 64-byte format for message buffers and there are six bytes of overhead in the structure.

Single master can connect to up to three slaves.

Messages can be sent to one of ten queues. The queue number is one of the overhead bytes.

When a message is sent from the master, it is put on a queue of outgoing BT messages.

Messages are transmitted from the queue in a FIFO basis whenever the previous queue item is completed.

The firmware looks at the stream ID -- ie. which of the three possible connections -- before transmitting a message.

If the stream ID does not match the currently "active" stream, then the active stream is switched to this stream by the 100+ millisecond process described above.

Slave devices cannot use the above process! The slave does not know whether it's stream is the master's "active" stream. The implementation for messaging from the slave is as follows:

An outgoing message from the slave is always added to one of the ten outgoing message queues. One queue for each of the ten possible "mailboxes".

The message sits in the outgoing queue until the slave receives a "poll for message from mailbox N" message from the master.

In response to the "poll for message" the slave responds with either "the selected mailbox is empty" or it sends the first message found in the queue.

If there is only a single slave, then the above process does not incur the 100+ msec delays of switching 'active' streams on the master. It still incurs a delay while the slave waits for a polling request from the master.