Click here to Skip to main content
15,035,600 members
Articles / Web Development / HTML
Posted 19 Aug 2015


2 bookmarked

C# Bluetooth Monitor for Lego Mindstorms NXT

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
19 Aug 2015CPOL6 min read
Program that continuously monitors the NXT via Bluetooth

Image 1


Inspired by Pierre Poliakoff and bigbro, I wrote a C# program to communicate with my Mindstorms NXT that continuously displays the battery voltage and a sensor value. The two values are read from the NXT in separate threads, each created with the .NET Thread class, and displayed in scrolling text boxes.


The project consists of a C# program called NXT BT Monitor and an NXC program called NXCBTMON. I developed the C# program with Visual Studio 2010 on Windows 7 and .NET 4.0. I used BricxCC version for the NXC program; the protocol and firmware versions on my NXT are 1.124 and 1.31. The NXT light sensor is attached to port 3, and an NXT motor is attached to port A. I used the Medialink Bluetooth adapter with the Windows 7 Broadcom driver, but other Bluetooth adapters will work; on-line NXT documentation lists adapters that are compatible with the NXT. Bluetooth drivers that are not compatible with the NXT seem to be the most common source of issues.


It is assumed the reader is familiar with the NXT and its sensors and motors, the C# and NXC languages, the Visual Studio and BricxCC IDEs, as well has having experience with Bluetooth on Windows 7 and the NXT. John Hansen and Daniele Benedettelli have both written books that are great resources for information on NXC and Bluetooth on the NXT. You may also want to get a copy of the "Mindstorms NXT Communication Protocol", "Mindstorms NXT Direct Command", and "Bluetooth Support for NXT" documents which can be found online or by contacting Lego directly. These documents describe the various commands which can be sent to the NXT and the data that is returned. Debugging and troubleshooting Bluetooth issues requires persistence and creativity, and may mean occasionally cycling power on the NXT, starting and stopping Visual Studio or BricxCC, or even rebooting Windows 7. The NXT must also be in close proximity to the Bluetooth adapter. Having fresh batteries on hand for the NXT is a must. Keep in mind that only one program at a time - either BricxCC or NXT BT Monitor - can be connected to the NXT.

Using the code

The program that runs on the NXT, NXCBTMON, consists of two files: NXCBTMon.nxc and protocol.h. Power on the NXT, build and download NXCBTMON using John Hansens's wonderful BricxCC IDE, then close BricxCC and power off the NXT.

Open the solution file for the C# program, NXTBTMonitor.sln, in Visual Studio. Build and run the NXT BT Monitor in Visual Studio. If you have the console window attached for debugging (described below), you can see that obtaining the available COM ports using WMI via the ManagementObjectSearcher class can take several seconds. (A future enhancement is to display a "Please Wait" dialog while the COM port query is running.)

Power up the NXT, and in NXT BT Monitor, select the port that corresponds to your Bluetooth adapter (available via Windows Control Panel=>View Devices and Printers) and click the "Connect" button. The status should change from "Disconnected" to "Connected" within a few seconds. If the connection is not successful, you may want to review the troubleshooting ideas above. Note that the port you select is saved as a user setting and automatically selected the next time you run the program (see the Settings.Settings file). After NXT BT Monitor is running and connected to the NXT, you can run NXCBTMON to start sending sensor readings to NXT BT Monitor.

Points of Interest

The essential class for communication between NXT BT Monitor and the NXT is the .NET SerialPort class.

private SerialPort bluetoothConnection = new SerialPort();

There is a Property on this class called ReadTimeout that specifies the number of milliseconds before a time-out occurs when a read operation does not finish. NXT BT Monitor has a corresponding parameter in the configuration file called ReadTimeout that you may need to experiment with. It is currently set to two seconds. After the NXT BT Monitor is connected to the NXT, two threads are started, one to monitor the light sensor and one to monitor the voltage of the batteries. The amount of time the threads sleep can be specified in the configuration file via the SensorThreadSleep and BatteryThreadSleep parameters. A consequence of updating controls from a new thread is that we must call BeginInvoke; see the code for the UpdateEditCallback and UpdateVoltageCallback delegates. Since both threads can access the serial port object, the .NET lock construct is used to only allow one thread at a time to access the Bluetooth port.

