/********************************************/
// tone関数で音を鳴らすプログラムその1
/********************************************/
#define Start_Sw 4 //Switci 入力
#define school_Sw 5 //予備入力
#define Down_Sw 6 //1オクターブダウン
#define Up_Sw 7 //1オクターブアップ
#define BAUDRATE 9600
int melo_300 = 300 ; // 音の長さを指定
int melo_500 = 500 ;
int melo_150 = 150 ;
int pin = 3 ; // ブザーを接続したピン番号
const int KeyNum = 8 ; // キーの数
// ド レ ミ ファ ソ ラ シ ド
const int threshold[KeyNum] = { 128, 281, 376, 522, 684, 820, 909, 1011 } ; // AD変換値の閾値
const int frequency[KeyNum] = { 524, 588, 660, 698, 784, 880, 988, 1046 } ; // 各キーの周波数
// ド レ ミ ファ ソ ラ シ ド
int sounds[ ] = { 262, 294, 330, 349, 392, 440, 494, 523 } ;
int kirakira[ ] = { 262, 262, 392, 392, 440, 440, 392, 0,
349, 349, 330, 330, 294, 294, 262, 0,
392, 392, 349, 349, 330, 330, 294, 0 } ;
int School_A[ ] = { 698, 880, 784, 523, 0, 698, 784, 880, 698, 0,
880, 698, 784, 523, 0, 523, 784, 880, 698, 0 } ;
int Jr1[ ] = { 784, 660, 588, 524, 588,660 } ;// 4回リピート
int Jr2[ ] = { 880, 660, 588, 524, 588,660 } ;// 4回リピート
int Jr3[ ] = { 784, 660, 524, 988, 524, 660, 660, 784, 1046, 784, 1046, 1764, 1980,
660, 524, 988, 784, 988, 524, 524, 660, 784, 660, 784, 988, 1046 } ;
// 遠き山に日は落ちて
int School_B[ ] = { 330, 0, 392, 392, 0, 330, 0, 294, 262, 0, 294, 0, 330, 392, 0, 330, 294, 0, 0, 0,/*0~19*/
330, 0, 392, 392, 0, 330, 0, 294, 262, 0, 294, 330, 294, 0, 262, 262, 0, 0, 0,/*20~38*/
440, 0, 523, 523, 0, 494, 392, 440, 0, 440, 523, 494, 392, 440, 0, 0, 0,/*39~55*/
440, 0, 523, 523, 0, 494, 392, 440, 0, 440, 523, 494, 392, 440, 0, 0, 0,/*56~72*/
330, 0, 392, 392, 0, 330, 0, 294, 262, 0, 294, 0, 330, 392, 0, 330, 294, 0, 0, 0,/*73~92*/
330, 0, 392, 392, 0, 523, 0, 588, 660, 0, 588, 0, 523, 588, 440, 523, 0,/*93~109*/
588, 0, 523, 588, 440, 523, 0 } ; /*110~116*/
void setup( ){
pinMode( Start_Sw, INPUT_PULLUP ) ; // ピンモード設定
pinMode( school_Sw, INPUT_PULLUP ) ; // ピンモード設定
pinMode( Down_Sw, INPUT_PULLUP ) ; // ピンモード設定
pinMode( Up_Sw, INPUT_PULLUP ) ; // ピンモード設定
Serial.begin( BAUDRATE ) ;
Serial.println( "\nIr Recive - Read" ) ;
delay( 1000 ) ;
}
void loop( ){
char i ;
char j ;
char k ;
int LastResult = -2 ; // 前回のキーデコード結果
int result ; // 今回のキーデコード結果
int cnt = 0 ; // デコード結果が一致した回数/
static int LastDisplayed = -2 ; // 前回loop関数が呼ばれたと時に表示したキー
// 複数回のloop関数の呼び出しにわたって値を保持するために、static変数にしている
if( digitalRead( Start_Sw ) != 1 ){
// ドレミファソラシド
for( i = 0; i <= 7; ++i ){
tone( pin, sounds[ i ], melo_300 ) ;
delay( melo_300 ) ;
}
delay( 1000 ) ;
for( i = 0; i <= 7; ++i ){
tone( pin, ( sounds[ i ] * 2 ), melo_300 ) ;
delay( melo_300 ) ;
}
delay( 1000 ) ;
// キラキラ星
for( i = 0; i <= 23; ++i ){
tone( pin, kirakira[ i ], melo_300 ) ;
delay( melo_500 ) ;
}
for( i = 16; i <= 23; ++i ){
tone( pin, kirakira[ i ], melo_300 ) ;
delay( melo_500 ) ;
}
for( i = 0; i <= 15; ++i ){
tone( pin, kirakira[ i ], melo_300 ) ;
delay( melo_500 ) ;
}
delay( 1000 ) ;
// 学校のチャイム
for( i = 0; i <= 19; ++i ){
tone( pin, School_A[ i ], melo_300 ) ;
delay( melo_500 ) ;
}
// JR
for( k = 0; k <= 1; ++k ){
for( j = 0; j <= 3; ++j ){
for( i = 0; i <= 5; ++i ){
tone( pin, Jr1[ i ], melo_150 ) ;//ソミレドレミ4回
delay( melo_150 ) ;
}
}
for( j = 0; j <= 3; ++j ){
for( i = 0; i <= 5; ++i ){
tone( pin, Jr2[ i ], melo_150 ) ;//ラミレドレミ4回
delay( melo_150 ) ;
}
}
}
for( i = 0; i <= 25; ++i ){ // ソミドシドミ
tone( pin, Jr3[ i ], melo_150 ) ;// ミソドソドレミ
delay( melo_150 ) ; // ミドシソシド
} // ドミソミソシド
}
// 遠き山に日は落ちて
if( digitalRead( school_Sw ) != 1 ){
for( i = 0; i <= 116; ++i ){
tone( pin, School_B[ i ], melo_300 ) ;
delay( melo_300 ) ;
}
}
// キーを読み取る
// チャタリングの除去などのため、A/D変換の値が落ち着くまで待つ
// 1ms間隔でキーを読み取り、10回連続で同じキーが押されていたら、落ち着いたと判断する
do{
result = KeyDecode( analogRead( A0 ) ) ;
if( result == LastResult ){
cnt++ ;
}
else{
LastResult = result ;
cnt = 0 ;
}
delay( 1 ) ;
}
while( cnt<10 ) ;
// 音を出す/止める
if( result != LastDisplayed ){
if( result < 0 ){ // 音を止める
noTone( pin ) ;
}
else{ // 音を出す
if( digitalRead( Down_Sw ) != 1 ){
tone( pin, ( frequency[ result ] / 2 )) ;
}
else if( digitalRead( Up_Sw ) != 1 ){
tone( pin, ( frequency[ result ] * 2 )) ;
}
else{
tone( pin, frequency[ result ] ) ;
}
}
}
LastDisplayed = result ;
}
// キーデコード関数
// 引数をA/D変換結果(0~1023)にして呼ぶと、押したキーの番号(0~KeyNum-1)を返す。
// 何もキーを押していない時は、-1を返す。
int KeyDecode( int n ){
int i = 0 ;
while( ( i < KeyNum ) && ( n > threshold[ i ] ) ) i++ ;
if( i >= KeyNum ) return -1 ;
//Serial.println( i,HEX ) ;
return i ;
} // KeyDecode