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:

  1. A quick intro to piezo speakers (aka piezo buzzers)
  2. How to set up a simple piezo speaker circuit
  3. The basics and more of using the tone() function
  4. 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.

A piezo buzzer circuit used to demonstrate the tone() Arduino function
  1. Place the piezo buzzer into the breadboard, so that the two leads are on two separate rows.
  2. 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).
  3. 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);
  1. The pin number that you will use on the Arduino.
  2. 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.

timing of tone() function with Arduino

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:

  1. 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.
  2. 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.
  3. 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:

  1. A piezo speaker use piezo-electric material to bend a metal diaphragm which makes noise.
  2. 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.
  3. 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.
  4. The limitations of the tone() function include:
    1. Not being able to use PWM on pins 3 and 11 while you use tone()
    2. You can’t go lower than 31 hertz.
    3. 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.

Further Reading:

  1. tone() in the Arduino reference
installing Arduino libraries

Installing Arduino Libraries | Beginners Guide

IoT sewage project

Pumping poo! An IoT sewage project

ESP32 webOTA updates

How to update ESP32 firmware using web OTA [Guide + Code]

error message Brackets Thumbnail V1

expected declaration before ‘}’ token [SOLVED]

Compilation SOLVED | 1

Compilation error: expected ‘;’ before [SOLVED]

Learn how to structure your code

38 Comments

  1. Jammus on September 4, 2015 at 9:20 pm

    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.

    • MICHAEL JAMES on September 6, 2015 at 6:22 am

      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().

  2. Jamil on July 30, 2016 at 4:03 pm

    Wait, what do I do with the dental floss?

    • vincenzo on November 30, 2016 at 9:24 am

      clean your teeth

  3. Dimitar on May 13, 2017 at 3:34 am

    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.

    • MICHAEL JAMES on May 26, 2017 at 6:12 am

      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!

    • Shivam Rai on November 26, 2020 at 2:48 am

      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/

  4. Kathia Coronado on October 23, 2017 at 11:35 pm

    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?

  5. Baun Baum on January 15, 2018 at 10:02 am

    how to do halbtöne?!

  6. Rick H on February 8, 2018 at 11:03 am

    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.

  7. Aayush roboteer on July 17, 2019 at 7:32 am

    How to play a recorded human voice and how to load it to the Arduino
    First of all can it be done

  8. terence saron on August 29, 2019 at 11:42 am

    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

    • Michael James on August 29, 2019 at 11:56 am

      What error message are you getting?

      • Terence saron on August 30, 2019 at 11:38 am

        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 .

  9. Terence saron on August 30, 2019 at 11:46 am

    The error message is
    avrdude: ser_open( ) :can’t open device “\\.\COM1” : The system can’t find the file specified

    • Michael James on August 30, 2019 at 11:50 am

      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

      • Terence saron on September 18, 2019 at 10:28 am

        Sir my problems on uploading was cleared

  10. Chandhu on September 9, 2019 at 1:48 am

    Can the buzzer beep until a button is pressed when both these circuits are integrated, leave ur opinion?

    • Michael James on September 9, 2019 at 6:56 am

      Yes, that would possible. A button press could “latch” the buzzer, and then another button press could unlatch it.

  11. Sarath k on September 18, 2019 at 10:31 am

    How to produce 70khz frequency tone using arduino nano board.

  12. […] Use tone() with Arduino for an Easy Way to Make Noise […]

  13. Muhammad Imam Rafi on December 13, 2019 at 10:23 pm

    Whats the library of ‘tone’?

  14. david f martin on December 17, 2019 at 7:43 pm

    Hi is there a way to make it say a number

  15. Aidan S on December 29, 2019 at 8:32 pm

    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?

  16. Natalia on April 22, 2020 at 9:00 am

    Hi there,
    thanks so much for this tutorial, it helped me to understand the basics and move one with my school project.

  17. Natalia on April 22, 2020 at 9:19 am

    and also, how to make it louder?

  18. StanJ on April 28, 2020 at 7:16 am

    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.

  19. HAT on September 7, 2020 at 12:33 am

    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 ?

  20. Kongyoyo on October 25, 2020 at 8:22 am

    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!

  21. Intan on November 18, 2020 at 6:54 am

    hye, can I connect the positive pole of buzzer to D0?

  22. Adriaa on March 2, 2021 at 12:45 pm

    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.

    • Michael James on March 2, 2021 at 4:12 pm

      Absolutely, an ultrasonic distance sensor might be a good fit for the distance measurement input.

  23. Loyce Velma Amondi on June 1, 2021 at 5:13 am

    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

  24. Celali on November 29, 2021 at 6:21 pm

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

Leave a Comment