Disconnecting a Bluetooth connection is even easier than making a connection.
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:
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.
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:
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.
Each BT device is unique identifed 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 then you can make susbsequent connections using the friendly name only and the devices remember the passwords so that they don't have to be re-entered.
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.
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.
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 device derives its clock from the received radio signal. This results in the following restrictions:
The BT protocol is asymmetric. At its lowest level,
BT implementation on the NXT use 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:
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:
The NXT-G firmware has built a message passing system on top of the NXT Bluectore implementation. It works as follows:
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.
The ROBOTC BT messaging has been optimized for a single slave connecton 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 each end of the stream can autonomously send 250 messages per second. The half-duplex implementation is limited to 13.
The NXT contains an integrated Bluetooth (BT) communications link. BT is an industry standard short-distance (up to 10 meters) wireless communications protocol.
BT communications can operate in either a master or slave mode. The NXT BT device can only be in one mode or the other at any one time.
The NXT GUI (Graphical User Interface) provides manual capabilities to manage the BT configuration on the NXT. The set of functions described here provide the ability to do all of the GUI capabilities, and more, within a user application program. You can set up and tear down connections, search for devices, remove items from the contacts list and many more functions.
The NXT firmware manages its BT communications through two lists: a connected device array and a contacts list.
While a NXT in master mode can connect to three slave devices / NXTs simultaneously, it can only communicate with one at a time. This means that a slave NXT/device cannot simply send a message to the master NXT; the master may be in communications mode with one of the other two possible devices and will not be listening to this particular slave. So, the slave must ‘buffer’ its message and wait for a polling request from the master asking for a buffer message. The BT protocol allows for simultaneous transmission over all links; this one at a time restriction is a function of the NXT firmware and the BT chip that it uses.
When compared with USB communications, BT is fairly slow. RobotC typically takes 28 milliseconds to send a message to another device and get a reply. This is almost three times faster than most other NXT firmware solutions.
BT is implemented on the NXT via a special purpose “Bluecore” hardware module. The main CPU on the NXT communicates with the Bluecore module via an internal messaging scheme. The main CPU sends a message to the Bluecore and then waits for a response. This means that the functions described below generally do not complete in a single transaction. Your program needs to request the action and then continually check the status until the transaction has completed and the result communicated back to the NXT CPU.
The Bluecore hardware can be in one of two modes: processing BT commands or data transmission mode. It cannot be in both modes at a time. This means, for example, that if in the middle of program execution that is communicating with one BT device you make a connection to another BT device during the time the connection is being set up the communications with the first device is stalled.
BT devices have a unique 7-character (256 possible values per character) address. This can be fairly cumbersome so the BT specifications have included a “friendly name” (i.e. a standard character string of printable characters) that can be used to refer to a device.
btConnect(nResult, nPort, sFriendlyName);
Attempts to connect BT device with specified name (sFriendlyName) on port nPort. This NXT will be the master and the other the slave.
btDisconnect(nResult, nPort);
Disconnects the BT connection on port nPort.
btDisconnectAll(nResult);
Disconnects all existing BT connections.
btFactoryReset(nResult);
Resets the NXT BT to the factory configuration. All connections will be dropped. The contacts list will be emptied.
btRemoveDevice(nResult, sFriendlyName);
Removes a device with the specified name (sFriendlyName) from the contacts lists
btSearch(nResult);
Begins a search for BT devices and adds new entries to the contacts lists. The search can take a long time (15 seconds).
btStopSearch(nResult);
Stops a search that is in progress.
getFirstDevice(nResult, nHandle);
getNextDevice(nResult, nHandle);
These two functions are used to scan through the entries in the contacts list. Get first device will initiate the search from the beginning of the list and get will find the next valid entry in the list.
getDeviceAddr(nResult, nHandle, sAddr);
getDeviceClass(nResult, nHandle, sCOD);
getDeviceName(nResult, nHandle, sName);
getDeviceStatus(nResult, nHandle, nStatus);
These functions are used to retrieve information about a particular entry in the contacts list.
getPortName(nResult, nPort, sPortName);
Gets the name (sPortName) of the device connected on port nPort
readLinkQuality(nResult, nQuality);
Reads the BT link quality (future)
requestLinkQuality(nResult);
Requests the current BT link quality
setBluetoothOff(nResult);
setBluetoothOn(nResult);
Turns Bluetooth ON or OFF on the NXT.
setBluetoothVisibility(nResult, bBluetoothVisible);
Sets whether the NXT BT is visible or invisible to searches from other Bluetooth devices. Invisible status means that the NXT will not respond to “search for devices” requests from other BT devices. However, if a device already knows the name/address of this NXT, then it can make a connection to this NXT.
setDefaultPIN(nResult, sPIN);
Sets a default PIN to use for Bluetooth connections (future)
setFriendlyName(nResult, sFriendlyName);
Sets the sFriendlyName that a NXT will be known by. The friendly names is normally displayed on the top status line of the NXT LCD.
transferFile(nResult, nPort, sFileName);
Transfers the file sFileName from this NXT to the NXT connected to port nPort.
nBluetoothCmdStatus
Gets the status/progress of the last BT 'command'
nBluetoothStatus
Gets the current BT status. See the enum for more details. Contains a bit map that indicates whether BT is on/off, visible/invisible and connected/not connected. These status bits are used to update the BT icon on the top line status display on the NXT.
nLastBTCommand
Gets the last BT command issued.
This section provides additional details for the technically inclined on the ROBOTC Bluetooth implementation and the NXT BT hardware. It highlights some of the areas that need careful treatment by software to implement a robust BT messaging scheme.
One of the hardware modules within the NXT is a self-contained Bluetooth (BT) module. It is called Bluecore (BC) by the module manufacturer. The NXT CPU communicates with the BC module via a high-speed serial link. The BC module can have up to three simultaneous connections to other NXTs.
The NXT CPU and BC need to operate in either CMD or DATA mode. BC cannot operate in both modes simultaneously.
In command mode, the NXT CPU is communicating with BC to perform “housekeeping” functions. Data transmitted between the two is interpreted as commands (and replies) to the BC chip; typical commands are connect/disconnect far end devices, enable/disable visibility, search for devices, etc.
Generally, all the command mode activities are performed at the beginning of a BT session. Once a connection has been set up, data “stream” mode is entered. When a session is complete, command mode is re-entered to drop (i.e. disconnect) the connection.
In data mode, BC simply transfers the data between the RF link and the serial link on the NXT CPU.
ROBOTC provides interfaces that enable user program access to most of the BC commands. For example, you can set up a connection to another NXT from within a user’s program. Programs should perform all “commands” requests first before beginning data transmission (i.e. sending messages) activity.
The NXT firmware smoothly manages the transition between command and data mode. There are a couple of digital I/O pins between the CPU and BC that are used to perform the transition which typically takes several milliseconds.
When in command mode, any data received over the RF link is simply discarded by BC. Similarly the NXT CPU discards any requests for transmission of data packets over the RF link.
BC allows a single “master” NXT to connect to up to three “slave” NXTs. The master provides the overall timing for the RF link used and the slaves derive their RF timing/synchronization from the master. You cannot mix master and slave devices on a single NXT. This limits the size of a network of BT connected NXTs to four devices – one master and three slaves.
BC communicates with the NXT’s CPU over a single high-speed serial link. When a NXT is in master mode, the CPU tells BC which one of the three possible slave ports (streams) should be currently active. BC simply transfers all data on the serial link to/from the active stream. Any data received from either of the two inactive streams is simply discarded by BC.
There is a command for the NXT CPU to tell BC to make a different slave port (stream) the active stream. This involves switching from Command to Data mode and sending a few requests to BC. It takes over 100 milliseconds to perform the active stream switch.
One implication of an architecture that supports simultaneous multiple slave connections is that the slave devices cannot autonomously send messages to the master device since they have no knowledge of whether their connection is currently the active stream on the master. The architecture requires a half-duplex protocol where the master device has to send a polling message to each slave device requesting any data that is buffered waiting for such a request.
The result is that the RF link is only used in a half-duplex mode. It is only transmitting in one direction at a time.
The incremental transaction delays in simultaneously handling multiple slaves – i.e. 100 to 300 milliseconds per transaction – make it impractical for high-performance real-time operation. It’s simply too slow.