NQC For Students
Introduction
NQC is a simple language for programming the LEGO RCX. NQC is very similar to C in many respects. NQC is not a general purpose language - there are many restrictions that originate from actual limitations and lack of detailed information about the RCX itself.
The compiler itself understands very little of the RCX. Most of the RCX functionality (such as playing a sound, reading an input sensor, etc) is added by the rcx.nqh include. This file is included automatically by the compiler, so you will not have to add an include file (ie. #include<begin.h>).
Usage
To compile your program type:
nqcc -d program.nqc (where program.nqc is your program)
The "-d" option causes nqcc to atttempt downloading the program to an RCX after compiling it. So you must have your robot and IR tower ready to go before you compile.
Values
Many statements (such as variable assignment, or conditional testing) make use of "values". A value can be many things: a constant, the contents of a global variable, a random number, the reading from an input sensor, etc. Each of these is covered in more detail below. In the description of a command its arguments will be noted as either "const" or "value". "const" arguments must be a numeric constant. "value" arguments may be either a numeric constant or another sort of value (such as a variable).
Constants can be combined using the standard arithmetic operators (+, -, *, /, %, <<, >>, &, |, ^, ~). Precedence and associativity are the same as C. Parentheses can be used to group lower precedence operations together.
The RCX provides 32 global variables. In order to use variables in your program, you must first declare them:
int foo;
All of the variables are global, hence they must be decalred outside the "task main". Variables can be assigned values using the following assigment operators:
var = value;
var += value; / same as: var= var + value; /
var -= value; / same as: var= var - value; /
var *= value; / same as: var= var * value; /
var /= value; / same as: var= var/value; /
Here is an example of a legal assignment and an illegal assignment:
int foo,bar;
task main
{
foo = 2 + 3; /*legal*/
foo = bar + 2; /* illegal*/
}
Control Structures
Conditions are comparisons between two values. There are six relations (<, >, <=, >=, ==, !=). Conditions may be combined using && and ||, or negated with '!".
Here are the control structures:
if (condition) statement
if (condition) statement else statement
while(condition) statement
wait (condition) statement
The "wait" structure executes the statement until the condition becomes true. It it handy when waiting for something to happen, such as bumping into a wall.
For example:
wait(IN_3 == 1); /* wait for sensor 3 to have value 1*/
Sensors
The constants IN_1, IN_2, and IN_3 can be used to either read an input sensor, or to specify a sensor. Sensor types are defined by IN_SWITCH, IN_LIGHT, IN_ANGLE, IN_PULSE, and IN_EDGE. The Sensor() function is used to initialize the sensor:
Sensor(value sensor, const type);
ClearSensor(value sensor);
The only supported value types for "sensor" in the above two examples are numeric constants and Input(n) - all other types have undefined behavior.
Here's a brief example that configures sensor 1 as a switch, then waits for it to be pressed before playing a sound.
Sensor(IN_1, IN_SWITCH);
wait (IN_1 == 1);
PlaySound(0);
The macros IN_1, IN_2, and IN_3 refer to the three inputs.
Motors
The constants OUT_A, OUT_B, and OUT_C refer to the three outputs. They can be combined (using +) in order to specify multiple outputs. Here's how to turn on all three motors for 1 second:
Fwd(OUT_A + OUT_B + OUT_C, 7 ); /* the 7 represents the speed you want. Speeds range
Sleep(100); from 0-7, seven being full speed*/
Off(OUT_A + OUT_B + OUT_C);
These commands control motors:
Fwd(OUT_A, 7) /* turn motor A on forwards to full speed*/
Rev(OUT_B, 2) /* turn motor B on backwards with speed 2 */
Off(OUT_A + OUT_B) /*stop motors A and B*/
Other Commands
PlaySound(5); /* play system sound #5 */
PlayNote(const freq, 10); /* play a note for 10 seconds*/
Sleep(value v) /* sleep for v ticks (100 ticks per second)*/