toneAC - Twice the volume, higher quality and frequency Arduino tone library

The toneAC library is now available.

http://code.google.com/p/arduino-tone-ac/downloads/detail?name=toneAC_v1.0.zip&can=2&q=

Here are the advantages over the standard tone library:

  • Nearly twice the volume (because it uses two out of phase pins in a push-pull manor)
  • Much higher quality (no clicking)
  • Capability of producing higher frequencies (even if running at a lower clock speed)
  • Nearly 2k smaller compiled code
  • Can set not only the frequency but also the tone volume (duty)
  • Less stress on the speaker so it will last longer and sound better

I tested it on an Uno and Teensy 2.0. Making sure it works on the Mega and other boards would be helpful to know. Enjoy!

The official development forum has been created and can be found here.

Further discussion should probably go there instead of with this thread.

----- Original message -----

Concept is simple. I wanted to create an AC type output from two PWM pins using the same timer (timer 1) at a very high speed. The purpose is to create a higher sound pressure level output from a piezoelectric transducer than the standard pulsed-DC method used in the Tone library. Basically, instead of a pulsed-DC +5v and 0v (5 volt range) signal, driving two pins out of phase yields an effective +5v and -5v (10 volt range).

The tone library won't work as it doesn't do in/out of phase (also may have high frequency issues when the ATmega is running at low speed). The TimerOne library won't work because it also doesn't do in/out of phase PWM.

I couldn't find such a library, so I wrote a very fast port register level library that provides a perfect in-phase and out of phase PWM signal on two PWM pins. On an Arduino Uno you would tie the piezoelectric buzzer to pins 9 and 10 and using my library specify the frequency and you're done. Even if running the ATmega at 4 MHz like I was, this library can still create an ultrasonic frequency, and much louder than with the Tone library as it's driving both pins out of phase with each other. It always keeps the duty at 50% for the highest output.

Anyway, did I miss a library that does this? Or, is there interest in me turning it into a library for the community. It wouldn't be difficult, but there's no reason to bother if no one is interested. Think of it like a high-power and faster version of the Tone library but fixed to the assigned PWM pins for timer 1 (9 & 10 for Uno) (14 & 15 for Teensy 2.0) (11 & 12 for Mega).

By fast, typically PWM can be as fast as 62.5 kHz. But, because my library sets the upper limit, it can be as fast as 8 MHz (if my math is correct) at 16 MHz. As I wanted to do ultrasonic frequencies and I was running the ATmega at 4 MHz, the highest frequency Tone or TimerOne could produce was only 15,625 Hz. But, with my library, even at a 4 MHz clock speed I could generate a 40 kHz or even higher signal, and do it so two pins are out of phase at the same time for increased output volume.

So, did I waste my time or should I release it? Anyone got a catchy name to call it? I've created other libraries like the very popular NewPing and LCDBitmap, so you can trust it will be a high quality library.

Tim

1 Like

asically, instead of a pulsed-DC +5v and 0v (5 volt range) signal, driving two pins out of phase yields an effective +5v and -5v (10 volt range).

I'm missing something, I guess. How will two +5V to 0 to +5V pins toggling out of phase result in a -5V output?

PaulS:

asically, instead of a pulsed-DC +5v and 0v (5 volt range) signal, driving two pins out of phase yields an effective +5v and -5v (10 volt range).

I'm missing something, I guess. How will two +5V to 0 to +5V pins toggling out of phase result in a -5V output?

Obviously, it never really generates -5 volts. But, the effect is like that as it's generating an AC current. Think of the speaker diaphragm and what happens when you apply voltage to it. When you apply positive voltage the diaphragm moves in one direction. When you apply negative voltage it moves in the other direction. If you alternate quickly between these, you get twice the range of movement from the diaphragm than you would if you just toggled one pin high and low. When two pins are out of phase with each other, the electrons are moving one direction then the other, which when you consider what's happening at the diaphragm level, it's as if it's getting a positive then negative voltage.

