LoginSignup
0
1

概要

子ども向けのプログラミング教育の一環として、電子工作とプログラムでメロディーを鳴らすプロジェクト(メロディーメイカー)を作成しました。

ドラマ「いちばんすきな花」の主題歌である藤井風の花をコーディングしてみました。

ソースコード

main.py
from machine import Pin, PWM
from utime import sleep

################ 電子回路に応じてピン番号を変更する ################
# LED
led_pins = [0, 2, 3, 9, 10, 1, 11, 12]
leds = [Pin(pin, Pin.OUT, value=1) for pin in led_pins]

# NPNトランジスタのベース
buzzer = PWM(Pin(15))

# 再生ボタン
play_button = Pin(13, Pin.IN, Pin.PULL_DOWN)

# 停止ボタン
stop_button = Pin(14, Pin.IN, Pin.PULL_DOWN)

######################## グローバル変数 #########################
# 演奏中ならTrue, 演奏していない時はFalse
PLAYING = False
# メロディー
MELODY = []
# スケール(メロディーの中で使っている音階)
SCALE = []
# BPM(1分あたりの拍数)
BPM = 0

##################################################  音階周波数 ##################################################
REST=    0
C3, Db3, D3, Eb3, E3, F3, Gb3, G3, Ab3, A3, Bb3, B3 = 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247
C4, Db4, D4, Eb4, E4, F4, Gb4, G4, Ab4, A4, Bb4, B4 = 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494
C5, Db5, D5, Eb5, E5, F5, Gb5, G5, Ab5, A5, Bb5, B5 = 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988
C6, Db6, D6, Eb6, E6, F6, Gb6, G6, Ab6, A6, Bb6, B6 =1047,1109,1175,1245,1319,1397,1480,1568,1661,1760,1865,1976

####################### 共通メソッド #######################
def turn_on_led(index=None):
    """
    LEDを点灯する。
    """
    if index is None:
        for led in leds:
            led.value(0)
    else:
        leds[index].value(0)
        
def turn_off_led(index=None):
    """
    LEDを消灯する。
    """
    if index is None:
        for led in leds:
            led.value(1)
    else:
        leds[index].value(1)

def tone(frequency, duration):
    """
    音を鳴らす。

    Parameters:
        frequency(int): 周波数
        duration(int): 音符の音の長さ
            * 四分音符: 1/4
            * 八分音符: 1/8
            * 付点四分音符: 1.5/4
    """
    beat = 60 / BPM
    duration = beat * 4 * duration

    if frequency == REST:
        turn_on_led()
        sleep(duration)
        turn_off_led()
        return
    index = SCALE.index(frequency) % 8
    turn_on_led(index)
    buzzer.freq(frequency)
    buzzer.duty_u16(30000)
    sleep(duration)
    buzzer.duty_u16(0)
    sleep(0.002)
    turn_off_led(index)

def play():
    """
    演奏を開始する。
    """
    global PLAYING
    PLAYING = True
    turn_off_led()
    for m in MELODY:
        if PLAYING:
            tone(m[0], m[1])
        else:
            break

def stop(pin):
    """
    演奏を停止する。
    """
    global PLAYING
    PLAYING = False

# 停止ボタンが押されたら演奏を停止する
stop_button.irq(trigger=Pin.IRQ_RISING, handler=stop)


def melody():
    """
    Hana: Fujii Kaze
    """
    global BPM
    global MELODY
    global SCALE

    # BPMを定義する
    BPM = 123

    # メロディーを定義する
    MELODY = [
        (C5,1/8),(Bb4,1/8),(Ab4,1/8),(G4,1/8),
        (F4,1/4),(Eb5,1/8),(F3,1/8),(D5,1/8),(Eb5,1/8),(F4,1/8),(Eb5,1/8),
        (REST,1/8),(Bb3,1/8),(Eb5,1/8),(Bb3,1/8),(D5,1/8),(Eb5,1/8),(Bb4,1/8),(D5,1/8),
        (REST,1/8),(Eb3,1/8),(D5,1/8),(Eb3,1/8),(C5,1/8),(D5,1/8),(Eb4,1/8),(D5,1/8),
        (REST,1/8),(C3,1/8),(D5,1/8),(C3,1/8),(C5,1/8),(D5,1/8),(C4,1/8),(Eb5,1/8),
        (REST,1/8),(F3,1/8),(Eb5,1/8),(F3,1/8),(D5,1/8),(Eb5,1/8),(F4,1/8),(Eb5,1/8),
        (REST,1/8),(Bb3,1/8),(Eb5,1/8),(Bb3,1/8),(D5,1/8),(Eb5,1/8),(Bb4,1/8),(F5,1/8),
        (REST,1/8),(Eb3,1/8),(F5,1/8),(Eb3,1/8),(Eb5,1/8),(F5,1/8),(Eb4,1/8),(F5,1/8),
        (REST,1/8),(C3,1/8),(F5,1/8),(C3,1/8),(Eb5,1/8),(Eb5,1/8),(C4,1/8),(G5,1/8),
    ] 

    # スケールを更新する
    unique_elements = []
    for note in MELODY:
        if note[0] not in unique_elements and note[0] != REST:
            unique_elements.append(note[0])
    SCALE = sorted(unique_elements)

    # 演奏する
    play()

index = 0
while True:
    turn_on_led(index)
    if play_button.value() == 1:
        melody()
    sleep(0.1)
    turn_off_led(index)
    if index < 7:
        index += 1
    else:
        index = 0

メロディーメイカーの作り方

メロディーメイカーの作り方は以下の動画で解説しています。

0
1
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
1