Searching for the KY-012 active piezo buzzer module, you will find a lot of articles on how to connect it with a Raspberry Pi. Unfortunately, some of them are wrong and could in the worst case damage your Raspberry Pi. This article explains why this is the case and what would be a better alternative.
The first image shows the module from top and bottom. As one can see it has three pins. The outer pins are marked as
- (ground) and
S (signal?). The middle pin is not marked.
Having a look in the datasheet (page 3), it says you can power it with
3.5-5.5V. It should then not drain more than
5V. For the Arduino the datasheet also shows a wiring example:
S is directly connected to a GPIO of the Arduino and
- goes to GND. For the Raspberry Pi there is no Fritzing diagram in the datasheet.
Some current draw measurements...
Now, the GPIOs for Arduinos have a output level of
5V. The Raspberry Pi uses
3.3V. I was interested whether the module also works at
3.3V (out of range according to the datasheet) and how much current it draws then. I also did measurements for
5V. I used a laboratory power supply and a multimeter for that:
I = 16mA @ 3.3V I = 24.75mA @ 5V
My buzzer worked fine at
5V it draws less then the maximum
30mA specified in the datasheet. So far, so good.
Arduino vs. Raspberry Pi - Maximum GPIO current draw
Now, according to this, for the Arduino up to
40mA current draw from a GPIO is ok. But, according to this the maximum current draw for a Raspberry Pi at
3.3V should be
50mA for the whole
3.3V rail! Since the Raspberry Pi has 17 GPIOs that would be
50mA/17 = 2.94mA per GPIO
So if all GPIOs would be used at the same time, a maximum of
2-3mA would be ok, but not more. But even if we would only use one GPIO, some state that the maximum current draw for one GPIO is
As I mentioned above, the datasheet shows a Fritzing diagram which shows how to connect it to an Arduino. If we would connect the module the same way to a Raspberry Pi, we would load the GPIO with
16mA or possibly more (module tolerances, different environment temeprature...) and we just found out that this is not a good idea.
Why many wiring diagrams are not correct for the Raspberry Pi
This brings me to the other instructions I came across. Some say that the mysterious middle pin is
V+. The idea is then to connect
5V of your Raspberry Pi (e.g. at pin 2),
S to a
GPIO. The thinking behind this seems to be that there is a hidden transistor. This transistor is used as a switch for the buzzer. By applying a high level signal to
S the buzzer will be turned on. That way, less current would be drawn from the GPIO and everything would be fine.
Now the fun fact: The middle pin is not connected at all. That means, connecting it is useless. As a result of this, again the RPi GPIO where the
S pin is connected, will be loaded with
16mA. So this approach and the one presented in the datasheet (for the Arduino) are the same.
You don't believe that? Have a look at the bottom of the module again (see image above). If you trace the middle pin and the corresponding conductor trace, it will end at a soldering pad which doesn't seem to be used. Now if you have again a look on how the module looks from the top (see image above), you will see that the buzzer sits on top of that pad. In order to proof that this pad is really not used, I desoldered the buzzer, which you can see in the next image. One can clearly see, that this pad is really not used. The piezo also has only two connector not three. Therefore applying 5V to it (see "second approach" above) won't do anything.
The proper way
So in order to do it correctly, you need a transistor. I had a
Diotec 2N2222A laying around, so I used that one (you could use a different one of course). In order to connect it to the Raspberry Pi GPIO, we need a series resistor at the transistor's base (see schematic below). The value of that transistor can be easily calculated by having a look at the datasheet. But first, let's check what we actually want.
What do we want?
We want to connect the base of the transistor to a GPIO port of the RPi which gives us
3.3V. We want to connect the piezo to the
5V rail of the Raspberry Pi, since that was designed for a higher current draw. We learned above that the piezo will roughly need
5V, so our transistor needs to provide that at least. In reality, we should use the maximum value of
30mA from the KY-012 datasheet.
Having a look at the transistor's datasheet, you will see the so called
DC current gain values. We need to chose a current value for
Ic which is most close to our
30mA and then take the
hFE value (DC current gain value) the datasheet gives us. The datasheet gives us a value for
Ic = 10mA and for
Ic=100mA. So lets take the first one since
10mA is closer to
30mA. This gives us a
75. From this we can calculate
Ib, which is the current which needs to be drawn from our GPIO in order to provide
Ic = 30mA.
Ib = Ic/hFE = 30mA/75 = 0.4mA
We want to use the transistor as a switch. For this we give a bit more current on the transistor's base (we want the transistor to saturate). The datasheet gives us minimum values for the
hFE. For such a "minimum" value we could use a factor of
3. If the datasheet would give us a "typical" value (that means the
hFE could also be below that value), we should go slightly higher. So let's take a factor of
Ibsat = Ib * 3 = 0.4mA * 3 = 1.2mA
So we would drain
1.2mA from the GPIO. Now we can calculate the base resistor.
Uoh is the high-level output voltage of the GPIO pin.
Ube is the base-emitter voltage of the transistor.
R = U/I = (Uoh-Ube)/Ibsat = (3.3V-0.7V)/1.2mA = 2.167kΩ
Looks good! We could use a
2.2kΩ resistor. The final schematic would then look like this:
Of course you could use other pins for
5V and the
That's it. We will roughly drain
1.2mA from our RPi GPIO. Of course this is only a theoretical value. In reality, depending on the tolerance of your resistor and other factors, the value will vary a bit. Still, this will be less than the
2-3mA which are the "safe" area for a RPi GPIO. Mission accomplished!