-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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
http://pikabu.ru/story/midi_fighter__igrushka_dlya_detey_upgraded_howto_4827586