Recents in Beach

header ads

Cómo hacer el controlador MIDI USB más fácil funcional y barato con ARDUINO LEONARDO



Les comparto este sencillo proyecto que sirve como base para crear controladores MIDI muy baratos y funcionales. Con esto podemos controlar diferentes programas de audio, controlar VST o instrumentos virtuales, sintetizadores y hasta controlar los niveles de volumen de programas gratuitos de mezcla como el MIXXX.


La arduino leonardo cuenta con un microcontrolador MEGA32U4 que tiene la capacidad de establecer comunicación USB HID directa con el pc, lo que hace mas fácil el desarrollo de teclados, mouse, controladores midi etc a través del puerto USB usando librerías.

NOTA: EL VALOR RECOMENDADO DE LOS POTENCIOMETROS ES DE 5KOHM, AUNQUE CON 10KOHM FUNCIONA BIEN...

Descarga aquí la carpeta del proyecto:

Aquí descargan el monitor MIDIBerry por si quieren ver los mensajes que genera la Arduino Leonardo al manipular los botones o potenciometros:

Si quieres conocer mas sobre la arduino leonardo ingresa aquí:

Las siguientes tarjetas son compatibles con este proyecto pues usan exactamente el mismo microcontrolador:

ARDUINO LEONARDO Comprar:
PRO MINI 32U4 Comprar: http://scadonsak.com/1G34

BEETLE 32U4 Comprar: http://scadonsak.com/1G7u

Aquí conseguí las PCB lista para prototipos 5 unidades x 2 dolares :

Los programas con los que pruebo el controlador son FL STUDIO y MIXXX
Aquí pueden descargar el MIXXX es gratis:

Aquí les dejo el código fuente:

/*
Mini controlador MIDI USB

Este proyecto es abierto, hagan lo que quieran con el :D
Autor: Sergio A. Yañez M.
Año: 2019
Tutorial para el canal AQUILES VAESA 
youtube.com/aqulesvaesa

Inspirado en los ejemplos de la libreria MIDIUSB
y el proyecto MIDI https://geekytheory.com/arduinomidi-tu-propio-piano
Usamos el filtro de mediana movil, para eliminar el ruido electrico en los potenciomteros.
INDISPENSABLE INSTALAR LAS LIBRERIAS

MIDIUSB:
https://github.com/arduino-libraries/MIDIUSB
MedianFilterLib:
https://github.com/luisllamasbinaburo/Arduino-MedianFilter

 */ 

#include "MIDIUSB.h"
#include "MedianFilterLib.h"


// Si quieres puedes añadir mas controles :)
const int numBotones=7;
const int numPotes=2;

int nota[]={59,57,55,53,52,50,48}; // Array con las notas en un orden diferente al de conexion 
int valorLeido[numBotones];    // Array con los valores leidos de cada boton
int valorAnterior[numBotones]; // Array con el valor anterior leido
int analogLeido[numPotes];    // Array con los valores leidos de cada boton
int analogAnterior[numPotes]; // Array con el valor anterior leido
int analogEscalado[numPotes]; // Array para guardar los valores de los potenciometros escalados
MedianFilter<int> medianFilter(20); // Inicia el filtro de mediana con una ventana de 10


void setup() {
  for(int i=0; i<numBotones; i++){
    pinMode(i+2, INPUT_PULLUP);// Recorremos cada pin y lo ponemos como entrada
    valorAnterior[i]=1;        // Inicializamos el valor anterior a 1 (no pulsado)
  }
}


void loop() {
  // Escaneo de pulsadores
  for(int i=0; i<numBotones; i++){ //
    valorLeido[i]=digitalRead(i+2); // Leer pulsador
    // Solo enviamos cuando ha existido un cambio
    if((valorLeido[i]==0) && (valorLeido[i]!=valorAnterior[i])){
      noteOn(0, nota[i], 64); // Activa nota correspondiente a cada pin 
      MidiUSB.flush();
    }
    else if ((valorLeido[i]==1) && (valorLeido[i]!=valorAnterior[i])){
      noteOff(0, nota[i], 64); // Desactiva nota correspondiente a cada pin 
      MidiUSB.flush();
    }
    valorAnterior[i]=valorLeido[i]; // El valor leido pasa a ser valorAnterior para el proximo ciclo
  }
  // Escaneo de potenciometros
  for(int i=0; i<numPotes; i++){
    // Se toman 30 muestras consecutivas de cada puerto analogico 
    for(int j=0;j<30;j++){
      medianFilter.AddValue(analogRead(i)); // Se agregan los valores analogicos al filtro de mediana movil
    }
    analogLeido[i]= map(medianFilter.GetFiltered(), 0, 1023, 127, 0); // El valor filtrado se acondiciona 
    // Verificamos si hay cambio en el potenciometro
    if(analogLeido[i]!=analogAnterior[i]){
      controlChange(0, i, analogLeido[i]); // Envia el valor del potenciometro que ha cambiado de estado
      MidiUSB.flush();
    }
    analogAnterior[i]=analogLeido[i]; // El valor analogLeido pasa a ser el analogAnterior para el proximo ciclo
  } 
}

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

Publicar un comentario

0 Comentarios