Home‎ > ‎CS 11M‎ > ‎

### Counting Loops

• Questions from last class?

## Counting Loops

• Counting is a way to solve many programming problems
• As an example, assume we want a program to write a list of numbers
• We want to start at the number `1` and let the user choose the ending number
• Thus the program output will look something like:
``````This program writes lists of numbers.
Enter the maximum number:
1
2
3
4
5```
```
• We cannot simply write five numbers with `cout` because the user chooses the maximum number
• To help us understand how to approach the problem we try out some counting examples

### Looping Statements

• It turns out that counting is a very common use of loops
• Loops that are controlled by a counter variable are called counter-controlled loops
• We can visualize a counter-controlled loop as a series of steps to reach a goal
• We use a counting variable to keep track of the number of times the loop has repeated
• We have looked at two looping statements previously: `for` and `while`
• Both statements can be used to solve counting problems, but the `for` loop is the one designed for counting
• To finish designing our counting application, we will review our previous use of the `for` statement

### Check Yourself

1. For a computer to remember a count, we write code to declare a ________.
2. Loops that are controlled by a counter variable are know as ________ loops.
3. True or false: counter-controlled loops end after a certain number of steps.

## Understanding `for` Statements

• We have used for loops previously to repeat commands a certain number of times
• For example, we wrote a sketch that:
2. Pauses for 3 seconds
3. Starts again
• We could have written the blink code 20 time, like:
``````digitalWrite(ledPin, HIGH);
delay(delayPeriod);
digitalWrite(ledPin, LOW);
delay(delayPeriod);
// repeat above 4 lines 20x
delay(3000);```
```
• Such code requires lots of typing and is error prone

#### Looping with `for`

• To repeat code a specific number of times we use a `for`-loop:
````for (int ``i`` = ``start``; ``i`` < ``end``; ``i`` = ``i```` + 1) {
// code to repeat
}```
```
• Where:
• i: the name of a counter variable
• start: the initial starting count
• end: the final ending count
• The commands to repeat are placed inside the curly braces
• The looping code is shorter and easier to maintain than repeated code

#### Example `for`-loop Code

``````for (int i = 0; i < 20; i = i + 1) {
digitalWrite(ledPin, HIGH);
delay(delayPeriod);
digitalWrite(ledPin, LOW);
delay(delayPeriod);
}
delay(3000);
``````

#### Execution Steps

1. When `for` loop is reached, execute the `initialize` statement (example: `int i = 0`)
2. Check if `condition` is `true` (example: `i < 20`)
1. if `true` then continue with Step 3
2. Otherwise it is `false` so continue with Step 6
3. Execute the block containing the statements to repeat (body)
4. When end of loop body is reached, execute the `update` statement (example: `i = i + 1`)
6. Loop is finished: continue with statements after the loop

#### Check Yourself

``````for (int i = 0; i < max; i++) {
cout << i << endl;
}```
```
1. In the loop above, the initialization statement is ________.
1. `int i = 0`
2. `i < max`
3. `i++`
4. `cout << 1 << endl;`
2. In the same loop, the test condition is ________.
1. `int i = 0`
2. `i < max`
3. `i++`
4. `cout << 1 << endl;`
3. In the same loop, the update statement is ________.
1. `int i = 0`
2. `i < max`
3. `i++`
4. `cout << 1 << endl;`
4. In the same loop, if `max` is 3 the loop prints ________.
1. 0, 1, 2, 3
2. 1, 2, 3
3. 0, 1, 2
4. 1, 2, 3, 4

## Exercise 1: Counting Numbers

1. Start the Arduino IDE with a new sketch and save the program as `counting`.
2. In the `setup()` function add the following code:
``````void setup() {
Serial.begin(9600);``````  cout << "This sketch writes lists of numbers." << endl;
cout << "Enter the maximum number:" << endl;
}```
```
3. In the `loop()` function, add the following code to get the maximum number from the user:
``````void loop() {
int max;```
`  cin >> max;`
```  // Add code from the next step here...
}```
```
4. After getting the input, add a `for`-loop
``````cout << "for loop:" << endl;
for (int i = 0; i < max; i++) {
cout << i << endl;
}```
```
5. Compile and run your code to verify it works.
1. Does it start and stop with the correct numbers?
2. If not, what needs to change?
6. Save your `counting.ino` file to submit to Canvas with the next homework.