NXCBTMON has a task called ReadLightSensor() that reads the light sensor and sends the value to NXT BT Monitor. The SensorRead() thread of NXT BT Monitor receives the message and displays the value. Likewise, the BatteryRefresh() thread queries the NXT for the voltage of the batteries and displays it, both in text and in a progress bar. The progress bar will show green, yellow, or red, depending on the voltage. Clicking the "Get Info" button will query the NXT for its name, the Bluetooth address, and free user flash memory in bytes.

Clicking the "Get Version" button will query the NXT for the protocol and firmware major and minor revision numbers. You can send a message to an NXT mailbox by typing in the textbox above the "Send" button, and then clicking the button. The NXCBTMON in turn will display the text on the NXT’s LCD screen. Currently NXCBTMON program only reads mailbox 0. Sending the message "start" to NXCBTMON will cause the motor attached to port A to start.

The code in NXT BT Monitor to communicate with the NXT is encapsulated in specific classes. For example, clicking the "Get Info" button causes the class GetDeviceInfo to be instantiated and the methods can then be called on it to get the information. In the comments of each class I have supplied the relevant information from the aforementioned "Mindstorms NXT Communication Protocol" document and constants with meaningful names to avoid "magic numbers" in the code. For example, here is a snippet from GetDeviceInfo.cs:

    // Reference: p. 14 of MINDSTORMS NXT Communication Protocol.pdf
    // Transmit
    //   0: 0x01 Reply Required
    //   1: 0x9B Get Device Info

    // Receive
    //   0: 0x02
    //   1: 0x9B
    //   2: Status: if 0 success, else error
    //   3-17: NXT Name (14 Characters + Null terminator)
    //   18-24: BT address
    //   25: LSB of Bluetooth signal strength - 32 bit
    //   26: -
    //   27: -
    //   28: MSB of Bluetooth signal strength
    //   29: LSB of free user Flash - 32 bit
    //   30: -
    //   31: -
    //   32: MSB of free user Flash
    public class GetDeviceInfo
        public const byte GetDeviceInfoCommandB0 = 0x01;
        public const byte GetDeviceInfoCommandB1 = 0x9B;
        public const int NameStart = 3;
        public const int NameEnd = 17;
        public const int BTAddrStart = 18;
        public const int BTAddrLen = 6;

Performance Monitor and Debugging

An interesting feature of NXT BT Monitor is the ability to display the battery voltage and sensor reading obtained from the NXT in the Windows Performance Monitor. Readers who have experience with the Windows Performance Monitor and want to enable this feature can add the counters using Server Explorer running as Administrator (illustrated below), and then uncomment the relevant lines of code shown below:

Image 2

// PerfCounter.SetSensor1((long)sensor1);
// PerfCounter.SetVoltage(perCent);

Here is a screen shot of the Performance Monitor displaying the values of the battery voltage (in green) and the sensor value (in red). They were added by clicking the green plus sign in the Performance Monitor toolbar.

Image 3

Another nice feature of NXT BT Monitor is the attachment of a console to the Windows Forms project for debugging purposes using AllocConsole and .NET Interop. It is enabled by default; to disable it, simply comment out the first 7 lines of Main:

IntPtr ptr = GetForegroundWindow();
int pid;
GetWindowThreadProcessId(ptr, out pid);
Process process = Process.GetProcessById(pid);
Console.WriteLine("{0} NXT BT Monitor started", DateTime.Now);


Version August 17, 2015


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior)
United States United States
Chuck Peasley is a developer in Orange County, CA

Comments and Discussions

-- There are no messages in this forum --