スピーカーを接続してメロディーを鳴らす2 繰り返し演奏させます。

スピーカーを接続してメロディーを鳴らす

スピーカーを接続してPWM信号を送ってメロディーを鳴らしてみました。

スピーカー

マイクロスピーカー
ノートパソコンやポータブル機器等に使われる超小型のダイナミックスピーカーです。
■主な仕様
・インピーダンス:8Ω@1kHz
・サイズ:23×16(長楕円)×4.6(最大厚)mm
・質量:3g
・リード:青32mm、白34mm、各先端ともはんだ仕上げ2mm

配線図

配線に極性はありません。どちらの線をさしても大丈夫です。

実際の配線

MicroPythonプログラム

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from machine import Pin, PWM, Timer
speaker = PWM(Pin(17, Pin.OUT)) # スピーカーを接続しているGPIO(この例では17番)を作成し、それをPWM()へ渡す
led_onboard = machine.Pin('LED', machine.Pin.OUT) # PICO Wの基板上のLEDを光らせたいのでmachine作成
# 使用する音の周波数を宣言しておく。ピタゴラスイッチは低いラ~高いドまでの音を使う
A4 = 440
B4 = 493.883
C5 = 523.251
C5s= 554.365
D5 = 587.330
E5 = 659.255
F5 = 698.456
F5s= 739.989
G5 = 783.991
A5 = 880
B5 = 987.767
C6 = 1046.502
# bps = 6.4 # 原曲128bpm / 60秒 = 2.1333...bps * 3連符 = 6.4bps
mspb = 156 # 6.4bpsの逆数 = 0.156ms これが8分3連符ひとつ分の音の長さ、音の間隔となる
# ピタゴラスイッチのメロディーを配列で作成。1要素が8分3連符ひとつ分の音の長さになる。0は無音(休符)
melody = [D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,G5,A5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,B4,A4,0,B4,C5,0,C5s,D5,0,0,D5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,G5,A5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,B4,A4,A4,A4,A4,A4,A4,A4,A4,A4,0,0,F5,E5,0,E5,F5s,E5,F5s,G5,G5,G5,D5,0,B4,C5,0,C5,D5,C5s,D5,B4,B4,B4,0,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,0,G5,0,0,0,0,0,0,0,0,0,0,0,0,0,D5,E5,0,D5,E5,0,C6,B5,0,0,G5]
i = 0
# 音を鳴らすためのコールバック関数
def beat(timer):
global melody
global led_onboard
global i
global speaker
if i >= len(melody): # メロディーを最後まで演奏し終えたら
speaker.deinit() # スピーカーのPWMを破棄して
led_onboard.value(0) # LEDを消して
timer.deinit() # タイマーを破棄して終了
elif int(melody[i]) == 0: # メロディー音が0、つまり無音(休符)の場合
speaker.duty_u16(0) # PWMのDutyを0とすることで波形は出力されずLOWとなり、音は出ない
led_onboard.value(0) # LEDを消す
else:
speaker.freq(int(melody[i] + 0.5)) # PWMの周波数を次のメロディー音の周波数に変更する。整数で渡す必要があるので、+0.5してから小数点以下切り捨て(thanks @naohiro2g)
speaker.duty_u16(0x8000) # PWMのDutyを50%に戻し、音を出す。Dutyは0~0xFFFFつまり65535までの間の値で設定
led_onboard.value(1) # LEDを光らせる
i += 1 # メロディーを次に進めて終わり
# 8分3連符の間隔でコールバックを呼ぶタイマーを作成し、メロディースタート
tim = Timer()
tim.init(period=mspb, mode=Timer.PERIODIC, callback=beat)
from machine import Pin, PWM, Timer speaker = PWM(Pin(17, Pin.OUT)) # スピーカーを接続しているGPIO(この例では17番)を作成し、それをPWM()へ渡す led_onboard = machine.Pin('LED', machine.Pin.OUT) # PICO Wの基板上のLEDを光らせたいのでmachine作成 # 使用する音の周波数を宣言しておく。ピタゴラスイッチは低いラ~高いドまでの音を使う A4 = 440 B4 = 493.883 C5 = 523.251 C5s= 554.365 D5 = 587.330 E5 = 659.255 F5 = 698.456 F5s= 739.989 G5 = 783.991 A5 = 880 B5 = 987.767 C6 = 1046.502 # bps = 6.4 # 原曲128bpm / 60秒 = 2.1333...bps * 3連符 = 6.4bps mspb = 156 # 6.4bpsの逆数 = 0.156ms これが8分3連符ひとつ分の音の長さ、音の間隔となる # ピタゴラスイッチのメロディーを配列で作成。1要素が8分3連符ひとつ分の音の長さになる。0は無音(休符) melody = [D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,G5,A5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,B4,A4,0,B4,C5,0,C5s,D5,0,0,D5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,G5,A5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,B4,A4,A4,A4,A4,A4,A4,A4,A4,A4,0,0,F5,E5,0,E5,F5s,E5,F5s,G5,G5,G5,D5,0,B4,C5,0,C5,D5,C5s,D5,B4,B4,B4,0,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,0,G5,0,0,0,0,0,0,0,0,0,0,0,0,0,D5,E5,0,D5,E5,0,C6,B5,0,0,G5] i = 0 # 音を鳴らすためのコールバック関数 def beat(timer): global melody global led_onboard global i global speaker if i >= len(melody): # メロディーを最後まで演奏し終えたら speaker.deinit() # スピーカーのPWMを破棄して led_onboard.value(0) # LEDを消して timer.deinit() # タイマーを破棄して終了 elif int(melody[i]) == 0: # メロディー音が0、つまり無音(休符)の場合 speaker.duty_u16(0) # PWMのDutyを0とすることで波形は出力されずLOWとなり、音は出ない led_onboard.value(0) # LEDを消す else: speaker.freq(int(melody[i] + 0.5)) # PWMの周波数を次のメロディー音の周波数に変更する。整数で渡す必要があるので、+0.5してから小数点以下切り捨て(thanks @naohiro2g) speaker.duty_u16(0x8000) # PWMのDutyを50%に戻し、音を出す。Dutyは0~0xFFFFつまり65535までの間の値で設定 led_onboard.value(1) # LEDを光らせる i += 1 # メロディーを次に進めて終わり # 8分3連符の間隔でコールバックを呼ぶタイマーを作成し、メロディースタート tim = Timer() tim.init(period=mspb, mode=Timer.PERIODIC, callback=beat)
from machine import Pin, PWM, Timer