## Summary

• The `for` statement is used to repeat a block of statements enclosed inside its curly braces
• A `for` statement is used whenever we have a certain number of commands to repeat
• We use a counter variable to keep count of the number of iterations
• Also, we use a test condition to decide when to keep looping and when to stop
• The following is an illustration of the syntax of a `for` loop

Source: www.arduino.cc

## Counting Loop Applications

`#include <ArduinoSTL.h>`

`using namespace std; `

`const int LightSensor = A0; `

`void setup() {`
`  Serial.begin(9600);`
`}`

`void loop() {`
`  int sum;`
`  int samples; `

`  cout << "How many samples do you wish to take?" << endl;`
`  cin >> samples;`
`  `
`  for (int i=0; i<samples; i++) {`
`    int reading = analogRead(LightSensor);`
`    cout << "Current reading: " << reading << endl;`
`    sum += reading;`
`    delay(1000);`
`  }`
`  int average = sum / samples;`

`  cout << "The average is: " << average << endl << endl;`
`}`

• Sometimes you want to slow down how quickly a program reacts to changes
• The automatic brightness setting on your phone or tablet.
• But... brightness should change slowly or it's annoying.

• One way to solve the problem is to take multiple readings and average them
• Continuously averaging a series of numbers is a form of data smoothing
• To find an average, we sum a series of numbers and then divide by the count of numbers
• If we wanted to average 5 readings, we would add a `for`-loop as shown below

``````  for (int i=0; i<samples; i++) {
delay(1000);
}
int average = sum / samples;
``````

#### Check Yourself

1. When sensor numbers are "jumpy", it is because the sensor readings ________.
2. True or false: one technique to smooth jumpy readings is to average the numbers.
3. In the following loop, if the `analogRead()` function returns the numbers 1, 2, 3, 4, 5 the value of `sum` after the loop finishes executing the sum is ________.
``````double sum = 0.0;
for (int i = 0; i < 5; i++) {
delay(1);
}```
```
4. After the above loop completes, the correct statement to average the readings is ________.
1. `int average = sum * 5;`
2. `double average = sum / 5;`
3. `int average = sum / 5;`
4. `double average = sum * sum / 5;`

### Iterating Over Strings

`#include <ArduinoSTL.h>`

`using namespace std; `

`void setup() {`
`  Serial.begin(9600);`
`}`

`void loop() {`
`  string str;`
`  cout << "Enter a word or phrase." << endl;`
`  getline(cin, str); `

`  for (int i=0; i<str.length(); i++) {`
`    cout << str[i];`
`  }`
`  cout << endl;`

`  for (int i=str.length()-1; i>=0; i--) {`
`    cout << str[i];`
`  }`
`  cout << endl;  `
`}`
• Strings are an array of chars.
• We'll talk about arrays soon...
• You can access a single `char` in a `string` using square brackets `[` and `]`.
• The above example takes a phrase and prints the phrase forward and backwards.

### Summing Numbers

• Whenever we need to sum a list of numbers, coding a loop is a good approach
• Notice that we have a separate variable to store the sum
``````double sum = 0.0;
``````
• We need two variables in a summing loop
• `i`: the counter variable to store the current count
• `sum`: the variable to store the sum of the numbers
• One we have a sum, we can divide by the number of numbers to find the average
``````double average = sum / 5;
``````

#### Variations

• Sometimes we only want to sum part of the numbers we get
• We can adjust the summing loop to read a different quantity of readings by changing the starting or ending value
• For example, if we wanted to read six values we would change the for-loop like:
````for (int i = 0; i < ``6````; i++)
``````
• We could change the summing loop to read every other value by changing the update statement like:
````for (int i = 0; i < 5; ``i += 2````)
``````
• What numbers does the above loop tally?
• Another option is to change the starting or ending value
````for (int i = ``1````; i < 5; i += 2)
``````
• What numbers does the above loop tally?
Be the computer

#### Tracing a Loop

