Page 1 of 2

use of LED control for buzzer?

Posted: Fri Jun 01, 2018 3:21 pm
by mzimmers
Hi all -

We had a minor ECO to our new board - the buzzer has been replaced with one that doesn't oscillate on its own, so the software has to manage it. I thought I'd re-use the LED control software, but it's not working (can't get the buzzer to sound).

Here's my set-up code:

Code: Select all

#define BUZZER_TIMER      (LEDC_TIMER_1)
#define BUZZER_CHANNEL    (LEDC_CHANNEL_1)
#define BUZZER_GPIO       (5)
#define BUZZER_FREQ         (2200)

const ledc_timer_config_t buzzer_timer = {LEDC_HIGH_SPEED_MODE,
                                          {LEDC_TIMER_13_BIT },
                                          BUZZER_TIMER,
                                          BUZZER_FREQ};

const ledc_channel_config_t buzzer_channel = {BUZZER_GPIO,
                                              LEDC_HIGH_SPEED_MODE,
                                              BUZZER_CHANNEL,
                                              LEDC_INTR_DISABLE,
                                              BUZZER_TIMER,
                                              0x1fff};
  
err = ledc_timer_config(&buzzer_timer);
assert (err == ESP_OK);
ledc_channel_config(&buzzer_channel);
assert (err == ESP_OK);
And here's the code:

Code: Select all

void Buzzer::setDuty(uint32_t duty)
{
    ESP_ERROR_CHECK(ledc_set_duty(LEDC_HIGH_SPEED_MODE, BUZZER_CHANNEL, duty));
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_HIGH_SPEED_MODE, BUZZER_CHANNEL));
}

void Buzzer::buzzer_task()
{
    BuzzerQueueEntry entry;

    while (1)
    {
        entry.value = 0; // reset between queue reads.

        // look for a change request from our queue. Process if present.
        if (xQueueReceive(m_buzzerQueue, &entry, portMAX_DELAY) == pdTRUE)
        {
            if (entry.value > 0)
            {
                ESP_LOGI(TAG, "turning buzzer on.");
                setDuty(0x3ff);
                // turn buzzer on
            }
            else
            {
                ESP_LOGI(TAG, "turning buzzer off.");
                setDuty(0x0);
                // turn buzzer off
            }
        }
    }
}
Anyone see anything obvious I'm doing wrong? If there's an easier way to do this, I'm open to that as well.

Thanks...

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 5:07 pm
by mikemoy
Need a little more info.
How are you driving the buzzer? GPIO directly, though a transistor, and if transistor did you add the blocking diode.
Did you look at the pin via a scope to ensure your getting the square wave output ?

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 5:41 pm
by mzimmers
I'm told that "We are diving it with a N-Channel FET from IO5 without any blocking diode."

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 5:47 pm
by mikemoy
ok, cool. what about "Did you look at the pin via a scope to ensure your getting the square wave output ?"

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 9:14 pm
by Archibald
It would help if you provide a link to the type of buzzer you are using. It sounds to me as if it's probably a piezo transducer such as this. If so, drive it directly from a GPIO, not through a transistor.

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 9:17 pm
by mzimmers
I haven't had a chance to do that yet, but I think it's producing a good wave. There's been a development since I first posted: I'm now getting a tone from the buzzer, though there are some remaining mysteries.

The tone starts when ledc_channel_config() is called, presumably because I have a non-zero value in the duty parameter. What's odd is, immediately after calling this routine, I then call ledc_get_duty() which returns 0.

Also, when the duty is set to 0x1fff (the maximum for a 13-bit precision) the buzzer is almost silent. According to the spec sheet, it's rated to 3.6VDC and 90mA, so I'm not overdriving it. When I set the precision to 10 bit, and set the duty to 1ff, it's nice and loud. I can live with this (may be a HW problem) but I wanted to make sure I was correctly reading the docs -- if I set the timer to 13 bits, and the duty to 0x1fff, shouldn't I expect this to work (at maximum volume)?

EDIT: the little noisemaker is a US Electronics magnetic transducer, model USE-8530DT23SLF.

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 9:22 pm
by mikemoy
Archibald wrote:It would help if you provide a link to the type of buzzer you are using. It sounds to me as if it's probably a piezo transducer such as this. If so, drive it directly from a GPIO, not through a transistor.
Just an FYI, it's not a good idea to drive a piezo electric device via a GPIO pin. Piezo devices can generate negative voltages.

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 9:57 pm
by Archibald
mzimmers wrote:-- if I set the timer to 13 bits, and the duty to 0x1fff, shouldn't I expect this to work (at maximum volume)?
To get 50% duty cycle square wave, I would expect to set duty to 50% of 2^13 = 0x1000.

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 10:01 pm
by Archibald
mikemoy wrote:Just an FYI, it's not a good idea to drive a piezo electric device via a GPIO pin. Piezo devices can generate negative voltages.
I'm getting only -40mV but no negative voltage if I reduce the GPIO drive strength to the lowest option.

Re: use of LED control for buzzer?

Posted: Fri Jun 01, 2018 10:04 pm
by mikemoy
Archibald wrote:
mikemoy wrote:Just an FYI, it's not a good idea to drive a piezo electric device via a GPIO pin. Piezo devices can generate negative voltages.
I'm getting only -40mV.
Is that measured with a scope or meter. You will get much higher voltages than this when you turn a piezo off at the right time. Similar to say when energize a coil and release it. It's just best practice to use a transistor or fet to drive them. No gpio pin like any negative voltage even though many GPIO pins nowadays have protection for this, but one should not depend on that to save on BOM costs.