There's really not a positive and negative terminal to a piezoelectric buzzer (it's not like an LED). So, you can alternate the current both directions to increase the sound pressure level (volume).

Maybe I'm doing a poor job explaining it. I found a couple links that may help:

http://www.aurelienr.com/electronique/piezo/applic.pdf - The second page (Page 85 in the document) seems to explain it best with a nice graphic.

Piezoelectricity - Wikipedia - The "Mechanism" section also explains it.

In addition to making a speaker louder by doing this, it also extends the life of the driver because supplying voltage in only one direction can cause the diaphragm to be permanently deformed reducing volume.

The advantages:

  • Louder
  • Higher frequency
  • Longer beeper life

The library obviously wouldn't work for LEDs. There's limitations like fixed to certain PWM pins and using two pins instead of just one. But, there's also benefits if you have the free pins anyway. Maybe I need to just post an example sketch so you could plug in a piezo buzzer to hear the difference yourself.

Tim

So it gets 5V in alternate directions, instead of 5V one way and then 0V for half a cycle? In effect it's 5V AC rather than the 2.5V AC of the standard output. Yes, I can see how that would increase the output.

Basically, instead of a pulsed-DC +5v and 0v (5 volt range) signal, driving two pins out of phase yields an effective +5v and -5v (10 volt range).

In concept, you're trying to fake a DIFFERENTIAL LINE.

But I still don't get how you'll generate a -5 volts (with respect to ground), to achieve a +5V - (-5V) = 10V range

EDIT:

you would tie the piezoelectric buzzer to pins 9 and 10 a

Ahhhh okay, sounds plausible (pardon the pun). Demo please. Youtube :slight_smile:

Below is an example sketch (designed to work with ATmega328 and ATmega32U4 running at 16 Mhz). Put a piezo buzzer (without internal oscillator) on pins 9 & 10 on the Uno (or 14 and 15 on the Teensy 2.0) and hear the difference in volume. The sketch alternates between my AC method and the Tone library (both at 4 kHz). The volume should be quite different.

As another test, install one wire of the piezo buzzer on pin 9 (or pin 14 on the Teensy 2.0) and the other to ground. Now you're canceling out the out of phase of my AC method so the volume will be identical.

#if defined (__AVR_ATmega32U4__) // ATmega32U4 (Teensy/Leonardo).
  #define PWM1 14
  #define PWM2 15
#else // For ATmega328 (Uno) ** This sketch doesn't work on Mega but the library will. This is just an example **
  #define PWM1  9
  #define PWM2 10
#endif

void setup() {
  pinMode(PWM1, OUTPUT);
  pinMode(PWM2, OUTPUT);
}

void loop() {
  // AC tone at 4000Hz.
  TCCR1A = 176;
  TCCR1B = 18;
  ICR1   = 250;
  OCR1A  = OCR1B = 125;
  delay(2000);

  // Turn off AC.
  TCCR1A = 1;
  TCCR1B = 2;
  digitalWrite(PWM1, LOW);
  digitalWrite(PWM2, LOW);

  // Pulsed-DC with Tone library at 4000Hz.
  tone(PWM1, 4000);
  delay(2000);
 
  // Turn off Pulsed-DC Tone library.
  noTone(PWM1);
}

Keep in mind I'm not asking if it's possible, as the above sketch will show it works. It's also not something I invented, this is kind of common knowledge. What I'm asking is if people are interested in such a library. Making it work much like the Tone library at nearly twice the volume is basically what it will do. I happen to have a SPL meter and it measures from 4-5 dB louder (6 dB is twice the volume). So, it's quite noticeable. Also, there's the other benefits I mentioned above.

Tim

vasquo:
But I still don't get how you'll generate a -5 volts (with respect to ground), to achieve a +5V - (-5V) = 10V range

Obviously, it can't produce -5 volts. But, you can't think of voltage at the pin level. You need to think of it at the diaphragm level. With the Tone library, only one side is ever positive (half the time) and the other side is always ground. Electrons only ever flow one way, driving the diaphragm in one direction. By using an AC signal driving both sides, there's a constant push/pull on the diaphragm as electrons are flowing both ways and the diaphragm is being bent in both directions.