• To understand what is happening with these loops it is important to trace iterations
• In essence, we must "be the computer" and follow it execution path
• The counting variable is used by the computer to track the number of iterations
• Thus a good technique is to keep track of the counting variable to understand the loop
• In addition, we want to keep track of any other variable processed inside the loop
• For example, with the following loop we would want to track the variables: sum, i, and reading:
``````int sum = 0;
for (int i = 0; i < 5```cout << endl;```

• ``````; i++) {
delay(1);
}```
```
• Thus we would write out headings for each value and update the variables for each pass of the loop
``````sum   i   reading
---   -   -------
0     0   1
1     1   2
3     2   3
...``````

#### Check Yourself

``````double sum = 0.0;
for (int i = 0; i < 5; i++) {
delay(1);
}```
```
1. True or false: summing numbers in a loop requires a dedicated variable to store the sum.
2. For the above loop, if the input numbers are 1, 2, 3, 4, 5 the value of `sum` after the loop finishes executing is ________.
1. 3
2. 5
3. 10
4. 15
3. In the above loop, to sum even numbers only we would change the update statement to ________.
4. To sum odd numbers only, we would additionally change the initialization statement to start at ________.
5. To compute the product of the numbers, we would change the update statement to use the operator ________.

### Graphing Bar Charts

• We can use a counting loop to graph a horizontal bar
• To make the chart, we display a series of `'*'` characters for the "bar", like:
``````cout << '*';
``````
• At the end of the bar, after the loop, we print a newline using:
``````cout << endl;
``````
• The following example prints a single bar for every number entered

#### Example Arduino Application That Displays a Bar Chart

`#include <ArduinoSTL.h>`

`using namespace std;`

`void setup() {`
`  Serial.begin(9600);`
`}`

`void loop() {`
`  int num; `
`  cout << "Enter a number" << endl;`
`  cin >> num;`
`  for (int i=0; i<num; i++) {`
`    cout << "*";`
`  }`
`  cout << endl;`
`}`

#### Variations

What if we wanted the program to display nicer bars? Here are some variations:
• The program uses the | (pipes) character to show "caps" on the ends of the bars.
`  for (int i=0; i<num; i++) {`
`    if (i == 0) {`
`      cout << "|";`
`    }`
`    else if (i == num - 1) {`
`      cout << "|";`
`    }`
`    else {`
`      cout << "*";`
`    }`
```  }   cout << endl;```
• Here's a addition to the last block that puts a plus sign every five steps to make it easier to read:
`  for (int i=0; i<num; i++) {`
`    if (i == 0) {`
`      cout << "|";`
`    }`
`    else if (i == num - 1) {`
`      cout << "|";`
`    }`
`    else if ((i % 5) == 0) {`
`      cout << "+";`
`    }`
`    else {`
`      cout << "*";`
`    }`
`  }`
`  cout << endl;`

### Smooth Fading of an LED

• As an example looping application, we use a `for`-loop to smoothly fade in and out an LED

#### Example Sketch for Pulsing an LED

``````#include <ArduinoSTL.h>

using namespace std;

const int greenLED = 10;

void setup() {
Serial.begin(9600);
}

void loop() {
for (int i=0; i<255; i++) {
analogWrite(greenLED, i);
delay(10);
}
}``````

#### Pulse-Width Modulation

• Recall that the analogWrite() function is controlling the duty cycle of power supplied to an output pin
• This technique is called Pulse Width Modulation (PWM)
• PWM is a technique for getting analog results with digital controls
• By changing the amount of time that power is supplied to a pin, the amount of power changes proportionally
• The function `analogWrite()` controls the pulse width on a scale of 0 to 255 as shown in the following diagram
• In the image below, the green lines represent a regular time period of around 2 milliseconds

In this exercise we'll complete the fade in code above.

#### Specifications

1. Start the Arduino IDE, copy the example code above and paste it into the main IDE window.
2. Save the project using the name fader (`File > Save As...`) to a convenient location like the Desktop or the Arduino projects folder.
3. Copy and paste the code from the previous section as your starter code.
4. Compile the sketch to verify you copied the starter code correctly.

When compiling is successful, you will see a message at the bottom of the source code window saying, "Done compiling."

6. Add another for loop that causes the LED to fade in.
1. To fade in the index variable must start at 255 and decrease to 0.
7. Verify that your LED fades in, then out, then in, then out, etc...
8. Save your `fader.ino` file to submit to Canvas with the next homework.

