<試作1号>
M5ATOM Matrixを使って音の出る電子楽器(キーボード)を作りました。そしてMatrix LED
にドレミファソラシドをカラー表示しましました。
1)使ったもの
|M5ATOM Matrix | 1個|
|プッシュスイッチ | 7個|
|ブレットボード | 1個|
|スピーカー | 1個|
|モバイルバッテリー | 1個|
2)回路(ピン端子ーーー音階)
G22ーーード
G19---レ
G23---三
G33---ファ
G32---ソ
G21---ラ
G25---シ
G39---ド
G26---外部スピーカー
3)<試作1号のコード>
#include <M5Atom.h>
#define C4 261
#define D4 294
#define E4 329
#define F4 349
#define G4 392
#define A4 440
#define B4 493
#define C5 523
#define NOTE_DURATION 500 // 各音の持続時間(ミリ秒)
#define BUTTON_PIN_1 22
#define BUTTON_PIN_2 19
#define BUTTON_PIN_3 23
#define BUTTON_PIN_4 33
#define BUTTON_PIN_5 32
#define BUTTON_PIN_6 21
#define BUTTON_PIN_7 25
#define BUTTON_PIN_8 39 //M5ボタンのピン番号
void playTone(int freq, int duration) {
ledcWriteTone(0, freq);
delay(duration);
ledcWriteTone(0, 0); // 音を止める
delay(50); // 各音の間に少し休止を入れる
}
void setup() {
M5.begin(true, false, true);
M5.dis.clear();
// 全てのピクセルを青色に設定
for (int i = 0; i < 25; i++) {
M5.dis.drawpix(i, 0x0000FF); // 0x0000FFは青色のRGB値
}
//M5.begin();
pinMode(BUTTON_PIN_1, INPUT_PULLUP);
pinMode(BUTTON_PIN_2, INPUT_PULLUP);
pinMode(BUTTON_PIN_3, INPUT_PULLUP);
pinMode(BUTTON_PIN_4, INPUT_PULLUP);
pinMode(BUTTON_PIN_5, INPUT_PULLUP);
pinMode(BUTTON_PIN_6, INPUT_PULLUP);
pinMode(BUTTON_PIN_7, INPUT_PULLUP);
pinMode(BUTTON_PIN_8, INPUT_PULLUP);
// スピーカーのピンを設定 (M5ATOMの場合、26ピンが一般的)
ledcAttachPin(26, 0);
}
void loop() {
if (digitalRead(BUTTON_PIN_1) == LOW) {
int heartShape[25] = {
//ドの表示
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
0, 0, 1, 0, 0,
0, 1, 0, 1, 1,
0, 0, 0, 1, 1
};
uint32_t heartColor = 0xFF0000; // 赤色、
// マトリックスに形を描画
for (int i = 0; i < 25; i++) {
if (heartShape[i] == 1) {
M5.dis.drawpix(i, heartColor);
} else {
M5.dis.drawpix(i, 0x000000); // 背景を黒色に設定
}
}
playTone(C4, NOTE_DURATION);
} else if (digitalRead(BUTTON_PIN_2) == LOW) {
int heartShape[25] = {
//レの表示
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0
};
uint32_t heartColor = 0x00FF00; // 緑色
// マトリックスに形を描画
for (int i = 0; i < 25; i++) {
if (heartShape[i] == 1) {
M5.dis.drawpix(i, heartColor);
} else {
M5.dis.drawpix(i, 0x000000); // 背景を黒色に設定
}
}
playTone(D4, NOTE_DURATION);
} else if (digitalRead(BUTTON_PIN_3) == LOW) {
int heartShape[25] = {
//ミの表示
1, 0, 0, 0, 0,
1, 0, 1, 0, 1,
1, 0, 1, 0, 1,
1, 0, 1, 0, 1,
0, 0, 0, 0, 1
};
uint32_t heartColor = 0x0000FF; // 青色
// マトリックスに形を描画
for (int i = 0; i < 25; i++) {
if (heartShape[i] == 1) {
M5.dis.drawpix(i, heartColor);
} else {
M5.dis.drawpix(i, 0x000000); // 背景を黒色に設定
}
}
playTone(E4, NOTE_DURATION);
} else if (digitalRead(BUTTON_PIN_4) == LOW) {
int heartShape[25] = {
//ファの表示
0, 1, 0, 0, 1,
0, 0, 1, 0, 1,
0, 0, 0, 1, 1,
1, 0, 1, 0, 1,
0, 1, 1, 0, 0
};
uint32_t heartColor = 0xFF00FF; // 紫色
// マトリックスに形を描画
for (int i = 0; i < 25; i++) {
if (heartShape[i] == 1) {
M5.dis.drawpix(i, heartColor);
} else {
M5.dis.drawpix(i, 0x000000); // 背景を黒色に設定
}
}
playTone(F4, NOTE_DURATION);
} else if (digitalRead(BUTTON_PIN_5) == LOW) {
int heartShape[25] = {
//ソの表示
0, 0, 0, 0, 1,
0, 0, 0, 1, 0,
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 1, 1
};
uint32_t heartColor = 0xFFFF00; // 黄色
// マトリックスに形を描画
for (int i = 0; i < 25; i++) {
if (heartShape[i] == 1) {
M5.dis.drawpix(i, heartColor);
} else {
M5.dis.drawpix(i, 0x000000); // 背景を黒色に設定
}
}
playTone(G4, NOTE_DURATION);
} else if (digitalRead(BUTTON_PIN_6) == LOW) {
int heartShape[25] = {
//ラの表示
0, 0, 1, 0, 1,
0, 0, 1, 0, 1,
1, 0, 1, 0, 1,
0, 1, 1, 0, 1,
0, 0, 1, 0, 1
};
uint32_t heartColor = 0x00FFFF; // 水色
// マトリックスに形を描画
for (int i = 0; i < 25; i++) {
if (heartShape[i] == 1) {
M5.dis.drawpix(i, heartColor);
} else {
M5.dis.drawpix(i, 0x000000); // 背景を黒色に設定
}
}
playTone(A4, NOTE_DURATION);
} else if (digitalRead(BUTTON_PIN_7) == LOW) {
int heartShape[25] = {
///シの表示
1, 0, 0, 1, 1,
1, 0, 0, 1, 1,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0
};
uint32_t heartColor = 0xFFFFFF; // 白色
// マトリックスに形を描画
for (int i = 0; i < 25; i++) {
if (heartShape[i] == 1) {
M5.dis.drawpix(i, heartColor);
} else {
M5.dis.drawpix(i, 0x000000); // 背景を黒色に設定
}
}
playTone(B4, NOTE_DURATION);
} else if (digitalRead(BUTTON_PIN_8) == LOW) {
int heartShape[25] = {
//ドの表示
1, 1, 1, 1, 1,
0, 0, 1, 0, 0,
0, 1, 0, 0, 0,
0, 0, 0, 1, 1,
0, 0, 0, 1, 1
};
uint32_t heartColor = 0xFFA500; // オレンジ色、
// マトリックスに形を描画
for (int i = 0; i < 25; i++) {
if (heartShape[i] == 1) {
M5.dis.drawpix(i, heartColor);
} else {
M5.dis.drawpix(i, 0x000000); // 背景を黒色に設定
}
}
playTone(C5, NOTE_DURATION);
}
}
<試作2号>
M5ATOM Matrixでは、7音階は各キーで鳴らす事は出来ましたが、和音がどうしても上手く鳴らない為、M5ATOM S3を使うことにしました。これのディスプレーには、和音コードを表示します。
1)使ったもの
・M5ATOM S3 1個
・キースイッチ 9個
・キースイッチ基板 1個
・スピーカー 1個
・モバイルバッテリー 1個
・ケース 1個(これから作る)
2)回路(ピン端子ーーー和音コード)
G5ーーーCメジャー
G6---Dメジャー
G7---Fメジャー
G8---Gメジャー
G1---Aメジャー
G38---Bメジャー
G39---♭
G ーーー~
G26---外部スピーカー
YouTube(試作2号機)
https://youtu.be/R-dJpS1Z2LM
3)<試作2号のコード>
#include <M5AtomS3.h>
#include <Arduino.h>
#define SPEAKER_PIN 2
const int sampleRate = 8000; // サンプルレート
const int amplitude = 127; // 振幅
const int offset = 128; // オフセット
#define NOTE_DURATION 300 // 各音の持続時間(ミリ秒)
#define BUTTON_PIN_1 5
#define BUTTON_PIN_2 6
#define BUTTON_PIN_3 7
#define BUTTON_PIN_4 8
#define BUTTON_PIN_5 1
#define BUTTON_PIN_6 38
#define BUTTON_PIN_7 39
// #define BUTTON_PIN_8 //M5ボタンのピン番号
void playTone(int freq, int duration) {
ledcWriteTone(0, freq);
delay(duration);
ledcWriteTone(0, 0); // 音を止める
delay(50); // 各音の間に少し休止を入れる
}
void setup() {
M5.begin(); //true, false, true);
// }
pinMode(SPEAKER_PIN, OUTPUT);
ledcSetup(0, sampleRate, 8); // チャンネル0、サンプルレート8000Hz、8ビット解像度
ledcAttachPin(SPEAKER_PIN, 0); // GPIO 26にチャンネル0をアタッチ
// 初期画面表示
AtomS3.Display.setTextColor(GREEN);
AtomS3.Display.setTextFont(&fonts::Font4);
AtomS3.Display.setTextSize(1); // 1~5
AtomS3.Display.setRotation(1); // 0~3
AtomS3.Display.setTextDatum(bottom_center); // middle__bottom__top
AtomS3.Display.drawString("AtomS3", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
AtomS3.Display.setTextDatum(top_center);
AtomS3.Display.drawString("Chorder", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
//M5.begin();
pinMode(BUTTON_PIN_1, INPUT_PULLUP);
pinMode(BUTTON_PIN_2, INPUT_PULLUP);
pinMode(BUTTON_PIN_3, INPUT_PULLUP);
pinMode(BUTTON_PIN_4, INPUT_PULLUP);
pinMode(BUTTON_PIN_5, INPUT_PULLUP);
pinMode(BUTTON_PIN_6, INPUT_PULLUP);
pinMode(BUTTON_PIN_7, INPUT_PULLUP);
// pinMode(BUTTON_PIN_8, INPUT_PULLUP);
}
void playChord(float freq1, float freq2, float freq3, int duration) {
for (int i = 0; i < sampleRate * duration / 1000; i++) {
int sample = (sin(2 * PI * freq1 * i / sampleRate) +
sin(2 * PI * freq2 * i / sampleRate) +
sin(2 * PI * freq3 * i / sampleRate)) * amplitude / 3 + offset;
ledcWrite(0, sample);
delayMicroseconds(1000000 / sampleRate);
}
ledcWrite(0, 0); // 音を停止
}
void loop() {
AtomS3.Display.setTextSize(3);
AtomS3.Display.setTextDatum(middle_center); // middle__bottom__top
AtomS3.update();
//1: Cメジャーコード (C4, E4, G4)
if (digitalRead(BUTTON_PIN_1) == LOW) {
AtomS3.Display.setTextColor(RED);
AtomS3.Display.clear();
AtomS3.Display.drawString("C", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
playChord(261.63, 329.63, 392.00, NOTE_DURATION); // (C4, E4, G4)
//ledcWrite(0, 0); // 音を停止
//2: Dメジャーコード (D4, F#4, A4)
} else if (digitalRead(BUTTON_PIN_2) == LOW) {
AtomS3.Display.setTextColor(ORANGE);
AtomS3.Display.clear();
AtomS3.Display.drawString("D", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
playChord(293.66, 369.99, 440.00, NOTE_DURATION); // (D4, F#4, A4)
//3: Eメジャーコード (E4, G#4, B4)
} else if (digitalRead(BUTTON_PIN_3) == LOW) {
AtomS3.Display.setTextColor(GREEN);
AtomS3.Display.clear();
AtomS3.Display.drawString("E", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
playChord(329.63, 415.30, 493.88, NOTE_DURATION); // (E4, G#4, B4)
//4: Fメジャーコード (F4, A4, C5)
} else if (digitalRead(BUTTON_PIN_4) == LOW) {
AtomS3.Display.setTextColor(YELLOW);
AtomS3.Display.clear();
AtomS3.Display.drawString("F", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
playChord(349.23, 440.00, 523.25, NOTE_DURATION); // (F4, A4, C5)
//5: Gメジャーコード (G4, B4, D5)
} else if (digitalRead(BUTTON_PIN_5) == LOW) {
AtomS3.Display.setTextColor(BLUE);
AtomS3.Display.clear();
AtomS3.Display.drawString("G", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
playChord(392.00, 493.88, 587.33, NOTE_DURATION); // (G4, B4, D5)
//6: Aメジャーコード (A4, C#5, E5)
} else if (digitalRead(BUTTON_PIN_6) == LOW) {
AtomS3.Display.setTextColor(RED);
AtomS3.Display.clear();
AtomS3.Display.drawString("A", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
playChord(440.00, 554.37, 659.25, NOTE_DURATION); // (A4, C#5, E5)
//7: Bメジャーコード (B4, D#5, F#5)
} else if (digitalRead(BUTTON_PIN_7) == LOW) {
AtomS3.Display.setTextColor(YELLOW);
AtomS3.Display.clear();
AtomS3.Display.drawString("B", AtomS3.Display.width() / 2, AtomS3.Display.height() / 2);
playChord(493.88, 622.25, 739.99, NOTE_DURATION); // (B4, D#5, F#5)
//8: Cメジャーコード (C5, E5, G5)
// } else if (digitalRead(BUTTON_PIN_8) == LOW) {
// playChord(523.25, 659.25, 783.99, NOTE_DURATION); // (C5, E5, G5)
}
}