新しいものづくりがわかるメディア

RSS


土日で完成! 趣味のラズパイ

土日で完成! 趣味のラズパイ ラズパイとChatGPTで遊ぼう——圧電ブザーで音を鳴らす

ChatGPTでさまざまな電子工作をしてきましたが、今回は圧電ブザーを使って音を鳴らしてみましょう。圧電ブザーはその名前の通り、電圧をかけると音が鳴る仕組みを使っています。早速ChatGPTに聞いてみましょう。鳴らすのは映画『未知との遭遇』で使われたあの有名な音階です。

なお、今回はRaspberry Pi 4と、最新の「Bookworm」から1つ前のOSである「Bullseeye」を使っています。このところに注意してください。Bullseeyeをインストールするためには、Raspberry Pi ImagerでOSに「legacy」を選ぶとインストールするための項目が表示されます。


問い
Raspberry Piと圧電ブザーを使って、未知との遭遇のシドララミの音階を鳴らしてください



これに対するChatGPTの返答は以下のようなものでした。


Raspberry Piと圧電ブザーを使って「未知との遭遇」のシドララミの音階を鳴らすための手順は以下の通りです。

### 必要なもの:
- Raspberry Pi
- 圧電ブザー
- ブレッドボード
- ジャンパーワイヤー

### 手順:

1. **ハードウェアの接続**:
- 圧電ブザーのプラス端子をRaspberry PiのGPIOピン(例:GPIO 18)に接続します。
- 圧電ブザーのマイナス端子をGNDピンに接続します。

2. **Pythonスクリプトの作成**:
- PythonのRPi.GPIOライブラリを使用して、圧電ブザーを制御します。
- 以下のスクリプトを作成し、`CloseEncounters.py`として保存します。

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

# GPIOの設定
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)

# 音階の周波数
notes = {
    'C': 261.63,
    'D': 293.66,
    'E': 329.63,
    'G': 392.00,
    'A': 440.00
}

# 音階の再生
def play_tone(frequency, duration):
    pwm = GPIO.PWM(18, frequency)
    pwm.start(50)
    time.sleep(duration)
    pwm.stop()

# シドララミ音階の再生
def play_close_encounters():
    melody = ['G', 'A', 'F', 'F', 'C']
    durations = [0.5, 0.5, 0.5, 0.5, 0.5]
    
    for note, duration in zip(melody, durations):
        play_tone(notes[note], duration)
        time.sleep(0.1)  # ノート間の短い休止

try:
    play_close_encounters()
finally:
    GPIO.cleanup()
