ArduboyBeep: low overhead tone generation

I was just going to play around with some sounds and thought I would use this example as a starting point. I’m not sure why but this example does nothing when I push the A button. the Steve example works and I used the same code as a starting point in Humanity Revenge.

Have I overlooked something again or should this example run as is?
NVM - I had to enable audio in setup…

Using both classes with same parameters produces some interesting sounds

beep1.tone(beep1.freq(60), 20); 
beep2.tone(beep2.freq(60), 20);

BeepPin1 will produce a lower raspy sound whereas BeePin2 will be a higher pitch peep, taking BeepPin1 down as low as between 10 to 50 although not very loud gives some nice sounds ideal for something like a motorbike.

Muting control for ArduboyBeep works the same as other sound libraries. It’s controlled by the Arduboy2Audio subclass of the Arduboy2 library.

Unless you add code to your sketch to control muting by using the Arduboy2 functions audio.on(), audio.off(), audio.toggle() and audio.saveOnOff(), then it should be controlled using the System Control mode invoked in begin(). (Hold the B button during boot and, while holding, press UP to enable sound or DOWN to mute the sound.)

For more information see the Audio mute control and Audio control functions headings in the Arduboy2 library documentation.

1 Like

You can get other interesting sounds by playing a tone on both pins at the same time, each with a very slightly different frequency. This is caused by creating an acoustic beat.

You may get beating even if you choose the same frequency for both pins because for some frequencies the actual frequency played will be more accurate on Pin 1 than on Pin 2.

Lots of experimentation is in order, if you’re interested.

1 Like

The frequency range (in Hz) that each pin can produce is:

Pin Min Max
1 15.26 1000000
2 61.04 15625

If I have understood the code correctly its (tone in Hz) , (duration @ 60 framerate = 1 sec).
If this is the case they appear to go lower as I am getting audio with the following

  if (arduboy.pressed(A_BUTTON)) {
    beep1.tone(beep1.freq(10), 20); //10Hz for 1/3 of a second @ 60 frames
    arduboy.print("BeepPin1 @10");
  }
  if (arduboy.pressed(B_BUTTON)) {
    beep2.tone(beep2.freq(30), 20); // 30Hz for 1/3 of a second @ 60 frames
    arduboy.print("BeepPin2 @30");
  }

Here’s the code in use

No, the first parameter that you give to tone() is the actual count value that is written to the timer’s Output Compare Register (OCR). For Pin 1 that value must be from 0 to 65535. For Pin 2 it must be from 3 to 1023. And because different clock prescalers are used for each timer, the count required for each pin will be different for the same frequency.

In order to allow the user to work in frequencies instead of counts, I provide a freq() function for each pin, which converts the specified frequency to the required count.

When you call beep1.freq(10) it will return a count value of 34463, which will produce a frequency of 29.02Hz, not 10Hz. 29.02Hz is still low enough get the raspy sound that you hear, but it’s not 10Hz.

When you call beep2.freq(30) it will return a value of 2082. When truncated to 10 bits (Timer 4, used for Pin 2, is only a 10 bit timer), the count value will be 34. This will produce a frequency of 1785.7Hz, which is why you hear such a high pitch instead of a low raspy 30Hz.


Edit (addition): You can confirm the above by trying it.
The following two lines should produce the same sound:

beep1.tone(beep1.freq(10), 20);
beep1.tone(beep1.freq(29.02), 20);

And the same for:

beep2.tone(beep2.freq(30), 20);
beep2.tone(beep2.freq(1785.7), 20);
1 Like

Thanks Scott it makes sense, I thought it was a little strange for me to hear anything as low as 10Hz lucky enough it wasn’t low enough that I would need to install a blow hole.

You’re not hearing even 29.02Hz. The piezo speaker is only capable of producing much higher frequencies. If you were to feed even a 100Hz pure sine wave into the speaker you probably wouldn’t hear anything. But we’re feeding it square waves, so what you’re hearing at low frequencies are the higher frequency overtones that a square wave produces.

1 Like

Does the Arduboy have one channel or two channels?
If the Arduboy has two channels, I could make the music on one and the sound effects on the other, although some sounds will be played on the music channel.
And because this is handled by frequencies, there will be lots of trial and error while coding the music.

The Arduboy’s piezo speaker is placed across two output pins of the microcontroller, rather than having one pin tied to ground. You can play different sounds on each pin and the speaker will mix them together. So the answer is: The Arduboy has two channels that are mixed to the single speaker.

The ArduboyPlaytune library is designed to do this.

Other options would be:

  • Use the ArduboyTones library to play music (normal volume only) and use the BeepPin2 class to play tones for sound effects.
  • Create functions that play music using one of the BeepPin classes and play tones for sound effects using the other BeepPin class.
  • Use ATMlib or ATMlib2, which both generate multiple channels using “Pulse Width Modulation” (PWM).

Edit: You already asked this type of question a few months ago

Team ARG is out of business and its code is archived. I cannot use ATM tracker because of it, which left me to use the beeper instead.

Why? What’s wrong with ArduboyPlaytune?