2025年8月12日火曜日

PWM でドレミと『かえるの歌』を鳴らす

 Raspberry Pi Pico Wは LED を光らせたりモーターを回したりと多芸なマイコンですが、「音」を出せるとなると一気にガジェット感が増しますよね。

今回は PWM(Pulse‑Width Modulation) を使って、ドレミ♪ とブザーでメロディを鳴らしてみましょう。

ハードもソフトもシンプルなので、ちょっとした電子工作にピッタリです。

回路


ソースコード

from machine import Pin, PWM
import time

# ── ハード設定 ──────────────────────────────────────────
BUZZER_PIN = 16        # 好きな GPIO に
VOLUME     = 32768     # 065535(≈50 %

# ── 音階(A4 = 440 Hz)─────────────────────────────────
FREQ = {
    "ド": 261, "ド#": 277, "レ♭": 277,
    "レ": 293, "レ#": 311, "ミ♭": 311,
    "ミ": 329,
    "ファ": 349, "ファ#": 370, "ソ♭": 370,
    "ソ": 392, "ソ#": 415, "ラ♭": 415,
    "ラ": 440, "ラ#": 466, "シ♭": 466,
    "シ": 493,
    "ド2": 523,
    "休": 0
}

# ── テンポ設定 ────────────────────────────────────────
BEAT_MS = 400           # ♪ = 400 ms  → 150 BPM
LONG_MS = BEAT_MS * 2   # 伸ばす音(2= 800 ms)
HALF_MS = BEAT_MS // 2  # 休符の 0.5 拍 = 200 ms
# 3/2= 1.5= 600 ms(整数で用意しておく)
TRIPLET_MS = BEAT_MS * 3 // 2

# ── 1. 上昇スケール ───────────────────────────────────
scale_up = [
    ("ド", BEAT_MS), ("レ", BEAT_MS), ("ミ", BEAT_MS), ("ファ", BEAT_MS),
    ("ソ", BEAT_MS), ("ラ", BEAT_MS), ("シ", BEAT_MS), ("ド2", TRIPLET_MS)
]

# ── 2. かえるの歌 ───────────────────────────────────
frog_song = [
    # ドーレーミーファーミーレードー.
    ("ド", LONG_MS), ("レ", LONG_MS), ("ミ", LONG_MS), ("ファ", LONG_MS),
    ("ミ", LONG_MS), ("レ", LONG_MS), ("ド", BEAT_MS), ("休", HALF_MS),

    # ミーファーソーラーソーファーミー.
    ("ミ", LONG_MS), ("ファ", LONG_MS), ("ソ", LONG_MS), ("ラ", LONG_MS),
    ("ソ", LONG_MS), ("ファ", LONG_MS), ("ミ", BEAT_MS), ("休", HALF_MS),

    # ドー ドー ドー ドー.
    ("ド", BEAT_MS), ("休", HALF_MS),
    ("ド", BEAT_MS), ("休", HALF_MS),
    ("ド", BEAT_MS), ("休", HALF_MS),
    ("ド", BEAT_MS), ("休", HALF_MS),

    # ドドレレミミファファミーレードー.
    ("ド", BEAT_MS), ("ド", BEAT_MS),
    ("レ", BEAT_MS), ("レ", BEAT_MS),
    ("ミ", BEAT_MS), ("ミ", BEAT_MS),
    ("ファ", BEAT_MS), ("ファ", BEAT_MS),
    ("ミ", LONG_MS), ("レ", LONG_MS), ("ド", TRIPLET_MS)
]

# ── 再生関数 ─────────────────────────────────────────
def play(pwm: PWM, score):
    """score = [(note, duration_ms), ...]"""
    for note, dur in score:
        freq = FREQ.get(note, 0)
        if freq:
            pwm.freq(freq)
            pwm.duty_u16(VOLUME)
        else:                    # 休符
            pwm.duty_u16(0)
        time.sleep_ms(int(dur))  # ← 必ず整数で渡す
        pwm.duty_u16(0)          # 余韻カット
        time.sleep_ms(20)        # 最小インターバル

# ── メイン ──────────────────────────────────────────
pwm = PWM(Pin(BUZZER_PIN))
try:
    play(pwm, scale_up)   # 1. ドレミファソラシド
    time.sleep_ms(300)    # 小休止
    play(pwm, frog_song)  # 2. かえるの歌
finally:
    pwm.deinit()


プログラムの流れ

  • 🛠️ ハードと定数を設定

    • BUZZER_PIN を PWM 出力に、VOLUME を 50 % に決定。

  • 🎹 音階テーブルを用意

    • FREQ 辞書に「ド〜シ」「休符」の周波数(Hz)を登録。

  • ⏱️ テンポを決める

    • 1 拍 (= ♪) を BEAT_MS (= 400 ms) とし、2 拍や 0.5 拍なども計算。

  • 🎼 楽譜データを作る

    • scale_up:ドレミファソラシドの上昇スケール。

    • frog_song:「かえるの歌」を拍ごとに (音名, 長さ) で列挙。

  • ▶️ play() 関数で再生処理

    1. 楽譜を 1 行ずつ読み取る。

    2. 休符なら出力を 0、音符なら pwm.freq() と duty_u16() で発音。

    3. 指定時間 sleep_ms() し、余韻を消して 20 ms インターバル。

  • 🚀 メイン処理

    1. PWM(Pin(BUZZER_PIN)) で PWM を開始。

    2. play(scale_up) → 300 ms 休止 → play(frog_song) の順に鳴らす。

    3. すべて終わったら pwm.deinit() で PWM を解放。

これで 昇順スケール → 小休止 → かえるの歌 がブザーから流れます。




0 件のコメント:

コメントを投稿

Google Spread Sheetの利用

  以前に ESP32 で作っていたものを、Raspberry Pi Pico W + MicroPythonで再現してみました。 1.Googleスプレッドシートの設定 1.Google Drive → 右クリック → Google スプレッドシート 2.作成して共有をクリック