Skip to content

Instantly share code, notes, and snippets.

@superyarik
Forked from arion/midi.ino
Last active March 26, 2017 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save superyarik/f8a1f5f17e354ee99ac403334cc56ee8 to your computer and use it in GitHub Desktop.
Save superyarik/f8a1f5f17e354ee99ac403334cc56ee8 to your computer and use it in GitHub Desktop.
MIDI Fighter + игрушка для детей -> http://pikabu.ru/story/midi_fighter__igrushka_dlya_detey_upgraded_howto_4827586
#include <MIDI.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#include <math.h>
SoftwareSerial mySerial(10, 11); // RX, TX
MIDI_CREATE_DEFAULT_INSTANCE();
bool isMp3Mode = false;
#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#endif
unsigned long debounceDelay = 50;
const byte ROWS = 4; //--Количество столбцов матричной клавиатуры
const byte COLS = 4; //--Количество строк матричной клавиатуры
byte rowPins[ROWS] = {2, 3, 4, 5}; //--Пины столбцов
byte colPins[COLS] = {6, 7, 8, 9}; //--Пины строк
byte buttonState[COLS][ROWS] = { //--Массив состояний кнопок
{1, 1, 1, 1},
{1, 1, 1, 1},
{1, 1, 1, 1},
{1, 1, 1, 1}
};
byte lastButtonState[COLS][ROWS] = { //--Массив предыдущих состояний кнопок
{1, 1, 1, 1},
{1, 1, 1, 1},
{1, 1, 1, 1},
{1, 1, 1, 1}
};
unsigned long lastDebounceTime[COLS][ROWS] = { //--Массив предыдущих состояний кнопок
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
byte kpdNote[COLS][ROWS] = { //Массив нот
{48, 44, 40, 36},
{49, 45, 41, 37},
{50, 46, 42, 38},
{51, 47, 43, 39}
};
//byte kpdNote[COLS][ROWS] = { //Массив нот
// {51, 47, 43, 39},
// {50, 46, 42, 38},
// {49, 45, 41, 37},
// {48, 44, 40, 36}
//};
int mp3File[COLS][ROWS] = { //--Массив файлов
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
};
byte dval = 0;
int pval = 0;
int potPrVal[4] = {0, 0, 0, 0}; //--Массив состояниея потенциометров
byte potPins[4] = {1, 2, 3, 4}; //--Пины потенциометров
byte mp3Pin = 12;
int prFolder = 1;
int folder = 1;
int foldersCount = 15; // количество папок, 15 это лимит на данной плате плеера.
void setup() {
MIDI.begin(); //Инициализация MIDI интерфейса
for(byte i = 0; i < COLS; i++){ //--Конфигурируем строки мтрчн клвтр как выходы--
pinMode(colPins[i], OUTPUT); //--и подаём на них лог. 1-----------------------
digitalWrite(colPins[i], HIGH); // ----------------------------------------------
}
for(byte i = 0; i < ROWS; i++) { //--Конфигурируем столбцы мтрчн клвтр как входы---------
pinMode(rowPins[i], INPUT); //--и включаем встроенные в мк подтягивающие резисторы--
digitalWrite(rowPins[i], HIGH); //------------------------------------------------------
}
pinMode(mp3Pin, INPUT);
digitalWrite(mp3Pin, HIGH);
//Serial.begin(9600);
Serial.begin(115200);
mySerial.begin(9600);
mp3_set_serial(mySerial); //--set softwareSerial for DFPlayer-mini mp3 module
//mp3_set_debug_serial(Serial);
delay(1); //--delay 1ms to set volume
mp3_set_volume(5); //--value 0~30
isMp3Mode = (digitalRead(mp3Pin) == HIGH);
}
void loop() {
for(byte chn = 0; chn < 4; chn++) //-Цикл чтения значений потенциометров-----------
{
pval = analogRead(potPins[chn]);
if (abs(pval-potPrVal[chn]) > 30) { //--Если текущее значение отл. от прошлого
MIDI.sendControlChange(1, chn, pval);
if (isMp3Mode) {
DEBUG_PRINTLN("Change channel: chn:" + String(chn) + " val:" + String(pval));
}
potPrVal[chn] = pval;
if (chn == 3) {
mp3_set_volume( map(pval, 0, 1023, 0, 30) );
}
if (chn == 2) {
mp3_set_EQ( map(pval, 0, 1023, 0, 5) );
}
if (isMp3Mode && (chn == 0 || chn == 1 )) {
folder = map(potPrVal[0] + potPrVal[1], 0, 2000, 1, foldersCount);
if (folder > foldersCount) {
folder = foldersCount;
}
if (prFolder != folder) {
mp3_stop ();
delay(200);
mp3_play(folder); //произнесем какую папку выбрали, т.к. у пользователя пока нет встроенного serial порта. Файлы в папке mp3, 0001.mp3 это слово "один" и т.д.
delay(200);
DEBUG_PRINTLN("Change folder:" + String(folder));
prFolder = folder;
}
}
}
}
//-------------------------------------
for(byte col = 0; col < COLS; col++) //-Цикл чтения матричной клавиатуры-----
{
digitalWrite(colPins[col], LOW); //--На считываем столбец выставляем 0---
for(byte row = 0; row < ROWS; row++) //--Построчно считываем каждый столбец--
{ //--И при нажатой кнопке передаём ноту--
dval = digitalRead(rowPins[row]);
if (dval != lastButtonState[col][row]) {
lastDebounceTime[col][row] = millis();
}
if ((millis() - lastDebounceTime[col][row]) > debounceDelay) {
if ( dval == LOW && buttonState[col][row] == HIGH ) {
MIDI.sendNoteOn(kpdNote[col][row], 127, 1);
if (isMp3Mode) {
DEBUG_PRINTLN("Start play: row:" + String(row) + " col:" + String(col) + " note:" + String(kpdNote[col][row]));
}
}
if ( dval == HIGH && buttonState[col][row] == LOW ) {
MIDI.sendNoteOff(kpdNote[col][row], 0, 1);
if (isMp3Mode) {
mp3_play_file_in_folder(folder, mp3File[col][row]);
DEBUG_PRINTLN("Play track: " + String(mp3File[col][row]) + " in folder " + String(folder));
DEBUG_PRINTLN("Stop play: row:" + String(row) + " col:" + String(col) + " note:" + String(kpdNote[col][row]));
}
DEBUG_PRINTLN(isMp3Mode);
}
buttonState[col][row] = dval;
}
lastButtonState[col][row] = dval;
}
digitalWrite(colPins[col], HIGH);
}
//--------------------------------------
isMp3Mode = (digitalRead(mp3Pin) == HIGH);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment