Mini tutorial: Arduino + midi por usb

Buenas, este es mi primer post en el foro. Quería escribir en algún sitio el tutorial para conectar la arduino al PC enviando comandos MIDI por USB, porque es un proceso complicadillo y se me iba a olvidar... ya aprovecho para traducirlo porque no sé si hay algo de documentación al respecto en castellano.

Arduino trae unos drivers llamados FTDI USB Drivers. Estos drivers se utilizarán para la conexión entre la Arduino y el PC pero necesitamos otros para la conexión entre el puerto serie (usb es un puerto serie también) y un teclado virtual para poder configurar en nuestro software. Estos drivers se pueden conseguir desde la web de Roland, googleando un poco o directamente en:

http://www.roland.dk/Drivers/drivers/Software/MIDI_drivers/WinXp/Seriel/

Este es un hack de los bonitos, como el protocolo MIDI funciona a una velocidad de 31250 bps hay que modificar la configuración de los drivers FTDI para que admita esta velocidad. Lo que se hace normalmente es mapear los 38400 bps a 31250 y para ello hay dos formas:


  • Modificar el fichero FTDIPORT.inf de los drivers. Este fichero se lee al instalar los drivers y dice al instalador lo que hay que tocar, por ejemplo, en el registro. Se encuentra en la carpeta de drivers de la instalación de la arduino.

Hay que buscar [FtdiPort232.NT.HW.AddReg] y hay que cambiar la línea larga por:

HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,60,00,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00

Ojo, no dejar retornos de carro, todos los valores deben estar en una misma línea,separados por comas sin espacios.
Una vez modificado se guarda el fichero, se reinstalan los drivers y ya se podría continuar.

  • La otra manera es modificar directamente el registro. Ejecutando regedit.exe navegamos hasta

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\FTDIBUS\VID_0403+PID_6001+A400
1drJA\0000\Device Parameters]

Ojo que el "VID_0403+PID_6001+A4001drJA" no tiene por qué llamarse así, pero no hay muchas posibilidades así que elegid por intuición.

Se edita el campo ConfigData, cambiando directamente sus valores hexadecimales e introduciendo

11,00,3f,3f,10,27,00,00,88,13,00,00,c4,09,00,00,e2,04,00,00,
71,02,00,00,38,41,00,00,9c,80,00,00,60,00,00,00,34,00,00,00,1a,00,00,00,0d,
00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,d0,80,00,00

En realidad sólo cambia uno de los números pero repasad todos y os aseguráis.

Se reinicia el equipo y pasamos al siguiente paso. Sobra decir que con el regedit hay que tener cuidado... si no lo controláis mínimamente intentad el paso anterior.


Seguimos, en el gestor de dispositivos debemos tener dos objetos: Uno que instala el driver FTDI y otro de Roland. Ambos deben apuntar al mismo puerto serie (COM1, COM2...) esto me supuso a mí un par de reinicios del windows así que paciencia.

Hecho esto conecté el Reason, configuré un teclado estándar y ya podía elegir la entrada del driver de Roland.

Todo perfecto, ya tengo mi theremin por infrarrojos funcionando en reason. Esto es lo primero que salió según lo conecté:

Ahora habrá que hacer que modifique el pitch, no que toque notas, y tendré un theremin hecho y derecho.

Saludos.

Por cierto casi toda la información está sacada de aquí:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1161023163/0

Que sensor de infrarojos usas? puedes postear el codigo para ver de que manera capturas la latencia de los infrarojos?.

El Sharp GP2Y0A02YK, alcanza metro y medio, es el mejor de la gama, creo.

Para enviar un comando hay que hacer

  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);

O más cómodo:

void noteOn(char cmd, char data1, char data2) {
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);
}

Con eso y por ejemplo con esto:

http://guymal.com/techCorner/MidiReference.html

Puedes hacerlo todo. Por ejemplo, para modificar el pitch:

noteOn(0xe0, 0x10, 0xaa);

Lo suyo sería pasar el valor recogido de la entrada analógica y convertirlo a sus dos bytes, el LL (menos significativo) y el MM (más significativo).

No tengo el código completo porque la actualización crítica de windows ha hecho que no se guardara el código que ahora tengo en la Arduino pero ya haré otro y lo cuelgo.

Saludos.

Gracias por tu respuesta.