Programming Lego Mindstorm "PenBot" with NXC

Definition of a Robot: A Robot is a machine that can be programmed to do a task without being directly controlled by a human being.   There are two parts to a robotic system.

1. Hardware: This is the mechanical robot. The motors, gears, wheels, parts, computers that make up the machine.  This is the part you build.

2. Software:  This is the instructions for the tasks and actions the robot will do.  This is the part you write.

NXC Language is used to create the software that controls the actions of the robot hardware.  NXC is a text based system of assembling instructions for the machine.  The flow of direction usually moves sequencially from top to bottom.  This software is an example of a compiled program.  Programs you write in NXC must be compiled with NBC and downloaded to the NXT Brick using Bricx Command Center before the Robot will perform the program.  (Scratch and Python are "Interpreted Languages.")

The website for NXC and Bricx Command Center:

More Online Resources:

Motors and Sensors for the "PenBot"

Building Instructions for PenBot - note the Lego Digital Designer does not have an image for the large wheels. Thus the design lacks the wheels, simply add them when finished building.

Building Instructions for PenBot

Two motors that control the drive wheels are connected to the B and C ports. The A motor controls the Pen.

C = Left Motor
B = Right Motor
A = Pen Motor

The Touch, Ultrasonic, and Light Sensors are plugged into their default positions.

Touch Sensor:       Port 1
Ultrasonic Sensor: Port 4
Light Sensor:         Port 3

Overview of Bricx Command Center IDE:

Basic Bricx / NXC Commands:

Motor (Output) Commands:

OnFwd("ports", "pwr");
OnRev("ports", "pwr");
OnFwdSync(“ports”, “pwr”, “turnpct”);
RotateMotor(“ports”, “pwr”, “angle”);

Flow Commands:

Wait(4000);     (milliseconds)
until (“condition”);
repeat (“value”)

Task and Sub Commands:

Sub methodName()

task main()

Structure of NXC Commands:

Process and Tutorial:

1. Getting Started:

  • Start Bricx Command Center
  • Select “usb” and “NXT”
  • Turn On Robot
  • Plug Robot Into Computer
  • Wait short time for computer to recognize Robot
  • Click “OK”

2. Take a test drive!

Click “Joystick” Tool
Set Motors to C Left and B Right
Try the Arrows! (Make sure the robot does not drive off the table!)

3.   First Robot Program: Out and Back

4.  Compile and Download!
  • Save Your Program (File -> Save)
  • Select “Compile->Compile” from menu bar. (Or “F5”)
  • Turn On Robot
  • Select Compile -> Download
  • Wait for Beep
  • Unplug Robot and Test! (Use Orange Button)
    • Robot: Software -> My Files -> Your Program
    • Select Program with Orange Button

5.  Swing and Point Turns:

The Robot needs to be able to Turn Right and Left. There are two types of turns:

Swing Turns: The Robot rotates one wheel and pivots on the opposite wheel.


By Time:

By Rotation Degrees:

Point Turns: The Robot rotates both wheels in opposite directions to pivot on a center point between the wheels.


By Time:

By Rotation Degree Left:

By Rotation Degree Right:

6.  Drive a Rectangle

Using the OnFwdSync() command and your choice of turns. Write a program that drives your robot in a rectangle. Here is a short code example to get you started:

7. Navigate a Maze

More fun with forward and turns. Find the right combination of OnFwdSync() and turns to navigate Maze #1 and Maze #2.

8.  Turns Worksheet

Use the following chart and figure out the Wait() times and degrees for 90 degree Swing and Point turns.

Swing and Point Turns Worksheet

9.  Create subs for Turns and Forward Commands

Retyping a long series of commands for each turn makes for a long process in programming. We need to "teach" the robot how to make a 90 degree Right Point Turn. Then we can use a one line command like "turn90DegRight()" to turn the robot instead of 4 lines.

We use the "sub" structure to teach the robot tricks. Here is an example of a "sub" defining the Right Point Turn and then using the "main" task to run the Right Point Turn command:

Here is an example of a sub that allows you to tell the robot to move straight forward for a certain number of Motor Rotation Degrees:

To use the subs in your program, call them in the "task main ()" section. Here is an example of the Rectangle Program using subs. Notice the use of the "include" command on line 5. You can define the subs in another file and then include them in your current program.

Make at least 3 other subs to simplify your turn commands. Here is a link to some common subs for turns and forwards. I suggest creating subs for forward degree and Point Turn right and left by degrees.

6 usefull subs to simplifiy movement commands

10.  Create a Dance Routine.

Choose music and create a 20 second dance routine for your robot. Mix up OnFwd() and turn commands to make an interesting sequence of moves.

Use Dance Worksheet to plan out your Robot Moves:

Dance Worksheet

The dance program should be organized according to the following format:

Here is an example of a simple dance program:

11.  Use the Pen to Draw a Picture

The PenBot has the A motor connected to an attachment that can hold a "Sharpie" pen. The A motor can lift the pen and place it back down to make drawing as the robot moves. Use large sheets of paper and program the robot to make simple drawings.

To make your programming easier - you may use this file with several pre-defined subs for movement, turns, and Pen up and down:


Steps to using PenSubs.nxc:

1. Download the above file.
2. Save it into the same directory that you save your other nxc programs.
3. In your programming put at the beginning of the program:

#include "PenSubs.nxc"

4. You have access to the following sub commands:

ForwardDeg("speed", "degrees"); ForwardDeg(50, 720); Drive Forward at a given speed for a given rotation of wheels.
ReverseDeg("speed", "degrees");
ReverseDeg(50, 720);
Drive Reverse at a given speed for a given rotation of wheels.
ForwardTime("speed", "time");
ForwardTime(50, 2000);
Drive Forward at a given speed for a given time in milliseconds (1000 = 1 second)
ReverseTime("speed", "time");
ReverseTime(50, 2000);
Drive Reverse at a given speed for a given time in milliseconds (1000 = 1 second)
PointTurnRightDeg("speed", "degrees");
PointTurnRightDeg(50, 360);
Point Turn Right at a given speed for a given rotation.
PointTurnLeftDeg("speed", "degrees");
PointTurnLeftDeg(50, 360);
Point Turn Left at a given speed for a given rotation.
PointTurnRightTime("speed", "degrees");
PointTurnRightTime(50, 1000);
Point Turn Right at a given speed for a time in milliseconds.
PointTurnLeftTime("speed", "degrees");    
PointTurnLeftTime(50, 1000);
Point Turn Left at a given speed for a time in milliseconds.
Point Turn 90 degrees to the right.
Point Turn 90 degrees to the left.
Pick up the pen.
Put the pen down.

Example Program: Draw a Square

12. More Ideas for drawing and creating subs with "PenSubs.nxc"

You can make your own subs to redraw shapes like rectangles and circles that you use over and over in your drawings. Here are some examples you may copy and paste into your own code above your task main() method. (***Make Sure to use the #include "PenSubs.nxc" command in your programs - or these shape subs will not work.***)

Circle Left

sub CircleLeft(int power)
    RotateMotor(OUT_B, power, 1150);

Circle Right

sub CircleRight(int power)
    RotateMotor(OUT_C, power, 1150);


sub Rectangle()
    repeat (2)
     ForwardDeg(50, 720);
     PointTurnLeftDeg(40, 125);
     ForwardDeg(50, 180);
     PointTurnLeftDeg(40, 125);

Sample Program creating a row of circles using Subs

Sub for creating "Flower Petals." How do the circles work in this sub?

For our High School Assistants (And any other brave student . . ): What does this sub do?

Combine rectangles and circles to draw composite images, like cars, buildings, ice cream cones, flowers, faces, trains, or anything else you can think of!

13. Arc sub for drawing curved lines

Arc draws curved lines. You man copy and paste this sub directly into your programs. Arc takes the values for C motor, then B motor, and then time in milliseconds. Motor values can range from -100 to 100.

Subs for ArcLeft and ArcRight

sub Arc(int motc, int motb, int time)
    OnFwd(OUT_C, motc);
    OnFwd(OUT_B, motb);

Example of Arc subs in program.

Email Mr.Michaud

Copyright ©2011 Mr. Michaud.