Schedule‎ > ‎

### 06A: Counting Loops and Bar Charts

• Questions from last class?
• Questions about labs or upcoming homework?

^ top

## Counting Loops

Learner Outcomes

At the end of the lesson the student will be able to:

• Design and implement counting loops
• Apply counting loops to solve counting problems
• Translate these designs into C/C++ code

^ top

### Using Loops to Count

• 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

#### Activity

• Clap your hands 10 times.
• True or false: as you are clapping, you are repeating an action.
• You know when to stop clapping because you ________.
• True or false: as you are counting, you are testing the count against the number 10.
• Every time you clap, you update the count by ________.

#### 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.

^ top

### 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;
}
```
1. In the loop above, the initialization statement is ________.
1. `int i = 0`
2. `i < max`
3. `i++`
4. `cout << i;`
2. In the same loop, the test condition is ________.
1. `int i = 0`
2. `i < max`
3. `i++`
4. `cout << i;`
3. In the same loop, the update statement is ________.
1. `int i = 0`
2. `i < max`
3. `i++`
4. `cout << i;`
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

^ top

### Exercise 1: Counting Numbers (5m)

1. Start the Arduino IDE with a new sketch and save the program as `counting`.
2. In the `setup()` function print the following to the user:
```This sketch writes lists of numbers.
Enter the maximum number:
```
3. In the `loop()` function, add the code to get the maximum number from the user:
4. After getting the input, add a `loop `to print out a count from 1 to the maximum number the user entered.
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?  make any changes needed.
6. Save your `counting.ino` file to submit to Canvas.

### 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
• We can use a counting loop to sum a series of numbers
```float sum = 0.0;
for (int i = start; i < end; i++) {
int value = Serial.parseFloat();
sum += value;
}
```
• The summing loop requires a separate variable to tally the sum
• With the sum, we can compute an average
```float average = sum / (end - start);
```
• By changing the update statement we can sum only a portion of the numbers, like:
```for (int i = 0; i < 5; i += 2)
```
• In addition, we can change the starting or ending value to remove some numbers from the sum
```for (int i = 1; i < 5; i += 2)
```
• Be the computer
To truly understand what a loop is doing, we need to "be the computer" and trace the loop
• To trace the loop we track all the values of the variables affected by the loop, like:
```sum   i   reading
---   -   -------
0     0   1
1     1   2
3     2   3
...
```
• As another looping application, we looked at Pulse-Width Modulation (PWM)
• The analogWrite() function controls the duty cycle of power supplied to an output pin
• This technique is called Pulse Width Modulation (PWM) and is used for getting analog results with digital controls
• The following graphic shows PWM with various duty cycles

^ top

^ top

## Counting Loop Applications

Learner Outcomes

At the end of the lesson the student will be able to:

• Apply counting loops to solve a number of problems
• Use counting loops to sum and average a series of numbers
• Use a counting loop to apply the complete range of pulses for Pulse Width Modulation (PWM)

^ top

• Recall the temperature testing we did with the TMP36 Sensor
• Here is the Fritzing file for the circuit: tmp36.fzz
• We started with the following circuit breadboard

• To measure the sensor we used a function like:
```double readTemperatureSensor() {
double voltage = (reading * 5.0) / 1024;
cout << voltage << " volts" << endl;
return voltage;
}
```

• 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

```double readTemperatureSensor() {
float sum = 0.0;
for (int i = 0; i < 5; i++) {
delay(1);
}
float average = sum / 5;
float voltage = (average * 5.0) / 1024;
cout << voltage << " volts" << endl;
return voltage;
}
```

#### 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;`

^ top

### Summing Numbers and Tracing Loops

