2

Goal:

  • I want to replace a status-LED with a status-buzzer
  • I use the same code which worked with the status-LED:
  • (1) on start set buzzer to LOW
  • (2) wait some time, than "blink" once (HIGH 200 ms then LOW)
  • (3) wait and repeat (2)

Problem:

  • On program start I execute buzzer = new Gpio(21, 'out');
  • after buzzer.write(0) I already hear a continuous loud buzzer noise (sound tone/frequency is higher, volume is lower and the sound is "unhealthy"/unstable)
  • after buzzer.write(1) the buzzer sound has a lower tone, higher volume and the sounds is more stable
  • it only shuts up when I execute: buzzer.unexport()

Question:

  • is the buzzer broken or do I use it wrongly?
  • where is the difference between write(0) and unexport()? I thought there is only LOW and HIGH, no "ZERO" voltage on GPIO?

Hardware and wiring:

  • active buzzer (this one): 3.3-5V, 2 KHz, with 9012 transistor-driver
  • Raspberry PI 3
  • Buzzer (+) with PIN 2 (5V) connected
  • Buzzer (-) with PIN 39 (GND) connected
  • Buzzer (out) with PIN 40 (GPIO 21) connected

Software:

  • nodejs Module onoff
  • OS: Raspbian 9 stretch (kernel 4.14.71-v7+ #1145, 2018-10-09-raspbian-stretch-lite.img)
  • nodejs v8.12.0

Update 1:

  • I noticed that when I switch the semantics of 0 and 1: write(0) as "buzzing" and write(1) as "stop buzzing" and leave the device in state 1 something very weird happens:
  • The noise of "state 1" is quieter and sounds unstable
  • When I cover the hole of the buzzer with my finger a couple of times it becomes quiet (as if I calmed down a swinging membrane)
  • This is reproducible and only works for "state 1", not with "state 0"
  • I'll buy another buzzer in a few days as this sounds like a hardware problem to me ...
tlfong01
  • 4,384
  • 3
  • 9
  • 23
hb0
  • 125
  • 1
  • 5
  • 2
    Have you got the buzzer wired correctly, those piezo buzzers have a strict polarity. Check the anode is connected to GPIO 21 and cathode to any GND pin. – Dougie Apr 27 '19 at 11:13
  • Yes, I am pretty sure that they are connected correctly, I double checked with the person who sells them and I used the same Pins with LEDs for years on many PIs. But thanks for the comment – hb0 Apr 28 '19 at 12:14
  • See my question: The "out" port of the buzzer must be used for the signal, thus, it's the one connected to GPIO 21. The 5V PIN 2 delivers permanent power for the buzzer and is connected to it's (+) port. – hb0 Apr 28 '19 at 12:38

3 Answers3

2

Update 2019may08hkt2153

I am testing out the following active buzzer to confirm my suggested get around of using 4k7 works.

The OP uses the following active buzzer with the ad saying is it both Rpi and Arduino compatible.

Active buzzer buzzer sound alarm module cable Raspberry Pi Arduino active

Active buzzer 1

I found the schematic for Sunfounder's buzzer but it doesn't look like the OP's buzzer. So I need to use a multimeter to trace the components to draw a schematic, as shown below.

active buzzer

/ to continue, ...

Question

Rpi3 node.js GPIO 21 blinking LED code works with LED but not with active 3V3~5V, 2kHz pizoelectric buzzer

Low frequency noise even buzzer.write(0), but buzzer.write(1) OK, buzzer.unexport() shuts up also OK.

Is the buzzer broken?

Update 2019apr28hkt2237

I think I have found the answer. Please ignore my old answer below. I will now explain why your node.js and other python programs do not work. Then I will suggest a get around which I already verified good.

Why

The root cause is that you are using an Arduino compatible active buzzer for Rpi. For this Arduino compatible buzzer, it is designed to be low active, ie, when input signal lower than about 1.0V buzzer will be on. And if input signal is higher than about 3.5V, buzzer will be off. Now Arduino has no problem, because its High is about 4.2V, well above 3.5V.

Now Rpi is in big trouble, because its High is only about 3V, no hope reaching the required 3.5V to switch off.

Workaround

Easy - insert a 4k7 resistor between Rpi GPIO pin and input of active buzzer. I have been telling newbies for almost a year this trick, but nobody listens, ...:(

Quick and dirty explanation

The buzzer circuit input front end is very likely a PNP BJT. It is biased such that when input signal to base, through a biasing resistor, is 3.5V or higher , the transistor is cut off (Arduino High is 4.2V, therefore a clean cut off), no base current flows, therefore not enough collector current to activate the piezo thing.

Now Rpi's High is only 3V, therefore not high enough to have a clean cut off, resulting some base current, and therefore some collector current to partially/weakly activate the piezo, therefore you hear the smaller buzzing sound.

The get around of inserting a 4k7 between Rpi GPIO and input is not to allow even small base current to flow, to get clean cut off, so no sound. Yes, I verified it! :)

Now for the activating/on case, both Arduino and Rpi have Low level lower than 1V, therefore both have no problems switching on.


Update2019apr29hkt2051

Actually Rpi has the same problem with a couple of other Arduino only devices, including 5V low level trigger relay. Similarly Rpi can only switch on, but not switch off. The same trick of adding a 4k7 resistor is the quick cure. Another get around it is the following:

To switch off relay, instead of set GPIO High,


set GPIO to input mode


I think node.js can use the same trick, that is


instead of buzzer.write.0 to switch off buzzer, use buzzer.unexport()


/ to continue, ...


Please ignore the old answer below.

Answer

  1. your buzzer is broken, or
  2. your node.js code is buggy, or
  3. buzzer.write(0) causes buzzer to oscillate

To check if buzzer is broken (less likely) you can use a simple python peep program to test the buzzer:

#!/usr/bin/env python
import RPi.GPIO as GPIO
import time

pin = 40

def setup():
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, GPIO.HIGH) # HIGH should turn the buzzer off

