> For the complete documentation index, see [llms.txt](https://s761111.gitbook.io/raspi-sensor/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://s761111.gitbook.io/raspi-sensor/feng-qi.md).

# 蜂鳴器

## 一、蜂鳴器

蜂鳴器是很常用的一種發音的零組件，它分為有源和無源二種！本次以介紹無源蜂鳴器為主。雖然可以透過gpiozero的TonalBuzzer類別，很方便的去play某個音階，但是，了解什麼是方波，什麼是頻率(Hz)，並且自己動手實作自己的音階播放會更有成就感！

{% embed url="<https://youtu.be/8iXoRp01sbE>" %}

```python
import RPi.GPIO as gpio
import time

piano = list([261, 293, 329, 349, 391, 440, 493, 523])
buzzer = 17

gpio.setmode(gpio.BCM)
gpio.setup(buzzer, gpio.OUT)


def play(pitch, sec):
    half_pitch = (1 / pitch) / 2
    t = int(pitch * sec)
    for i in range(t):
        gpio.output(buzzer, gpio.HIGH)
        time.sleep(half_pitch)
        gpio.output(buzzer, gpio.LOW)
        time.sleep(half_pitch)


for p in piano:
    play(p, 1)

gpio.cleanup()
```

## 二、雙音蜂鳴器

樹莓派是單板電腦，加上Python是強大的程式語言，結合二者，就可以做到讓蜂鳴器同時發出二個音階，甚至可以讓二個、三個、四個蜂鳴器同時演奏。 本次的程式碼有點難度，要看懂它必須了解python的物件導向、物件繼承及Multi Threading多執行緒的概念，如果還沒有足夠的基礎而看不懂，也不要灰心，看看就好不用太在意，未來再慢慢打好python的程式能力即可。

{% embed url="<https://youtu.be/WNlqztfPErE>" %}

```python
import RPi.GPIO as gpio
import time
from threading import Thread

piano1 = list([261, 293, 329, 349, 391, 440, 493, 523])
piano2 = list([261, 391, 329, 391, 261, 391, 329, 391])
buzzer = 17
buzzer2 = 27

gpio.setmode(gpio.BCM)


class PlayTone(Thread):
    def __init__(self, pin):
        super().__init__()
        self.pin = pin
        gpio.setup(self.pin, gpio.OUT)

    def tone(self, pitch, sec):
        half_pitch = (1 / pitch) / 2
        t = int(pitch * sec)
        for i in range(t):
            gpio.output(self.pin, gpio.HIGH)
            time.sleep(half_pitch)
            gpio.output(self.pin, gpio.LOW)
            time.sleep(half_pitch)


class Play(PlayTone):
    def __init__(self, pin, piano):
        super().__init__(pin)
        self.piano = piano

    def run(self):
        for p in self.piano:
            self.tone(p, 1)


p1 = Play(17, piano1)
p1.start()

p2 = Play(27, piano2)
p2.start()

while p1.is_alive():
    time.sleep(0.5)

gpio.cleanup()
```