```


3. **スクリプトの実行**:
- ターミナルを開き、`CloseEncounters.py`が保存されているディレクトリに移動します。
- 以下のコマンドを実行します。

    
```bash
python CloseEncounters.py
```

これで、Raspberry Piに接続された圧電ブザーが「未知との遭遇」のシドララミの音階を再生します。



ラズパイと圧電ブザーをつないだら早速鳴らしてみましょう。GPIO18は12番ピンです。

しかしエラーが出て止まってしまいました。原因は音階の設定がめちゃくちゃになっているためです。ChatGPTはあの音階をきちんと理解していないようです。ちなみに音階と周波数の関係は以下のようになります。

ド(C):261Hz
レ(D):294Hz
ミ(E):329Hz
ファ(F):349Hz
ソ(G):392Hz
ラ(A):440Hz
シ(B):493Hz
ド(1オクターブ高いC):523Hz>

ではこれで設定し直します。また、最後のミはもう少し長い方があの音に近いですね。プログラムを改編したものは以下のようになります。

import RPi.GPIO as GPIO
import time

# GPIOの設定
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)

# 音階の周波数
notes = {
    'B': 493,
    'C': 261
    'A': 440
    'E': 329
}

# 音階の再生
def play_tone(frequency, duration):
    pwm = GPIO.PWM(18, frequency)
    pwm.start(50)
    time.sleep(duration)
    pwm.stop()

# シドララミ音階の再生
def play_close_encounters():
    melody = ['B', 'C', 'A', 'A', 'E']
    durations = [0.5, 0.5, 0.5, 0.5, 0.5]
    
    for note, duration in zip(melody, durations):
        play_tone(notes[note], duration)
        time.sleep(0.1)  # ノート間の短い休止

try:
    play_close_encounters()
finally:
    GPIO.cleanup()

しかし何かおかしいです。あの曲のようになっていません。原因は2番目のラの音がオクターブ下になっていないためです。ラの音の周波数を見ると440Hzで鳴っています。1オクターブ下にするためには、ラの音の周波数を半分にすればOKです。もう一度プログラムを改編しましょう。

import RPi.GPIO as GPIO
import time

# GPIOの設定
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)

# 音階の周波数
notes = {
    'B': 493,
    'C': 261,
    'A': 440,
    'A2': 220, # 下のラの音
    'E': 329
}

# 音階の再生
def play_tone(frequency, duration):
    pwm = GPIO.PWM(18, frequency)
    pwm.start(50)
    time.sleep(duration)
    pwm.stop()

# シドララミ音階の再生
def play_close_encounters():
    melody = ['B', 'C', 'A', 'A2', 'E']
    durations = [0.5, 0.5, 0.5, 0.5, 1] # 秒数を変更
    
    for note, duration in zip(melody, durations):
        play_tone(notes[note], duration)
        time.sleep(0.1)  # ノート間の短い休止

try:
    play_close_encounters()
finally:
    GPIO.cleanup()

ではもう一度鳴らしてみましょう。今度は1オクターブ下の音が出たはずです。このように、それぞれの周波数を倍にすると上の音、半分にすると下の音が鳴ります。なお、音に関してはラの音を基準として調整していきます。クラシックのオーケストラが音を合わせるためにラの音を最初に流して調律していることに気が付けば分かります。なお、ラの音が440Hzなのは国際的に決められた周波数であるためです。ただし現在ではオーケストラの調律には442Hzのラの音が使われています。この周波数は時代によって変わります。

ところで、今回はRaspberry Pi 4とBullseeyeでプログラムを組みましたが、Raspberry Pi 5とBookwormで利用するには、gpiozeroを使うと実行できます。最終的にできたプログラムを、gpiozeroで使うようにChatGPTに聞いてみます。


問い
このプログラムをgpiozeroで使うように改変してください



これに対するChatGPTの返答は以下の通りでした。


`gpiozero`ライブラリを使用して、Raspberry Piと圧電ブザーで音階を鳴らすプログラムに改変します。以下は、`gpiozero`を使った新しいスクリプトです。

### 必要なもの:
- `gpiozero`ライブラリのインストール(まだインストールしていない場合)

  ```bash
  sudo apt-get install python3-gpiozero
  ```

### 修正後のPythonスクリプト:

```python
from gpiozero import PWMOutputDevice
from time import sleep

# GPIOの設定
buzzer = PWMOutputDevice(18)

# 音階の周波数
notes = {
    'B': 493,
    'C': 261,
    'A': 440,
    'A2': 220,  # 下のラの音
    'E': 329
}

# 音階の再生
def play_tone(frequency, duration):
    buzzer.frequency = frequency
    buzzer.value = 0.5  # デューティサイクルを50%に設定
    sleep(duration)
    buzzer.off()

# シドララミ音階の再生
def play_close_encounters():
    melody = ['B', 'C', 'A', 'A2', 'E']
    durations = [0.5, 0.5, 0.5, 0.5, 1]  # 秒数を変更
    
    for note, duration in zip(melody, durations):
        play_tone(notes[note], duration)
        sleep(0.1)  # ノート間の短い休止

try:
    play_close_encounters()
finally:
    buzzer.off()
```

### 実行方法:
1. 上記のスクリプトを`CloseEncounters_gpiozero.py`として保存します。
2. ターミナルを開き、スクリプトが保存されているディレクトリに移動します。
3. 以下のコマンドを実行します。

```bash
python3 CloseEncounters_gpiozero.py
```

これで、Raspberry Piに接続された圧電ブザーが`gpiozero`ライブラリを使用して「未知との遭遇」の音階を再生します。



これを実行してみると、Raspberry Pi 5でも圧電ブザーを鳴らすことができました。新しくgpiozeroを使うことで、GPIOの制御が可能となります。

いかがでしたでしょうか。ChatGPTも万能でないことが今回は分かりました。しかしプログラムの中身を追っていけば、どこを修正したらよいのか分かるはずです。ちなみに音階を変えるのは簡単でしたが、音を鳴らすためにはPWMという、パルス幅を変更する制御方法を使っています。このあたりを調べてみると、何をしているのかが分かるでしょう。

長きにわたって掲載してきたこの連載も、今回で最後になります。これまでお付き合いいただきありがとうございました。ラズパイに関しては、また新しい連載も始まる予定ですので、そちらも楽しみにしてください。

ニュース

編集部のおすすめ

連載・シリーズ

注目のキーワード

もっと見る