@peekay, that sounds complicated! Thanks for looking into this!, I’m glad you know what you’re doing!
@peekay123, looking at the added functionality of using the duty cycle on analogwrite the below controls the volume of the buzzer.
This might be an intermediate use for the other tone libraries.
Do you know if changing the duty cycle would affect anything else?
#include "application.h"
#define BuzzerPin A7 //Buzzer for sound notification
int maxFreq = analogWriteMaxFrequency(BuzzerPin);
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
void setup(){
Serial.begin(9600);
pinMode(BuzzerPin, OUTPUT); // sets the pin as output
analogWriteResolution(BuzzerPin, 12); // sets analogWrite resolution to 12 bits
analogWrite(BuzzerPin, 204, 2000); // 204/4095 = ~5% duty cycle
delay(1000);
analogWrite(BuzzerPin, 0, 2000); // 0/4095 = 0% duty cycle
delay(1000);
analogWrite(BuzzerPin, 2046, 2000); // 2046/4095 = ~50% duty cycle max volume
delay(1000);
analogWrite(BuzzerPin, 0, 2000);
}
void loop(){
}
@wesner0019, the duty cycle dictates the total “on” time for a given period set by the frequency. The volume is loudest at 50% duty cycle when using a single pin for driving the buzzer. The ToneAC library uses a “push-pull” method for achieving a simulated AC signal across the buzzer. Using two pins, one pin is driven low for while the other pin is driven high and vice versa over the duty cycle and frequency of the tone. This effectively doubles the amplitude/volume of the sound produced by the buzzer. In your code, changing the duty cycle will have an effect but it will not increase the volume.
@Thanks for the explanation, but in our certain scenario, our buzzer is too loud at the standard 50% duty cycle so we need a way to decrease it. The 50% duty cycle can be too annoying to some of our customers.
But the ToneAC library would be good to have to increase the volume for our older aged customer base.
@peekay123 Hi Im looking at the ToneAC library again for a new project.
I’m wondering if you ever had a chance to port it?
thanks
@wesner0019, no I haven’t ported it. However, looking at the code, it looks like a variant of Tone() with variable PWM duty cycle to vary the volume. The Tone library uses Timer Output Compare interrupts to reload the timer register, changing the frequency. I’d have to look if varying the duty cycle (thus the volume) is also possible.
Ok thanks!
I was excited to find this thread but sad to see it fizzled. Would love to see one of these libraries ported by a savvy individual.
What exactly are you looking for where you’d need this?
Maybe there are also other ways to get your intended job done.
I’m looking to dynamically adjust the volume of a piezo buzzer via software.
You can use this to decrease from the maximum volume. Set by the voltage of your buzzer. So if you use Tone right now that would be the maximum volume but the below will make the volume quieter. So its volume adjustment it just that you cant make it louder than what your piezo is currently at.
#include "application.h"
#define BuzzerPin A7 //Buzzer for sound notification
int maxFreq = analogWriteMaxFrequency(BuzzerPin);
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
void setup(){
Serial.begin(9600);
pinMode(BuzzerPin, OUTPUT); // sets the pin as output
analogWriteResolution(BuzzerPin, 12); // sets analogWrite resolution to 12 bits
analogWrite(BuzzerPin, 204, 2000); // 204/4095 = ~5% duty cycle
delay(1000);
analogWrite(BuzzerPin, 0, 2000); // 0/4095 = 0% duty cycle
delay(1000);
analogWrite(BuzzerPin, 2046, 2000); // 2046/4095 = ~50% duty cycle max volume
delay(1000);
analogWrite(BuzzerPin, 0, 2000);
}
void loop(){
}
Thanks! I had read in my searches that this method wouldn’t work, but I do hear a volume difference. In attempting a full sweep from 0-4095, it appears only values below 512 produce a noticeably softer tone, at least on my piezo. Still, I think this should do the trick!