OPTIONS: An Exploration of Possibilities

EE/CS: Basic C Using the Robotics Library

Summer 2003

This handout basic programming constructs and how they are implemented using the C programming language syntax and semantics using the UE robotics library.

What is a program?

A program generally consists of three parts, constants, variables, and executable statements. A constant is name whose associated value cannot be changed. Basically, anywhere the constant name is used in a program, its value is substituted. A variable is a named piece of memory that can be used to store some data. This data can be input by the user of the program or it can be the result of some sensor or it can be computed using other pieces of data. In most languages, we can also specify the type of constants and variables, which restricts the type of data that can be stored in the constant or variable. Some common types include integer, floating point, character, and string.


Executable statements tell the computer what to do with the data. There are several different kind of control statements:

Main program

The main program in Keil C for the robotics controller has the following syntax:
   /* included libraries go here */

   /* constant definitions go here */

   void main (void)
   {
       /* variable declarations go here */

       /* executable statements go here */
   }
Sometimes we want to write notes to ourselves about what the program is doing. This can be done by using comments which in C begin with /* and end with */. Everything between these marks is ignored. So in the above example, we would replace the comments with the actual code that does those things.

Included libraries

If we had to write code for absolutely everything every time we wanted a new program, it would take a very long time to write a program and most of it would be the same as previous programs. Luckily, others have already written these parts and put them in a library. For example, the routines to read sensors and control motors and LEDs on the LEGO board are contained in a library. We tell the compiler we want to use this library by including it in our program. Since the name of the OPTIONS LEGO robotics library is robotic7opt.h, we write at the beginning of our programs.
   #include "robotics7opt.h"
Every OPTIONS LEGO project program must have this line at the beginning.

Constants

Sometimes we'd like to give a constant value a name, so we can remember why we used a particular value or to make it easy to change the value in a lot of places. This can be done using the #define syntax. For example, from the robotics library,
   /* Sound constants */
   #define OFF 0
   #define ON 1
defines the word OFF to have value 0 and the word ON to have value 1. Now we do not have to remember which value (0 or 1) will turn the buzzer off or on, and only have to remember the words, which is much easier to do. By convention, constant names are written in all uppercase letters with words separated by underscores.

Variables

Recall that a variable is a memory location where a piece of data can be stored and retrieved. Variables are declared (made known to the compiler) in C using the following syntax:

type namelist ;
The namelist is one or more names separated by commas. A name must start with a letter (either uppercase or lowercase), and can be any combination of letters, digits, or the underscore character ('_'). C is case sensitive, which means that it cares about the difference between uppercase and lowercase, so that the name sum is different than SUM or Sum. Keil C supports a number of different types, but for now we will only be using one of them: unsigned char which is used to hold characters and small positive integers. Here are some examples of variable declarations:
   unsigned char i, j, k;
   unsigned char channel0, channel1;
Each type has some literal values. For unsigned char, they can be small integers like 0 1 23 42 or a character enclosed in single-quotes. For example, 'A' 'z' '3' '?'. Note that integer 3 is not the same as character '3'. For the OPTIONS LEGO project, we will be storing small integers.

Assignment statements and expressions

To give a variable a value, you can assign a value to it by using the following syntax:

variable = expression;
The expression can be a literal value (e.g., 10), a variable name, a function call (more on that later), or a mathematical, relational, boolean, or bitwise expression involving literals, variables, function calls or other expressions. The operations supported as operators by C include:
Operation Operator Operation Operator
Unary Negation - Equality ==
Addition + Inequality !=
Subtraction - Less than <
Multiplication * Less than or equal <=
Division / Greater than >
Integer remainder % Greater than or equal >=
Logical negation (NOT) ! Bitwise XOR ^
Logical conjunction (AND) && Bitwise AND &
Logical disjunction (OR) || Bitwise OR |
The mathematical operations have usual precedence and associativity, and are of higher precedence than the relational and logical operators. The relational and logical operators compute a result of 1 (for true) or 0 (for false). The bitwise operators are used in the robotics library to manipulate single bits and are included here for completeness. Some examples of assignment statements and expressions:
   var1 = 1;
   var2 = var1 + 5;
   var3 = var1 < var2;
   var4 = var1 + var2 - var3;
   ch1 = 'A';

Input/Output

Because the LEGO controller board does not have a keyboard or a monitor, we cannot use built-in C language constructs for input and output. Instead, the controller board allows a program to read a sensor or make the buzzer sound using function calls.


The OPTIONS LEGO project has one type of sensor, an A to D converter (that can be used to read light sensors). There is a function for reading the A to D converter. It is used as follows:

   GetAtoD(chNum)