def peep():
    while True:
        GPIO.output(pin, GPIO.LOW) # peep
        time.sleep(1.0)
        GPIO.output(pin, GPIO.HIGH) # should make the buzzer quiet
        time.sleep(3.0)

def tearDown():
    GPIO.output(pin, GPIO.HIGH)
    GPIO.cleanup()

if __name__ == '__main__':
    print 'Peeping!'
    setup()
    try:
        peep()
    except KeyboardInterrupt:
        tearDown()

If python can beeps the buzzer correctly then perhaps your node.js program is buggy or has a problem talking to RPI3. Perhaps you can post the node.js code here, and let us join in debugging.

Comment from the questioner:

  1. the buzzer seems to be broken, see my comments
  2. the nodejs code seems to be ok(ish)
  3. I expected write(1) to produce a sound and write(0) to make the buzzer quiet but in fact it is the other way around for my buzzer (if the buzzer would get completely quiet at all)
tlfong01
  • 4,384
  • 3
  • 9
  • 23
  • Thanks, that's very helpful. #python: A sample code snippet would be good, also for other people with the same problem in the future. If the python script does reproduce this I will buy another one and keep this thread updated. #nodejs-code: I only use the nodejs module "onoff" as I use it for years with LEDs on the same GPIO pins with the same RPI. Thus, I think an error here is less likely. But I will post the code, too, if the other ways fail. #versions: I update my question, thanks! – hb0 Apr 28 '19 at 12:21
  • See my updated question: I noticed that when I switch the semantics of "0" and "1" and leave the buzzer in "1" I can stop the very unstable sounding, less loud noise by tabbing/covering the buzzer hole (where the sound comes out) with my finger ~ 2 times. – hb0 Apr 28 '19 at 13:01
  • I added a python script to your answer myself. Result: it reproduces what I see with my nodejs code. Thus, this seems to be a hardware problem: LOW makes a normal buzzer sound, HIGH does not shut the buzzer completely up but still produces a sound with lower volume (and an unstable noise frequency) – hb0 Apr 28 '19 at 13:44
  • Yes, I expected that. So I am not going to send you the python program. I am going to update my answer to explain what is going on, and a get around, which I already test OK. – tlfong01 Apr 28 '19 at 14:32
  • I have updated the answer, with a get around. Good luck. – tlfong01 Apr 28 '19 at 15:09
  • Wow, you really put in some effort.Thank you very much, this makes much sense. I'll report back to you as soon as I get my hands on a 4k7 resistor. – hb0 Apr 29 '19 at 10:42
  • Ah, I forgot to add that another get ground is obvious - instead of buzzer.write(0) to switch off buzzer, use buzzer.unexport(). Rpi guys use the same trick to switch off relay - instead of set GPIO high, they just cheat by setting GPIO to input mode. It is cheating, but works. But actually both get arounds are problematic. Perhaps I will explain later. – tlfong01 Apr 29 '19 at 13:09
  • Nö worries, I eventually have to use another buzzer anyways, I need a clean solution in the end. But all this information really helped and I learned a lot. The problem is solved, I know that the hardware is incompatible. Just for fun I will test the workaround 1 anyways. The other workaround does not seem healthy as I would need to do this about 5 times per second potentially for hours and it should not be blocking / using much more time than write() and the code would get more complex – hb0 Apr 29 '19 at 13:26
  • To report back: I tested the 4.7k resistor workaround: I put it between the GPIO and the buzzer's signal port - and I am able to use the buzzer for testing now (with HIGH = quite and LOW = buzzing), thank you very much! Hopefully, this thread will help others, too, in the future! – hb0 Apr 29 '19 at 20:20
1

I tried putting a 5100 ohm resister (I didn't have a 4.7k handy) in series with my output pin but my buzzer module would still stay on constantly. After reading about it triggering on a low signal and being for an Arduino, I finally stumbled onto using 3.3V to power the module and setting the control pin output to LOW to turn it on and HIGH to turn it off. It worked in a simple on/off program but later I had to add GPIO.setup(12, OUT, initial=GPIO.HIGH) to keep it from turning on at the start of a more complex program. HTH

John Blake
  • 11
  • 1
0

Python, just in case. With gpiozero lib you can use close() to stop it

simple function that Im using

def beep(s):
    tb = TonalBuzzer(BuzzerPin)
    tb.play(Tone(frequency=880))
    sleep(s)
    tb.stop()
    tb.close()