• 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; 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
...
```

#### Activity: Tracing a Loop (4m)

In this activity, we will trace the execution of the following summing loop.

```const int END = 10;
int sum = 0;
for (int i = 1; i <= END; i += 2) {
int input = getNumber(); // assume 1, 2, 3, ... ,10
sum = sum + i;
}
```
1. Take out a piece of paper, write your name on the paper and add headings for the variables in the above code.
2. Assume that the inputs to the loop are: 1, 2, 3, ... , 10.
3. Perform each computation of the loop repeatedly until complete, recording both the starting values for every variable and all the changes.
4. When finished tracing, have a classmate verify your trace and you verify a classmates trace.
5. Add your name to the paper to show who verified the trace, like:
```Trace verified by Fred George
```
6. Go over any issues with the class mate that you find in their trace.
7. Turn in your paper to the instructor after the trace is verified.

#### 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 ________.

Be the computer

## Bar Charts and Nested Loops

 Learner Outcomes At the end of the lesson the student will be able to: Write code to graph a bar chart Write nested for loops Alternate symbols inside a loop

^ top

### 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

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ``` ```void setup() { Serial.begin(9600); cout << "This sketch displays a barchart." << endl; cout << "Enter the number to chart:" << endl;}void loop() { if (Serial.available()) { int num = 0; cin >> num; cout << num << ": "; for (int i = 0; i < num; i++) { cout << '*'; // print one character } cout << endl; // newline after the bar }} ```

#### Display Variations

• We can alternate the symbols displayed by adding an `if-else` statement inside the `for`-loop
```for (int i = 0; i < num; i++) {
if (i % 2 == 0) {
cout << '*';
} else {
cout << '+';
}
}
```
• Remember that the modulus operator is written as `%` in C/C++
• The expression `i % 2` evaluates to `0` when `i` evenly divides by `2`
• When the remainder of `i / 2`, which is written as `i % 2`, is `0` then `i` evenly divides by `2`
• If we wanted a tick mark to show every 5 characters we would code something like:
```for (int i = 1; i <= num; i++) {
if (i % 5 == 0) {
cout << '+';
} else {
cout << '*';
}
}
```

#### Check Yourself

1. The modulus operator used to calculate the remainder is ________.
2. The following code snippet displays ________.
```for (int i = 0; i < 5; i++) {
cout << '*';
}
cout << endl;
```
1. `****`
2. `*****`
3. `******`
4. `*+*+*+`
3. The following code snippet displays ________.
```for (int i = 0; i <= 5; i++) {
if ((i % 2) == 0) {
cout << '+';
} else {
cout << '*';
}
}
cout << endl;
```
1. `*+*+*`
2. `*+*+*+`
3. `+*+*+*`
4. `+*+*+*+`
4. The following code snippet displays ________.
```for (int i = 0; i < 5; i++) {
if (i == (num - 1)) {
cout << '*';
} else {
cout << '.';
}
}
cout << endl;
```
1. `    *`
2. `.....*`
3. `*.*.*`
4. `....*`

^ top

### Exercise 2.  Bar Chart

`void setup() {  Serial.begin(9600);  cout << "This sketch displays a barchart." << endl;  cout << "Enter the number to chart:" << endl;}void loop() {  if (Serial.available()) {    int num = 0;    cin >> num;    cout << num << ": ";    for (int i = 0; i < num; i++) {      cout << '*'; // print one character    }    cout << endl; // newline after the bar  }}`

Change the code so that it prints a '+' sign every 3 characters.  Save your code as barchart.ino and upload it to Canvas.

