I have a YL-44/MH-FMD passive piezo buzzer hooked up to an ESP8266/NodeMCU.

It's connected like this: Buzzer ---> NodeMCU
- GND ---> G
- VCC ---> 3V
- I/O ---> D2

This code makes a clear beep.

void loop() {
  analogWrite(BUZZER, 255);
  analogWrite(BUZZER, 0);

This code makes a weird low clicking sound, no beep.

void loop() {
  digitalWrite(BUZZER, HIGH);
  digitalWrite(BUZZER, LOW);

I have no idea why the second one doesn't work, as all the tutorials reference that one.

Also, why does the buzzer have a weird constant static noise and gets hot?

Am I doing something wrong in the wiring? I use no resistors, as the tutorials don't show that.

  • 2
    it is passive as you have in the title. it doesn't vibrate by itself. use tone() function. example is with basic examples in IDE
    – Juraj
    Commented Nov 11, 2018 at 18:26
  • @Juraj Do you have any idea why there is static noise and it gets hot? Commented Nov 11, 2018 at 18:30
  • 2
    it is like a coil. under current it is pulled together. the click is the sound. 0 Hz :-) the noise is that it is not good to have it under constant current
    – Juraj
    Commented Nov 11, 2018 at 18:31
  • @juraj Can you please explain how do I fix the constant noise? I don't see a way. Commented Nov 11, 2018 at 18:49
  • 1
    it is the WiFi. I set the pin as INPUT after the tone(). it makes it better
    – Juraj
    Commented Nov 11, 2018 at 18:53

3 Answers 3


To sound a passive buzzer, use Arduino tone() function. If you set the pin HIGH the piezo surfaces are pulled together (or pulled away). It is what makes one click but nothing more. To make a tone the input must oscillate at right frequency. PWM is one way how to do a beep. Use tone() function to generate tones of desired frequency.

Your analogWrite(255) is PWM at 1/4 of full on, because max analogWrite value on esp8266 is at default 1023. So it makes a nice beep with 255.

If you use a speaker or passive piezo with esp8266 you can expect noise generated by WiFi operations. I set the pin as INPUT after tone() to eliminate the noise.

  • But why does analogWrite work, and digitalWrite not? Commented Nov 11, 2018 at 18:45
  • 1
    analogWrite is PWM. oscillation or 'pulse train'. en.wikipedia.org/wiki/Pulse-width_modulation
    – Juraj
    Commented Nov 11, 2018 at 18:46
  • On the ESP8266 analogWrite goes from 0 to 1023 not 0-255, so analogWrite(BUZZER, 255); is not the same as digitalWrite(BUZZER, HIGH);. It's more like analogWrite(BUZZER, 63); on the Arduino.
    – Majenko
    Commented Nov 11, 2018 at 20:00
  • @Majenko, thank you. I added it to answer
    – Juraj
    Commented Nov 11, 2018 at 20:06

One thing to note about the digital write part. While you have a delay between the HIGH to LOW, there is no delay to go back to HIGH (other than the time to leave loop and re-enter; which can be very small amount of time).

While on a slower processor (like AVR) this time maybe enough to cause some buzz (and consistent buzz), on the esp8266 its going to be fast enough that IO pin may not change state at all from LOW to HIGH. On Esp8266, IO physical pin state is at a different frequency than instruction counts. I believe its only 8 MHz. Due to the time before a pin state change to take effect, changing back before it got around to changing the physical state may ignore that state change. In the specific example, the LOW may get ignored often and you will have more random effects from that sketch.

Try adding another delay of 100 ms after setting the pin LOW. this will simulate a PWM of 1000 ms on width of a 1100 ms duty cycle. And even better, lower the delays by a factor of 100 (first being delay 10 ms, the new one a delay of 1 ms), you get a 10 (or so) Hz buzz.


Your code example does not work because you have a PASSIVE buzzer. Your example would work okay with an ACTIVE buzzer.

With a passive buzzer you must turn on/off the digital I/O pin at the desired audio frequency. Using the tone() API is an easy way to do this.

tone(BUZZER_PIN, 432, 250); // Play the buzzer at 432Hz for 250ms

Your buzzer is getting hot because it likely uses a PNP transistor to switch the coil on your buzzer module. This type of transistor conducts when the input is LOW. Some buzzer modules use NPN transistors and conduct when the input is HIGH.

To keep your buzzer from getting hot (and wasting current) set its input HIGH to turn it off (assuming it's using a PNP transistor which it sounds like it is based on your description)

digitalWrite(BUZZER_PIN, HIGH);

You'll need to do this after using tone() each time as it leaves the output pin LOW.

I recently created a discussion on this topic on AVRFreaks forum: Buzzer Module gets Warm and Wastes Power

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.