
Archivos del proyecto
¿Qué es MIDI? ¿Para qué sirve?
MIDI (Musical Instrument Digital Interface) es un protocolo de comunicación serial que permite conectar ordenadores, sintetizadores, controladores y demás elementos destinados a la creación de sonidos. Dicho protocolo data de los años ochenta pero aún se sigue usando hoy en día y de manera muy extendida, nos podemos encontrar gente que lo usa hasta para controlar luces y servo motores por ejemplo.
Este es un ejemplo de controlador MIDI comercial, el cual posee una salida USB para conectar al ordenador.
Lo que haremos será usar varios botones conectados al Arduino que leerá cuando se pulsan. En el caso de que se pulse uno haremos que Arduino envié a nuestro ordenador por medio del cable USB unos datos indicando que botón ha sido pulsado y qué nota debe enviar (un Do, un Re,…). Una vez en el ordenador deberemos usar algún programa como Touchdesigner, que interpretará los datos MIDI recibidos, para tener control de algún parámetro dentro de nuestro sistema. Este último paso es importante ya que MIDI es solamente un protocolo.
Como Arduino no es un dispositivo pensado para estos fines, no puede ser reconocido por los programas mencionados anteriormente como si fuera un dispositivo midi comercial. Una de las formas es emplear unos convertidores Serial a MIDI y unos puertos virtuales (cosa muy extendida por Internet, como HairLess y MidiYoke). Sin embargo, lo que vamos a hacer es reflashear nuestro Arduino UNO con un nuevo firmware llamado Hiduino, lo que nos permitirá crear un dispositivo «Plug & Play» como si fuera un controlador MIDI comercial.
Manos a la obra, necesitaremos:
- Pulsadores
- Resistencias 10k Ohm
- Arduino UNO/Mega y cable USB (Original)
- ProtoBoard
- Programa Arduino
- Flip Software
- Hiduino Firmware
- Librería MIDI
- Touchdesigner
Protocolo MIDI
Los mensajes MIDI tienen dos componentes:
Comandos
Le dice al instrumento MIDI qué tipo de mensaje se está enviando y en qué canal MIDI,
Bytes de datos
Almacenan los datos reales.
- Un byte de comando podría decirle a un instrumento MIDI que tiene información sobre una nota, y los siguientes bytes de datos describirán qué nota y qué tan fuerte.
- Un byte de comando también podría decirle a un instrumento MIDI que va a enviar información sobre pitchbend, luego los siguientes bytes de datos describirían cuánto pitchbend.
- Un byte de comando y los bytes de datos que le siguen forman un ‘mensaje MIDI’.
- Un byte es un tipo de datos (otros tipos de datos son int, boolean y long).
- Los bytes almacenan enteros positivos entre 0 y 255.
- Los mensajes MIDI se componen de una serie de bytes y se pueden decodificar en función de su valor para comprender lo que significan.
Aquí hay una lista de bytes de comando comunes en su forma decimal (base diez):
Nota desactivada = 128
Nota activada = 144
Pitchbend = 224
Los bytes de comando son siempre mayores que 127 y los bytes de datos siempre están entre 0 y 127, de hecho, así es como un instrumento MIDI puede distinguir entre un byte de comando y un byte de datos. Así es como enviaríamos un mensaje MIDI para activar Middle C con un volumen alto:
144, 60, 127
El primer número, 144, es el byte de comando, le dice al instrumento MIDI que este mensaje MIDI es un mensaje Note On.
El segundo número, 60, es un byte de datos.
El primer byte de datos en un mensaje de Note On MIDI es ‘note’ – este comando Note On activa la nota MIDI 60 (C central, puede encontrar una lista de conversiones de nota / MIDI aquí).
El último número también es un byte de datos, el segundo byte de datos en un mensaje Note On MIDI es ‘velocidad’, que se utiliza para controlar el volumen de una nota. Dado que los bytes de datos están entre 0 y 127, 127 es el volumen máximo de una nota.
Cada nota MIDI comienza con un mensaje Note On y termina con un mensaje Note Off. Algunos instrumentos de percusión sonarán como si se hubieran apagado si los mantienes presionados durante mucho tiempo, pero en realidad no se apagarán hasta que envíes un mensaje de nota desactivada. Es importante recordar desactivar una nota antes de intentar activarla nuevamente para evitar resultados inconsistentes. Hay dos formas de desactivar una nota MIDI, la primera es usando un comando Note Off:
128, 60, 0
Este comando apagará la nota 60, comienza con el byte de comando para Note off, establece note = 60 y velocity = 0 (la velocidad generalmente no es muy notable para Note Off, cualquier número que desee elegir está bien). También puede desactivar una nota enviando un mensaje Note On con velocidad = 0:
144, 60, 0
Este es un enfoque más común en MIDI, por lo que trataremos con Note Off en este tutorial.
Si está interesado en aprender más sobre el protocolo MIDI, el binario y los bits, consulte este artículo y esta tabla.
1. Realizar conexiones
Pero vayamos paso a paso, lo primero conectar los 11 botones. Como podéis ver la conexión es muy sencilla, conectamos cada botón entre GND y el pin correspondiente (del 2 al 12). Para que pueda funcionar así, será necesario habilitar las resistencias de pullup internas (se hace desde el código). Ojo si usáis el pin 13, que requiere una resistencia de pullup externa.
2. Introducir código prueba (no es MIDI)
Vamos a cargar un código que verifique el correcto funcionamiento de todos los botones. Aún no hemos empezado con MIDI.
/** Alvaro Lopez Revuelta para http://geekytheory.com/ http://alvarorevuelta.net/ Este ejemplo es para ver en el monitor serial los botones pulsados/despulsados En el siguiente ejemplo veremos como enviar midi Ojo con usar mas de 11 botones empleando la resistencia de pullup interna Para el pin 13 debe usarse una resistencia de pullup externa */ const int numBotones=11; // Definir aqui el numero de botones (11 max) int valorLeido[numBotones]; // Array con los valores leidos de cada boton int valorAnterior[numBotones]; // Array con el valor anterior leido void setup() { Serial.begin(9600); // Inicializamos la comunicacion serial 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(){ for(int i=0; i<numBotones; i++){ valorLeido[i]=digitalRead(i+2); // Leer valor // Solo enviamos cuando ha existido un cambio, para no sobrecargar el puerto serial if((valorLeido[i]==0) && (valorLeido[i]!=valorAnterior[i])){ Serial.print("Pulsado el boton: "); Serial.println(i); Serial.println("------------"); } else if ((valorLeido[i]==1) && (valorLeido[i]!=valorAnterior[i])){ Serial.print("Ya no el boton: "); Serial.println(i); Serial.println("------------"); } valorAnterior[i]=valorLeido[i]; // El valor anterior es el nuevo valor para la siguiente iteracion } }
Ahora abrir el puerto serial con un baud rate de 9600 e ir pulsando y liberando los botones. Podréis ver como al pulsarlo se nos indica por el monitor serial que botón ha sido pulsado, y cuando se libera cual ha sido liberado. Hasta aquí no hemos hecho nada de MIDI, simplemente estamos testando el hardware e introduciendo el código que usaremos.
3. Vamos con MIDI
A continuación debemos cargar el siguiente código. Este código hace uso de la librería MIDI de Arduino. (Descargar la librería e instalarla).
Nos centraremos en el mensaje de NoteOn es decir, nota activada. Este mensaje lleva información de la nota pulsada (Do, Re,…), con que intensidad se pulsó esta nota (127 es el máximo, nosotros usaremos el máximo ya que nuestros botones no tienen sensibilidad) y en que canal MIDI se quiere enviar el mensaje (hay 16 disponibles). Cargamos el código:
#include // Incluimos la libreria MIDI /** * Alvaro Lopez Revuelta para http://geekytheory.com/ * http://alvarorevuelta.net/ * * Este ejemplo sirve para enviar midi a nuestro ordenador * Sera necesario emplear el firmware hiduino para que funcione correctamente * https://github.com/ddiakopoulos/hiduino * Ojo con usar mas de 11 botones empleando la resistencia de pullup interna * Para el pin 13 debe usarse una resistencia de pullup externa */ const int numBotones=11; int valorLeido[numBotones]; // Array con los valores leidos de cada boton int valorAnterior[numBotones]; // Array con el valor anterior leido MIDI_CREATE_DEFAULT_INSTANCE(); void setup() { MIDI.begin(); // Inicializamos la comunicacion midi (realmente es serial) 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(){ for(int i=0; i<numBotones; i++){ valorLeido[i]=digitalRead(i+2); // Leer valor // Solo enviamos cuando ha existido un cambio, para no sobrecargar el puerto serial if((valorLeido[i]==0) && (valorLeido[i]!=valorAnterior[i])){ MIDI.sendNoteOn(48+i, 127, 1); //48 corresponde a C es decir DO. } else if ((valorLeido[i]==1) && (valorLeido[i]!=valorAnterior[i])){ MIDI.sendNoteOff(48+i, 0, 1); } valorAnterior[i]=valorLeido[i]; // El valor anterior es el nuevo valor para la siguiente iteracion } }
Se puede apreciar que el código es muy parecido al anterior, solo que cuando se detecta botón pulsado/liberado se envía un mensaje de nota activada o desactivada. El valor de nota enviado por el primer botón es 48 que según el protocolo MIDI corresponde a DO. Por lo tanto el siguiente botón enviará DO Sostenido, el siguiente RE,…
Ahora ya no tiene sentido visualizar el puerto serial, ya que veremos caracteres sin aparente sentido. Lo que tenemos que hacer es que nuestro Arduino sea reconocido como un dispositivo MIDI, para lo que actualizaremos el Arduino con un nuevo firmware.
4. Reflasheando el Arduino con Hiduino. Archivos necesarios
Lo primero que deberemos hacer es localizar el firmware Hiduino Vayamos a la carpeta «Hiduino16U2» y localicemos el archivo que nos interesa «Hiduino16U2.hex«. Pon ese archivo en el escritorio por ejemplo, es simplemente por tener una ruta mas fácil para después.
A continuación necesitaremos que nuestro Arduino entre en modo DFU para que se nos permita introducirle el código. Es muy importante que hayáis cargado el código anterior (el del MIDI). Una vez que introducimos este nuevo firmware, no podemos volver a meter código en el Arduino, pero ¡tranquilos! que si volvemos a meter el firmware original de Arduino todo volverá a la normalidad (Se hace de manera idéntica a introducir cualquier firmware). Como he dicho hay que entrar en modo DFU con nuestro Arduino.
Para incorporar este archivo .hex vamos a instalar el software Flip,
les comparto un breve tutorial para realizar la instalación correctamente.
Desconecta y vuelve a conectar el cable del Arduino.
Ahora tu Arduino ya se comporta como si fuera un controlador MIDI comercial.
Touchdesigner MIDI
El simple hecho de iniciar Touch Designer y conectar un controlador MIDI generará una advertencia.
Primero, abra el Mapeador de Diálogos de Dispositivos MIDI.
Presione Crear nueva asignación y seleccione el nombre del dispositivo que desea usar para el dispositivo In recién creado.
Cambiemos la imagen presionando 4 botones.
Ingrese MidiIn CHOP para que FanCHOP sepa qué botón se está presionando.
FanCHOP-> Todos los canales desactivados: Establecer en -1
Use HoldCHOP para que el valor se actualice cuando se presione el botón.
Luego agregue +1 con mathCHOP y conecte a la entrada Trigger del operador hold.
Las imágenes se pueden cambiar conectando nullCHOP y haciendo referencia al valor índice de switchTOP.
Recomiendo investigar a los colegas Argentinos de Yaeltex, quienes crean sus propios controladores utilizando Arduino
http://wiki.yaeltex.com.ar/index.php?title=Yaeltex_Wiki
https://yaeltex.com
Fuentes:
https://geekytheory.com/arduinomidi-tu-propio-piano
https://www.instructables.com/id/Arduino-Sensors-and-MIDI/
https://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/