編集履歴一覧に戻る
momoのアイコン画像

momo が 2021年02月28日23時57分36秒 に編集

初版

タイトルの変更

+

アシスト付き電子ピアノ

タグの変更

+

XIAO

+

ピアノ

+

TM1638

+

圧電スピーカー

本文の変更

+

### はじめに 5線で7セグ/LEDとスイッチ入力ができるLED&KEY(TM1638)を使って、 簡易電子ピアノを作りました。ただ、自分はピアノは全然弾けません…。 なので、次の音をLEDで示すようにアシスト機能を付けました。 ### 部品 - XIAO - TM1638 LED&KEY - 圧電スピーカー ### 回路図 ![キャプションを入力できます](https://camo.elchika.com/2c8fb2e70e9b897062a3d77425526085aef230ca/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f65343964323538632d663631612d346363642d393865302d3439323165303732366539302f64336636383263632d633337372d343634622d386364632d646430626261623933646563/) ### 概観 ![キャプションを入力できます](https://camo.elchika.com/b761193e141598776715a6b61f7f8cd3f9c7baf9/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f65343964323538632d663631612d346363642d393865302d3439323165303732366539302f33346134643731372d373339302d346639642d383237652d356134393866663339313131/) ### プログラム ```スケッチ #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); } } }; }; // PORT: C 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が点灯している位置のキーを順に押下していくと、ドレミの曲が弾けます。