【arduino】ボタンを押すとメロディが流れるおもちゃを作ってみた。(プログラム編)

こんにちは、kazuです。
本日は久しぶりにarduinoを使って
電子工作をしましたので、そのプログラムを紹介していきます。

どのようなものを作ったか

まずはどのようなものを作ったかといいますと。
ボタンを押すとメロディが流れるというものです。
ボタンを3つ設置して、各ボタンごとに流れるメロディが違います。
1つ目のボタンのメロディがきらきら星
2つ目のボタンのメロディがHappy birthday to you
3つ目のボタンが帝国の曲(スターウォーズ)
のプログラムの紹介です。

関連記事

こんにちは、kazuです。 本日は前回のプログラム編の引き続き 回路編をまとめていきます。 はじめに まずいきなりパーツとか説明しても読んでいるあなた「ん?」となると思いますので 簡単にどのようなおもちゃを作ったかといいますと […]

実際にプログラムを見てみよう

/**
緑LED
緑ボタン
赤LED
赤ボタン
黄色LED
黄色ボタン
*/
#include "pitches.h"

// LEDとボタンのピン番号
const int GREEN_LED = 12;
const int GREEN_BUTTON = 10;
const int RED_LED = 8;
const int RED_BUTTON = 6; 
const int YELLOW_LED = 4;
const int YELLOW_BUTTON = 2;
// ボタンフラグ
int greenVal = 0;
int redVal = 0;
int yellowVal = 0;
// LEDフラグ
int greenLedFlag = 0;
int redLedFlag = 0;
int yellowLedFlag = 0;
int buttonFlag = 0;
// スピーカ
int duration = 200 ; // 音の長さを指定
int spekerpin = 13; 
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  // LED アウトプット
  pinMode(YELLOW_LED,OUTPUT);
  pinMode(RED_LED,OUTPUT);
  pinMode(GREEN_LED,OUTPUT);
  // ボタン インプット
  pinMode(YELLOW_BUTTON,INPUT);
  pinMode(RED_BUTTON,INPUT);
  pinMode(GREEN_BUTTON,INPUT);

}

// スピーカー
// happyBirthDayの極
int happyBirthDay[] = {
   NOTE_G3,0 ,NOTE_G3,0 ,NOTE_A3,0 ,NOTE_G3,0 ,NOTE_C4,0 ,
   NOTE_B3,0 ,0 ,0 ,NOTE_G3,0 ,NOTE_G3,0 ,NOTE_A3,0 ,
   NOTE_G3,0 ,NOTE_D4,0 ,NOTE_C4,0 ,0 ,0 ,NOTE_G3,0 ,
   NOTE_G3,0 ,NOTE_G4,0 ,NOTE_E4,0 ,NOTE_C4,0 ,NOTE_B3,0 ,
   NOTE_A3,0 ,0 ,0 ,NOTE_F4,0 ,NOTE_F4,0 ,NOTE_E4,0 ,
   NOTE_C4,0 ,NOTE_D4,0 ,NOTE_C4, 0, 0, 0
};

// きらきら星
int twinkleTwinkleLittleStar[] = {
  NOTE_C4,0 ,NOTE_C4,0 ,NOTE_G4,0 ,NOTE_G4,0 ,NOTE_A4,0 ,
  NOTE_A4,0 ,NOTE_G4,0 ,0 ,0 ,NOTE_F4,0 ,NOTE_F4,0 ,NOTE_E4,0 ,
  NOTE_E4,0 ,NOTE_D4,0 ,NOTE_D4,0 ,NOTE_C4,0 ,0 ,0 ,NOTE_G4,0 ,
  NOTE_G4,0 ,NOTE_F4,0 ,NOTE_F4,0 ,NOTE_E4,0 ,NOTE_E4,0 ,
  NOTE_D4,0 ,0 ,0 ,NOTE_G4,0 ,NOTE_G4,0 ,NOTE_F4,0 ,NOTE_F4,0 ,
  NOTE_E4,0 ,NOTE_E4,0 ,NOTE_D4,0 ,0 ,0 ,NOTE_C4,0 ,NOTE_C4,0 ,
  NOTE_G4,0 ,NOTE_G4,0 ,NOTE_A4,0 ,NOTE_A4,0 ,NOTE_G4,0 ,0 ,
  NOTE_F4,0 ,NOTE_F4,0 ,NOTE_E4,0 ,NOTE_E4,0 ,NOTE_D4,0 ,
  NOTE_D4,0 ,NOTE_C4,0 ,0
};

// 帝国の曲
int empireMelody[] = {
  NOTE_G3,0 , NOTE_G3,0 , NOTE_G3,0 , NOTE_DS3,0 , NOTE_AS3,0 , NOTE_G3,0 , NOTE_DS3,0 , NOTE_AS3,0 , NOTE_G3,0 ,0 ,
  NOTE_D4,0 , NOTE_D4,0 , NOTE_D4,0 , NOTE_DS4,0 , NOTE_AS3,0 , NOTE_FS3,0 , NOTE_DS3,0 , NOTE_AS3,0 , NOTE_G3,0 ,0 ,
};

