Using HiC to Program LEGO Mindstorms Robots

This writeup describes how to use HiC to program the LEGO Mindstorms robots. Depending on the number of robots that are available, some people may need to work with a partner for this portion of the lab.

LEGO Robots 101

You should see a simple LEGO robot on your table. The heart of this robot is a special brick shown to the right. This brick, known as the RCX unit, contains a small computer with three inputs (the gray squares marked 1-3), three outputs (black squares marked A-C), an infrared port in the front, and a control panel. The inputs are hooked to sensors and the outputs to motors. Your computer sends signals to the control tower shown to the left, and the tower in turn uses infrared light to communicate with the RCX unit.
The first part of this lab is to make the robot play a sound and turn in circles. Start up HiC in the usual way and enter the following program (note you can just copy it off this page):
#include <rcx.h>                // include file for LEGO robots

int main()
{
   playSound(UP_SCALE);         // play simple scale
   MotorAOnFwd();               // turn motor A on in forward direction
   MotorCOnRev();               // turn motor C on in reverse
   return 0;
}
Try running this program in the normal way; that is, click on the button with the green arrow on
it. The program should run successfully, but nothing will happen since it must be downloaded to the robot first. To download it, do the following:
  1. Insert the control tower's USB plug into the computer. If you get a message about having "insufficient privileges to install devices", try plugging the tower into a different port. If none of the ports work, talk to your instructor.

  2. In HiC, select Options from the Edit menu. Click on the "Lego RCX" tab and set "NQC Path:" to
            H:\Apps-EMS\HiC\nqc.exe
    
    This allows HiC to use "NQC" - aka "Not Quite C" - to download your program to the brick.

  3. Turn on the RCX brick by clicking on the red On/Off button. You should see a bunch of 0's, a standing person, and a number between 1 and 5. If you do not see the 0's - that is, if you see a picture such as shown to the right - contact your instructor to have the firmware reset on your system. (If you're adventurous, you can simply start up a DOS prompt and execute "H:\Apps-EMS\HiC\rcxfirm.bat".)

  4. Aim the front panel of the robot at the tower with a few inches between the two (as shown to the right). The picture is a thumbnail - click on it to make it larger.

  5. Make sure the unit is turned on - it turns itself off after a few minutes of inactivity - and click on the button with a red arrow pointing from a document to a
picture of the RCX unit. During the download, you should see dots flashing across the top of the RCX display. When the program is downloaded the robot will play a quick tune and you should see "No errors! Downloading Program:....complete" at the bottom of the HiC window. If you get a message about "no firmware", you need to reload the firmware as described above. For other error messages, contact your instructor.

  6. Put the robot near the center of the table and click the green Run button on the RCX unit. The robot should play a quick tune and start spinning around. Since there's nothing to make the motors stop, it will keep spinning until you turn it off (by pressing the red button).

    Warning! Be careful that the robot does not fall off the table. It should survive the fall onto the carpet, but all of the pieces will fall off and you'll have to reconstruct the robot before continuing.

  7. Next we will extend the program so that the robot reacts to the world. There should be a small light sensor (see right) attached to the robot on input port 3. Change your main to use the following to spin the robot right or left depending on how much light is reaching the sensor.
       int level;
       readLightSensor(3, level);
       if ( level > 40 )
       {
          // bright light, spin right
          MotorAOnRev();
          MotorCOnFwd();
       }
       else
       {
          // dark, spin left
          MotorAOnFwd();
          MotorCOnRev();
       }
       wait(500);   // turn for 5 seconds
       MotorAOff(); // stop
       MotorCOff();
    
    When you press the run button, if there's a decent amount of light in the room then the robot should spin to the right. Next, cover the light sensor with something like a mouse pad (or anything black - your hand will probably not work) and run the program again. This time the robot should spin the other direction. Note the sensor has to be covered before you press the run button; the program reads the light sensor just once and so later changes are ignored.

    If you're having troubles getting the robot to spin both directions, press the View button on the RCX unit until there's a little "^" below the light sensor port. The display will show the current level; you can use this information to adjust what level controls whether the robot spins right or left. The number read by the sensor is between 0 and 100 with 0 being very dark and 100 being very light. The above program uses 40 simply because that's been found to work well in the lab; you might need a larger value if your room lighting is brighter and a smaller value if it's darker.

    Further robot commands are documented in the next section. You might want to skim through the list to get an idea of what commands are available.

  8. Once you have run through the demo, click on the new document button to create a new program and work on the lab problem. Please turn the robot off when it's not in use to conserve the batteries.

Robot Commands

There are a number of commands you can use to program the robots. This section covers all of the ones you may need for the first lab.
Category Command Effect
Movement MotorAOn();
MotorBOn();
MotorCOn();
Turn on the specified motor.
  MotorAFwd();
MotorBFwd();
MotorCFwd();
Set specified motor to go forward.
  MotorARev();
MotorBRev();
MotorCRev();
Set specified motor to run in reverse.
  MotorAOnFwd();
MotorBOnFwd();
MotorCOnFwd();
Run specified motor forward.
  MotorAOnRev();
MotorBOnRev();
MotorCOnRev();
Run specified motor in reverse.
Stopping MotorAOff();
MotorBOff();
MotorCOff();
Turn off specified motor.
Waiting wait(hundredths); Wait for given hundredths of a second; wait(100); waits 1 second.
Sound playSound(s); Play sound s where s is one of CLICK, DOUBLE_BEEP, DOWN_SCALE, UP_SCALE, LOW_BEEP, or FAST_UP.
Checking Sensors readLightSensor(p, x); Read value of light sensor from port p (1, 2, or 3) into int variable x.
  int lightSensorLevel(p) Get value of light sensor from port p (1, 2, or 3).
This is the preferred variant on readLightSensor. The code
  if ( lightSensorLevel(1) > 50 )
     MotorAOnFwd();
would turn on motor A if the light level on port 1 is over 50.
  readTouchSensor(p, pressed); Set bool variable pressed to whether or not touch sensor on port p is currently pressed.
  bool touchSensorActive(p) Get whether touch sensor on port p is currently pressed. This is the preferred variant on readTouchSensor.
  displaySensor(p); Show current value of sensor on port p.