Use tone() with Arduino for an Easy Way to Make Noise
Do you need to make some noise with Arduino? Maybe a simple tone for an alarm, maybe a beep to alert you when a specific input threshold is met, or maybe to play the Super Mario Brothers soundtrack to entertain your juvenile mind (it’s OK, we are all there, too).
Whatever your audible need, you will likely find the easiest, quickest and possibly the cheapest way to make some noise is using the tone() function and piezo speaker with your Arduino.
This is exactly what you will learn in this lesson:
- A quick intro to piezo speakers (aka piezo buzzers)
- How to set up a simple piezo speaker circuit
- The basics and more of using the tone() function
- The limits you should know when using tone()
Programming Electronics Academy members, check out the Audio Boards course to learn about more advanced noise making, and even prototype your own mp3 player!
Not a member yet? Sign up here.
Hardware You Will Need:
- Arduino board, I am using an Arduino Uno [1]
- Solderless breadboard [1]
- Jumper wire [2]
- 100 ohm resistor [1]
- Piezo speaker (aka piezo buzzer) [1]
- At least 12 cm dental floss, with a thick wax coating (mint flavored works best) [1]
A Quick Intro to Piezo Speakers (AKA Piezo Buzzers)
Ahh, noise….
Birds make it, kids make it – it can be music to our ears or pure torture.
We are going to use a piezo buzzer to make some noise with Arduino.
A piezo buzzer is pretty sweet. It’s not like a regular speaker that you might think of. It uses a material that’s piezoelectric, it actually changes shape when you apply electricity to it. By adhering a piezo-electric disc to a thin metal plate, and then applying electricity, we can bend the metal back and forth, which in turn creates noise.
The faster you bend the material, the higher the pitch of the noise that’s produced. This rate is called frequency. Again, the higher the frequency, the higher the pitch of the noise we hear.
So basically, by shocking the plate over and over really fast, we can make noise. I don’t know who comes up with this stuff, but they’re friggin’ mean.
Let’s set up this circuit first, and then talk about using the tone() function to make some noise.
How to Set Up a Simple Piezo Speaker Circuit using Arduino
It’s painfully easy to set up a simple piezo speaker circuit with an Arduino.
- Place the piezo buzzer into the breadboard, so that the two leads are on two separate rows.
- Using jumper wires, connect the positive lead to Arduino digital pin 8. The case of the buzzer may have a positive sign (+) on it to indicate the positive lead (if not, then the red wire usually indicates the positive lead).
- Connect the other lead to the 100 ohm resistor, and then to ground.
That’s it.
Now let’s go ahead and jump into the Arduino sketch and actual use the the tone() function to make some noise.
The basics and more of using the tone() function
The tone() function works with two arguments, but can take up to three arguments. Let’s address the two required items first:
tone( pin number, frequency in hertz);
- The pin number that you will use on the Arduino.
- The frequency specified in hertz. Hertz are cycles per second.
The frequency is an unsigned integer and can take a value up to 65,535 – but if you are trying to make tones for the human ear, then values between 2,000 and 5,000 are where our ears are most tuned.
Here is a simple sketch demonstrating the tone() function:
//A sketch to demonstrate the tone() function //Specify digital pin on the Arduino that the positive lead of piezo buzzer is attached. int piezoPin = 8; void setup() {} //close setup void loop() { /*Tone needs 2 arguments, but can take three 1) Pin# 2) Frequency - this is in hertz (cycles per second) which determines the pitch of the noise made 3) Duration - how long the tone plays */ tone(piezoPin, 1000, 500); }
As an experiment, try changing the second argument in tone() to 100, 1000, 10000, 650000 and listen to the effect it has on the audio signal.
You will notice that the higher the number, the higher the pitch that is created.
Programming Electronics Academy members, check out the Arduino Course for Absolute Beginners to jump start your Arduino programming skills.
Not a member yet? Sign up here.
How to Separate the Noise – AKA Make a Beat with tone()
What if we want to add some space between the noise, so we can get a beat?
We can try adding a delay(1000) after the tone(), but if you test this out, you will find it doesn’t get you anywhere.
This is because the tone() function uses one of the built in timers on the Arduino’s micro-contoller. tone() works independently of the delay() function. You can start a tone and do other stuff – while the tone is playing in the background.
But, back to that question, how can we separate the noise a little?
Let’s talk about that third parameter we can pass to the tone() function – it is the duration of the tone in milliseconds.
tone( pin number, frequency in hertz, duration in milliseconds);
If you want to generate distinct beats, and you want to do this with the delay() function, then you need to keep in mind what we just said, that the tone() function uses one of the built in timers on the Arduino board.
Therefore, if you use 500 milliseconds as the third argument in tone(), and follow that by a delay of 1000 milliseconds, you will only be creating a “quiet time” of 500 milliseconds.
//This code only generates a delay of 500 milliseconds between the tone tone( 8, 2000, 500); delay(1000);
Instead of the time being added together – as in 500 millisecond of noise, and then 1000 milliseconds of delay – the delay and the tone start at about the exact same time, so we get 500 millisecond of tone separated by 500 milliseconds of quiet.
It’s a little quirky to wrap your mind around, but if you play around with it a little, you’ll pick up on the intricacies.
The Limits You Should Know When Using tone()
Like everything else in the world, the tone() function has some limitations of which you should be aware. Let’s touch on them here:
- You can’t use tone() while also using analogWrite() on pins 3 or 11. If you do – you get some whacky results – neither will work like you expect. That’s because the tone() function uses the same built in timer that analogWrite() does for pins 3 and 11. It’s worth trying just hear the weird noises.
- You cannot generate a tone lower than 31 HZ. You can pass values 31 and less to the tone() function, but it doesn’t mean you will get a good representation of it.
- The tone() function cannot be used by two separate pins at the same time. Let’s say you have two separate piezo speakers, each on a different pin. You can’t have them both play at the same time. One has to be on, and then the other. Furthermore, before you can have the other pin use the tone() function, you must call the noTone() function and “turn off” the tone from the previous pin.
Review the Lesson
Here is a quick breakdown of what we just covered:
- A piezo speaker use piezo-electric material to bend a metal diaphragm which makes noise.
- The tone() function needs at least two arguments to operate (pin#, frequency in hertz), but can take a third argument, duration – which is in milliseconds.
- The tone() function works independently of the delay() function. The duration of the tone() will be continuous if you don’t use the third parameter.
- The limitations of the tone() function include:
- Not being able to use PWM on pins 3 and 11 while you use tone()
- You can’t go lower than 31 hertz.
- When using tone() on different pins, you have to turn off the tone on the current pin with noTone() before using tone() on a different pin.
I find it can facilitate learning to review what you cover after you learn about it.
The best teacher is practice though – so get a piezo speaker and start making some mad jams with your Arduino! I would love to hear about them in the comments.
Does tone() works simultaneously with an addressable LED strip? I couldn’t make it work right. When there is a LED, weird sounds is generated. Without LED, speaker works fine.
Hi Jammus, That is a good question and thanks for asking. Which pins were you using to control the LED strip? I think you should be able to use analogWrite() (PWM) on pins other than 3 and 11 when using tone().
Wait, what do I do with the dental floss?
clean your teeth
first i want to thank you ,it works. But when i disconnect the buzzer from the bord and try to conect it to bateries . Its like i have done nothing. No sound.
Hi Dimitar, great question!
The Tone() function use Pulse Width Modulation to create that tone form the buzzer, which means the voltage goes up and down real fast at different cycles depending on the input you send to the tone() function.
https://www.arduino.cc/en/reference/tone
With just a battery, you don’t get that modulation of voltage, which is why I am guessing you do not hear a buzz. Hope this helps some and thanks for asking!
If you want to use buzzer without arduino, you can use 555 timer ic. 555 timer will work as a crystal oscillator and do what the tone() function does.
Look up this page : https://www.instructables.com/555-alarm-circuit/
This is great! I have one question can one code a motor to only activate to the specified frequency and duration in the tone function?
how to do halbtöne?!
what is the purpose for the 100 ohm resistor? is it to lower the volume or ??? I want this to play a tone very loud.
[…] The proyect: https://www.programmingelectronics.com/an-easy-way-to-make-noise-with-arduino-using-tone/ […]
How to play a recorded human voice and how to load it to the Arduino
First of all can it be done
sir i am copying the above programme in my IDE but it show error message. please give me the complete code for generating 40000hz tone
What error message are you getting?
I get this message while compiler
Avrdude: ser_open ( ): can’t open the device “\\.\COM1”: the system cannot find the file specified .
Please give your opinion .
The error message is
avrdude: ser_open( ) :can’t open device “\\.\COM1” : The system can’t find the file specified
Terence, Are you able to load other sketches onto your Arduino board – or is it just this one giving you trouble?
Have you seen this thread by chance about the error you are having?
https://forum.arduino.cc/index.php?topic=334741.0
Sir my problems on uploading was cleared
Can the buzzer beep until a button is pressed when both these circuits are integrated, leave ur opinion?
Yes, that would possible. A button press could “latch” the buzzer, and then another button press could unlatch it.
How to produce 70khz frequency tone using arduino nano board.
[…] https://www.programmingelectronics.com/an-easy-way-to-make-noise-with-arduino-using-tone/ […]
[…] Use tone() with Arduino for an Easy Way to Make Noise […]
Whats the library of ‘tone’?
Hi is there a way to make it say a number
so im trying to play a sound through a speaker depending on which key on a keypad is pressed, and a LED corresponding to that key is lit. it works fine up until key 5, it then plays the exact same tone for keys 5-8 and the last LED is lit. is there a limit to how high the frequency can be? the tone I try to play is only 783.99 so im very confused. do you think its a software problem or a problem in my coding?
Hi there,
thanks so much for this tutorial, it helped me to understand the basics and move one with my school project.
and also, how to make it louder?
Aidan, although a number of sources say the tone() maximum frequency is 65535, the actual limit (depending on your board / CPU) may be 5KHz due to a limit in the library. I’ve seen that limit in several examples, including the one at arduino.cc. Additionally, piezo buzzers all have different ranges that they can operate within. Your buzzer may not be able to handle the higher frequencies. When you’re outside the fundamental range the piezo is designed to operate at, the volume will be 10-20 dB lower as it’s vibrating on a harmonic. Speakers are even worse: if you exceed the range of the speaker, it only warms up a little if the voice coil can’t respond that fast. Speakers can’t operate on harmonics, generally.
i am searching for the code to play bell sound using a buzzer i was hoping for a website which tells you what frequencies any sound is being played but could not find any
Any help ?
Thank you so much! It helped me debug successfully my Arduino project.
“tone() works independently of the delay() function.” is so important! I didn’t understand why my buzzer didn’t want to buzzer as long as tone() argument asked. Now I know!!
And thank you for all the explanations on tone() limitations as well! Super useful!
So glad it helped!
hye, can I connect the positive pole of buzzer to D0?
Hi this was really helpful. Is there a way to make the buzzer sound when an object is at a certain distance from a sensor? I am actually trying to make a project which displays the distance and there’s a buzz when it is too close.
Absolutely, an ultrasonic distance sensor might be a good fit for the distance measurement input.
Hello i really loved this site am still a young developer an i was having a hard time with IOT but now i have an understanding in things to do with arduino …Thanks
Thanks for the note Loyce!
Merhabalar, öncelikle verdiğiniz bilgiler için çok teşekkürler, çok faydalı lar.. Benim size bir sorum var: ” Tone ” komutu ile anolog ses frekansı okuyabilir miyiz?? Yani tam tersi bir sistemde mevcut bir ses kablosunu Anolog girişe başlarsak eğer okuma mümkün olur mu??
==
Hello, first of all, thank you very much for the information you have provided, they are very useful. I have a question for you: Can we read analog audio frequency with the ”Tone” command?? In other words, if we start the analog input of an existing audio cable in a reverse system, will it be possible to read??