Controls

Controls, aka Control Flow, change the flow of your program and enable conditional or branching logic. For example, "if speed > 20, then turn LED lights red." There are lots of different types of controls to make interesting programs that go beyond a procedural set of Action commands.

Delay

controls_delay delay runs the active code for a duration, or creates a gap in activity if there is no active code. For example, use the below to set Speed to 100 for a duration of 3s, then stop:

void startProgram()
{
    controlSystemTargetSpeed = 100;
    delay(3);
    controlSystemTargetSpeed = 0;
}

Loop

controls_loop A loop repeats the code within for the number of loops, also known as a "while" loop. Notice we use loopCount# below, which is different than in the C-language. Oval requires you to set a unique int value for each loop. The loopCount syntax is not required, you can just use the unique int value, but we use it here to make it very clear for new users because it is a departure from C.

int _loopCount_int# = 0;
while (_loopCount_int# < #loops)
{
    _loopCount_int# = _loopCount_int# + 1;
    // code to loop
}

For example, to set a random color on the main LED's every 0.2s for 20 loops, use:

void startProgram()
{
    int _loopCount_1 = 0;
    while (_loopCount_1 < 20)
    {
        _loopCount_1 = _loopCount_1 + 1;
        setRgbLed(nextRandomFloat * 255, nextRandomFloat * 255, nextRandomFloat * 255);
        delay(.2);
    }
}


To add a second loop to this program, increment the int value using _loopCount_2. For example, use the below to run the random color loop from above, then a second loop that replicates the colors of a traffic light, 4 times:

void startProgram()
{
    int _loopCount_1 = 0; // random color loop
    while (_loopCount_1 < 20)
    {
        _loopCount_1 = _loopCount_1 + 1;
        setRgbLed(nextRandomFloat * 255, nextRandomFloat * 255, nextRandomFloat * 255);
        delay(.2);
    }
    int _loopCount_2 = 0; // traffic light loop
    while (_loopCount_2 < 4)
    {
      _loopCount_2 = _loopCount_2 + 1;
      setRgbLed(0, 255, 0); // green
      delay(.8);
      setRgbLed(255, 250, 57); // yellow
      delay(.8);
      setRgbLed(255, 0, 0); // red
      delay(.8);
    }
}

Loop Until

controls_loopUntil Loop until repeats the code within until a condition is met, also known as a "while not true" loop. You will need to understand how to write conditions with Operators and Comparators before using Loop Until and the rest of the controls below.

while (not(true)) //code to evaluate a condition 
{
    // code to loop until the condition is met, then exit the loop
}

For example, you can recreate the Loop Until portion of the Speeding ticket program from the "Blocks 3: Variables" Activity to increase Speed until reaching the "Speed Limit", which is 80 in this case. Given 20 + (20*x) = 80, you should see the Loop repeat 3 times (hearing the ding sound each time) before reaching Speed 80 and then stopping. You will need about 12ft of clear floor space to run this program:

void startProgram()
{
    setRgbLed(16, 255, 0);
    controlSystemTargetSpeed = 20;
// increase speed until it reaches 80
    while (not((controlSystemTargetSpeed == 80)))
    {
        playSound(0, 7);
        delay(0.05);
        controlSystemTargetSpeed = (controlSystemTargetSpeed + 20);
        delay(1.5);
    }
    setRgbLed(255, 11, 45);
    controlSystemTargetSpeed = 0;
    playSound(0, 7);
    delay(0.05);
}

Loop Forever

controls_loopForever Loop Forever repeats the code within forever until you stop the program, also known as a "while (1)" loop.

while (1) // 1 signifies infinity 
{
    // code to loop forever
}


For example, to create a metronome program that adds 180° to the heading every 1s and runs forever, use:

void startProgram()
{
    backLed = 255;
    while (1) // loop heading changes forever
    {
        controlSystemTargetYaw = (controlSystemTargetYaw - 180); 
        delay(1);
        controlSystemTargetYaw = (controlSystemTargetYaw + 180);
        delay(1);
    }
}


You can also nest loops rather than running them sequentially. For example, the below metronome program replaces the basic delay code with a light sequence using a nested loop of light commands to make it a little more interesting, but maintains the 2 second period:

void startProgram()
{
    backLed = 255;
    while (1)
    {
        controlSystemTargetYaw = (controlSystemTargetYaw - 180);
        int _loopCount_1 = 0;
// add blnking lights instead of the basic delay
        while (_loopCount_1 < 2) 
        {
            _loopCount_1 = _loopCount_1 + 1;
            setRgbLed(255, 0, 25);
            delay(.25);
            setRgbLed(255, 255, 255);
            delay(.25);
        }
        controlSystemTargetYaw = (controlSystemTargetYaw +180);
        int _loopCount_2 = 0;
// add blnking lights instead of the basic delay
        while (_loopCount_2 < 2)
        {
            _loopCount_2 = _loopCount_2 + 1;
            setRgbLed(8, 54, 255);
            delay(.25);
            setRgbLed(255, 255, 255);
            delay(.25);
        }
    }
}

If Then

controls_ifThen If Then statements call the code within only if the given condition is true. Use and to combine, and or to exclude conditions.

if (true) // code to evaluate a condition 
{
    // code executed if condition is true
}


For example, to change the main LED's to green when you tap the robot on a table measured with the accelerometer as accelSensorZUp > 3, nest an if then statement within a while (1) loop like this. The parent while (1) loop is needed because we need the condition to be continually evaluated, not just once:

void startProgram()
{
    while (1)
    {
// is the accelerometer z-axis reading more than 3G's?
// hint: tap the robot on a table
        if ((accelSensorZUp > 3)) 
        {
// if true, change the LED's to green for 1 second
        setRgbLed(0, 255, 0);
        delay(1);
        setRgbLed(0, 0, 0);
        }
    }
}

And

and requires a second condition for the statment to be true. You can add as many required conditions as you want, but let's just add a second requirement to turn the LED's green. The second condition will be a forward pitch measured by the gyroscope as imuPitchAngle < -45. You will need to aim the robot ensuring the tail light faces you, pitch it forward 45° then tap it on the table and the LED's will turn green if you have the pitch angle correct:

void startProgram()
{
    controlSystemIsOn = 0;
    while (1)
    {
// is the accelerometer z-axis greater than 3G's AND the pitch angle less than -45?
// hint: tap the robot on the table while pitching it forward  
        if (((accelSensorZUp > 3) and (imuPitchAngle < -45))) 
        {
// if true, change the LED's to green for 1 second
            setRgbLed(0, 255, 0); 
            delay(1);
            setRgbLed(0, 0, 0);
        }
	}
}

Or

or is the opposite of and; it requires one of N conditions for the statment to be true. Let's take the prior program and change and to or, making it so that the forward pitch or the table tap will change the main LED's to green:

void startProgram()
{
    controlSystemIsOn = 0;
    while (1)
    {
// is the accelerometer z-axis greater than 3G's OR the pitch angle less than -45?        
        if ((accelSensorZUp > 5) or (imuPitchAngle < -45))
        {
// if true, change the LED's to green for 1 second
            setRgbLed(0, 255, 0);
            delay(1);
            setRgbLed(0, 0, 0);
        }
	}
}

If Then Else

controls_ifThenElse If Then Else statements call the "if" code when the given condition is true; otherwise calls the "else" code.

if (true) //code to evaluate a condition 
{
    // code executed if condition is true
}
else
{
    // code executed if conidtion is false
}


For example, let's build on the "if then" sample above by offering an "else" condition setting the LED's to red when the condition is not true:


void startProgram()
{
    while (1)
    {
        if ((accelSensorZUp > 5))
        {
            setRgbLed(0, 255, 0);
	        delay(1);
        }
        else
		{
// if false, change the LED's to red
        	setRgbLed(255, 0, 0); 
		}
    }
}


To create > 2 outcomes you can nest N "if then else" statements. For example, let's create a program with 3 conditions where the LED's are red at rest, blink green when you tap the robot on the table, or blink blue when I pitch the robot forward:


void startProgram()
{
    controlSystemIsOn = false;
    while (1)
    {
// green if tapped
        if ((accelSensorZUp > 5))
        {
            setRgbLed(0, 255, 0); 
            delay(1);
        }
// blue if pitched forward
        else
        {
            if ((imuPitchAngle <= -45))
            {
                setRgbLed(0, 0, 255); 
                delay(1);
            }
// red at rest
            else
            {
                setRgbLed(255, 0, 0); 
            }
        }
    }
}

Else if

Else If is used after an if statement to create conditional else logic. This is not available in the block canvas.

if (true) // code to evaluate a condition 
{
    // code executed if condition is true
}
else if (true) // code to evaluate a condition 
{
    // code executed if condition is true 
}

For example, to create a statement where the LED's are red at rest, green with a light tap, and blue with a hard tap use, use:

void startProgram()
{
	while (1)
	{
// red at rest
		if (accelSensorZUp < 3)
		{
			setRgbLed(255, 0, 0);
		}
// green if tapped lightly
		else if (accelSensorZUp < 7)
		{
			setRgbLed(0, 255, 0);
			delay(1);
		}
// blue if tapped hard
		else
		{
			setRgbLed(0, 0, 255);
			delay(1);
		}
	}
}

Wait

Wait requires a child sequence (typically a function) to be completed before the main loop contiues. This is not available in the block canvas. For example, to create a program where a function must be complete before returning to the main loop, use:

void red()
{
    setRgbLed(255,0,0);
    delay(3);
    wait;
}

void startProgram()
{
    red();
    setRgbLed(0,255,0);
}

Return

Return terminates the execution of a function and returns control to the calling function. A return statement can also return a value to the calling function. This is not available in the block canvas. See our modulo operand function for an example.