const int numRows = 4; // Número de filas
const int numCols = 4; // Número de columnas
const int calibracion = 80;
boolean notaioff[numRows][numCols];
int contador[numRows][numCols];
byte notas[numRows][numCols] = {
{60, 61, 62, 63},
{64, 65, 66, 67},
{68, 69, 70, 71},
{72, 73, 74, 75}
};
int rowPins[numRows] = {9, 8, 7, 6}; // Pines de las filas
int colPins[numCols] = {5, 4, 3, 2}; // Pines de las columnas
void setup() {
Serial.begin(115200);
for (int i = 0; i < numRows; i++) {
pinMode(rowPins[i], OUTPUT);
digitalWrite(rowPins[i], HIGH); // Inicializar las filas en alto
}
for (int i = 0; i < numCols; i++) {
pinMode(colPins[i], INPUT_PULLUP); // Habilitar las resistencias de pull-up
}
}
void loop() {
for (int i = 0; i < numRows; i++) {
digitalWrite(rowPins[i], LOW); // Seleccionar una fila
for (int j = 0; j < numCols; j++) {
if (digitalRead(colPins[j]) == LOW) { // Botón presionado
if (contador[i][j] == 0) {
if (notaioff[i][j] == 1) {
contador[i][j] = calibracion; // Valor de cuenta regresiva
midi(144, notas[i][j], 100); // Se envía la nota
notaioff[i][j] = 0; // La nota no está apagada (está encendida)
}
}
} else { // Botón sin presionar (posible envío de Note Off)
if (contador[i][j] == 0) { // Cuenta regresiva terminada?
if (notaioff[i][j] == 0) { // ¿La nota está activada?
contador[i][j] = calibracion; // Valor de cuenta regresiva
midi(128, notas[i][j], 0); // Envío de Note Off
notaioff[i][j] = 1; // La nota ya no está encendida
}
}
}
}
digitalWrite(rowPins[i], HIGH); // Desactivar la fila
}
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
// Cuentas regresivas
if (contador[i][j] > 0) {
contador[i][j]--;
}
}
}
}
void midi(unsigned char command, unsigned char note, unsigned char vel) {
Serial.write(command);
Serial.write(note);
Serial.write(vel);
}