はじめに
5線で7セグ/LEDとスイッチ入力ができるLED&KEY(TM1638)を使って、
簡易電子ピアノを作りました。ただ、自分はピアノは全然弾けません…。
なので、次の音をLEDで示すようにアシスト機能を付けました。
部品
- XIAO
- TM1638 LED&KEY
- 圧電スピーカー
回路図
概観
プログラム
#include <TM1638lite.h>
class Speaker {
private:
int port_no;
int a2d(char a) {
return (('0' <= a) && (a <= '9')) ? (a - '0') : 0;
};
public:
Speaker(int port) {
this->port_no = port;
};
void Init(void) {
pinMode(this->port_no, OUTPUT);
};
void Sound(char nte, unsigned int len, unsigned oct) {
static const struct {char n; int f[2];} tbl[] = {
{'c', {262, 523}},
{'d', {294, 587}},
{'e', {330, 659}},
{'f', {349, 689}},
{'g', {392, 784}},
{'a', {440, 880}},
{'b', {494, 988}},
{'.', {0, 0}}};
Serial.printf("%c %d %d\n", nte, len, oct);
if (len < 2) {
len = 800;
} else if (len < 4) {
len = 400;
} else if (len < 8) {
len = 200;
} else {
len = 400;
}
if (oct > 1) {
oct = 1;
}
for (int i=0; i<sizeof(tbl)/sizeof(tbl[0]); i++) {
if (nte == tbl[i].n) {
tone(this->port_no, tbl[i].f[oct], len);
delay(len);
}
}
};
void Play(char *snd) {
int o = 0;
while ('\0' != *snd) {
if ('o' == *snd) {
snd++;
o = a2d(*snd++);
} else {
Sound(*snd++, a2d(*snd++), o);
}
}
};
};
TM1638lite tm(9, 8, 7);
Speaker spk(10);
static char *drm =
"o0c2d4e2c4e2c2e2.4"
"d2e4f4f4e4d4f2.4"
"e2f4g2e4g2e2g2.4"
"f2g4a4a4g4f4a2.4"
"g2c4d4e4f4g4a2.4"
"a2d4e4f4g4a4b2.4"
"b2e4f4g4a4b4o1c2.4"
"o1c4o0b4a2f2b2g2o1c2.4"
"o0c4d4e4f4g4a4b4o1c4.4"
"o1c4o0b4a4g4f4e4d4.4"
"c4e4e2e4g4g2d4f4f2a4b4b2.4"
"c4e4e2e4g4g2d4f4f2a4b4b2.4"
"g2c2a2f2e2c4d2.4"
"g2c2a2b2c2d2o1c1.4"
"\0";
static char *pos = drm;
void setup()
{
tm.reset();
tm.displayText("--------");
tm.setLED(0, 1);
spk.Init();
spk.Play(drm);
}
void loop()
{
int f, o;
unsigned char k = get_key_input();
for (int i=0; i<8; i++) {
tm.displayASCII(i, "-o"[k & 1]);
if (k & 1) {
spk.Sound("cdefgabc"[i], 4, (i == 7) ? 1:0);
}
k >>= 1;
tm.setLED(i, 0);
}
f = 1;
o = 0;
while (*pos && f) {
switch (*pos++) {
case 'o': o = (('1' == *(pos) ? 7 : 0)); break;
case 'c': tm.setLED(o, 1); f = 0; break;
case 'd': tm.setLED(1, 1); f = 0; break;
case 'e': tm.setLED(2, 1); f = 0; break;
case 'f': tm.setLED(3, 1); f = 0; break;
case 'g': tm.setLED(4, 1); f = 0; break;
case 'a': tm.setLED(5, 1); f = 0; break;
case 'b': tm.setLED(6, 1); f = 0; break;
case '\0': pos = drm; break;
default:
;
}
}
}
unsigned char get_key_input(void)
{
static unsigned char pre = 0;
unsigned char ege;
do {
unsigned char btn = tm.readButtons();
ege = (~pre) & btn;
pre = btn;
delay(100);
} while(!ege);
return ege;
}
動作
最初に見本のメロディーが流れます。
そのあと、上のLEDが点灯している位置のキーを順に押下していくと、ドレミの曲が弾けます。
投稿者の人気記事
-
momo
さんが
2021/02/28
に
編集
をしました。
(メッセージ: 初版)
-
momo
さんが
2021/02/28
に
編集
をしました。
-
momo
さんが
2021/03/01
に
編集
をしました。
-
momo
さんが
2021/03/20
に
編集
をしました。
-
momo
さんが
2021/03/20
に
編集
をしました。
-
momo
さんが
2021/12/27
に
編集
をしました。
-
momo
さんが
2022/02/19
に
編集
をしました。
ログインしてコメントを投稿する