toneAC v1.2 - Twice the volume, higher quality, higher frequency, etc.

My sketch size was different, because I used my own example.

I like the mini function. Perhaps it will not be used often, it's nice to have as an extra.

Using 'L' or 'UL' for long numbers is something I do for myself, so that I know what I'm doing.

I agree with everything else. Perhaps that ping-pong sound (the second smooth one) can be used as an example ? I'm trying to make more sounds that show what the volume can do.

A page in the playground section would be nice. I can make one, with links to your code and this thread.

But, not sure if 116 bytes is worth confusing people.

think not, but by the time their sketches fill up all memory and the last 116 bytes are critical I assume they aren't confused any more by a stripped lib :wink:

robtillaart:

But, not sure if 116 bytes is worth confusing people.

think not, but by the time their sketches fill up all memory and the last 116 bytes are critical I assume they aren't confused any more by a stripped lib :wink:

If I only knew how to set a define in a sketch so the library knew about it I'd be done by now.

Tim

Don't bother about the mini, it's not that important.

Example 1 : alert (soft and loud)

  // soft and loud alert.
  // For the toneAC library.
  // public domain
  int i, j;

  // Soft alert
  for( i=0; i<10; i++)
  {
    for( j=0; j<3; j++)
    {
      toneAC( 720, 3, 0, true);
      delay( 50);
      toneAC( 610, 3, 0, true);
      delay( 50);
      noToneAC();
      delay( 30);
    }
    delay( 500);
  }

  delay( 2000);
  
  // Loud alert
  for( i=0; i<10; i++)
  {
    for( j=0; j<3; j++)
    {
      toneAC( 720, 10, 0, true);
      delay( 50);
      toneAC( 610, 10, 0, true);
      delay( 50);
      noToneAC();
      delay( 30);
    }
    delay( 500);
  }

  delay( 2000);

Krodal:
Don't bother about the mini, it's not that important.

Example 1 : alert (soft and loud)

  // soft and loud alert.

// For the toneAC library.
  // public domain
  int i, j;

// Soft alert
  for( i=0; i<10; i++)
  {
    for( j=0; j<3; j++)
    {
      toneAC( 720, 3, 0, true);
      delay( 50);
      toneAC( 610, 3, 0, true);
      delay( 50);
      noToneAC();
      delay( 30);
    }
    delay( 500);
  }

delay( 2000);
 
  // Loud alert
  for( i=0; i<10; i++)
  {
    for( j=0; j<3; j++)
    {
      toneAC( 720, 10, 0, true);
      delay( 50);
      toneAC( 610, 10, 0, true);
      delay( 50);
      noToneAC();
      delay( 30);
    }
    delay( 500);
  }

delay( 2000);

If you want a loud alert from a piezo, it's best to first find its harmonic frequency. You can do it with a miltimeter. Just look for the frequency where the most current is drawn. It will typically be quite a large spike right at the loudest point. If you want something loud, this will be the frequency to play. With a piezo, it's typically 4,000 Hz.

Tim

Example 2 : A whistling kettle with boiling water sound.
This is a full sketch.

// Example for the toneAC library
// A whistling kettle with boiling water sound.
// public domain

#include <toneAC.h>

void setup()
{
}

void loop()
{
  int i, freq, freq_extra, freq_shift, vol;

  freq = 1440;
  vol = 1;

  for (i=0; i<1000; i++)
  {
    freq_shift = random (-15, 15);
    freq += freq_shift;
    
    // Stay around the frequency 1440
    if (freq < 1440)
      freq ++;
    else
      freq --;

    vol = i/50;      
    if (vol > 10)
      vol = 10;
    if (i > 800)
      freq_extra = (vol * vol) + 800;
    else
      freq_extra = (vol * vol) + i;
    
    toneAC( freq + freq_extra, vol, 0, true);
    delay(30);
  }
  noToneAC();
  
  delay(5000);
}