### 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

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ``` ```void setup() { Serial.begin(9600); cout << "Outer Inner" << endl; for (int outer = 1; outer < 4; outer++) { for (int inner = 1; inner < 4; inner++) { cout << outer << "\t" << inner << endl; } }}void loop() { // no loop code} ```

Put the above code into the Arduino IDE and run it.  What does it print out?

#### 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 special 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)   `  `

#### Odometer Analogy

• By analogy, nested loops are like an odometer on a car
• The inner loop is like the digit to the right on an odometer
• The numbers to the right loop completely before the number to the left increments by one

#### Check Yourself

1. True or false: a loop can be nested inside another loop.
2. By analogy to an odometer, an inner loop is like the digits to the ________.
3. Every time an outer loop iterates once, an inner loop runs ________.
1. completely
2. incrementally
3. partially
4. twice
4. To trace a counting loop we need to keep track of the ________.
1. counter variable
2. initialization statement
3. test condition
4. update statement

^ top

### 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

#### PWM Starter Code

```// Pulse an LED using a PWM pin
const int PWM_PIN = 10; // LED in series with 560 ohm resistor

void setup() {
// no setup needed
}

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

#### 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

• 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
```int end = i;
for (int j = 0; j < end; j++) {
cout << '*';
}
cout << endl;
```
• 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

```if (i % 8 == 0) { // every eighth iteration
int end = i / 8; // scale the width
for (int j = 0; j < end; j++) {
cout << '*';
}
cout << endl;
}
```

#### Check Yourself

1. The expression `i % 8 == 0` evaluates to `true` when the value of `i` is ________.
1. `21`
2. `16`
3. `42`
4. `50`
2. The value of the expression `17 / 10` is ________.
3. For the following code snippet, the newline is printed ________.
```for (int j = 0; j < end; j++) {
cout << '*';
}
cout << endl;
```
1. at the end of each row
2. at the end of each column
3. when j < end

^ top

### 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.

#### Parts

• Arduino board
• USB cable
• LED (any color)
• 560Ω resistor
• Jumper Wires

• Breadboard the circuit as shown in the image.
• The flat edge (cathode) of the LED is connected to ground through a 560Ω resistor
• The longer LED lead is connected to pin 10, which supplies power
• To test the circuit use the following code

#### PWM Starter Code

```// Pulse an LED using a PWM pin
const int PWM_PIN = 10; // LED in series with 560 ohm resistor

void setup() {
// no setup needed
}

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

#### Specifications

2. Open the Arduino IDE, which should have the starter code shown above.
3. Compile the sketch to verify the starter code is correct.

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

4. Add the following code inside the current `for`-loop
```if (i % 10 == 0) {    /*only print every 10th, so the printout isn't 255 characters wide  */
int end = i / 10;   //have to divide end by 10 also.
for (int j = 0; j < end; j++) {
cout << '*';
}
cout << endl;
}
```

By opening the Serial Monitor, you should now be able to see the following graph.

```*
**
***
****
*****
******
*******
********
*********
**********
***********
************
*************
**************
***************
****************
*****************
******************
*******************
********************
*********************
**********************
***********************
************************
*************************
**************************
***************************
****************************
*****************************
******************************
*******************************
```
6. Change the code to alternate the printing of '*' and '+' like this:  *+*+*+*+*+  etc.
7. Change the code to scale by 7 instead of 10.
8. Answer the questions below in the Comment area of this assignment.
9. Save your updated `pulse.ino` file and submit to Canvas.

#### 1.  What are 3 values of i for which (i % 7 == 0) will evaluate to true?

2.   Why do we scale a bar chart?

3.   How do you scale bar chart?  (what are the two statements that force the scaling?)

4.   What is a nested loop?  Write an example of one.

5.   In your nested loop example,  which is the outer loop and which is the inner loop?

6.   Every time the outer loop iterates once,  how has the inner loop run?  (completely?, partially?, twice?)

7.   Trace your nested loop from #4.  Make your loop limits small so you don't have to do too many iterations.

12 points  (Header 1pt, Compiles 2 pts, Proper Formatting 1 pt,  Works as Specified 4 pts, questions answered 4)

^ top

### Summary

• We looked at how to graph a bar chart using a `for`-loop
```for (int i = 0; i < num; i++) {
cout << '*'; // print one character
}
```
• Inside the basic loop, we can add variations using `if-else` statements
• For example, t alternate characters we would add:
```for (int i = 0; i < num; i++) {
if ((i % 2) == 0) {
cout << '*';
} else {
cout << '+';
}
}
```
• 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++) {
cout << outer << "\t" << inner << endl;
}
}
```
• We added a bar chart to the PWM project with a nested `for`-loop

^ top

## Wrap Up and Reminders

• For the next homework, see the schedule