More waveforms? Sine me up!

A project log for 10-bit Component-less Volume Control for Arduino!

Using PWM at an ultrasonic frequency, I've given Arduino 10-bit volume control for Tone() generation using nothing but the speaker.

Connor NishijimaConnor Nishijima 09/02/2016 at 18:310 Comments

I've branched development of the Volume library to a second version, which now supports multiple waveform types such as sine, sawtooth, and more!


This new Volume2 Library is not a successor, but a separate project I've decided to library-ize to see if people like it. Just like the Volume1 lib, it provides 8-bit volume control with no extra components. The kicker here is that now you can choose from the following waveform shapes:

SQUARE | Your friendly neighborhood square wave

PWM_12 | PWM "square" at 12.5% duty cycle

PWM_25 | PWM "square" at 25%. The NES used these PWM voices!

SAWTOOTH / SAWTOOTH_HIGH | Sawtooth wave, low and high quality

TRIANGLE / TRIANGLE_HIGH | Triangle wave, low and high quality

SINE / SINE_HIGH | Sine wave, low and high quality

CUSTOM | Custom 32-byte array defined by the user for custom voices

NOISE | Ignores frequency, returns fast volume-controlled RNG

The CUSTOM waveform is an exciting option. You can use this to define you own complex waveshapes to produce sound similar to things like pianos, guitars, cellos, and more. The array given must be 32 8-bit signed values. For example, this is an array for generating several square wave octaves:

byte wave[32] = {

With this array, setting the frequency to 220 Hz will generate 220, 440, 880, and 1760 Hz simultaneously!


While the new library is great at generating waves, it's max frequencies are lower and it doesn't handle fades well yet. For now, I'm keeping the two separate to allow people to choose what's best for their own needs until I can optimize each further for a smooth merge!


As always, I've provided a ton of documentation on the GitHub, and examples can be found as well. But the easiest way to try the Volume and Volume2 libraries is to grab them through the Arduino Library Manager!

- Connor