Krodal:
Don't bother about the mini, it's not that important.

To save a bit of compiled code size, use toneAC(). instead of noToneAC(). noToneAC() was meant to be familiar to the Tone library and the noTone() command. But, it's totally not needed for toneAC() and as a bonus you save 10 bytes.

Also, I created a TONEAC_TINY switch that allows you to save around 110 bytes that uses an alternate version of toneAC(). Would be useful for projects where maximum speed or the lowest code size is required.

I'm considering creating another library named something like ToneTiny or NewTone where it's a plug-in replacement for Tone including pin assignment but is much smaller, faster, and better quality. I know lots of people that have timer interrupt issues with the Tone library and are looking for an alternative. Not that toneAC doesn't provide that already, but toneAC is designed more for highly accurate AC switching speed and maximum volume.

Tim

teckel:
I'm considering creating another library named something like ToneTiny or NewTone where it's a plug-in replacement for Tone including pin assignment but is much smaller, faster, and better quality. I know lots of people that have timer interrupt issues with the Tone library and are looking for an alternative. Not that toneAC doesn't provide that already, but toneAC is designed more for highly accurate AC switching speed and maximum volume.

It was so easy I just did it, NewTone is a working library. Plug-in replacement for the Tone library, but over 1,200 bytes smaller compiled code size, faster, better quality sound, etc. Also uses timer 1 if you're having a conflict on timer 2 with the Tone library and some other library or hardware. Seriously took 30 minutes to write.

A little bit surprising is that toneAC still produces slightly smaller code (60-170 bytes). This is possible because toneAC doesn't need to find the ports and masks for the pins as it's fixed. But, I believe NewTone still has a place for those who need smaller, tighter code, yet need the flexibility of connecting to any pin. toneAC is still better in every way, with the exception being the fixed pins, but that's also why it's so good.

I'll probably package up NewTone and upload it later today for those who need a flexible drop-in replacement for the Tone library.

Tim

I'm considering creating another library named something like ToneTiny or NewTone

TinyTony? sounds Italian, would fit the Arduino :wink:

Example 3: Tone Tutorial with fade out tones.
You have to listen to this for yourself. It is not like a piano, because it sounds very computer/robotic.

Use the tone tutorial : http://arduino.cc/en/Tutorial/tone
But connect the loudspeaker to two output pins as is required for the toneAC library.

Replace the setup() function with this:

// Example for toneAC with tone fade out.
// Using the tone tutorial : http://arduino.cc/en/Tutorial/Tone
// public domain

void setup()
{
  for (int thisNote = 0; thisNote < 8; thisNote++) {
    // to calculate the note duration, take one second 
    // divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000/noteDurations[thisNote];
    
    // Add some to the length for the pauses between the notes.
    noteDuration += noteDuration/2;
    int i, vol;
    // Setting the volume to 12 is a trick to reduce the code.
    // The maximum volume is 10, but 12 is allowed.
    vol = 12;
    for (i=0; i<=noteDuration; i+=25)
    {
      // Double the frequency to make it sound better.
      toneAC( 2* melody[thisNote], vol, 0, true);
      // fade out
      if (vol > 0)
        vol--;
      delay( 25);
    }
    noToneAC();
  }
}

@teckel

I tried your sketch on a Bobuino with a 1284 chip, the speaker buzzed but nothing more. The board is found halfway down this page. Cross Roads Electronics

This may be asking too much but, would you consider making your library work with the 1284P? I have built a few boards using the chip.

This page may help you in the process if your interested. Arduino on ATmega1284P | maniacbug

I will be happy to test for you of course. :slight_smile:

cyclegadget:
I tried your sketch on a Bobuino with a 1284 chip, the speaker buzzed but nothing more. The board is found halfway down this page. Cross Roads Electronics

This may be asking too much but, would you consider making your library work with the 1284P? I have built a few boards using the chip.

This page may help you in the process if your interested. Arduino on ATmega1284P | maniacbug

I will be happy to test for you of course. :slight_smile:

I had believed it would work with the 1284P. Don't have one to confirm, but looking into it further I see that the ATmega1284P is different. I've updated my development v1.2 to support ATmega640, ATmega644, ATmega1281, ATmega1284P and ATmega2561. I've private messaged you a file for you to test to verify it works on the ATmega1284P. The pins you should use are D12 and D13 (the timer 1 PWM pins) on that microcontroller.

Let me know how it works.

Tim

Krodal:
Example 2 : A whistling kettle with boiling water sound.

I don't have the code handy - but waaaay back when I was kid, I remember playing around on my TRS-80 Color Computer with the PLAY command; there was a way, via using certain values (I think random notes played with very, very short durations) with a rapidly decreasing volume level (the CoCo had a 6 bit DAC - so there were 64 volume levels) - you could make an "explosion" or "gun" sound of sort...

...care to try making something like that?

:wink:

Since the toneAC library is ideal for kids toys (extra loud, no nasty clicks, volume control), these kind of sounds came to my mind. But so far I could not make something that sounds right.

Krodal:
Since the toneAC library is ideal for kids toys (extra loud, no nasty clicks, volume control), these kind of sounds came to my mind. But so far I could not make something that sounds right.

If you'd like to post your sound effect sketches to the toneAC library page I believe I can arrange it. You need a Gmail email address and let me know what it is and I'll try to set it up for you. Never done it before, but it seems like it's possible.

Tim

No need to set it up for me. I hope to add one or two more sounds with the library, and I will post them in this thread. I don't know if others want to contribute, and I also can't find a site with melodies and sounds that make use of the volume.

Example 4: Random sound

This is just a random. To make it random to the human ear, the frequency is not linear.
It can be used as startup-sound or to simulate that device is totally confused.
Set the volume to your own need.

// Random sound
// public domain

int i, j, frequency, volume, duration;

for( i=0; i<1000; i++)
{
  j = random (5, 60);
  frequency = j * j;
  volume = random(6, 11);
  toneAC( frequency, volume, 0, true);
  j = random( 1, 12);
  duration = j * j;
  delay( duration);
}
noToneAC();
  
delay(2000);

Example 5 : misuse of the toneAC library

The next example is able to generate noise sounds.
Both random functions are part of the delay. The random change in volume is needed for the noise.

// example of noise sounds with toneAC library
// public domain
//
// The lower and higher frequency define the sound.
//     300, 1500 : noise
//     340, 345   : computer noise
//     600, 14500 : rain drops noise

#define FREQUENCY_LOWER   300
#define FREQUENCY_HIGHER   1500
  
int i, frequency, volume;

for( i=0; i<10000; i++)
{
  volume = random(6, 11);
  frequency = random( FREQUENCY_LOWER, FREQUENCY_HIGHER);
  toneAC( frequency, volume, 0, true);
  delay(1);
}
noToneAC();
  
delay(2000);

First of all this library is awesome, and I'm very pleased that I found it. Registered just for this.

Secondly though, I'm running into trouble because of the 9 & 10 pin requirements. (Arduino Uno)

Is there a way someone could point in the right direction to modify the library to use pins 5 & 6? (or other PWM pins in general?) Or perhaps I misunderstand and the relevant timer is ONLY accessible on 9 & 10.

Any reason we couldn't use Timer 0 or Timer 2, per: Arduino Playground - TimerPWMCheatsheet

Alternately, I think it'd be an excellent addition to the library to be able to set options to switch between all possible PWM pins, just to give a little bit more flexibility.

countofangels:
First of all this library is awesome, and I'm very pleased that I found it. Registered just for this.

Secondly though, I'm running into trouble because of the 9 & 10 pin requirements. (Arduino Uno)