Where chNum is a channel number 0-7, and the function returns the value read in from the sensor attached to that channel. Some examples:
   channel0 = GetAtoD(0);
   channel1 = GetAtoD(1);


The buzzer can be turned on and off using the Sound(state) or Beep(num) functions. The Sound function turns the buzzer on if argument state is 1 and off if the argument is 0. As noted above, the robotics library defines constants ON and OFF for use with this routine. Beep oscillates the buzzer for num cycles. An example:

   /* Beep 5 times */
   Beep(5);

Selection statements

Selection statements are for choosing between different sets of statements to be run. The if-statement in C has the following syntax:
if ( condition )
{  
  statements for true condition
}  
else  
{  
  statements for false condition
}  
The condition can be any expression. The semantics of this statement is if the condition is true (a value that is not 0), then the statements for true condition are run and the statements for false condition are ignored. If the condition is false (a 0 value), then the opposite happens and the statements for the true condition are ignored and the statements for false condition are run. In both cases, after the appropriate statement is run, the next statement after the if-statement is run. The else portion is optional. If it is missing, nothing is run when the condition is false. Since the if-statement is just another statement, it can nested inside another if-statement. For example,
   if (channel0 + 20 < channel1)     /* Right eye darker than left eye */
   {
      Beep(1);                       /* Beep once */
   }
   else
   {
      if (channel1 + 20 < channel0 ) /* Left eye darker than right eye */
      {
         Beep(2);                    /* Beep twice */
      }
      else                           /* Both eyes about the same */
      {
         Beep(3);                    /* Beep three times */
      }
   }
will make the controller board beep the appropriate number of times depending on which ``eye'' is darker.

Repetition

Repetition statements are used to repeat a set of statements. There are several kinds of repetition statements in C, but we will only use one in the OPTIONS LEGO project. It is the while-statement. Its syntax is:
while ( condition )
{  
  statements to be repeated
}  
In this repetition statement, the condition is checked to see if it is true or false (just as for the if-statement). If it is true, the statements to be repeated are run. If it is false, the repetition stops and the next statement after the while-statement is run. For example, the following code will check the eyes 10 times and stop.
   count = 1;
   while (count <= 10) /* repeat until count become greater than 10 */
   {
      channel0 = GetAtoD(0);            /* Right "eye" */
      channel1 = GetAtoD(1);            /* Left "eye" */
      if (channel0 + 20 < channel1)     /* Right eye darker than left eye */
      {
         Beep(1);                       /* Beep once */
      }
      else
      {
         if (channel1 + 20 < channel0 ) /* Left eye darker than right eye */
         {
            Beep(2);                    /* Beep twice */
         }
         else                           /* Both eyes about the same */
         {
            Beep(3);                    /* Beep three times */
         }
      }
      count++;  /* Increment count */
   }
For the LEGO car, usually we want the program to just repeat continuously, so we write:
   while (1)  /* Repeat continuously, since the condition is always true */
   {
      /* statements to be repeated */
   }

Functions

A function is a subprogram. When a function is used, we say it is called, and the subprogram that uses the function the caller. When a function is called, the caller can pass data to it called the arguments, and the program jumps to the function code and executes it. When the function is finished, it can return a result, and the program jumps back to where the function was called and resumes executing.


A function call is just the name of the function and a comma-separated list of arguments you want to pass to the function. The syntax is:

function-name ( argument-list ) ;
An argument can be a constant, an expression, or a variable. If the function returns a result, you need to assign it to a variable to save it.


The robotics library routines are all functions. For example, when you write something like

    Beep(2);        /* Beep twice */
you are telling the program to go to the subprogram called Beep giving it the values 2. The subprogram then does whatever it is suppose to do, in this case making the buzzer beep twice. A sensor reading function like GetAtoD returns a value that you can use to determine the state of the sensor.


For the OPTIONS LEGO project, you will not need to write your own functions. However, the robotics library consists of only functions, so you can look at robotics7opt.c if you want to see some examples.


There are a few other functions of interest in the robotics library. There is an initialization routine for the motors called InitializeMotors(), There are two functions related to controlling the motors. AllStop() causes all motors to stop. SetMotor(motorID, speed) will set the motorID motor (1-3) based on the speed, which should be an integer between -255 and 255. A negative speed will make the motor go ``left'' or ``reverse'', while a positive speed will make the motor go ``right'' or ``forward''. (Which actual direction these are depends on how the motors were wired to the controller.) A speed of 0 will cause the motor to stop. Finally, there is Delay(count), which causes the processor to ``busy wait'' for approximately 200 microseconds for each count.



Converted using latex2html on Wed Jun 25 10:59:47 CDT 2003