Close

Updates - over 768 of them! ;)

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.

lixie-labsLixie Labs 11/14/2016 at 01:360 Comments

Woo! Update time again!

Last time we talked, I had branched development of Volume into a second library allowing for custom waveforms like sine or sawtooth.

I've decided to branch again, to provide a third, higher-quality, lower-consumption library. Let's take a look at the specs!

VOLUME3 LIBRARY:

10-bit Control - 768 more volume levels!

After adopting the lovely TimerOne library to drive this technique, Volume3 now offers 10-bit volume control, 0 - 1,023.

Only using Timer1!

Because of the lovely TimerOne lib, we can now produce our PWM AND the interrupts for driving waves on a single timer.

No More Awful Prescaler!

We're now producing the ultrasonic PWM on Timer 1, leaving that nasty Timer 0 to manage delay and millis() like normal with it's default 64x prescaler. This means you can now use the native delay/millis functions with Volume3!

No More God-Awful Distortion

As proud as I was of the first version, it had a characteristic "fizzle" when you lowered the volume of certain frequencies. This is virtually gone now, due to raising the PWM carrier frequency from 62,500 Hz to 100,000 Hz. Nice and clean now!

HOWEVER

I'm still going to actively maintain these three as SEPARATE libraries. I'll explain why after this table:

Volume Library Comparison:

Library Volume1 Volume2 Volume3
Accuracy 8-bit 8-bit 10-bit
Frequency Range (Hz) 120 - 5,000 1 - 3,400 1 - 4,186
PWM Frequency (Hz) 62,500 62,500 100,000
Polyphony 1 1 1
Needs vol.begin() YES YES NO
Compiled Library Size (Bytes) 2,501 2,542 1,054
RAM Usage (Bytes) 39 457 24
Frequency Slide Quality GREAT BAD GOOD
Timer Usage 0, 1 0, 1 1
Delay Issue (Timer0 Prescaler) YES YES NO
Square Wave YES YES YES
Sawtooth Wave NO YES NO
Triangle Wave NO YES NO
Sine Wave NO YES NO


As you can see, each library has it's strengths and weaknesses. Volume1 is best for range and slides, Volume2 is best for custom waveforms, and Volume3 is best for accuracy, size, and ease of use. Speaking of ease of use, here's a comparison of Volume1 and 3:

Volume1:

#include "Volume.h"
Volume vol;
uint16_t frequency = 440;
void setup() {
  vol.begin();
  vol.alternatePin(true);
}
void loop() {
  for(byte volume = 0; volume < 255; volume++){
    vol.tone(frequency,volume);
    vol.delay(5);
  }
  for(byte volume = 255; volume > 0; volume--){
    vol.tone(frequency,volume);
    vol.delay(5);
  }
  vol.noTone();
  vol.delay(1000);
}

Volume3:

#include "Volume3.h"
uint16_t frequency = 440;
void setup() {}
void loop() {
  for(int volume = 0; volume < 1023; volume++){
    vol.tone(10,frequency,volume);
    delay(3);
  }
  for(int volume = 1023; volume > 0; volume--){
    vol.tone(10,frequency,volume);
    delay(3);
  }
  vol.noTone();
  delay(1000);
}

Several improvements have been made here:

I'm still working on catching up Volume3 to include original functions like a master volume control and one-liner fades, but for now I'm sharing in excitement to see how people use the new library!

GIVE IT A GO!

https://github.com/connornishijima/arduino-volume3


I promise I'm not making a Volume4. ;)

- Connor

Discussions