NXT Programming


Lesson 1

In this lesson we build a LEGO car and equip it with a light sensor. If not already installed then we install the leJOS Java system, [1], and use this to compile and upload a Java control program to the LEGO Mindstorms NXT control unit. The Java control program will make the car follow a black line on a white surface.

The 9797 LEGO car

In the LEGO Mindstorms Education NXT Base Set 9797 there is a building instruction for a car, page 8 to page 22. Page 32 to page 34 shows how a light sensor can be added to the car. Build this car with a light sensor added.

Figure 1 The 9797 LEGO car with two motors.

A Java Control Program: LineFollower

The first Java program that we are going to execute on the NXT is the following Java program that makes the LEGO car follow a black line on a white surface: (LineFollower.java):
import lejos.nxt.*; /** * A simple line follower for the LEGO 9797 car with * a single light sensor. * * The light sensor should be connected to port 3. The * left motor should be connected to port C and the right * motor to port B. * * Variables initialized with a constant string are used * in the LCD.drawString calls of the control loop to * avoid garbage collection. * * @author Ole Caprani * @version 22.08.08 */ public class LineFollower { public static void main (String[] aArg) throws Exception { String left = "Turn left "; String right= "Turn right"; LightSensor light = new LightSensor(SensorPort.S3); final int blackWhiteThreshold = 45; final int forward = 1; final int stop = 3; final int flt = 4; final int power = 80; // Use the light sensor as a reflection sensor light.setFloodlight(true); LCD.drawString("Light %: ", 0, 0); // Show light percent until LEFT is pressed LCD.drawString("Press LEFT", 0, 2); LCD.drawString("to start", 0, 3); while (! Button.LEFT.isDown()){ LCD.drawInt(light.readValue(), 3, 9, 0); } // Follow line until ESCAPE is pressed LCD.drawString("Press ESCAPE", 0, 2); LCD.drawString("to stop ", 0, 3); while (! Button.ESCAPE.isDown()){ if (light.readValue() > blackWhiteThreshold){ // On white, turn right LCD.drawString(right, 0, 1); MotorPort.B.controlMotor(0,stop); MotorPort.C.controlMotor(power, forward); } else{ // On black, turn left LCD.drawString(left, 0, 1); MotorPort.B.controlMotor(power, forward); MotorPort.C.controlMotor(0,stop); } LCD.drawInt(light.readValue(), 3, 9, 0); Thread.sleep(10); } // Stop car gently with free wheel drive MotorPort.B.controlMotor(0,flt); MotorPort.C.controlMotor(0,flt); LCD.clear(); LCD.drawString("Program stopped", 0, 0); Thread.sleep(1000); } }
To make the program control the car we first of all need to install the leJOS Java system for the NXT and second the program should be compiled and uploaded onto the NXT by means of the leJOS system: Follow the description in leJOS NXJ installation guide.

When the upload is completed the LineFollower program can be executed on the NXT. When the program is started the light percent is shown in the LCD until the LEFT button is pressed (the grey button to the left of the orange button in the middle of the NXT). When pressed the program starts to execute its control loop until the ESCAPE button is pressed ( the grey squared button below the ENTER button). In the control loop the light percent is read and compared to a threshold value, the value of the constant blackWhiteThreshold. This means that the program assumes that the light sensor is above a black area when the light percent is below the threshold value and above a white area when the light percent is above the threshold. The actions taken is to either turn left er right. This will make the car follow a black line on a white surface when the car is placed close to the line. Or rather oscillate on the edge between black and white. The control loop is called a controller in control theory, "a controller manipulates the inputs to a system to obtain the desired effect on the output of the system", [2]. The actual controller used in the line follower is called a bang-bang controller, [3], because it only has two states, on black and on white, and an action to be performed in each state.

In the program a constant blackWhiteThreshold is used to separate light percent values into regions that are interpreted by the program as black or white. This constant should be changed if the car do not follow a black line.

Exercise 1

Try to place the light sensor above different colors and make a table of light values corresponding to the different colors. Use the light percent values for black and white to explain how the threshold value could be obtained from a reading above black and white.

Exercise 2

The light sensor is used with the red LED turned on light.setFloodlight(true). This means that the sensor measures the reflection of the red LED. Try to turn the LED off and notice the differens in measurements obtained by making a similar table of readings above different colors. With the LED turned off the ambient light level is measured. This is e.g. usefull in day/night detection.

Exercise 3

In the program a delay of 10 msec is used between light sensor readings. We call this the sample interval. Try with a sample interval of 100 msec, 500 msec and 1000 msec. Explain what happends.

Exercise 4, Data logger

A data logger, [4], is a mechanisme that can be used to collect and record data from e.g. a sensor for later inspection. In the leJOS system a data logger can be implemented to collect data and record them in a flash file. An example of a simple data logger is DataLogger.java. By means of this data logger e.g. the light values read in the control loop can be collected and recorded in a file e.g. Sample.txt. How the DataLogger class is used can be seen in SLineFollower.java. After the program has been stopped, the data in the flash file can be transfered to the PC by means of the tool nxjbrowse. The sampled data can then be used to plot a graph of the light values:

Figure 2 Light values sampled during line following.

Try with different sample intervals and see how this influences the oscillations in the graph.

Exercise 5

Try to use text strings directly in the calls to LCD.drawString instead of the variables right and left. Use Runtime.getRuntime().freeMemory() to show the amount of free memory on the heap during the execution. Use this to explain what happend when text strings are used directly in method calls.


Last update: 4-02-13