*Начну с того, что я первый раз на этом форуме, так что если выбрал не тот раздел - извините. А теперь, к делу! И так, я решил сделать MIDI клавиатуру на базе Arduino Nano. На днях нашёл детский синтезатор с клавиатурой на 44 клавиши (маловато, согласен. Но мне пойдёт.) Загуглил приблизительную схему на неё: Т.е. у меня 14 выводов (6 - от анодов диодов, 8 от кнопок) При помощи Keypad сделал считывание значений с клавиатуры: Код (C++): #include <Keypad.h> const byte ROWS = 8; const byte COLS = 6; char hexaKeys[ROWS][COLS] = { {'1','9','G','O','X','^'}, {'2','0','H','P','Y','&'}, {'3','A','I','Q','Z','/'}, {'4','B','J','R','!','*'}, {'5','C','K','S','@','0'}, {'6','D','L','T','#','0'}, {'7','E','M','U','$','0'}, {'8','F','N','W','%','0'}, }; byte rowPins[ROWS] = {2, 3, 4, 5, 6, 7, 8, 9}; // выводы с кнопок byte colPins[COLS] = {10, 11, A0, A1, A2, A3}; // выводы с диодов Keypad keypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS ); void setup(){ Serial.begin(9600); } void loop(){ char key = keypad.getKey(); if (key){ Serial.println(key); } } Нашёл в гугле код, его переделал под себя: Код (C++): #include <Keypad.h> const byte ROWS = 8; const byte COLS = 6; char hexaKeys[ROWS][COLS] = { {'1','9','G','O','X','^'}, {'2','0','H','P','Y','&'}, {'3','A','I','Q','Z','/'}, {'4','B','J','R','!','*'}, {'5','C','K','S','@','0'}, {'6','D','L','T','#','0'}, {'7','E','M','U','$','0'}, {'8','F','N','W','%','0'}, }; byte rowPins[ROWS] = {2, 3, 4, 5, 6, 7, 8, 9}; // выводы с кнопок byte colPins[COLS] = {10, 11, A0, A1, A2, A3}; // выводы с диодов Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); #define note_C 0x3C // C4 #define note_D 0x3E // D4 #define note_E 0x40 // E4 #define note_F 0x41 // F4 #define note_G 0x43 // G4 #define note_A 0x45 // A4 #define note_B 0x47 // B4 int buttonState_C = 0; int buttonState_D = 0; int buttonState_E = 0; int buttonState_F = 0; int buttonState_G = 0; int buttonState_A = 0; int buttonState_B = 0; int note_C_send_off = false; int note_C_send_on = false; int note_D_send_off = false; int note_D_send_on = false; int note_E_send_off = false; int note_E_send_on = false; int note_F_send_off = false; int note_F_send_on = false; int note_G_send_off = false; int note_G_send_on = false; int note_A_send_off = false; int note_A_send_on = false; int note_B_send_off = false; int note_B_send_on = false; uint8_t buf[8] = { 0 }; void setup() { Serial.begin(115200); } void loop() { char key = customKeypad.getKey(); // Нота C if (key == '1' && note_C_send_on == false) { noteOn(0x90, note_C, 0x7F); note_C_send_on = true; // Команда Note On послана note_C_send_off = false; // Команда Note Off не послана } else if (key == '1' && note_C_send_on == true) { noteOn(0x00, note_C, 0x7F); note_C_send_on = true; note_C_send_off = false; } else if (key != '1' && note_C_send_off == false) { noteOn(0x90, note_C, 0x00); note_C_send_on = false; note_C_send_off = true; } // Нота D if (key == '2' && note_D_send_on == false) { noteOn(0x90, note_D, 0x7F); note_D_send_on = true; note_D_send_off = false; } else if (key == '2' && note_D_send_on == true) { noteOn(0x00, note_D, 0x7F); note_D_send_on = true; note_D_send_off = false; } else if (key != '2' && note_D_send_off == false) { noteOn(0x90, note_D, 0x00); note_D_send_on = false; note_D_send_off = true; } // Нота E if (key == '3' && note_E_send_on == false) { noteOn(0x90, note_E, 0x7F); note_E_send_on = true; note_E_send_off = false; } else if (key == '3' && note_E_send_on == true) { noteOn(0x00, note_E, 0x7F); note_E_send_on = true; note_E_send_off = false; } else if (key != '3' && note_E_send_off == false) { noteOn(0x90, note_E, 0x00); note_E_send_on = false; note_E_send_off = true; } // Нота F if (key == '4' && note_F_send_on == false) { noteOn(0x90, note_F, 0x7F); note_F_send_on = true; note_F_send_off = false; } else if (key == '4' && note_F_send_on == true) { noteOn(0x00, note_F, 0x7F); note_F_send_on = true; note_F_send_off = false; } else if (key != '4' && note_F_send_off == false) { noteOn(0x90, note_F, 0x00); note_F_send_on = false; note_F_send_off = true; } // Нота G if (key == '5' && note_G_send_on == false) { noteOn(0x90, note_G, 0x7F); note_G_send_on = true; note_G_send_off = false; } else if (key == '5' && note_G_send_on == true) { noteOn(0x00, note_G, 0x7F); note_G_send_on = true; note_G_send_off = false; } else if (key != '5' && note_G_send_off == false) { noteOn(0x90, note_G, 0x00); note_G_send_on = false; note_G_send_off = true; } // Нота A if (key == '6' && note_A_send_on == false) { noteOn(0x90, note_A, 0x7F); note_A_send_on = true; note_A_send_off = false; } else if (key == '6' && note_A_send_on == true) { noteOn(0x00, note_A, 0x7F); note_A_send_on = true; note_A_send_off = false; } else if (key != '6' && note_A_send_off == false) { noteOn(0x90, note_A, 0x00); note_A_send_on = false; note_A_send_off = true; } // Нота B if (key == '7' && note_B_send_on == false) { noteOn(0x90, note_B, 0x7F); note_B_send_on = true; note_B_send_off = false; } else if (key == '7' && note_B_send_on == true) { noteOn(0x00, note_B, 0x7F); note_B_send_on = true; note_B_send_off = false; } else if (key != '7' && note_B_send_off == false) { noteOn(0x90, note_B, 0x00); note_B_send_on = false; note_B_send_off = true; } } void noteOn(int cmd, int pitch, int velocity) { Serial.write(cmd); Serial.write(pitch); Serial.write(velocity); delay(20); } Но оно не может считывать удержание клавиши или нажатие нескольких клавиш. Помогите пожалуйста осуществить это. Сделать надо без всяких сдвиговых регистров, расширителей и т.п. просто всё к ардуино. Также, обязательна возможность нажатия и удержания сразу нескольких клавиш (на самом синтезаторе одновременно можно было зажимать 8 клавиш). Заранее спасибо!
А где вопрос? Загляните в keypad.h, даст общее представление. Дальше дополняйте до нужного вам функционала.
Сесть и написать программу, как. Или идите в "закажу проект", там за вас напишут. Не бесплатно, разумеется.
Мда... хороший видимо этот форум, с наидобрейшими людьми..... Можно хоть принцип объяснить, как должно происходить считывание клавиши, которая ужерживается? И считывание зажатых одновременно клавиш.
У вас уже есть на руках код, который опрашивает клавиши. Дальше надо просто написать автомат, который после каждого цикла опроса будет сравнивать состояние клавиатуры с предыдущим. И на основе этого решать, что нажали, что отпустили, что удержали. Была нажата, а теперь нет - значит отпустили.
Ну и как тут быть добрым? Когда уже на пальцах разжевываешь, а человек просто игнорирует. что ты пишешь.
Это даёт возможность зажимать одновременно не более 2-ух клавиш, а как сделать больше? Код (C++): #include <Keypad.h> const byte ROWS = 8; const byte COLS = 6; char keys[ROWS][COLS] = { {'1','9','G','O','X','^'}, {'2','0','H','P','Y','&'}, {'3','A','I','Q','Z','/'}, {'4','B','J','R','!','*'}, {'5','C','K','S','@','0'}, {'6','D','L','T','#','0'}, {'7','E','M','U','$','0'}, {'8','F','N','W','%','0'}, }; byte rowPins[ROWS] = {2, 3, 4, 5, 6, 7, 8, 9}; byte colPins[COLS] = {10, 11, A0, A1, A2, A3}; String msg; Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); #define note_C 0x3C // C4 #define note_D 0x3E // D4 #define note_E 0x40 // E4 #define note_F 0x41 // F4 #define note_G 0x43 // G4 #define note_A 0x45 // A4 #define note_B 0x47 // B4 unsigned long loopCount; unsigned long startTime; void setup() { Serial.begin(115200); loopCount = 0; startTime = millis(); msg = ""; } void loop() { if (kpd.getKeys()) { for (int i=0; i<LIST_MAX; i++) // Scan the whole key list. { if ( kpd.key[i].stateChanged ) // Only find keys that have changed state. { switch (kpd.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED case PRESSED: kpress(kpd.key[i].kchar); break; case HOLD: msg = " HOLD."; break; case RELEASED: kreleased(kpd.key[i].kchar); break; case IDLE: msg = " IDLE."; } //Serial.print("Key "); //Serial.print(kpd.key[i].kchar); //Serial.println(msg); } } } } // End loop void noteOn(int cmd, int pitch, int velocity) { Serial.write(cmd); Serial.write(pitch); Serial.write(velocity); //delay(20); } void kpress(char knum) { switch (knum) { case '1': noteOn(0x90, note_C, 0x7F); break; case '2': noteOn(0x90, note_D, 0x7F); break; case '3': noteOn(0x90, note_E, 0x7F); break; case '4': noteOn(0x90, note_F, 0x7F); break; case '5': noteOn(0x90, note_G, 0x7F); break; case '6': noteOn(0x90, note_A, 0x7F); break; case '7': noteOn(0x90, note_B, 0x7F); break; } } void kreleased(char knum) { switch (knum) { case '1': noteOn(0x90, note_C, 0x00); break; case '2': noteOn(0x90, note_D, 0x00); break; case '3': noteOn(0x90, note_E, 0x00); break; case '4': noteOn(0x90, note_F, 0x00); break; case '5': noteOn(0x90, note_G, 0x00); break; case '6': noteOn(0x90, note_A, 0x00); break; case '7': noteOn(0x90, note_B, 0x00); break; } }
Всё, решение нашёл сам, экспериментальным путём- поставить подтягивающие резисторы на выводы с кнопок и на 5 вольт по 10к
Требуется помощь! У меня есть номер клавиши, например 41. Её надо переконвертировать в MIDI - формат, т.е. в HEX и 0x вначале, Например просто в HEX, это так: (41, HEX), а как на выходе ещё в начало поставить 0x?
Извиняюсь за то что не хотел посидеть 4 часика и погуглить и подумать. Модеры. можете удалять данную тему. Продолжение этой истории всегда будет тут: http://forum.amperka.ru/threads/midi-usb-клавиатура-на-arduino-nano.11123/