LMICSE: Lego Mindstorms in Computer Science Education

Site Map | Contact Us
Project Overview | Staff | Grant Information
Short Workshops | Primary Workshops
CS 1 | Data Str. & Algo. | Prog. Languages | Architecture | Intelligent Sys. | Operating Sys. | Net-centric
Ada | C | C++ | Java | Lisp

Simon Says - Using Lego Assembler

small logo

Goal

Use Lego’s LASM assembly language to write a program that can play a game of Simon Says on the yellow RCX brick. The brick will tell the user a pattern of input signals (using tones and lights) and then expect the user to repeat that pattern via three touch sensors (or light sensors) correctly in order for the length of the pattern to increase. The pattern’s creation and maintenance during a game will be supported in the program through use of the abstract concept of a queue for the program to “remember” the key sequence and use of the concept of randomness to generate test sequences. In addition to experience with assembly language programming, this project will give you familiarity with the following:

  • the concept of indirect addressing (as you use it to access entries in an array being used as a queue),
  • the practice of polling sensors for input while waiting for an input signal from the user, and
  • the writing and debugging of embedded programs.

Equipment

  • Lego® MindstormsTM SDK
  • Lego RCXTM Microcomputer
  • Infrared Transmitter (Serial or USB)
  • Three LEDs (optional, since LCD display can also be used to tell the user the sequence of input signals required of the user)
  • Three Touch Input Sensors

Algorithm (in pseudocode)

  1. Set up sensors & LCD
  2. Set up a random sequence of length X (at least 8) of input port numbers
  3. I = 1
  4. LOOP:
    1. Display in sequence the first I numbers (with accompanying lights or sounds) for user
    2. Have user re-enter sequence in a set period of time
    3. IF: user fails
      1. play error tone, jump out of LOOP and terminate.
    4. ELSE:
      1. add one to I
      2. IF I is greater than X, play victory tune, jump out of LOOP, and terminate
  5. Go to TOP OF LOOP

Instructions

Using the RCX: When you turn on your RCX (press the ON-OFF button), you’ll see four zeros on the RCX's LCD display followed by a stick figure, followed by a 1 (see figure). The four zeros actually are a clock that shows how long the RCX has been turned on. As each minute goes by, the clock will increase by one unit. If you do not see four zeros when you turn the RCX on, that means your batteries either died or temporarily lost contact inside the RCX, causing all firmware in the RCX to be lost. If this happens, you will need to redownload the firmware to the RCX. When you start coding and downloading your program into the RCX, remember that after you get the code into your RCX you need to press the green RUN button to execute the program. You should not need to press the VIEW or PRGM buttons at all. VIEW is used to see what value is being read in by the sensor port, or what direction a motor port is running in. By repeatedly pressing VIEW you can cycle through all sensor and motor ports. If the number after the stick figure ever becomes something other than 1, please press the PRGM button repeatedly until you see a 1. Your RCX may turn itself off after 5 minutes. This is to conserve battery power and is completely normal.

Using the LASM Editor: At the end of this description is a screen shot of the LASM Editor/Assembler, with a sample portion of code displayed in the editor.

The RCX can actually support the interleaved execution of more than one task (process) at a time. You will not need to use more than one task for this project. However, you’ll still need to start the one task you’re writing with the task 0 directive, and you’ll need to end that task’s code with the endt directive.

You should find the text boxes in the screen shot helpful in using the Editor. The buttons not referenced in the screen shot won’t be needed in your project. In the Editor’s top menu there is a HELP menu from which you can look up all LASM commands as well as the meanings of all Editor buttons and settings.

Coding Help Part 1: Write code in the LASM editor to set up your sensor ports so that they can access touch sensors in Boolean mode. For this part’s preliminary version of the final program, define some fixed-length constant sequence of input signals in an array ahead of time and have the program only play that for easier debugging. Implement the Simon Says algorithm taking into account what to do if the user is incorrect. Things to consider: how will the user know which sensor to press? You can display a number or character on the RCX’s LCD, light up LEDs attached to the output ports, play sounds, or perhaps do something else. How will the user know he/she entered the next correct signal in the sequence? Should you play a tone when the user presses an input button? How will the program mark time before deciding that the user is too late in entering a signal (hint: you may need to consider looping over a command that checks what a timer register contains...see the “timer source” documentation on page 6-7 of the Firmware Overview)? Figure out all of these ideas before coding.

