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:
- No more Volume class definition needed
- No more vol.begin() init needed
- No more special delay/millis functions
- Ability to use either Timer1 pin at will, no more vol.alternatePin()
- 10-bit accuracy, adding 768 new volume levels!
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
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.