## Nested Loops

• Some looping applications have loops nested within other loops
• For example, we may use a nested loop to print a table of values or draw shapes
• The following example shows a simple table created with nested loops
• Let's follow the execution sequence before running the code

### Example of Nested Loops

`#include <ArduinoSTL.h>`

`using namespace std;`

`void setup() {`
`  Serial.begin(9600);`
`  cout << "Outer   Inner" << endl;`
`  for (int outer=0; outer < 4; outer++) {`
`    for (int inner=0; inner < 4; inner++) {`
`      cout << outer << "\t" << inner << endl;`
`    }`
`  }`
`}`

`void loop() {`
`}`

#### Tracing the Variables

• To understand a looping application, we need to trace the loop by hand
• To trace the loop, write the variables used in the loop as headings across a page
• On the first line under the headings, write the initial values
• Execute the loop 3-5 times and record the values of the variables each time through the loop
• Pay especial attention when entering the loop the first time and when ending the loop
• We can slightly modify the computations if it helps to test the loop
• Below is an annotated trace of the variables for the inner and outer loops
• Note that the outer loop changes only after the inner loop is finished
Memory  Screen
` outer ` ` inner `
`  1` `  1` `1 1`
`  2` `1 2`
`  3` `1 3`
`  4` (end of loop)
`  2` `  1` `2 1`
`  2` `2 2`
`  3` `2 3`
`  4` (end of loop)
`  3` `  1` `3 1`
`  2` `3 2`
`  3` `3 3`
`  4` (end of loop)
`  4` (end of loop)   `  `

#### Nested Loop Example: Graphing PWM

• As an example of nested loops, let us add a bar chart to the PWM project
• In the `loop()` section, we had coded a `for`-loop to pulse the LED

### Loops Inside of Loops

• Notice that we already have a loop inside of another loop
• The `loop()` section of an Arduino sketch is a built-in loop that every sketch must have
• Inside of the `loop()` function we have a `for`-loop to pulse the LED
• However, we want to add yet another `for`-loop inside the existing `for`-loop
• This will give us a loop structure that is three loops deep!

#### Adding a PWM Bar Chart

• Combine the "Bar Chart" code example with the previous exercise.
• The loop we want to add is to display a bar chart of the current PWM level
• Since the counter variable `i` has the current PWM level, we can use it for the ending value of the loop
``````  for (int j=0; j<num; j++) {
cout << "*";
}```
```
• Notice that the new loop has a new counter variable "`j`"
• Use of `i`, `j` and k are common in `for`-loops

#### Scaling the Bar Chart

• PWM values range from 0 to 255
• Thus adding the above loop displays a bar chart that is up to 255 characters wide
• We can reduce the range of values to make a more displayable chart
• A convenient value is to reduce the width of the chart by a factor of 8
• Thus, we would print a single `'*'` character for every 8 values
• Why is a factor of 8 a convenient value?
• The following code displays a the bar chart scaled by a factor of 8

#### Code for a Scaled Bar Chart

`for (int j=0; j<num; j+=8) {`
`     cout << "*";`
` }`

## Exercise 3: Graphing the PWM Value

In this exercise we add bar graphs to the starter code of the PWM project from the last exercise.

#### Specifications

2. Save As a new sketch called `graph-fader`
3. Compile the sketch to verify the starter code is correct.
4. When compiling is successful, you will see a message at the bottom of the source code window saying, "Done compiling."
5. Add the following code inside the current `for`-loop
``` for (int j=0; j<num; j+=8) {```
`    cout << "*";`
```} cout << endl; ```
7. If you have problems, ask a classmate or the instructor for help.
8. Verify your code with the example shown below. Your code does not need to be the same but comparing helps understand other ways of coding.
9. Save your `graph-fader.ino` file to submit to Canvas with the next homework.

## Summary

• We looked at how to graph a bar chart using a `for`-loop
• Inside the basic loop, we can add variations using `if-else` statements
• Some looping applications have loops nested within other loops
• The structure of nested loops looks like:
``````for (int outer = 1; outer < 4; outer++) {
for (int inner = 1; inner < 4; inner++) {

}
}```
```
• We added a bar chart to the PWM project with a nested `for`-loop