それでは、Arduinoの統合開発環境「Arduino IDE」で、スケッチ(プログラム)を作成していきましょう(スケッチ1)。
#include "pitches.h"
//-----------------------
// 定数の定義
//-----------------------
const int BZ = 2; //ブザー(TMP36)の出力ピン
const int nos = 5; //スイッチの数
const int SW[nos] = {3,4,5,6,7}; //各スイッチの入力ピン番号
//const int BOM = 10; //電磁石ピンの出力ピン(オプション)
//スイッチの回路は負論理なので、ONがLOWになる
const int SW_ON = LOW;
const int SW_OFF = HIGH;
//-----------------------
// グローバル変数の定義
//-----------------------
int G_old_val[nos] = {SW_OFF, SW_OFF, SW_OFF, SW_OFF, SW_OFF}; //前回のスイッチの値
int G_sw_val;
void setup() {
pinMode(BZ, OUTPUT); //ブザーを出力モードに設定
//スイッチを全て入力モードに設定
for(int i = 0; i < nos; i++){
pinMode(SW[i], INPUT);
}
// pinMode(BOM, OUTPUT); //電磁石ピンを出力モードに設定(オプション)
randomSeed(analogRead(A0)); //乱数の初期設定に未接続ピンのノイズを利用
// digitalWrite(BOM, HIGH); //電磁石の電流を流す(オプション)
bz_start(); //ゲームスタート音楽
}
void loop() {
int int_swNumber = -1; //何も押してないときの番号を設定
int int_rand = random(nos); //ランダムでハズレスイッチ番号を決定する
//スイッチ1〜5の状態を取得
for(int i = 0; i < nos; i++){
G_sw_val = digitalRead(SW[i]); //スイッチの状態を読み取る
if(G_sw_val == SW_ON && G_old_val[i] == SW_OFF){
int_swNumber = i; //スイッチの番号を取得
}
G_old_val[i] = G_sw_val; //スイッチの値を保存
}
//スイッチの入力があったとき
if(int_swNumber != -1){
//ハズレスイッチ番号が押されたら、ゲーム終了
if(int_rand == int_swNumber){
bz_ending(); //エンディング音楽
// digitalWrite(BOM, LOW); //電磁石の電流をカット
} //クリア音を流す
else{
bz_levelup();
}
}
}
1行目の#includeで、「pitches.h」を読み込んでいます。これは、音階を宣言したファイルで、Arduinoのサンプルスケッチ「toneMelody」に入っています。この音階を使用して、ゲーム用のメロディーを作りました。
31行目のrandomSeed()は、乱数を発生するための初期処理です。使用していないアナログ入力ピン(A0)のノイズを引数にすることで、random()使用時に毎回違う値を取得できるようになります。
36行目から始まるloop()の中で、ゲームの判定を行います。int_swNumber変数にスイッチが押されていないときの番号「−1」をセットした後(37行目)、ランダム関数でハズレスイッチ番号を選んでいます(38行目)。
41〜47行目は、スイッチ1〜5までの入力値を見て、スイッチの状態をチェックしています。スイッチが押されていた場合は、int_swNumberにスイッチ番号を取得します(44行目)。
スイッチが押されていたときは、50〜59行目が実行され、アタリ/ハズレの判定を行い、それぞれに該当するメロディーを呼び出します。
今回、toneMelody()とゲームスタートを含む3曲分の楽譜を、ユーザー関数として作成しました。Arudino IDEには、音を鳴らすためのtone()が用意されています。tone()は引数に、出力するピン番号、周波数を指定して、メロディーを奏でることができます。
toneMelody()と、ゲームスタートのbz_start()でメロディーの作り方を見てみましょう(スケッチ2)。
//-----------------------------------
// 指定した音階と長さでブザーを鳴らす
// note:音階 duration:長さ
//-----------------------------------
void toneMelody(int note, int duration){
int noteDuration = 1000 / duration; //音の長さを決める
tone(BZ, note); //ブザーを指定周波数
delay(noteDuration); //指定時間 鳴らす
//音の切れ目を作る
noteDuration = noteDuration * 0.1; //長さを決めている
noTone(BZ); //ブザーへの出力を止める
delay(noteDuration); //指定時間保つ
}
//-----------------------
// スタート
//-----------------------
void bz_start(){
int melody[] = {NOTE_G5, NOTE_G5, 0, NOTE_G5, NOTE_F5, NOTE_G5, NOTE_AS5};
int noteDurations[] = {8,8,8,4,8,4,4};
for (int i = 0; i < 7; i++) {
toneMelody(melody[i], noteDurations[i]);
}
toneMelody()は、引数に音階と音の長さを指定して呼び出します。実際に鳴らす音の長さは計算で求めます。durationが「8」の場合は、1000÷8=125、つまり125ミリ秒間だけ音が鳴ります(5行目)。
tone()の引数に、出力するピン、周波数を指定し、delay()で出力する時間を指定しています(7〜8行目)。音と音が連続すると曲が歯切れよく聞こえないので、noTone()で音を止めます(12〜13行目)。
bz_start()には、音階と長さを記録してあります。要するに、これが楽譜です。20行目のmelody配列の要素は、「pitches.h」に宣言されている音階です。「pitches.h」には、B0〜DS8まで8オクターブの音(周波数)が定義されています。noteDurations配列には、melodyに入れた音の長さを要素として宣言します。
for文で配列の要素をループして、toneMelody()を呼び出せばブザーが鳴ります。
レベルアップとエンディングの音階は、ファイルに入っているのでダウンロードして確認してください。
Copyright © ITmedia, Inc. All Rights Reserved.
組み込み開発の記事ランキング
コーナーリンク