Doorbell

Introduction


How does Arduino produce sound through a piezo that's connected to one of its digital pins?

Parts


Do this

Collect these parts and get ready to make the next circuit!

In addition to these parts, you will need an Arduino UNO or Mehackit Board, a USB cable, a breadboard and a bunch of jumper wires.

PartImageDescription
Piezo speaker

Piezo speakers may look different, here's two examples.

A piezo can transform a quickly alternating voltage into sound. Some piezos can be used as a knock sensor. 
You will need a so-called passive piezo for this chapter. Active piezo speakers are a bit more expensive and they are programmed differently (they also work with Arduino!)

Button

The button in the Mehackit Maker Kit is white, not brown.


Educator notes

There are two basic types of piezo speakers (or piezo buzzers), active and passive. In this tutorial you’ll use a passive piezo. Active piezos cost a bit more and are programmed differently. Both active and passive piezos work nicely with Arduino, but it is recommended that you use a 100 ohm resistor with an active piezo.

Passive and active piezos may look quite similar! If you have the Mehackit Maker Kit, you’ll have the passive one for sure. Some kits have both, so check out the components listing and search the model number of the piezo if necessary!

An active piezo has built-in components that produce sound immediately when you activate the piezo with a direct current (DC). You can use the digitalWrite command to play sounds. However, to control the pitch of the sound you have to manipulate the speed at which the piezo pin is turned on and off.

As you will learn, the tone command is an easy way to make sounds with a passive piezo!


Circuit


Do this

Make a circuit according to the diagram below.

  • Connect the pushbutton to pin 2 and ground (GND)
  • Connect the piezo to pin 7 and ground

Here's how you connect a piezo that has pins instead of wires:


Why are there three blue wires in this circuit?

Programming 1: First Sounds


Do this

Write a new program following the example below. 

  • Rows that start with " // " are comments. You can write the comment first and then your own code after it, like this: 
  • OR you can leave the comments out.
  • make sure you have all the parentheses ( ) and curly brackets { } in place!
  • remember – commands must end with a semicolon ; 
  • Check how to write the tone command from the video above, or from the Arduino Reference

Code example


EXTRA

  • Test what kind of sounds you can create with different pitch and duration values!

tone(12, 400, 2000)
What does the command above do?

Educator notes

Example code

void setup() {
  pinMode(7, OUTPUT);
  pinMode(2, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(2) == LOW) {
    tone(7, 440, 80); 
  }
}

Programming 2: Control Sound with a Variable

Transcript

I think a doorbell with just one note is so dull. So I programmed a bell that plays one note when the button is pressed down and another one when it's released. The program looks like this. If the button is pressed down, the first note is played. If it's not pressed, you'll hear the second one. Okay, let's upload and hear how it works. Oh no, this is this is a horrible doorbell, it doesn't shut up. When the button is down, Arduino keeps running this part. And always when the button is up, Arduino runs the lower part of the code, with the second note. And there's no alternative. I have to fix this. Luckily I can solve this problem with a great tool called variable. Variables are storages for different types of information. With Arduino you often store numbers. Now I need a variable to store an important piece of information: is it time to play the second note. I'll make a variable that stores a number like this. It goes to the top of the program, outside of setup and loop. This is where you often make new variables in Arduino. Int is the type of the variable. It stands for integer, which means numbers that are whole, numbers that don't have any decimals. playSecond is just a name I gave to the variable. It could be anything but it's a good idea to use a name that says what the variable is meant for. And I also gave the variable an initial value. Let's say zero means that it's not time to play the second note yet. How to use that variable? That's the big question. Inside the brackets of the first statement I add: playSecond equals 1. Now every time the button is pressed, a note is played and playSecond gets the value 1. Now I'll change the second if part of the program: I'll add a new condition there. There can be two conditions in the same if statement. The new, improved if statement checks if it's time to play the second note or not. Both conditions must be true or there won't be a second note. So the button must be up and the value of playSecond must be 1 or else there won't be a new note. Fun fact: double ampersand is the right way to say 'and' inside an if statement and it works in pretty much all the programming languages. And the last important thing to do is to change playSecond back to zero. If I don't do that it remains 1 and Arduino gets stuck in this part of the program again. We'll talk a bit about some details in this code soon, but let's test the doorbell first. Well the bell is far from perfect but the logic works now. The rest is up to you: change the duration of the notes and add some new notes the code blocks.

Do this

Continue your doorbell: follow the instructions in the example below.

  • You can write comments first and then your own code under them, like this:
  • OR you can leave the comments out.
  • Check the video again if you don't remember how to write the missing commands.

Code example


EXTRA

  • Add new tone commands with different notes inside the if statements
  • Insert a delay command between notes so you can hear them! Change the delay values to create rhythms:
  • Check out this table of notes if you want to use certain notes! Pick the number after a note name and give it to the tone command as the second argument.

You wrote int in the beginning of your code. What does it mean?
Why do you need to use a variable in this code?

Educator notes

Example code

