0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ラズパイで圧電スピーカーをMIDIで奏でる(HardwarePWMを使う)

Last updated at Posted at 2025-03-31

内容

以前実装した方法ではソフトウェアPWMを使用しているため、雑音の入った音色が出力されます。調査したところ、ハードウェアPWMを使用することで改善できました。ラズパイの設定変更とライブラリのインストール、ソースコードの修正をします。

ハードウェアPWMを設定する手順

ラズパイの設定変更と再起動

ラズパイの設定ファイルを追記し再起動することで、ハードウェアPWMを有効にします。

sudo vim /boot/firmware/config.txt
/boot/firmware/config.txt
dtoverlay=pwm-2chan

この設定を追加することにより、GPIO18、19にそれぞれPWMのチャンネル0、1が割り当てられます。

  • PWM Channel0: GPIO18
  • PWM Channel1: GPIO19

※上記の代わりに以下の設定とすることで、ハードウェアPWMを使用するPINをGPIO12、13へ変更できます。

  • PWM Channel0: GPIO12
  • PWM Channel1: GPIO13
/boot/firmware/config.txt
dtoverlay=pwm-2chan,pin=12,func=4,pin2=13,func2=4

ラズパイを再起動することで、設定が有効になります。

sudo reboot

ライブラリのインストール

ハードウェアPWMをPythonから操作するライブラリを導入します。今回も--break-system-packagesとしてインストールしてしまいます。

pip install rpi-hardware-pwm --break-system-packages

ソースコードの修正

@@ -6 +6 @@
-import RPi.GPIO as GPIO
+from rpi_hardware_pwm import HardwarePWM
@@ -25,3 +24,0 @@
-# GPIO XX の XXの数値でPIN番号を指定する
-GPIO.setmode(GPIO.BCM)
-
@@ -29,2 +25,0 @@
-GPIO.setup(13, GPIO.OUT, initial=GPIO.LOW)
-p = GPIO.PWM(13, 1)
@@ -40 +34,0 @@
-        p.start(50)
@@ -42 +36,3 @@
-        p.ChangeFrequency(freq)
+        # Rpi 1,2,3,4 は chip=0, Rpi 5は chip=2
+        pwm = HardwarePWM(pwm_channel=1, hz=freq, chip=0)
+        pwm.start(50)
@@ -45 +41 @@
-        p.stop()
+        pwm.stop()

ソースコード全体は以下のようになります。

import math
import sys
import time

import mido
from rpi_hardware_pwm import HardwarePWM


def midi_number_to_note_number(midi_number: int):
    """MIDIのnote numberを鍵盤番号へ変換します"""
    # 鍵盤番号: 1:ラ0(A0) = MIDIのnote number: 21
    return midi_number - 20


def onkai(n):
    """鍵盤番号nに応じた周波数[Hz]を返します"""
    # 鍵盤番号は、ラ0(A0)を1とした連番
    # n=1(ラ0(A0))   -> 27.500Hz
    # n=2(ラ#0(A#0)) -> 29.135...Hz
    # n=3(シ0(B0))   -> 30.867...Hz
    # ...
    return 27.500 * math.pow(math.pow(2, 1 / 12), n)


# GPIO 13 = PWM 1 の33番PINに圧電スピーカーの+端子を接続する

# 圧電スピーカーの-端子はGroundならどこでもよい
# 今回は34番PINに接続する


for msg in mido.MidiFile(sys.argv[1]):
    time.sleep(msg.time)
    if msg.type == "note_on":
        # 圧電スピーカー
        freq = onkai(midi_number_to_note_number(msg.note))
        # Rpi 1,2,3,4 は chip=0, Rpi 5は chip=2
        pwm = HardwarePWM(pwm_channel=1, hz=freq, chip=0)
        pwm.start(50)
        print(f"note_on {freq} {msg}")
    if msg.type == "note_off":
        pwm.stop()
        print(f"note_off {msg}")

以下のコマンドで実行します。

python3 midi.py sample.mid

動作環境

  • Raspberry Pi 4 Model B Rev 1.5
  • Raspberry Pi OS Lite (64-bit)(Debian GNU/Linux 12.2.0 (bookworm))
  • Python 3.11.2
  • mido 1.3.3
  • rpi-hardware-pwm 0.2.2
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?