void loop() {
  // put your main code here, to run repeatedly:
  greenVal = digitalRead(GREEN_BUTTON);
  redVal = digitalRead(RED_BUTTON);
  yellowVal = digitalRead(YELLOW_BUTTON);
  if(greenVal == HIGH) {
    //緑ボタンが押されたときの処理
    buttonFlag = 1;
    changeButton(buttonFlag);
    playMelody(buttonFlag);
  } else if(redVal == HIGH) {
    // 赤ボタンが押されたとき
    buttonFlag = 2;
    changeButton(buttonFlag);
    playMelody(buttonFlag);
  } else if(yellowVal == HIGH){
    // 黄色ボタンが押されたとき
    buttonFlag = 3;
    changeButton(buttonFlag);
    playMelody(buttonFlag);
  } else if(greenLedFlag==0 && redLedFlag==0 && yellowLedFlag==0) {
    // 全LEDを消したいときの処理
    buttonFlag = 0;
    changeButton(buttonFlag);
  }
}

/**
* changeButton ボタンを押した時どのLEDを光らせるメソッド
* @param Flag ボタンを押した時変数に入った数値
*/
void changeButton(int Flag) {
  switch(Flag) {
    case 1:
        // 緑のボタンを押して緑のLED点灯する
        // LEDの点灯を消すときのフラグを立てる
        if(greenLedFlag == 1){
          greenLedFlag = 0; 
          return;
        }
        digitalWrite(GREEN_LED,HIGH);
        digitalWrite(RED_LED,LOW);
        digitalWrite(YELLOW_LED,LOW);
        greenLedFlag = 1;
        redLedFlag = 0;
        yellowLedFlag = 0;
        break;
    case 2:
        // 赤のボタンを押して赤のLED点灯する
        // LEDの点灯を消すときのフラグを立てる
        if(redLedFlag == 1){
          redLedFlag = 0; 
          return;
        }
        digitalWrite(RED_LED,HIGH);
        digitalWrite(GREEN_LED,LOW);
        digitalWrite(YELLOW_LED,LOW);
        greenLedFlag = 0;
        redLedFlag = 1;
        yellowLedFlag = 0;
        break;
    case 3:
        // 黄色のボタンを押して黄色のLED点灯する
        // LEDの点灯を消すときのフラグを立てる
        if(yellowLedFlag == 1){
          yellowLedFlag = 0; 
          return;
        }
        digitalWrite(YELLOW_LED,HIGH);
        digitalWrite(GREEN_LED,LOW);
        digitalWrite(RED_LED,LOW);
        greenLedFlag = 0;
        redLedFlag = 0;
        yellowLedFlag = 1;
        break;
    default:
        // 全てのLEDの点灯を消す
        // 全てのフラグを0にする
        digitalWrite(YELLOW_LED,LOW);
        digitalWrite(GREEN_LED,LOW);
        digitalWrite(RED_LED,LOW);
        greenLedFlag = 0;
        redLedFlag = 0;
        yellowLedFlag = 0;
        break;
  }
}

/**
* playMelody 曲を流すメソッド
* @param Flag ボタンを押した時変数に入った数値
*/
void playMelody(int Flag){
  switch(Flag) {
    case 1:
      //happybirthdayの曲
      //0~58まで繰り返す。58になったらfor文を抜ける
      for (int i = 0; i < 58; i++) {     
        //配列melodyの周波数で、0.2秒  
        tone( spekerpin, happyBirthDay[i], duration );  
        //音がなっている間待つ
        delay(duration);                   
      }
      break;
    case 2:
      // きらきら星の曲
      //0~94まで繰り返す。94になったらfor文を抜ける
      for (int i = 0; i < 94; i++) { 
        //配列melodyの周波数で、0.2秒        
        tone( spekerpin, twinkleTwinkleLittleStar[i], duration );  
        //音がなっている間待つ
        delay(duration);                   
      }
      break;
    case 3:
      // 帝国の曲(スターウォーズ)
      //0~38まで繰り返す。38になったらfor文を抜ける
      for (int i = 0; i < 38; i++) { 
        //配列melodyの周波数で、0.2秒      
        tone( spekerpin, empireMelody[i], duration );  
        //音がなっている間待つ
        delay(duration);                   
      }
      break;
    default:
        break;
  } 
}

最後に

いかがでしたでしょうか?
特に動作に問題はないのですが、
もっと良い書き方があるのでは?と考えます。
でも動いたので今回はこれで良しとしましょう!
ぜひ電子工作を作ってみてください!
最後までご覧いただきありがとうございました!