# FOR…NEXT

FOR...NEXT Examples

Syntax : FOR Counter = StartValue TO EndValue {STEP {-} StepValue} ... NEXT{Counter}

Syntax : FOR Counter = StartValue TO EndValue {STEP StepValue}... NEXT

## Function

Create a repeating loop that executes the program lines between FOR and NEXT, incrementing or decrementing Counter according to StepValue until the value of the Counter variable passes the EndValue.

- Counter is a variable (usually a byte or a word) used as a counter.
- StartValue is a variable/constant/expression* (0 - 65535) that specifies the initial value of the variable (Counter).
- EndValue is a variable/constant/expression* (0 - 65535) that specifies the end value of the variable (Counter). When the value of Counter is outside of the range StartValue to EndValue, the FOR...NEXT loop stops executing and the program goes on to the instruction after NEXT.
- StepValue is an optional variable/constant/expression* (0 - 65535) by which the Counter increases or decreases with each iteration through the FOR...NEXT loop. On the BS1, use a minus sign (-)† in front of the StepValue to indicate a negative step. On all other BASIC Stamp models, if StartValue is larger than EndValue, PBASIC understands StepValue to be negative, even though no minus sign is used.

* Note: expressions are not allowed as arguments on the BS1.

† Note: Use a minus sign to indicate negative StepValues on the BS1.

## Quick Facts

| BS1 | BS2 Family
Max. nested commands | 8 | 16
To decrement counter variable | Set StartValue > EndValue and enter negative StepValue * | Set StartValue > EndValue
Counter comparison | Exit loop if Counter exceeds EndValue | Exit loop if Counter outside of range set by StartValue to EndValue
Related Commands | None | DO…LOOP, EXIT

*Note: Direction (ie: increment/decrement) cannot be changed at runtime.

## Explanation

FOR...NEXT loops let your program execute a series of instructions for a specified number of repetitions (called iterations). By default, each time through the loop, the counter variable is incremented by 1. It will continue to loop until the result of the counter is outside of the range set by StartValue and EndValue. Also, FOR...NEXT loops always execute at least once. The simplest form is shown here:

    SYMBOL  reps    = B2                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 1 TO 3                     ' repeat with Reps = 1, 2, 3
        DEBUG  "*"                          ' print * on the screen
      NEXT
      END

    reps    VAR     Nib                     ' FOR...NEXT loop counter

    Main:
      FOR reps = 1 TO 3                     ' repeat with Reps = 1, 2, 3
        DEBUG  "*"                          ' print * on the screen
      NEXT
      END

In the above code, the FOR command sets Reps = 1. Then the DEBUG line (within the FOR...NEXT loop) is executed; printing an asterisk (*) on the screen. When the BASIC Stamp sees the NEXT command, it goes back to the previous FOR command, adds 1 to Reps and compares the result to the range set by StartValue and EndValue. If reps is still within range, it executes the code in the loop again. Each time the FOR...NEXT loop executes, the value of reps is updated (incremented by 1) and the code within the loop (the DEBUG line) is executed; printing another asterisk on the screen. This code will run through the loop three times; setting reps to 1, 2 and 3, and printing three asterisks on the screen. After the third loop, again the BASIC Stamp goes back up to the FOR command, adds 1 to reps and compares the result (4 in this case) to the range. Since the range is 1 to 3 and the value is 4 (outside the range) the FOR...NEXT loop is done and the BASIC Stamp will jump down to the first line of code following the NEXT command.

You can view the changing values of reps by including the reps variable in a DEBUG command within the loop:

    SYMBOL  reps    = B2                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 1 TO 3                     ' repeat with Reps = 1, 2, 3
        DEBUG #reps, CR                     ' print number on the screen
      NEXT
      END

    reps    VAR     Nib                     ' FOR...NEXT loop counter

    Main:
      FOR reps = 1 TO 3                     ' repeat with Reps = 1, 2, 3
        DEBUG DEC reps, CR                  ' print number on the screen
      NEXT
      END

Running this example should display "1" , "2", and "3" on the screen.

FOR...NEXT can also be made to decrement (rather than increment) the counter variable. The BS1 does this when you specify a negative StepValue(as well as a StartValue that is greater than the EndValue). All other BASIC Stamp models do this automatically when the StartValue is greater than the EndValue. Examples of both are shown below:

    SYMBOL  reps    = B2                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 3 TO 1 STEP -1             ' repeat with Reps = 3, 2, 1
        DEBUG #reps, CR                     ' print number on the screen
      NEXT
      END

    reps    VAR     Nib                     ' FOR...NEXT loop counter

    Main:
      FOR reps = 3 TO 1                     ' repeat with Reps = 3, 2, 1
        DEBUG DEC reps, CR                  ' print number on the screen
      NEXT
      END

Note that the code for the BS2 series did not use the optional STEP argument. This is because we wanted to decrement by positive 1 anyway (the default unit) and the BASIC Stamp realizes it needs to decrement because the StartValueis greater than the EndValue. A negative StepValue on the BS2 series would be treated as its positive, two's complement counterpart. For example, -1 in two's complement is 65535. So the following code executes only once:

    reps    VAR     Nib                     ' FOR...NEXT loop counter

    Main:
      FOR reps = 3 TO 1 STEP -1             ' decrement 3 by 65535
        DEBUG DEC reps, CR                  ' print number on the screen
      NEXT
      END

