Hace relativamente poco conseguí un teclado Toshiba HX-MU901 en muy buen estado, con su cartucho HX-MU900. Aunque no soy músico, de siempre me ha gustado la cuestión de las tecnologías musicales electrónicas. De hecho, en su día realicé el programa Simphony para MSX-1, y hacía mis pinitos con el Amiga 2000.
El HX-MU900 es un cartucho MSX-AUDIO que permite reproducir notas de un banco de instrumentos que lleva. Es muy sencillo, pero funciona bastante bien. No tiene sensibilidad de pulsación de tecla, pero para mi nivel no lo necesito :-). Tengo un sintetizador Kawai XS-1 y me pareció interesante estudiar si era posible conectar este teclado mediante MIDI. Y el resultado es el que relato en esta entrada del blog.
Además del HX-MU900, tengo el Philips NMS 1205 (conocido como el Philips Music Module) que también es MSX-AUDIO, al que se le puede conectar un teclado similar de Philips, que no tengo. El conector es también de tipo (IDC-20), pero el conexionado es distinto al del Toshiba. El Music Module tiene conexiones MIDI IN y OUT, aunque el programa que contiene su ROM no utiliza el MIDI IN. Me dejo pendientes dos manualidades: a) hacer un adaptador de un conector de teclado a otro (esto es trivial), b) hacer un programa MSX que utilice el MIDI IN del Music Module (esto es relativamente sencillo, ya que se puede deshabilitar el arranque del programa de la ROM del módulo, pero requiere decodificar los mensajes MIDI). En algún momento me gustaría poder conectar el teclado al programa Simphony.
El dispositivo
Los componente son sencillos y fáciles de encontrar. El trabajo de montaje es relativamente simple. La lista de componentes (BOM) es la siguiente:
- Adafruit Feather M0
- Adafruit Featherwing MIDI
- Adafruit Feather Quad 2x2
- Placa de prototipo PCB
- Tira de pines / Conector IDC-20 macho
Como mi objetivo es la funcionalidad, no me ha importado el coste ni el hacerlo compacto. Obviamente, para fabricar en serie habría utilizado otro procesador (aunque basado en el Cortex M0) y el resto iría en una PCB específica.
La única cuestión delicada es el conexionado. Lo mas complicado has sido encontrar precisamente el patinaje del conector. Tras muchos tumbos di con un documento (realizado por Ton Valkenburgh) con el esquema. El teclado es básicamente una matriz de filas y columnas, con 8 filas de entradas (IN0-IN7) y 10 columnas de salidas (OUT0-OUT9). Total 18 líneas. Por fortuna el Feather M0 tiene precisamente 18 pines libres que podemos usar como E/S, ya que tenemos que dejar 2 para el puerto serie necesario para la comunicación MIDI. La forma de leer este tipo de matrices es utilizando resistencias de pull-up en las entradas, por lo que he utilizado pines con pull-up interno para las líneas IN (y así me ahorro soldar resistencias). El conexionado final es el siguiente:
El montaje final es muy simple ya que sólo hay que montar el Feather M0, el interfaz MIDI y la placa de conexionado en la placa Quad. Aquí hay poco que comentar. El resultado es el siguiente.
El programa
El concepto del programa es muy simple. Comprobamos periódicamente el estado de las distintas teclas. Si detectamos algún cambio enviamos un mensaje MIDI noteOn (pulsamos tecla) o noteOff (soltamos tecla) con la nota correspondiente a la tecla. Y repetimos. De esta forma podemos registrar la pulsación simultánea de todas las teclas del teclado (otra cosa es que después el equipo que reciba pueda gestionar todas esas notas de forma simultánea). El código completo para el entorno Arduino está disponible en GitHub:
https://github.com/humbertomb/mymsx/blob/master/midi/FeatherMidiToshiba.ino
Las cuestiones más relevantes a cómo funciona el mismo las describo a continuación. Comenzamos con las estructuras de datos más importantes.
Los arrays in y out corresponden al patillaje de las entradas y salidas respectivamente. El array keys contiene los valores lógicos de la matriz de teclado (0 pulsado, 1 sin pulsar). El array de booleanos chan tiene a true aquellas teclas que han cambiado de valor. Por último el array notes contiene la correspondencia entre cada tecla pulsada y la nota o acción MIDI correspondiente. En este caso las 8 primeras columnas corresponden a las teclas del teclado (blancas y negras) y las últimas 2 columnas corresponden a las teclas del multi-sensor (pads coloreados sensibles al tacto).
El procedimiento de lectura de la matriz de teclas es genérico para este tipo de circuitos. La idea es ir activando secuencialmente las salidas, y para cada una hacer la lectura de las diferentes entradas, también de forma secuencial. La activación de cada salida se realiza configurando el puerto correspondiente como salidas y estableciéndola a nivel bajo. La lectura de cada entrada se realiza configurando el puerto correspondiente como entradas y habilitando su resistencias interna de pull-up. Posteriormente hay que hacer una espera de 0.05ms para permitir que la línea se estabilice, y posteriormente se realiza una lectura digital de dicho puerto. Con el valor de la lectura se actualizan las celdas correspondientes de los arrays chan y keys. Una vez realizada la lectura de una entrada se deshabilita su resistencia interna de pull-up. Cuando se termina de utilizar una salida, esta se configura como puerto de entrada.
El procedimiento de envío de los valores MIDI correspondientes es muy sencillo. Para ello utilizo la fantástica librería Arduino MIDI, de Forty Seven Effects. Hay que distinguir dos casos: a) el envío de las notas por pulsación de las teclas, b) envío de comandos de control por pulsación del multi-sensor. En el primer caso sólo hay que verificar qué teclas han cambiado de valor y enviar un noteOn o noteOff en función del valor del estado de la matriz de teclas. Como el teclado no tiene sensibilidad se envía el valor de presión fijo a 127 (máximo) y se utiliza el canal MIDI 1.
En el segundo caso sólo hay que verificar qué pads del multi-sensor han cambiado de valor y enviar los comandos MIDI correspondientes. En este caso sólo se utiliza el Program Change, que habitualmente sirve para cambiar el instrumento que se utiliza para reproducir el sonido. Se utiliza una variable global program que contiene el valor del programa seleccionado. Si se pulsa el pad amarillo, el valor de program se reduce 5 unidades. Si se pulsa el pad verde, el valor de program se reduce 1 unidad. Si se pulsa el pad azul, el valor de program se incrementa 1 unidad. Si se pulsa el pad violeta, el valor de program se incrementa 5 unidades.
El resultado
Considero que el objetivo se cumple razonablemente bien, con materiales que no son excesivamente caros, en torno a unos 40€. A continuación un sencillo vídeo de prueba.