Lego MindStorms: Programming with NQC

by Jonathan Knudsen

Parts of this article:

An introduction to NQC (Not Quite C)

Program flow, reading inputs, and variables

A sample program

In the second column in his series on Lego MindStorms robots, O'Reilly & Associates author Jonathan Knudsen introduces us to an alternative programming environment for the robots, NQC. On the first page, he introduces NQC and its properties and tells how to get it. On page two, he explains more details, including program flow, inputs, and variables. On the final page, he lists the code for a more complex program that has the robot seeking out a dark place to hide.

Last month I told you about the Lego MindStorms Robotics Invention System and why it's such an interesting product. This month, you'll get right to the fun stuff: building and programming your own robot. You'll learn how to program using Not Quite C (NQC). Created by Dave Baum, NQC is one of the alternate development environments I talked about in last month's column. NQC is a great piece of software for several reasons:

  • NQC is freely distributed under the Mozilla Public License (MPL).
  • It runs on Linux and Mac OS as well as Windows.
  • It has a syntax that looks like C, making it easy to learn for C programmers.
  • NQC uses the default firmware that comes with the Robotics Invention System. This makes it easier to deal with than some of the other, more powerful development environments that use alternate firmware.

The RoboTag robot, a programming testbed

Before you start writing programs, you'll need to build a robot for testing. I suggest the RoboTag robot from The Unofficial Guide to Lego MindStorms Robots. RoboTag is a simple, sturdy, tank-style robot. It has a front bumper and a downward-pointing light sensor.

Figure 1. RoboTag, from The Unofficial Guide to Lego MindStorms Robots

RoboTag's building instructions are online. To get the most out of this tutorial, click here for the building instructions and then return to get into the NQC programs. If you're only interested in NQC's capabilities, keep reading.

A first look at NQC

Previous Lego Mindstorm Columns:

Mindstorms in Education

The Straight and Narrow

Tools to Save Your MindStorm Models

Lego MindStorms: Lego Glasnost

Although you could certainly program your robot using RCX code (the programming environment that comes with the Robotics Invention System), there are compelling reasons to make the jump to NQC. Variables are probably the most important thing -- NQC has them and RCX code doesn't. Using variables can make your robot a lot smarter. Later on, for example, you'll see how using a variable makes a program more robust, allowing us to determine a light sensor threshold on the fly rather than hard coding the value. To get started, you'll need to download NQC. There are versions for Mac OS, Linux, and Windows.

You can use any text editor to create NQC source files. If you're running on Windows, consider Mark Overmars' RCX Command Center (RcxCC), a smooth graphic interface that runs over NQC.

RcxCC provides a nice, syntax-colored editor. MacNQC also includes an editor. On Linux or Windows, just use the text editor of your choice. Save the following as "Hello.nqc":

task main() {
  OnFor(OUT_A + OUT_C, 200);
To compile this program, just use the nqc command, like this:
C:\nqc Hello.nqc
(With MacNQC, you'll use a menu item instead. With RcxCC, there's a toolbar button that compiles a program.)

If you get any errors, check your typing and try again. Otherwise, you're ready to download the program to the RCX. Make sure your RCX is turned on and use the nqc command with the -d option:

C:\>nqc -d Hello.nqc
(If you need to use a serial port different from the default, use the -S option.)

NQC Resources

The Unofficial Guide to Lego MindStorms Robots contains a chapter about NQC. It's available online.

• The NQC web site includes documentation.

• The RcxCC web site also includes a tutorial about NQC.

Go ahead and run the program by pressing the Run button on the RCX. Your robot should move forward for 2 seconds, then stop.

Controlling outputs

NQC includes a suite of commands for controlling the outputs. The three output properties that can be independently controlled are

  • mode,
  • power, and
  • direction.
You might, for example, want an output to be on (mode) with full power (power) going forward (direction).

In the Hello.nqc program, we took advantage of the fact that outputs are full power and forward by default. All we had to do was turn on outputs A and C to make the robot move forward.

The OnFor() command turns one or more outputs on for a certain amount of time, measured in hundredths of a second. Outputs are specified with some combination of the constants OUT_A, OUT_B, and OUT_C. Multiple outputs can be specified by adding the constants together. If you want to control more than one output, you can just add the constants together (equivalent to a boolean "OR" here). In our simple program, we used OUT_A + OUT_C to specify outputs A and C.

Let's look at the modes first. You can turn outputs on and off with the On() and Off() commands. There are two flavors of off: braking and floating. The default, Off(), puts the motors in a braking mode, so they resist turning. The other flavor, Float(), turns off power to the motors but does not resist turning.

To see how this works, let's try a simple modification of our first program. Save the following as "Coaster.nqc":

task main() {
  OnFor(OUT_A + OUT_C, 200);
  Float(OUT_A + OUT_C);
After this program exits, you'll notice that RoboTag coasts to a stop, rather than stopping abruptly. Also, you can freely turn the treads with your fingers.

The OnFor() command is an interesting variation that turns outputs on for a certain amount of time, then off (in brake mode).

The outputs have variable power, from 1 to 7. NQC defines some handy constants, like OUT_LOW (1), OUT_HALF (4), and OUT_FULL (7). You can set the power of one or more outputs with the SetPower() command.

The direction of the outputs is either forward or reverse. You can control this with the Fwd() and Rev() commands. Two combination commands, OnFwd() and OnRev(), allow you to specify a mode and a direction at the same time.

By default, the outputs have full power in the forward direction. Instead of relying on the defaults, we could rewrite the first program as follows:

task main() {
  SetPower(OUT_A + OUT_C, OUT_FULL);
  Fwd(OUT_A + OUT_C);
  OnFor(OUT_A + OUT_C, 200);

On the next page, I'll go into more details of program flow, reading inputs, and variables.

Pages: 1, 2, 3

Next PageNext