speaker = PWM(Pin(17, Pin.OUT)) # スピーカーを接続しているGPIO(この例では17番)を作成し、それをPWM()へ渡す
led_onboard = machine.Pin('LED', machine.Pin.OUT) # PICO Wの基板上のLEDを光らせたいのでmachine作成

# 使用する音の周波数を宣言しておく。ピタゴラスイッチは低いラ~高いドまでの音を使う
A4 = 440
B4 = 493.883
C5 = 523.251
C5s= 554.365
D5 = 587.330
E5 = 659.255
F5 = 698.456
F5s= 739.989
G5 = 783.991
A5 = 880
B5 = 987.767
C6 = 1046.502

# bps = 6.4 # 原曲128bpm / 60秒 = 2.1333...bps * 3連符 = 6.4bps
mspb = 156 # 6.4bpsの逆数 = 0.156ms これが8分3連符ひとつ分の音の長さ、音の間隔となる

# ピタゴラスイッチのメロディーを配列で作成。1要素が8分3連符ひとつ分の音の長さになる。0は無音(休符)
melody = [D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,G5,A5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,B4,A4,0,B4,C5,0,C5s,D5,0,0,D5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,G5,A5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,B4,A4,A4,A4,A4,A4,A4,A4,A4,A4,0,0,F5,E5,0,E5,F5s,E5,F5s,G5,G5,G5,D5,0,B4,C5,0,C5,D5,C5s,D5,B4,B4,B4,0,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,G5,F5s,0,D5,E5,0,D5,E5,0,D5,E5,0,C6,B5,0,0,G5,0,0,0,0,0,0,0,0,0,0,0,0,0,D5,E5,0,D5,E5,0,C6,B5,0,0,G5]
i = 0

# 音を鳴らすためのコールバック関数
def beat(timer):
    global melody
    global led_onboard
    global i
    global speaker

    if i >= len(melody): # メロディーを最後まで演奏し終えたら
        speaker.deinit() # スピーカーのPWMを破棄して
        led_onboard.value(0) # LEDを消して
        timer.deinit() # タイマーを破棄して終了

    elif int(melody[i]) == 0: # メロディー音が0、つまり無音(休符)の場合
        speaker.duty_u16(0) # PWMのDutyを0とすることで波形は出力されずLOWとなり、音は出ない
        led_onboard.value(0) # LEDを消す

    else:
        speaker.freq(int(melody[i] + 0.5)) # PWMの周波数を次のメロディー音の周波数に変更する。整数で渡す必要があるので、+0.5してから小数点以下切り捨て(thanks @naohiro2g)
        speaker.duty_u16(0x8000) # PWMのDutyを50%に戻し、音を出す。Dutyは0~0xFFFFつまり65535までの間の値で設定
        led_onboard.value(1) # LEDを光らせる

    i += 1 # メロディーを次に進めて終わり

# 8分3連符の間隔でコールバックを呼ぶタイマーを作成し、メロディースタート
tim = Timer()
tim.init(period=mspb, mode=Timer.PERIODIC, callback=beat)

実行

ピタゴラスイッチのメロディーが流れてLEDが点滅します。
お気に入りの曲を入力してみましょう。

お気に入りの曲を入力してみましょう。
入力できたらプログラムで繰り返し演奏させてみましょう。

入力したメロディーを繰り返して演奏させるプログラム

テンテン
テンテン

パイソンで繰り返し処理をします。

range() 関数 × for 文の基本構文

for 変数名 in range(繰り返し回数):
繰り返したい処理①
繰り返したい処理②
処理のプログラムは一段下げます。
例 range() 関数を使い3 回 A B を出力
for i in range(3):
  print(‘A’)
print(‘B’)

timer()はコールバック関数で使い終わったらプログラムを終了してしまうようです。
そのため、for文で繰り返すのはmelodyという配列に入れた音符を増やすことで対応してみました。

for x in range(1):
melody = melody + melody
このブロックを入れて演奏する音符を回数分増やします。
プログラムのどこに入れるか考えて入れてみてください。