The above code would run through the loop once with reps set to 3. The second time around, it would decrement reps by 65535 (-1 is 65535 in two's complement) effectively making the number -65532 (4 in two's complement) which is outside the range of the loop.

All the arguments in the FOR...NEXT command can be constants, variables or expressions (on the BS2 series). This leads to some interesting uses. For example, if you make the StartValue and EndValue a variable, and change their values within the loop, you'll change the behavior of the loop itself. Try the following:

    reps            VAR     Byte            ' counter for the FOR/NEXT loop
    startVal        VAR     Byte
    endVal          VAR     Byte

    Setup:
      startVal = 1                          ' initialize startVal to 1
      endVal = 3                            ' initialize endVal to 3

    Main:
      FOR reps = startVal TO endVal         ' repeat for 1 to 3
        DEBUG DEC reps, CR
        IF (reps = 3) THEN                  ' if reps = 3 then swap startVal and endVal
          startVal = 3                      '   otherwise continue loop
          endVal = 1
        ENDIF
      NEXT

Here the loop starts with a range of 1 to 3. First, the DEBUG line prints the value of reps. Then the IF...THEN line makes a decision; if reps is equal to 3, then swap the order of startVal and endVal, otherwise continue the loop execution. The next time through the loop (after startVal and endVal have been swapped), reps will be decremented instead of incremented because startVal is greater than endVal. The result is a display on the screen of the numbers 1, 2, 3, 2, 1.

The following example uses the value of reps as the StepValue. This creates a display of power's of 2 (1, 2, 4, 8, 16, 32, 64, etc):

    SYMBOL  reps    = B2                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 1 TO 256 STEP reps         ' each loop add current value of Reps
        DEBUG reps                          ' show reps in Debug window.
      NEXT
      END

    reps    VAR     Byte                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 1 TO 256 STEP reps         ' each loop add current value of Reps
        DEBUG ? DEC reps                    ' show reps in debug window.
      NEXT
      END

There is a potential bug that you should be careful to avoid. The BASIC Stamp uses unsigned 16-bit integer math for any math operation it performs, regardless of the size of values or variables. The maximum value the BASIC Stamp can internally calculate is 65535 (the largest 16-bit number). If you add 1 to 65535, you get 0 as the 16-bit register rolls over (like a car's odometer does when you exceed the maximum mileage it can display). Similarly, if you subtract 1 from 0, you'll get 65535 as the 16-bit register rolls under (a rollover in the opposite direction).

If you write a FOR...NEXT loop who's StepValue would cause the counter variable to go past 65535, this rollover may cause the loop to execute more times than you expect. Try the following example:

    SYMBOL  reps    = W1                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 0 TO 65535 STEP 3000       ' each loop add 3000
        DEBUG  reps                         ' show reps in debug window
      NEXT
      END

    SYMBOL  reps    = W1                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 0 TO 65535 STEP 3000       ' each loop add 3000
        DEBUG  reps                         ' show reps in debug window
      NEXT
      END

The value of reps increases by 3000 each trip through the loop. As it approaches the EndValue, an interesting thing happens; reps is: 57000, 60000, 63000, 464, 3464... It passes the EndValue, rolls over and keeps going. That's because the result of the calculation 63000 + 3000 exceeds the maximum capacity of a 16-bit number and then rolls over to 464. When the result of 464 is tested against the range ("Is reps > 0 and is reps < 65500?") it passes the test and the loop continues.

A similar symptom can be seen in a program whose EndValue is mistakenly set higher than what the counter variable can hold. The example below uses a byte-sized variable, but the EndValue is set to a number greater than what will fit in a byte:

    SYMBOL  reps    = W1                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 0 TO 300                   ' each loop add 1
        DEBUG reps                          ' show reps in debug window
      NEXT
      END

    reps    VAR     Byte                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 0 TO 300                   ' each loop add 1
        DEBUG DEC ? reps                    ' show reps in debug window
      NEXT
      END

Here, reps is a byte variable; which can only hold the number range 0 to 255. The EndValue is set to 300, however; greater than 255. This code will loop endlessly because when reps is 255 and the FOR...NEXT loop adds 1, reps becomes 0 (bytes will rollover after 255 just like words will rollover after 65535). The result, 0, is compared against the range (0 - 255) and it is found to be within the range, so the FOR...NEXT loop continues.

It's important to realize that on the BS2 series, the test is against the entire range, not just the EndValue. The code below is a slight modification of the previous example (the StartValue is 10 instead of 0) and will not loop endlessly.

    reps    VAR     Byte                    ' FOR...NEXT loop counter

    Main:
      FOR reps = 10 TO 300                  ' each loop add 1
        DEBUG DEC ? reps                    ' show reps in debug window
      NEXT
      END

Reps still rolls over to 0, as before, however, this time it is outside the range of 10 to 255. The loop stops, leaving reps at 0. Note that this code is still in error since reps will never reach 300 until it is declared as a Word.

NOTE: On the BS1, the loop will continue until Counter has gone past EndValue. The rollover error will still occur if the BS1 cannot determine if Counter went past EndValue.

Go to Welcome page

BASIC Stamp Help Version 2.5.4

Copyright © Parallax Inc.

8/8/2012