6.ボタンの使用 TOPへ 8.超音波センサの使用

7.音を鳴らす


NXTはスピーカーを内蔵しているので、音を鳴らすことができます。ここでは音を鳴らすプログラムを学習します。


1.音を鳴らす

まずは、単純に音を鳴らすプログラムを作成します。 次のプログラムを作成してください。ここでは sound1.c とします。
sound1.c
#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_interface.h"

DeclareTask(Task1);				/* Task1を宣言 */

void ecrobot_device_initialize(){}		/* OSEK起動時の処理(何もしない)*/

void ecrobot_device_terminate(){}		/* OSEK終了時の処理(何もしない)*/


void user_1ms_isr_type2(void){}

TASK(Task1)
{

	ecrobot_sound_tone(440,10, 50);	/* 音を鳴らす */
	systick_wait_ms(100);			/* 100ms待つ */
   		
   	display_string("THAT'S ALL !");		/* メッセージを表示する */
	display_update();
	TerminateTask();					/* 処理終了 */
}

今回新たに用いたAPIなどについて解説します。

ecrobot_sound_tone(440,10, 50)
スピーカーから音を鳴らします。
第一の引数は音程を指定します。単位はHzです。範囲は 31Hz 〜 2100Hz の間です。
第二の変数は音の長さを指定します。単位は1msです。
第三の変数は音の大きさを指定します。範囲は0〜100までです。


これで単純に音を鳴らすことができました。ecrobot_sound_tone関数は鳴り終わるまで待つ動作をせず、次の処理に移ってしまいます。
よって、systick_wait_ms関数と同様に使うとよいです。
また、ecrobot_sound_tone関数の周波数指定で音を出すときに音階に従って指定したい場合は、次の表を参考にすると良いでしょう。

音と周波数の関係
音階 オクターブ
3 4 5 6
B 247 494 988
A# 233 466 932
A 220 440 880 1760
G# 415 831 1661
G 392 784 1568
F# 370 740 1480
F 349 698 1397
E 330 659 1319
D# 311 622 1245
D 294 584 1175
C# 277 554 1109
C 262 523 1047




2.メロディーを作成する

先ほどの機能を用いれば、メロディーを作成することができます。
それでは次のプログラムを作成してください。ここでは sound2.c とします。
sound2.c
#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_interface.h"

DeclareTask(Task1);				/* Task1を宣言 */

void ecrobot_device_initialize(){}		/* OSEK起動時の処理(何もしない)*/

void ecrobot_device_terminate(){}		/* OSEK終了時の処理(何もしない)*/


void user_1ms_isr_type2(void){}

#define TEMPO 250
#define DURATION 100
#define VOLUME 50

void RingTone(int freq, int time, int vol){	/* 音符を再生するユーザー関数を定義 */
	ecrobot_sound_tone(freq, DURATION , vol);
	systick_wait_ms(time);
}

TASK(Task1)
{
	RingTone(523, TEMPO*2, VOLUME);
	RingTone(587, TEMPO*2, VOLUME);
	RingTone(659, TEMPO*2, VOLUME);
	RingTone(698, TEMPO*2, VOLUME);
	RingTone(659, TEMPO*2, VOLUME);
	RingTone(587, TEMPO*2, VOLUME);
	RingTone(523, TEMPO*4, VOLUME);

	RingTone(659, TEMPO*2, VOLUME);
	RingTone(698, TEMPO*2, VOLUME);
	RingTone(784, TEMPO*2, VOLUME);
	RingTone(880, TEMPO*2, VOLUME);
	RingTone(784, TEMPO*2, VOLUME);
	RingTone(698, TEMPO*2, VOLUME);
	RingTone(659, TEMPO*4, VOLUME);

	RingTone(523, TEMPO*4, VOLUME);
	RingTone(523, TEMPO*4, VOLUME);
	RingTone(523, TEMPO*4, VOLUME);
	RingTone(523, TEMPO*4, VOLUME);

	RingTone(523, TEMPO, VOLUME);
	RingTone(523, TEMPO, VOLUME);
	RingTone(587, TEMPO, VOLUME);
	RingTone(587, TEMPO, VOLUME);
	RingTone(659, TEMPO, VOLUME);
	RingTone(659, TEMPO, VOLUME);
	RingTone(698, TEMPO, VOLUME);
	RingTone(698, TEMPO, VOLUME);
	RingTone(659, TEMPO*2, VOLUME);
	RingTone(587, TEMPO*2, VOLUME);
	RingTone(523, TEMPO*4, VOLUME);
	
   	display_string("THAT'S ALL !");		/* メッセージを表示する */
	display_update();
	TerminateTask();					/* 処理終了 */
}

プログラムを動かすとご存知「カエルの歌」が演奏されます。
今回は、音符を鳴らすために、同じ処理が何度も登場します。これを上の例では、ユーザー関数を定義してひとまとめにしています。
繰り返し使う処理をユーザ関数としてまとめると、プログラム全体の流れが分かりやすくなります。
このプログラムでは RingTone という音を鳴らして一定時間待つという部分だけを関数化しましたが、音楽演奏全体を一つの関数として定義することも可能です。


3.課題

1.サンプルプログラムの動作を確認せよ。

2.何かの曲の一小節を演奏するようなプログラムを作成せよ。



6.ボタンの使用 TOPへ 8.超音波センサの使用