Pages: [1] 2   Go Down
Author Topic: toneAC - Twice the volume, higher quality and frequency Arduino tone library  (Read 2371 times)
0 Members and 1 Guest are viewing this topic.
Toledo, OH
Offline Offline
God Member
*****
Karma: 35
Posts: 508
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

http://arduino.cc/forum/index.php/topic,142097.msg1066968.html

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
« Last Edit: January 11, 2013, 04:18:51 am by teckel » Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Toledo, OH
Offline Offline
God Member
*****
Karma: 35
Posts: 508
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

http://en.wikipedia.org/wiki/Piezoelectricity#Mechanism - 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
« Last Edit: January 09, 2013, 09:04:20 pm by teckel » Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12534
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Sr. Member
****
Karma: 9
Posts: 296
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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:
Quote
you would tie the piezoelectric buzzer to pins 9 and 10 a
Ahhhh okay, sounds plausible (pardon the pun). Demo please. Youtube smiley
« Last Edit: January 09, 2013, 09:14:45 pm by vasquo » Logged

Toledo, OH
Offline Offline
God Member
*****
Karma: 35
Posts: 508
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
#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
« Last Edit: January 09, 2013, 10:16:04 pm by teckel » Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Toledo, OH
Offline Offline
God Member
*****
Karma: 35
Posts: 508
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: January 09, 2013, 10:23:46 pm by teckel » Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Toledo, OH
Offline Offline
God Member
*****
Karma: 35
Posts: 508
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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
Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Portland, Oregon
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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...
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13478
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 smiley-wink


Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Toledo, OH
Offline Offline
God Member
*****
Karma: 35
Posts: 508
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Toledo, OH
Offline Offline
God Member
*****
Karma: 35
Posts: 508
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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
Logged

Arduino - Teensy - Raspberry Pi
My libraries: NewPing - LCDBitmap - toneAC - NewTone - TimerFreeTone

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17259
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
 
Logged

Pages: [1] 2   Go Up
Jump to: