Adjust frequency of Buzzer in Serial Monitor

Hi everyone,

I am doing a project that I hope I can adjust the frequency in Arduino Serial Monitor. I know there is a solution which I could use "analogWrite" to do the math. Here's my code in analogWrite control:

#define buzzer_pin 9


void setup() {
  pinMode(buzzer_pin, OUTPUT);
  analogWrite(buzzer_pin, 0);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()){
    char buzzer_picked = Serial.read();
    int buzzer_freq = Serial.parseInt();
    write_freq(buzzer_picked, buzzer_freq);
  }
}
void write_freq(char buzzer, int frequency)
{
  if (buzzer == 'f'){
    analogWrite(buzzer_pin, 0 + frequency);
    return;
  }

  return;
}

But the value of analogWrite shows 0 - 255, I would like to use frequency value (HZ unit) to control my Buzzer's sound. I used "tone" to control it but I can't do math in "tone" syntax. Could you guys help me and provide some suggestion please?

One more question is when I used "tone" syntax and I am not sure why there's still a low sound when I set my frequency 0, like this:

const int buzzer = 9;


void setup(){
 
  pinMode(buzzer, OUTPUT);
  tone(buzzer, 0); // <===== set frequency to 0
  Serial.begin(9600);

}

void loop(){

}

Please give me some suggestion. Thank you guys so much in advance.

'analogWrite()' sets the duty-cycle of the PWM output, not the frequency.

This is useless:-

0 + frequency

From the 'tone' reference page:-

It is not possible to generate tones lower than 31Hz.

This compiles:-

tone(3, 500+500, 500+500);

So what do you mean by "I can't do math in "tone" syntax."

If you want to set the frequency of PWM, pins 9/10, look at the TimerOne library.

.

OldSteve:
So what do you mean by "I can't do math in "tone" syntax."

Hi OldSteve,

First of all, thanks for your help:)
I would like to control the Buzzer frequency through entering a number in Serial Monitor. Cause the code I wrote, it's the method for controlling LED by entering 0~255 in Serial Monitor to adjust the luminosity of LED. I know it's totally a different value between LED and Buzzer's frequency. So do you know any method to do controlling Buzzer's frequency by entering a number in Serial Monitor, the unit is HZ?

LarryD:
If you want to set the frequency of PWM, pins 9/10, look at the TimerOne library.

Hi LarryD,

Thank you so much for your information. I will check on it.

MaciveXiong:
Hi OldSteve,

First of all, thanks for your help:)
I would like to control the Buzzer frequency through entering a number in Serial Monitor. Cause the code I wrote, it's the method for controlling LED by entering 0~255 in Serial Monitor to adjust the luminosity of LED. I know it's totally a different value between LED and Buzzer's frequency. So do you know any method to do controlling Buzzer's frequency by entering a number in Serial Monitor, the unit is HZ?

What about exactly what you originally wrote, but using "Tone" instead of 'analogWrite()'?

By the way, don't use '#define' for pin allocations. It can lead to errors. Use 'const byte'.

This should work:-

const byte buzzer_pin = 9;

void setup()
{
    pinMode(buzzer_pin, OUTPUT);
    Serial.begin(9600);
}

void loop()
{
    if (Serial.available()>0)
    {
        char buzzer_picked = Serial.read();
        int buzzer_freq = Serial.parseInt();
        write_freq(buzzer_picked, buzzer_freq);
    }
}

void write_freq(char buzzer, int frequency)
{
    if (buzzer == 'f')
    {
        tone(buzzer_pin, frequency);
        return;
    }
    
    return;
}

Just keep in mind that 31Hz is the lowest tone you can produce using "Tone". Do you actually need lower?

Note that I changed the "Serial.available" line to:-

if (Serial.available()>0)

Edit: I also just removed this from 'setup()':-    analogWrite(buzzer_pin, 0);(Overlooked it earlier.)

Hi OldSteve,

Thank you so much for your help. It's really helpful. Now I solve the problem I faced yesterday, It turns out I can control my frequency on "tone" syntax and I set "noTone" in the beginning for turning off first. Then I enter numbers as frequency in serial monitor and it totally works!!! Thank you guys all this help:)

MaciveXiong:
Hi OldSteve,

Thank you so much for your help. It's really helpful. Now I solve the problem I faced yesterday, It turns out I can control my frequency on "tone" syntax and I set "noTone" in the beginning for turning off first. Then I enter numbers as frequency in serial monitor and it totally works!!! Thank you guys all this help:)

Glad to help.
Another happy customer. :smiley: