Syntax : FOR Counter = StartValue TO EndValue {STEP {-} StepValue} ... NEXT{Counter}
Syntax : FOR Counter = StartValue TO EndValue {STEP StepValue}... NEXT
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.
* Note: expressions are not allowed as arguments on the BS1.
† Note: Use a minus sign to indicate negative StepValues on the BS1.
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 |
*Note: Direction (ie: increment/decrement) cannot be changed at runtime.
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.
BASIC Stamp Help Version 2.5.4
Copyright © Parallax Inc.
8/8/2012