When you want to display a value on the LCD in some format, you will often need to use the disp command followed immediately by the view command. The disp only sets up special hidden registers to show what thing you want to display in the way you want to display it; the view command is what you use to actually cause something in a register to be displayed according to the settings set up in the last disp command executed.

Coding Help Part 2: Once the pre-defined sequence works, we must now concentrate on a random sequence. Lego has a built in source number (4) for specifying random values as arguments to machine instructions, so there is not even a need to create a junk variable or call a subroutine of some sort as with other hardware platforms. Remember, however, to take into account that the random numbers are generated in the range from 0 to the bound specified, so it will make your program’s logic more straightforward to represent the input buttons internally as 0,1,2 instead of the 1,2,3 shown on the RCX case. Remember though that on the LCD you’ll need to display 1, 2, 3 if you are using the LCD to tell the user what button to push next in the sequence. Each new random number your program creates will have to be stored into the queue, but this is only if the user can enter the correct sequence. The sequence should begin with one random input number and grow as the user enters data correctly. How will the program know that the sequence has reached a maximum length?

Syntax and Programming Conventions

All of the commands listed should be referenced to the manual distributed in printed form or available in the Mindstorms SDK as the .pdf LASM Byte Codes. The following is by no means an exhaustive account of the functions, but is meant to call attention to the most important ones. The exhaustive account is the aforementioned .pdf file.

  • The Variables are numbered 0-31, and function like Machine Registers, but are called variables.
  • Certain commands accept parameters as a source and value pair. The source tells the type of the parameter and the value is typically the index of that particular type of parameter.
    • Important source numbers: 0 (register), 2 (literal value), 13 (Boolean sensor input), 36 (indirect addressing... access the Variable whose number is found in the Variable whose number is the value supplied for this source), and 4 (random)
    • To set variable 31 to the literal number 12, do the following:
      • setv 31, 2, 12
    • However, to set variable 31 to the value in variable 29:
      • setv 31, 0, 29
    • To display the data held in the address held in variable 20 on the LCD
      • set 0, 8, 36, 20
      • (register 8 is the LCD's display register, variable 20 holds the address of what will actually be displayed.)
    • To set the data held in the address held in variable 19 to a random
      • set 36,19,4,2
      • (special note on randoms: the second value in the source value pair is the range for the random)
  • The following commands will be most useful for you in writing your program:
    • setv variable number, source, value
      • Sets the given variable with the given number.
    • chk src1, val1, relop, src2, val2, (forward label or jump distance)
      • If the comparison fails between source value pair one and source value pair 2 (src1,val1 and src2,val2)
      • The comparison itself is designated by relop: (relational operator) 0 == Greater than, 1 == Less than, 2 == Equal to, 3 == Different from
    • task 0
      • begins main task (like an int main())
      • other tasks can be numbered and will be processed in order
    • endt
      • ends task
    • disp precision, display source, display value
      • The command sets the user option for the LCD display. The LCD update process will then track the given data source and display it in the LCD display with the given decimal point position.
    • view view source, view value
      • The value is evaluated and the LCD display will then show and update the corresponding data source.
      • view 2,7 will set the LCD to display what is specified in the disp command
    • jmp address
      • The command jumps a certain number of steps if a number is address, otherwise to a label named by address
    • calls subroutine number
    • sub number
      • designates a subroutine
    • ends
      • ends a subroutine
    • sent sensor number, sensor type
      • Sets the given sensor to the given type. Resets previous sensor state and sensor information. Default sensor modes are assigned or each type of sensor.
      • For this lab, set the sensor to type 1 (switch), which is by default boolean
    • senm sensor number, sensor mode, slope
      • slope of 0 is absoute measurement (yes/no)
      • modes are listed on pg 53 in manual, 1 for boolean (yes/no) is appropriate for this lab
  • Execution begins with task 0, terminated by the endt command
  • Labels for jmp commands are always ended with a colon
  • To Display a variable to the screen, it needs to be placed in an infinite loop
    • Use the disp and view commands together
  • Document your code by typing out what variables are being used for what. Because the variables are numbers and unnamed, it can be confusing to track them down later.

Script Editor

Acknowledgements

This project was created by Frank Klassner.