This tutorial will show you how to add a small speaker to your cyber:bot board that can emit different frequencies. Using the cyberbot module’s tone function, you will learn to write programs that make sounds and even write simple songs using lists (similar to arrays).
You will need:
You will be ready to continue with the main cyber:bot tutorial sequence. You will also be equipped to add your own custom audio alerts and sound effects to personalize your cyber:bot projects.
To emit sound, the cyber:bot uses a device called a piezoelectric speaker (piezospeaker). This speaker can make different tones depending on the rate of high/low electrical signals it receives. The schematic symbol and part drawing are shown below.
A piezoelectric element is a crystal that changes shape slightly when voltage is applied to it. Applying high and low voltages alternating at a rapid rate causes the crystal to rapidly change shape. The resulting vibration in turn vibrates the air around it, and this is what the ear detects as sound.
Piezoelectric elements have many uses. As opposed to sending voltage to the piezoelectric element to make it change shape, when force is applied to a piezoelectric element (which impacts its shape), it actually creates voltage.
Some electronic drum sets use piezoelectric elements to detect when, and how hard, a drummer has hit a sensor.
Some barbeque grills have push button lighters that use a piezoelectric element to cause a spark to start the grill. A spring-loaded hammer inside the button impacts a piezoelectric element to generate a small spark.
Piezoelectric elements, depending on their shape and thickness, have a frequency at which they naturally vibrate. This natural vibration can be used to create voltages at set frequencies that function as the clock oscillator for many computers and microcontrollers. If you have ever seen a clock or watch that says “quartz”, there is a piezoelectric quartz crystal inside.
Adapted Wikimedia Commons image "Inside Quartz Crystal Tuning Fork" by Chribbe76 [Public domain]
It is time to add a piezospeaker to your cyber:bot board.
(1) piezospeaker from the Small Robot Electronics Component Pack. (Just peel off the “Remove the seal after washing” sticker if it has one).
The picture above shows the schematic for the piezospeaker connected to P22. Notice that the cyber:bot board has two slots that fit the piezospeaker, and will connect it to P22.
The cyber:bot board was designed for a piezospeaker with long leads, like the one on the left. But due to supply chain challenges, some kits may include a piezospeaker with short leads, like the one shown on the right. Either will work!
The speaker should stay in place for the rest of the activities as it does not interfere with any other circuits since it’s not positioned on the breadboard.
If your piezospeaker has short leads, it may fall out of the socket when inserted from the top of the cyber:bot board. But that is okay, it can still be plugged into the socket from the bottom of the board.
Note: you can also build a piezospeaker circuit on the breadboard.
To use a piezospeaker on the breadboard, make sure its legs go in different breadboard rows. Using jumper wires, connect its (+) leg to an I/O pin socket (P4 for example) and connect its other leg to a GND socket. In your scripts, you will need to change bot (22) to bot (4) or the number for whichever pin you used.
Let's test the piezospeaker using calls to the cyberbot module's tone function. True to its name, this function instructs an I/O pin to alternate high/low electrical signals at a specific frequency, allowing a piezospeaker to emit a tone.
The tone function allows you to specify the frequency with the f parameter, and the duration of the tone in milliseconds with the ms parameter.
bot(22).tone(f, ms)
This piezospeaker is designed to play 4.5 kHz tones for smoke alarms, but it can also play a variety of audible tones and usually sounds best in the 1 kHz to 3.5 kHz range. The start-alert tone we’ll use is:
bot(22).tone(3000, 1000)
That will make P22 send a series of high/low signals repeating at 3 kHz (3000 times per second). The tone will last for 1000 ms, which is 1 second. The micro:bit will wait until the tone function is complete before moving on to the next command.
This example script makes a beep when it starts running, then it sends the message “Waiting for Reset” scrolling across the micro:bit LED matrix. These messages will continue indefinitely because they are in the while True: loop. If the reset button is pressed, the speaker will replay the sound.
# piezospeaker_test from cyberbot import * bot(22).tone(3000, 1000) while True: display.scroll("Waiting for Reset")
It is easy to make sound effects by using a for loop.
# sound_effect from cyberbot import * for freq in range (500, 3100, 100): bot(22).tone(freq, 100)
You should hear a series of tones that increase in pitch.
Just for fun, modify the sound_effect script by varying the values in the range function's start, stop, and step parameters.
You can use musical note frequencies in the chart below for the tone function’s f parameter to play music.
Example:
bot(22).tone(1975.5, 500)
This command plays a B6 note for half of a second. Using this chart, you are able to create songs with the piezospeaker and the cyber:bot.
The notes to the first line of the Happy Birthday song go in the following order: D - D - E - D - G - F. Matching the notes with their frequencies, we can make the following program.
This example script plays out the first line of “Happy Birthday.”
# happy_birthday from cyberbot import * bot(22).tone(2349.3, 125) #D for an eighth bot(22).tone(2349.3, 62) #D for a sixteenth bot(22).tone(2637.0, 250) #E for a quarter bot(22).tone(2349.3, 250) #C for a quarter bot(22).tone(3136.0, 250) #G for a quarter bot(22).tone(2793.8, 500) #F for a half
Did you hear your cyber:bot play Happy Birthday?
A good way to keep track of notes in a song is to use a list. Sometimes, in other languages, these structures are referred to as an array. For now, they can be thought of as the same thing but there are some behind-the-scenes differences between these two which will be covered at some other time.
A list is a collection of values that can be referred to as a single, cohesive unit. Think about how a song is a single collection comprised of several individual notes. While each note is important, it is all the notes together that make up the song.
Taking the previous example, each of the notes in the script happy_birthday are grouped in order into a list called notes. The lengths of each note are grouped, in order, into another list called lengths.
To make use of data stored in a list, each element of a list is referred to by its index. The index of a list is simply the number of each element beginning with zero. So, the first element is referred to as element 0. To refer to element 0 of notes would be notes[0]. The code to refer to the fifth element, would be notes[4]. Notice how the index appears to be “off by one”. When working with lists, this can be a common mistake.
Element | 0 | 1 | 2 | 3 | 4 |
Contents | "Do" | "Re" | "Me" | "Fa" | "So" |
Code | alphabet = [ “Do”, “Re”, “Me”, “Fa”, “So” ] |
With lists, you do not have to hard code numbers for the index. A variable, like index, can stand in for a number and then that variable can be changed as the program runs. Doing this allows code to “walk” through a list.
# song_with_list from cyberbot import * notes = [2349.3, 2349.3, 2637.0, 2349.3, 3136.0, 2793.8] lengths = [125, 62, 250, 250, 250, 500] index = 0 while index <= 5: bot(22).tone(notes[index], lengths[index]) index = index + 1
In the example above, the variable index is created after the two lists. The while loop checks the value of index each time it repeats, or iterates. As long as index is less than or equal to 5, the loop continues. Inside the loop, the tone function gets the values from each of the arrays depending on the current value of index. The second line in the loop increases the value of index by 1. This occurs over and over until the value of index becomes 6 and the loop stops. (And it’s a good thing it stops there because there is not an element number 6 in either of these lists!)
Links
[1] https://commons.wikimedia.org/wiki/File:Inside_QuartzCrystal-Tuningfork.jpg