Experiment 8:

The Last Array

Source: Nicko Tumamak/Instagram

Arrays are the last programming concept we will learn in this course. After this experiment we have covered all the essential rudiments of programming. We will spend the rest of the course practicing and gaining expertise in anlyzing a problem, identifying which of these rudiments to use (do we need a for-loop here or an if-statement) and implementing things correctly. Years ago, I took a college course on functional guitar where we learned the six magic chords. With those chords you could play a huge number of songs, just be remixing those chords. This differed from a traditional guitar course where you might learn 50 chords. The approach in this Arduino course mirrors the 6 magic chord approach. Instead of covering a wide range of topics, we focus on the essentials. We can remix these essentials to implement a wide range of projects.

With that introduction let’s get started with arrays.

A silly example

When we implemented the potentiometer bike light we might have had the following variables:

int led1 = 13;
int led2 = 11;
int led3 = 5;
int led4 = 6;
int led5 = 0;

This worked fine for the 5 leds, but at some point—maybe if we had 8 leds—this approach is a bit tedious.

And now for my silly example. Suppose, instead of LEDs, I just want to keep track of my friends, and print out their names. I might have something like

int friend1 = "Ann";
int friend2 = "Mary";
int friend3 = "Clara";

void setup(){
  Serial.begin(9600);
  Serial.println(friend1);
  Serial.println(friend2);
  Serial.println(friend3);
}

void loop(){

}

That works fine. But now suppose I want to keep track of students in a class:

Arduino Class

  • Addie
  • Faith
  • Dylan
  • Erin
  • Maddie
  • Hannah
  • Siobhan
  • Margaret
  • Kaylie
  • Abby

Following the approach above we might have

link to larger image

which definitely does not seem like the way to go.

When we think of this problem outside of the computer realm, we might think that we would have a class list—list being the important word here. So something like

{"Addie", "Faith", "Dylan", "Erin", "Maddie", "Hannah", "Siobhan", "Margaret", "Kaylie", "Abby"};

An array is simply a list of values. So the above is an array.

We want to give that array a name …

classlist = {"Addie", "Faith", "Dylan", "Erin", "Maddie",
             "Hannah", "Siobhan", "Margaret", "Kaylie", "Abby"};

That is not complete correct since when we create a variable we have to specify what type of thing can be its value — an integer as an example:

int redLed = 13;

In our case the value of classlist is an array of strings, so the complete correct form is

String classlist[] = {"Addie", "Faith", "Dylan", "Erin", "Maddie",
                      "Hannah", "Siobhan", "Margaret", "Kaylie", "Abby"};

The [] after the word classlist specifies that it is an array and the word String before classlist says the array contains strings.

An array of integers could be declared as

int ages[] = {21, 19, 20, 22, 19, 16, 17, 23, 20, 18};

Accessing members of an array

Now that we know how to create an array (a list) we would like to get the values of the different people in the list. Say, for example, we want the name of the first person on our class list. The position of an element in a list is called its index. So the person in the following list with index 5 would be Maddie.

  1. Addie
  2. Faith
  3. Dylan
  4. Erin
  5. Maddie
  6. Hannah
  7. Siobhan
  8. Margaret
  9. Kaylie
  10. Abby

It’s just like saying who is the fifth person on the list or who is the first person on the list. Unfortunately, in nearly every single programming language, arrays don’t start at index 1. This may seem completely bonkers and counterintuitive but arrays start at index 0:

0. Addie
1. Faith
2. Dylan
3. Erin
4. Maddie
5. Hannah
6. Siobhan
7. Margaret
8. Kaylie
9. Abby

(There is actually a good historical reason for this which I will not get into).

So if I wanted the first person in the list I would have to ask Who is at index 0 and if I wanted the fifth person in the list I would ask Who is in index 4.

To get the value at that position we use the syntax:

classlist[0]

with the index we are interested in inside the brackets []. So

Serial.println(classlist[0]);
Serial.println(classlist[6]);

Would print

Addie
Margaret

So to print the entire class list we might have …

link to larger image

It sure would be nice if we could somehow automatically go 0, 1, 2, 3, … instead of typing those numbers by hand. Is there anything we previously covered that we can use:

  • variables
  • if statements
  • for loops
  • procedures
  • a procedure with some arguments

A for-loop seems like a great idea. It will start at 0 and go up to but not include 10.


String classlist[] = {"Addie", "Faith", "Dylan", "Erin",
                      "Maddie", "Hannah", "Siobhan",
                      "Margaret", "Kaylie", "Abby"};

void setup() {
   Serial.begin(9600);
   for (int i = 0; i < 10; i++){
      Serial.println(classlist[i]);
   }
}

void loop() {

}

That will print out all the names!

Remix 1: Airbender

Suppose we have a circuit with 4 leds: a red, blue, green, yellow one arranged in that order.