int playSecond = 0;
void setup() {
  pinMode(7, OUTPUT);
  pinMode(2, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(2) == LOW) {
    tone(7, 440, 80); // button down, note 1 is played
    playSecond = 1;
  } if (digitalRead(2) == HIGH && playSecond == 1) {
    tone(7, 250, 200);
    delay(800);
    tone(7, 230, 100);
    delay(1000);
    playSecond = 0;
  }
}

Alternative way to write the code

There's often more than one way to make an Arduino code work. Here's an other option - you could replace the structure:

if (digitalRead(2) == HIGH && playSecond == 1)

with an else if structure:

  if (digitalRead(2) == LOW) {
    tone(7, 440, 80); // button down, note 1 is played
    playSecond = 1;
  } else if (playSecond == 1) {
    tone(7, 250, 200);
    delay(800);
    tone(7, 230, 100);
    delay(1000);
    playSecond = 0;
  }

Tone and delay

The students can create rhythms and melodies with the piezo sounds if they want. The result may be something like this:

tone(7, 450, 500);
delay(1000);
tone(7, 359, 500);
delay(800);

It is not required to understand just yet how Arduino sets the timing of tone and delay commands, but the students may wonder how their Arduino rhythms are realized and what the logic is behind the code.

Arduino has built-in timers for keeping track of timed events. These include playing a note, counting how long a delay is or what kind of electric pulses must be fed to a motor.  

In the example above, the length of the note is 500ms, and there are delays of 1000ms and 800ms written after each tone command. But how long does it take to play through the whole thing? 

Instead of first playing a note for 500ms and then having a break of 1000ms, then playing the second note and executing the second delay, Arduino times the events a bit differently:

The first tone starts simultaneously with the first delay command, and likewise, the second tone and second delay start at the same time. 

This is due to how Arduino's timers work: tone uses a different timer than delay! But remember, delay affects the whole program meaning that no new commands can be executed while a delay is "on".


Learn More: Programing Tips

Transcript

Let's go through the code once more and check out a couple of details. Remember you created something called a variable in your code? It's here in the beginning of the code so you can use it anywhere in your program. Sometimes you'll create variables inside a code block like loop, too, but then it will work only inside that code block. Int was short for integer, which means that this variable will contain whole numbers. You used the equals sign to give a starting value 0 to the playSecond variable. Later on you changed the value to 1 here and to stop the second note from playing you turned the value to 0 again. The most important thing about the play second variable is that you used it to store the status of the program. Is it time to play the second note or not? With 0 no it's not, with 1, yes it is. Without storing this information to the variable the program won't remember the status when the loop part starts over again. But why are we using values 0 and 1 here? Well, the program would work with other numbers, too - 10 and 11 for example. But I think 0 and 1 are logical and easy to remember. You always change the value with one equals sign. If you look at an if statement in the code you'll see two equal signs in here. You'll run into this everywhere in programming. When you give a new value to a variable it's always one equal sign, but when you're checking a condition it is two signs. The reason is you need to make things very clear for computers, so you need to use different symbols for different tasks, like changing a value and checking a value. There's something else worth noting in this if statement, too. You can check two conditions at the same time. Two ampersand symbols mean both conditions must be true or the program won't execute commands inside this code block. You could write this in a different way, too. Let's see. The same thing can be written with two if statements inside one another. First the program checks if the button is pressed. And only if it's not, it will check the value of play second. And, if the value is 1, only then will this part of the program happen. So both conditions must be true. But it's faster to write the whole thing like this. Less curly brackets and all.

Conditional statements

In the code you made an if statement, which is very common in programming. 

If you have two equal signs (==) in the condition of an if statement, it is known as a relational operator - this one means "equals". 

Other relational operators are:

  • a <= b
    a is less than or equal to b
  • a < b
    a is less than b
  • a > b
    a is greater than b
  • a >= b
    a is greater than or equal to b
  • a != b
    a and b are not equal


What happens if you make a new variable inside the setup part?

Educator notes

&& (double ampersand) is one of the logical (or boolean) operators used in programming. It is also called logical or boolean AND. As described, it is typically used in an if statement with two conditions that are simultaneously true.

In addition to AND, there are other logical operators, as well.

|| - logical OR

Example: 

if (digitalRead(2) == LOW || digitalRead(3) == LOW) {

    tone(7, 440, 80);
}

Imagine a button connected to both pin 2 and pin 3 - in this case, the note defined in the tone function will be played when either of the buttons is pressed

! - logical NOT

Example:

if ( !(digitalRead(2) == LOW)) {

    tone(7, 440, 80);
}

Now the tone is played if the button in pin 2 does not produce the reading LOW. This particular example could be written differently - it is the same as: 

if ( digitalRead(2) == HIGH) {

    tone(7, 440, 80);
}

Logical NOT is a quick and practical way to invert a program's logic in many cases.


Learn More: Coding Sounds


If you have a piezo connected to pin 5 on your Arduino, which of these commands plays a high note with the piezo?