これは CPS Lab Advent Calendar 2018 1日目の記事である.
2日目の記事は JavaScript だけで BLE に入門する - たこつぼ .
概要
M5Stack Basicでメトロノーム(設定したBPMに沿って音を鳴らす)を作成した.
Q.動機は?
my new gear... pic.twitter.com/8C00zsSOb0
— Rone@G2R'DuαlCore' (@Rone_Loreto) 2018年11月29日
A. もしかめを極めるため.
BPMとは
曲のテンポのことで,BPM=1分間における四分音符の数 で表される.
BPMの計算を考える
BPM = 1分間における四分音符の数 = 60秒あたりの四分音符の数 である.
更に言い換えると 60000ミリ秒(ms)あたりの四分音符の数 である.すなわち,
1分間あたりの四分音符の数 → 60秒あたりの四分音符の数 → 60000ミリ秒(ms)あたりの四分音符の数
これより, 「四分音符の長さ = (60000[Hz] / 設定したいBPM) / 4」 と分かる.
[ex: BPM120の場合]
BPM120の場合,四分音符は 60秒で四分音符120回 → 60000msで四分120回
であるので,
四分音符1回辺りの秒数(ms)は
60000 ÷ 120 = 150
よって,150msで四分音符1回.
実装した機能
-
BPMの変更
Aボタン(左)で遅く,Bボタン(真ん中)で速くできる. -
メトロノームの スタート / ストップ
Cボタン(右)を押すごとにスタートとストップができる.
デモ
メトロノーム (Metronome) #M5Stack pic.twitter.com/p1pRbeopF2
— Rone@G2R'DuαlCore' (@Rone_Loreto) 2018年12月1日
ソースコード
#include <M5Stack.h>
// メトロノーム音を設定
#define C4 262
// テンポ変数 デフォルト120
int bpm = 120;
// 音符変数の宣言
float note; // 8分音符
// ステート変数の宣言
int runstate = 0;
void PrintBPM()
{
M5.Lcd.setCursor(0, 0);
M5.Lcd.println(bpm);
}
void SelectBPM()
{
if (M5.BtnA.wasPressed())
{
--bpm;
PrintBPM();
M5.update();
}
else if (M5.BtnB.wasPressed())
{
++bpm;
PrintBPM();
M5.update();
}
}
void AdjustBPM()
{
// 音の長さをBPMに合わせる
note = (60000 / bpm) / 4;
}
void MetronomePlay()
{
AdjustBPM();
M5.Speaker.tone(C4, note);
delay(note);
M5.Speaker.mute();
delay(note * 3);
}
void CheckRunState()
{
if (M5.BtnC.wasPressed())
{
switch (runstate)
{
case 0:
runstate = 1;
break;
case 1:
runstate = 0;
break;
}
}
M5.update();
}
void setup()
{
M5.begin();
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.setTextSize(10);
PrintBPM();
}
void loop()
{
SelectBPM();
CheckRunState();
if (runstate == 1)
{
MetronomePlay();
}
}
*汚い部分が多いコードなので,
「このように書き換えできそう?」 などあればどしどし教えていただけると幸いである.
今後の予定
- ディスプレイ表示の修正
- BPMの表示位置を中心にする
-
メトロノーム動作中でもBPMをスムーズに変更できるようにする
- 現状のコードでは引っかかったような変動をするため
-
BPM変更のボタン長押し対応
- 長押ししている間,続けてBPM変更がされるようにする(100msごとに1BPM変動,のようなイメージ)
モチベが保たれている近日中にブラッシュアップ予定.