Is there a way someone could point in the right direction to modify the library to use pins 5 & 6? (or other PWM pins in general?) Or perhaps I misunderstand and the relevant timer is ONLY accessible on 9 & 10.

Any reason we couldn't use Timer 0 or Timer 2, per: Arduino Playground - TimerPWMCheatsheet

Alternately, I think it'd be an excellent addition to the library to be able to set options to switch between all possible PWM pins, just to give a little bit more flexibility.

The library uses timer 1, which are hard-coded to the PWM pins 9 & 10 on the Arduino Uno. It's not that my library hard-codes this, this is how the ATmega microcontroller is designed. While it's possible to have the timer interrupt run a small routine that would allow you to use different pins, the speed and accuracy would suffer. This isn't a big deal if you're doing human-audible frequencies as the Arduino would be plenty fast to do this. But, toneAC is designed to do frequencies well beyond even typically ultrasonic range (like 1 MHz) and do so with precise accuracy.

If it was just about flexibility, I would have written the library that way from the beginning (I basically already did when I wrote the NewTone library, which is based on toneAC but allows you to specify a pin). There's no way to keep the speed and accuracy while allowing you to select the pins.

Further, typically the only reason why you wouldn't want to use the timer 1 PWM pins is because you have a conflict with timer 1, not because you can't just move pins around. So, the real issue isn't that you use other pins, it's that you need it to use a different timer. The problem with doing that is that you'll get just as many people complain about using a different timer as it conflicts with a different set of libraries. Timer 0 is basically off-limits because that would mess with the ATmega's internal timers (millis, micros). Timer 2 would be possible, but more complicated as not all ATmega's have a timer 2 (Leonardo, Teensy 2.0) and they would use timer 4 instead.

So, switching over to use timer 2&4 instead of timer 1 would solve a problem for 10%, but create a problem for 10%, in other words a wash. Adding both timer 1 and timer 2/4 support would make the library more than twice the size, which would cause problems for some as it's small enough to be used on microcontrollers like the ATmega8 while the tone library won't fit.

In other words, we wouldn't really be solving anything by adding timer 2/4 support. We would for some, but we'd be creating problems for others.

I would think the only real option would be to rework toneAC and create a new library, say toneAC2 for example. It would simply be a timer 2/4 version of toneAC that would be fixed to the timer 2/4 PWM pins.

Now that I say this, and think about it for a minute, maybe it's not possible. Timer 2 doesn't have a Phase and Frequency Corrected PWM mode, so I don't think you can do it exactly like toneAC. It would need to be a slower and less accurate way.

It's not really that big of a project to do, but I don't have the need for it, therefore not the desire either. If someone is versed in timer interrupts, it would be really easy to take my toneAC and NewTone libraries and make a toneAC2 library that would use timer 2/4 as well as allow you to specify the pins. If I get bored one night maybe I'll do it (probably a 2 hour job). I guess as a bonus I wouldn't need to create a new development page for it. I could just piggy-back it on the toneAC site as an alternative version that uses timer 2/4 and has flexible pin assignments. Ah crap, maybe I will just do it.

Tim

teckel:
Ah crap, maybe I will just do it.

Tim

Ah my name is Tim as well. :stuck_out_tongue:

So from one Tim to another: Thanks for the detailed information involved as to the concerns with the timers. It's helpful for me to learn more about this as a beginner to the Arduino world.

At the moment, I'm mostly trying to figure out how to use your library without conflicting with the SD library's use of the 10 pin as a selector (per: SD - Arduino Reference) Based on what I've read there, though it looks like I may be able to just use SD.begin() to select a different pin for card initiation, and as long as 10 remains an Output that shouldn't actually cause problems.

So actually, with a little reading, I think the library will work for my particular application as it is.

Though I still think it would be awesome to have versions of the library for each of the available timers, just for that extra flexibility. From the pretty robust response you've received on the library in only a couple weeks, I think it's clear that people are finding it useful.

Anyway! Thanks for your efforts.