UIAPduinoを使って、音を鳴らしながら遊べる「連打ゲーム」を作ってみましょう。
ボタンを使った入力、LEDの点灯、ブザーの音を組み合わせて、5秒間でどれだけ連打できるかを競うゲームを作ります。
時間の計測、カウント処理など、ゲームづくりに欠かせない基本をマスターしよう!
サンプルのINOファイルをダウンロード
動画で解説もしているので
こちらも参考にしてみてください
ブザーで音を鳴らしてみよう
圧電ブザーやパッシブブザーは、「電気を流すと少しだけ形が変わる材料」を使った部品です。
この“形が変わる動き”がとても小さい振動になり、それが空気をふるわせて音になります。
UIAPduinoにブザーをつないでみましょう。
- 6番ピン
- GND
ピン配置図を見てみよう
電子工作をするときは、このピン配置図がとっても大事なので
ちょっとずつ読めるようになっていきましょう!
まずは、UIAPduino公式サイトのピン配置図を見てみましょう。
UIAPduinoにはたくさんのピンがありますが、それぞれに役割があります。
今回のようにブザーで音を鳴らす場合は、「PWM」の波線マークが書かれたピンをさがします。
PWMピンは、信号を高速でON/OFFさせることができるため、音を鳴らすのに向いています。
波線マークがついている6番ピンを使います。
プログラムを書こう
以下のようにプログラムします。(赤字が追加した部分です)
#define LED 2
#define BUTTON 3
#define BUZZER 6
bool ledState = false;
int lastButton = HIGH;
void setup() {
pinMode(LED, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
startSound();
}
void loop() {
int nowButton = digitalRead(BUTTON); // 今の状態を読む
// 「押された瞬間」を見つける(HIGH → LOW)
if (lastButton == HIGH && nowButton == LOW) {
ledState = !ledState; // ON/OFFを反転
delay(50); // チャタリングを防ぐ
}
digitalWrite(LED, ledState);
lastButton = nowButton; // 状態を保存
}
void startSound() {
tone(BUZZER, 1000, 200);
delay(500);
tone(BUZZER, 1000, 200);
delay(500);
tone(BUZZER, 1500, 400);
delay(500);
}
関数でまとめよう
処理をまとめておきたいときに、関数を使います。
ここでは startSound() という関数を作って、音を鳴らすプログラムをまとめました。
setup()の中で呼び出すことで、スタート時に音を鳴らすことができます。
💡 ワンポイント
関数は「処理をまとめた部品」のようなものです。
何度も使う処理や、ひとまとまりにしたい処理を分けて書くことで、プログラムが見やすくなります。
音を鳴らす tone()
tone()は、ピンをとても速くON/OFFさせて、その振動で音を作っています。
この速さを「周波数(Hz)」といい、数値を変えると音の高さが変わります。
tone(ピン番号, 周波数, 音の長さ)
指定された周波数の信号をピンから出して、音を鳴らします。
音の長さを指定しない場合は、ずっと鳴り続けます(noTone()で止めます)
音階を変えてみよう
ドレミの音にも、それぞれ決まった周波数があります。(音階周波数の一覧)
- 523Hz → ド
- 587Hz → レ
- 659Hz → ミ
- 698Hz → ファ
- 783Hz → ソ
- 880Hz → ラ
- 987Hz → シ
- 1046Hz → ド
「1000」の部分を変えると、好きな音を鳴らすことができます。
動作確認
マイコンに書き込んで、音が鳴るか試してみましょう。
うまくいったら、自分の好きな曲を鳴らしてみるのもおすすめです。
連打ゲームにアレンジしよう
スタートの音が鳴ったあと、連打ゲームが始まるようにしてみましょう。
5秒間で何回ボタンを連打できたかをチェックします。
そのために、押した回数を数えるカウンターや、スタート時刻を保存します。
準備(変数の追加)
#define LED 2
#define BUTTON 3
#define BUZZER 6
bool ledState = false; // LEDの状態(ON/OFF)
int lastButton = HIGH; // 1回前のボタンの状態
int count = 0; // 連打カウンター
unsigned long startTime; // 時間を保存
void setup() {
pinMode(LED, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
startSound(); // スタート音
startTime = millis(); // 開始時間を保存
}
時間を扱う変数
startTime には、少し大きな数を扱える型が使われています。
unsigned long(アンサインドロング)型は、「符号なしlong整数型」です。
簡単にいうと、マイナスを数えられないかわりに、プラスの値をたくさん保存しておける変数です。
- int型 → 約3万まで(-32,768 ~ 32,767)
- long型 → 約20億まで(-2,147,483,648 ~ 2,147,483,647)
- unsigned long型 → 約42億まで(0 ~ 4,294,967,295)
今回は時間(ミリ秒)を扱うため、たくさん数えられる unsigned long を使います。
💡 ワンポイント
millis() を使うと、マイコンが起動してからの時間(ミリ秒)を取得できます。
1秒 = 1000ミリ秒なので、時間を計るときに便利です。
連打ゲームの処理
つぎに、loop()の中に、連打ゲームのプログラムを書きましょう。
void loop() {
if (millis() - startTime < 5000) { // 5秒以内なら
int nowButton = digitalRead(BUTTON);
if (lastButton == HIGH && nowButton == LOW) {
count++; // カウントアップ
delay(50); // チャタリング防止
}
lastButton = nowButton;
}
else {
resultSound(count); // 結果発表
while (true); // 終了
}
}
時間のはかり方
次の式で、どれくらい時間が経ったかを調べています。
millis() - startTime
スタート時の時間を引くことで、「経過時間」を計算できます。
この値が5000(=5秒)より小さい間だけ、ゲームを続けます。
⏱ ワンポイント
delay() を使わずに時間を測れるのが millis() のポイントです。
プログラムを止めずに時間を管理できるので、ゲームなどに向いています。
カウントの仕組み
トグルボタンの仕組みと同じように、「押した瞬間」だけをカウントしています。
- HIGH → LOW の変化で検出
- 押しっぱなしでは増えない
ゲーム終了
5秒が経過したらゲーム終了です。
resultSound(count); を呼び出して、結果を音で発表します。
その後、while (true); で処理を止めています。
⚡ ワンポイント
while (true); は、その場所でずっと止まる命令です。
これ以上プログラムを進めないことで、ゲームを終了させています。
結果発表のプログラムをしよう
さいごに、音とランプで連打回数を知らせる関数を作りましょう。
// 結果発表:連打した数だけLEDとブザーでカウント
void resultSound(int c) {
for (int i = 0; i < c; i++) {
digitalWrite(LED, HIGH);
tone(BUZZER, 1200);
delay(80);
digitalWrite(LED, LOW);
noTone(BUZZER);
delay(80);
}
}
引数ってなに?
void resultSound(int c) の int c の部分を「引数」といいます。
引数とは、関数を呼び出すときに値を受け渡しするための変数です。
たとえば resultSound(5) のように呼び出すと、関数の中では c = 5 として処理されます。
💡 ワンポイント
引数を使うと、「同じ処理を、違う値で使い回す」ことができます。
今回は、連打回数に応じて音とLEDの回数を変えています。
UIAPduinoに書き込んでみよう
UIAPduinoのリセットボタンを押しながらケーブルを差し込み
プログラムを書き込んでみましょう。
もう一度リセットボタンを押すと、スタート音のあとにゲームがはじまります。
ボタンを連打してみましょう。
5秒後、連打した回数だけ、LEDが光って音が鳴ります。
- 5回 → 5回ピカピカ+ピッピッ
- 10回 → 10回ピカピカ+ピッピッ
ちょっとアレンジ(音を変えてみよう)
同じ音だけだと回数が分かりづらいので、「ドレミファソラシド」を繰り返すようにしてみましょう。
// 結果発表:連打した数だけLEDとブザーでカウント
void resultSound(int c) {
int scale[] = {523, 587, 659, 698, 783, 880, 987, 1046};
int index = 0;
int size = sizeof(scale) / sizeof(scale[0]);
for (int i = 0; i < c; i++) {
digitalWrite(LED, HIGH);
tone(BUZZER, scale[index]);
delay(80);
digitalWrite(LED, LOW);
noTone(BUZZER);
delay(80);
index = (index + 1) % size;
}
}
配列を使おう
配列に音階のヘルツ数を入れておくことで、順番に音を取り出すことができます。
index を使って、配列の中の音を1つずつ選んでいます。
🎵 ワンポイント
index = (index + 1) % size; とすることで、最後までいったら最初に戻ります。
これによって、ドレミファソラシドを繰り返すことができます。
これで、連打ゲームの完成です!
ぜひ記録更新にチャレンジしてみましょう。



コメント