I guess maybe a more understandable way of saying it is normally, the Tone library only supplies 2.5 volts to a speaker as the duty cycle is 50%. By using an out of phase AC signal on two pins, you're sending 5 volts (2.5 volts on one pin and 2.5 volts on the other). Maybe I should have said I can supply the full 5 volts to a speaker at 50% duty while Tone supplies 2.5 volts. But, then I believe I'd be having a similar conversation with other people claiming that the Tone library is sending 5 volts not 2.5.

In any case, it does work, it's much louder, and the way I'm doing it, it allows for much higher frequencies (even if you're running your microcontroller well bellow 16 MHz). There's other advantages as well, with the only two disadvantages is that you're locked into using certain pins and you must use two pins instead of one. But, in many cases this isn't a problem and in my case the Tone library would never work (couldn't produce high enough frequency and wasn't loud enough).

Tim

It seems that some don't understand why they need a toneAC library. So, I created one anyway :stuck_out_tongue:

It should work with any ATmega328, ATmega32U4, ATmega1280, ATmega2560, ATmega1284P. Just need to do frequency testing based on different microcontroller speeds. Will create the library later today:

http://code.google.com/p/arduino-tone-ac/

Tim

Or you could use a 10c transistor to amplify the 2.5v AC signal.

teckel:
Concept is simple. I wanted to create an AC type output from two PWM pins using the same timer (timer 1) at a very high speed. The purpose is to create a higher sound pressure level output from a piezoelectric transducer than the standard pulsed-DC method used in the Tone library. Basically, instead of a pulsed-DC +5v and 0v (5 volt range) signal, driving two pins out of phase yields an effective +5v and -5v (10 volt range).

The tone library won't work as it doesn't do in/out of phase (also may have high frequency issues when the ATmega is running at low speed). The TimerOne library won't work because it also doesn't do in/out of phase PWM.

I couldn't find such a library, so I wrote a very fast port register level library that provides a perfect in-phase and out of phase PWM signal on two PWM pins. On an Arduino Uno you would tie the piezoelectric buzzer to pins 9 and 10 and using my library specify the frequency and you're done. Even if running the ATmega at 4 MHz like I was, this library can still create an ultrasonic frequency, and much louder than with the Tone library as it's driving both pins out of phase with each other. It always keeps the duty at 50% for the highest output.

Anyway, did I miss a library that does this? Or, is there interest in me turning it into a library for the community. It wouldn't be difficult, but there's no reason to bother if no one is interested. Think of it like a high-power and faster version of the Tone library but fixed to the assigned PWM pins for timer 1 (9 & 10 for Uno) (14 & 15 for Teensy 2.0) (11 & 12 for Mega).

Tim

While I don't have a project right now that would use it, why would anyone say no to a new useful library?

Yes...Yes..Yes...

So, did I waste my time or should I release it?

No, ideas like this move frontiers just like your ping lib did.

From functionality point of view, please add a flag to select single or double volume (maybe runtime).
It would be nice to have an volume alternating mode on another frequency that the tone itself.

possible?

Could also be used for bi-colour leds (anti-parallel or whatever its called) in fast alternating mode

Or as a carrier for some new serial protocol. The alternating mode is ground frequency, modulating it adds information.
The alternating mode may (don't know for sure) allow longer cables?

...

In short I think it has possibilities we cannot imagine now, so build/post the library so others can surprise you :wink:

sbright33:
Or you could use a 10c transistor to amplify the 2.5v AC signal.

If you have a higher voltage available, a transistor will work. But, I was working with a 3.3 volt battery powered project that didn't have a higher voltage available. I guess you could also say a solution would be a charge pump. But, that also typically uses PWM and we're already using PWM for the audio output. A charge pump is also more complex than a 10c transistor. Further, there's other advantages of using an AC driving method, like speaker life. Finally, I wanted to do ultrasonic frequencies while the ATmega was running at 4Mhz, which the tone library doesn't do.

Tim

robtillaart:

So, did I waste my time or should I release it?

No, ideas like this move frontiers just like your ping lib did.

From functionality point of view, please add a flag to select single or double volume (maybe runtime).
It would be nice to have an volume alternating mode on another frequency that the tone itself.

possible?

Not only possible, volume is already built into my development library (which, by the way, I'm almost done with).

robtillaart:
Could also be used for bi-colour leds (anti-parallel or whatever its called) in fast alternating mode

Yes, this would work. Although a slightly different implementation because you'd want to vary the color with the duty cycle instead of volume (which 50% is full volume).

Tim

Didn't mean to sound negative. Some of your new features sound great compared to a pulse or square wave!

The full complementary output (which the 180 phase relationship is) of your timer outputs, coupled with output pins that both sink and source current can be a real electrical advantage to interfacing with certain circuit configurations. Running the timer outputs like that has wider applications then just making louder sound.

Lefty

The toneAC library is now available.

http://code.google.com/p/arduino-tone-ac/downloads/detail?name=toneAC_v1.0.zip&can=2&q=

Here are the advantages over the standard tone library:

  • Nearly twice the volume (because it uses two out of phase pins in a push-pull manor)
  • Much higher quality (no clicking)
  • Capability of producing higher frequencies (even if running at a lower clock speed)
  • Nearly 2k smaller compiled code
  • Can set not only the frequency but also the tone volume (duty)
  • Less stress on the speaker so it will last longer and sound better

I tested it on an Uno and Teensy 2.0. Making sure it works on the Mega and other boards would be helpful to know. Enjoy!

The official development forum has been created and can be found here.

Further discussion should probably go there instead of with this thread.

Tim

Hi Teckel,

Cool. Like to see people digging way below the usual detail level of Arduino into the Atmel reality.

Fantasy: At some Ultrasonic frequency there are TWO outputs of this type. But the PHASE between those can be varied and they drive two separate Ultrasonic transducers. There is one (maybe 2?) Ultrasonic transducer receivers. Some kind of Phased Array technique allows not just distance but some spatial location information to be recovered from object(s) in front of the array. Maybe.

About that Word: I used to give some little talk called "Fantasy as an Engineering Design Tool" which was actually well received, even by Software types. I once told a meeting at Perkin-Elmer Corp. that they had "A really nice Fantasy about this Deep-UV technique being applied to chip lithography". They were a little miffed. But later a couple guys told me they really understood, and that they fought with Management which wanted them to "Stop the Blue Sky Stuff" and Get To Work.

One great thing about Arduino is that most of us are not doing this stuff At Work...

terryking228:
Fantasy: At some Ultrasonic frequency there are TWO outputs of this type. But the PHASE between those can be varied and they drive two separate Ultrasonic transducers. There is one (maybe 2?) Ultrasonic transducer receivers. Some kind of Phased Array technique allows not just distance but some spatial location information to be recovered from object(s) in front of the array. Maybe.

With the toneAC library you can also connect two piezo/speakers that will generate out of phase signals. On the Uno, one tied to 9 and GND and the other tied to 10 and GND. Both will produce the same frequency. Not sure what exactly the volume (duty) will do. If it will adjust the duty for each equally or opposite of each other.

terryking228:
One great thing about Arduino is that most of us are not doing this stuff At Work...

I'm trying to change that. We have a new overhead audio marketing division and I'm trying to do the full design from hardware to software. The difference in price from commercial options for hardware are making my proposal very interesting to the owner. I can envision moving all my Arduino stuff out of my house and converting my office to a "tinker shed". My wife would also appreciate it to get her house back.

Tim

Thanks, nice job. This could come in handy.

Pauly:
Thanks, nice job. This could come in handy.

I've modified a few projects to use toneAC and it was quite easy with obvious benefits.

Much higher sound output level was the primary reason for the library. But, saving 2k and being able to set the volume to a lower level has also come in really handy as well.

Tim