In an array, we represent the pattern we want the leds to blink. Here is the start of our code:

String pattern[] = ["red", "blue", "green", "yellow", "green", "blue", "red", "red",
                    "blue",  "blue", "green", "green", "yellow", "yellow","green", "green", "blue",  "blue"  ]


void loop(){
  play();
  delay(1000);
}

Each led should blink 200 ms on and 200 off. Can you write the procedure play() and any others you might need to complete this task?

Two arrays are better than one

Let’s go back to our original example:

String classlist[] = {"Addie", "Faith", "Dylan", "Erin", "Maddie",
                      "Hannah", "Siobhan", "Margaret", "Kaylie", "Abby"};

int ages[] = {21, 19, 20, 22, 19, 16, 17, 23, 20, 18};

The names and the ages are aligned meaning the first name, Addie, is the first age, 21. We can print both the name and the associated age with:

String classlist[] = {"Addie", "Faith", "Dylan", "Erin",
                      "Maddie", "Hannah", "Siobhan",
                      "Margaret", "Kaylie", "Abby"};
                     
int ages[] = {21, 19, 20, 22, 19, 16, 17, 23, 20, 18};

void setup() {
   Serial.begin(9600);
   for (int i = 0; i < 10; i++){
   
      Serial.print(classlist[i]);
      Serial.print(" is ");
      Serial.print(ages[i]);
      Serial.println(" years old.");
   }
}

void loop() {

}

which will print

Addie is 21 years old.
Faith is 19 years old.
Dylan is 20 years old.
Erin is 22 years old.
Maddie is 19 years old.
Hannah is 16 years old.
Siobhan is 17 years old.
Margaret is 23 years old.
Kaylie is 20 years old.
Abby is 18 years old.

Remix 2: Light Beats

This is a variation of remix 1. Now we have:

String pattern[] = ["red", "blue", "green", "yellow", "green", "blue", "red", "red",
                    "blue",  "blue", "green", "green", "yellow", "yellow","green", "green", "blue",  "blue"  ]
int beats[] = {2, 2, 2, 2, 2, 2, 1, 1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1}

void loop(){
  play();
  delay(1000);
}

The beats array represents how long to have the led light on. For example, the first element of the pattern is red for 2 beats. This will be realized as:

digitalWrite(redLed, HIGH);
delay(wait * 2);
digitalWrite(redLed, LOW);
delay(wait);

The 2 in

delay(wait * 2);

is from beats[0]

Have fun coding!

Searching

Back to our original arrays:

String classlist[] = {"Addie", "Faith", "Dylan", "Erin",
                      "Maddie", "Hannah", "Siobhan",
                      "Margaret", "Kaylie", "Abby"};
                     
int ages[] = {21, 19, 20, 22, 19, 16, 17, 23, 20, 18};

Suppose we want a procedure, lookup that is given a name as an argument and returns that person’s age. That would look like this:

1.  void setup() {
2.     Serial.begin(9600);
3.     Serial.println(lookup("Erin"));
4.     Serial.println(lookup("Margaret"));
5.  }
6.
7.  int lookup(String name){
8.    String classlist[] = {"Addie", "Faith", "Dylan", "Erin",
9.                          "Maddie", "Hannah", "Siobhan",
10.                         "Margaret", "Kaylie", "Abby"};
11.
12.   int ages[] = {21, 19, 20, 22, 19, 16, 17, 23, 20, 18};
13.   for (int i = 0; i < 10; i++){
14.     if (classlist[i] == name){
15.          return ages[i];
16.     }
17.   }
18.   return -1;
19. }
20.
21. void loop() {
22.
23. }

On line 3 we call lookup lookup("Erin") so we jump to line 7 and name now equals “Erin”. We moved the arrays classlist and ages inside this procedure and made them local variables because we only need them in this procedure. On line 13 we start the for loop.

  1. initially i is 0.
  2. so on line 14, we have (classlist[0] == name). `classlist[0] is Addie and name is Erin.
  3. They aren’t the same so we skip the if statement.
  4. now we are back on line 13, we increment i so now i is 1.
  5. so on line 14, we have (classlist[1] == name). `classlist[1] is Faith and name is Erin.
  6. They aren’t the same so we skip the if statement.
  7. now we are back on line 13, we increment i so now i is 2.
  8. so on line 14, we have (classlist[2] == name). `classlist[2] is Dylan and name is Erin.
  9. They aren’t the same so we skip the if statement.
  10. now we are back on line 13, we increment i so now i is 3.
  11. so on line 14, we have (classlist[3] == name). `classlist[3] is Erin and name is Erin.
  12. They are the same so we go inside the if
  13. Now we execute return ages[i]. i is 3 and ages[3] is 22 so we return 22.
  14. Now we are back on line 3. lookup("Erin") returned 22, so we have `Serial.println(22) and we print 22.

Understanding this example is important for the next experiment.


Previous section:
Next section: