Go Down

Topic: Programmatically change the volume of a piezo buzzer (Read 10117 times) previous topic - next topic


Hello everyone,

I'm working on my first 'big' arduino project, which is a midi file player. Bascially, it reads midi files from an SD card and play the notes on differents piezo buzzers.

So far, I've got it working, but I would like to adjust the volume of my buzzers depending on the velocity of the notes.

I can control the volume by changing the value of the resistor of each buzzer, and I thought of doing something like the attached picture.

In this example, I would have 2 pins controlling one buzzer, each pin would be connected to a different resistor value.That way :
- Playing the tone on pin 2 would give me a high volume
- Playing the tone on pin 3 would give me a low volume

I'm using Tone library (https://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation). In order to change the pin, I thought I could just call tone.begin(pin) like this :

Code: [Select]
#include <Tone.h>

Tone t1;

void setup(void)

void loop(void)
  // Play a high volume note
  // Switch to pin 3 and play a low volume note

But everytime I call tone.begin(pin), it eats a new timer instead of using the same.

So right now, I'm looking for a way to re-use the same timer, or maybe another way to change the volume of the buzzer with code.

Thanks in advance :)


Hi, welcome to the forum.

I would call that a piezo element. It is a flat piezo disc inside a plastic housing to make it louder.
A buzzer is buzzing with 5V, a piezo element needs the tone library.
I hope you didn't include that tone library, because it has already been included with the Arduino software.
Have a look at the examples. Like the "Tutorial: multiple tones".


Hello, and thank you :)

Sorry for the misuse of the word buzzer. I've been told it is a "piezo buzzer"., and being lazy, I thought I could just get rid of the "piezo" :P

I'm aware of the built-in tone() function, but unfortunately it doesn't allow me to activate multiple piezo elements simultaneously. That's why I had to use the tone library I linked above, it allows me to use tone on more than one pin at the same time. I know the schema only shows one piezo element, but my real circuit is more complex and has 5 of them connected on my arduino. I only wanted to simplify the schema ;)

My question was more related to the tone library itself.
Everytime I want to initialize a pin as an output, it "eats" an internal timer of the arduino. So I start by initializing my 5 piezo elements like this :
Code: [Select]

Tone tonePlayer[5];
tonePlayer[0].begin(3); // Will use timer 2
tonePlayer[1].begin(4); // Will use timer 3
tonePlayer[2].begin(5); // Will use timer 4
tonePlayer[3].begin(6); // Will use timer 5
tonePlayer[4].begin(7); // Will use timer 1

This code eats 5 timers on my arduino mega.
When I try to change the output pin of one player by calling, for example :
Code: [Select]
Instead of re-using the timer 2, it looks for another available timer. Since the only remaining timer is  timer 0, my sketch doesn't work anymore because it screws the delay() function, which is crucial  for the application.

Maybe the title of the topic isn't relevant enough, but I was looking for either the answer to my question about the tone library, or any other  possible way to achieve what I really want to do : control the volume of my piezo elements in a way or another.

Maybe what I'm really looking for, is some kind of IC that will receive one input, and have multiple output (but only one active at once). Like a demultiplexer or something. That way I could connect the piezo element with different resistors values, and use the IC to select which resistor the tone will go through...

Sorry if it sounds confusing, I'm having a hard time explaining, as english is not my primary language  :smiley-zipper:


It's a little confusing.
Did you click on that link to the tone library, and did you have a look at the "Tutorial: multiple tones" ?

Tell us what you want to achieve ?
The Arduino producing a single tone at a time, but with different volumes ?
There are (too) many options for that, for example with a music shield.

But using just one piezo element/buzzer is also possible.
For example the toneAC library has some kind of volume control.

Scroll through the Audio section in the Playground : http://playground.arduino.cc/Main/InterfacingWithHardware#Audio

Have a look at this website: http://sensorium.github.io/Mozzi/
Those examples on that webpage can come out of your Arduino without an extra synthesizer chip. The Arduino can't do anything else, since the Mozzi library pushes the Arduino to the limit.
You can try the Mozzi library just for fun, it is awesome.


Sorry if I'm not clear enough, I'm trying to provide as much information as possible, but I guess it's more confusing than helping :P

What I want to achieve is having 5 piezo elements playing simultaneously, with the ability to change the volume of each piezo element individualy with some lines of code.

I did look at the "Tutorial: multiple tones", but it doesn't allow me to play multiple tones at the same time. The same problem would occur with toneAC library. That's why I'm using an alternative tone library (found here: https://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation). And it works great.

Now, for changing the volume of a piezo element, I can manually change the resistor I put in front of it, but I want to be able to do this within my code. I was looking for a way to have multiple resistors in parallel in front of each piezo element, and find a way to programmatically switch from one resistor to another (schema attached). In this schema, the "IC" would be a switch that I could program, and tell whenever I want to use output 1 or output 2. Note that in the schema, I only displayed one piezo element, but I want to use 5 of them.

I did some more researches, and it looks like a 4051 would allow me to do this (http://playground.arduino.cc/learning/4051).

I'm probably gonna try that, and see it it works :)


I understand now  8)

This question was a few weeks ago in the forum, I don't know what the result was.

An Arduino pin directly to a piezo element/buzzer is not very good. The piezo is like a capacitor and you need a resistor of 100 ohm to reduce the peak currents.

I can think of an alternative way. Use the Arduino pin to the piezo, and the other wire of the piezo to 100 ohm to ground.
Then replace the 100 ohm with some NPN transistors with different resistors.
With 3 transistors you can create 8 levels of volume, and the pin for the tone is still the same pin.


Yes, I will always put a resistor with each piezo ;)

Thanks for the suggestion about using transistors, I will see what I can do with those infos and find a way to make it work  :)

Go Up