Hacer un teclado MIDI a partir de un sintetizador para niños viejos

imagen

Un día, volviendo a casa, cerca del vertedero de basura en la entrada, vi un sintetizador de juguetes para niños viejos. Pasé por alto, ya que era "pecaminoso" sacarlo de la basura, pero en mi corazón quería sacarlo de allí. Ya a altas horas de la noche, alrededor de las 2 en punto, decidí ver si ella todavía estaba parada allí. ¡Y sí, ella todavía estaba allí! En apariencia, estaba completamente completa y limpia, por lo que no había aprensión para no tomarla. Entonces sí, la llevé.

Hace tiempo que quería un piano para mí, no soy músico profesional, pero solo para complacerme, ¿por qué no? Al comprar algo "por el mimo" me "estranguló un sapo", y aquí, un juguete gratis. Cuando lo saqué de la basura, ni siquiera pensé en usarlo como un juguete para niños, inmediatamente pensé: "Ohhhh ... una buena base para intentar hacer un teclado MIDI".
Como ya tengo cierta experiencia en la comunicación con teclados profesionales y teclados MIDI, entendí de inmediato todas las desventajas de mi idea. Es decir, un juguete seguirá siendo un juguete. Sobre esta base, será imposible darse cuenta del poder de las pulsaciones de teclas. Las propias teclas de plástico "livianas", que también están incompletas, no permitirán realizar algo que valga la pena.

En primer lugar, el sintetizador de juguetes se desmontó "al tornillo", todo el plástico se lavó bien con jabón. Los tableros y los grupos de contacto de llaves también se limpian.

Después del desmontaje, se comprendió por qué la gente lo tiró. Un juguete (no sé por qué: de vez en cuando, por la calidad de los componentes chinos o por un funcionamiento difícil) en primer lugar: los altavoces incorporados se desmoronaron, y en segundo lugar: un conector roto de ellos se clavó en la toma de auriculares, por lo que prácticamente no había forma de sacarlo . Probablemente, después de que el juguete dejó de jugar con los altavoces incorporados, lo usaron con auriculares, y luego, después de que rompieron el conector allí, simplemente lo tiraron.

En el interior, el sintetizador de juguete constaba de tres tableros que estaban interconectados por un bucle de cable. La placa central, que era responsable de generar sonido y otras cosas, se soltó inmediatamente de las otras dos placas y se dejó a un lado. En los otros dos tableros había contactos para los botones en el panel frontal del juguete y las teclas del piano. Les soldeé los conectores PBS, especialmente porque el paso del agujero en las placas era de solo 2,54 mm.





Después de eso, pasé un par de horas dibujando diagramas de estos tableros con llaves. Al final resultó que, el esquema es un teclado de matriz simple.



En la imagen en círculos amarillos, los números son los números de los contactos "horizontales", y los números en las teclas son los números de los contactos "verticales" en el conector PBS-13 en la placa del teclado.







Después de eso, todo esto fue arrojado a una esquina y desempolvado durante un año. Y luego comenzó el período de autoaislamiento ... Se volvió aburrido y quise hacer algo con mis propias manos, especialmente porque no hay a dónde ir, y es imposible ...

Al final, decidí tratar de terminar este juguete al menos un poco. La placa Arduino se tomó como base para el controlador, y dado que la cantidad de llaveros es mayor que la cantidad de pines Arduino UNO, decidí usar los registros de desplazamiento 74HC595 y 74HC165. Como resultado, obtuvimos tal esquema.



El circuito se ensambló originalmente en una placa de prueba sin soldadura. Para probar la operabilidad del circuito (que no hay errores en las conexiones en ninguna parte), se desarrolló un programa de prueba que mostró que todo parecía funcionar. El algoritmo del programa de prueba era simple: una de las salidas del chip de salida de cambio se activa y los valores se leen en un ciclo desde el chip de entrada de cambio, mientras se presionan las teclas. A primera vista, nada presagiaba problemas ... y todo parecía funcionar bien ...



Los siguientes días, lentamente trabajé en "tarea", es decir, soldar cuidadosamente todos los componentes del tablero en una placa de pruebas. Lo recogí todo de lo que estaba en mi casa. Tomó el Arduino NANO como tablero de control.



Tal "emparedado" de las tablas se debe al hecho de que las dos tablas del juguete (una con botones y la otra con el teclado) se encuentran en diferentes niveles, y antes de soldarlo todo pensé: "¿Es posible conectarlo de alguna manera? ¿Qué componentes tengo en casa para parecer más o menos buenos? Y así resultó este diseño de dos placas interconectadas por conectores. Desde mi punto de vista, para la opción de casa, cuando nos sentamos en autoaislamiento, resultó bastante bien. Todo lo que tenía que hacer era cortar la placa de pruebas y modificar ligeramente el cuerpo del juguete para poder conectar el cable USB a la placa Arduino.



Al finalizar el programa de prueba, me di cuenta de que el dispositivo no funciona exactamente como quería. El algoritmo era simple: encienda cada salida del chip 74HC595, teniendo en cuenta el estado de las entradas del chip 74HC165, y escriba el resultado en variables separadas. En total, 5 salidas del 74HC595 están conectadas al teclado, por lo que al final obtuve 40 bits (5 * 8) de datos después de esta encuesta. Se emitió una cadena de 40 bits a la consola y se presionaron las teclas para ver cómo el dispositivo maneja las pulsaciones simultáneas de varias teclas.



Aquí es donde surgió el problema: si presiona una tecla, todo estaba bien, pero cuando intenta presionar más de 2 teclas al mismo tiempo, surgió una situación en la que era imposible predecir lo que se leería. El resultado podría ser correcto con una combinación, y con otra podría ser completamente impredecible. El problema era que la característica de este esquema no se tenía en cuenta. Cuando se presionan varias teclas al mismo tiempo, no solo se bloquean varias verticales del escaneo del teclado (esto está permitido), sino que se pueden cerrar varias líneas horizontales a través de las teclas (lo que de ninguna manera está permitido). Puede leer más sobre este problema y cómo resolverlo aquí.

Elegí la "solución cardinal" del problema, a saber: decidí que para cada tecla del teclado habrá un diodo.

En mi cabeza, ya comencé a pensar mentalmente cómo tendría que cortar las pistas en el tablero y colocar el diodo en el caso de SMD en la brecha. Subí a mis cuartos de almacenamiento y vi que simplemente no tenía tantos diodos en el caso de SMD (no olviden que todos nos sentamos en el autoaislamiento e ir a la tienda por componentes de radio no es muy posible, ya que estos definitivamente no son bienes esenciales). Un poco molesto, decidí mirar más de cerca la placa: puede ser posible colocar diodos de salida en algunas de las pistas (también tuve algunas). Y luego vi que cada tecla tiene un puente (la placa es de un solo lado) y el circuito está hecho para que en lugar de este puente pueda poner un diodo. Inmediatamente pensé: ni siquiera tiene que cortar nada, solo tiene que poner diodos de salida en lugar de puentes en todas partes.Tampoco tenía tantos diodos de salida. Un pensamiento cruzó por mi cabeza: "¿quizás LED?" El circuito funciona a + 5V y si coloca LED rojos que tienen una caída de voltaje mínima (entre los LED), al final debe haber un nivel lógico para la determinación correcta: la tecla se presiona o no.



Con esto en mente, volví a subir a mis acciones y agarré los LED rojos de donde sea posible. ¡Había exactamente tantas como las teclas del teclado! Esta es una señal, pensé, y soldamos varios LED en lugar de puentes para probar. Los resultados de la prueba mostraron que la solución está funcionando. Después de eso, soldeé los LED restantes en lugar de los puentes. El programa de prueba mostró que puede presionar al menos todas las teclas al mismo tiempo, y todas se leen correctamente.



Decidí no poner diodos en los botones adicionales que están en el juguete, porque es poco probable que sean presionados por varias piezas a la vez. Además, en el programa todavía no tengo procesamiento para hacer clic en estos botones. Bueno, todavía no he decidido cómo usarlos.

Ha llegado el momento de descubrir cómo hacer que este dispositivo aparezca en su computadora como un teclado MIDI y en qué formato necesita enviar datos.

La información que se encuentra en Internet me dijo que es posible hacer un teclado MIDI de Arduino de manera muy fácil y sencilla simplemente agregando firmware, lo que hará que la computadora lo vea no como un puerto COM, sino como un teclado MIDI. Inicialmente, me guié por esta decisión , no particularmente en cómo se implementa.

Ahora, cuando llegué a él y lo leí cuidadosamente, me di cuenta de que mi placa Arduino NANO no sería adecuada para esta solución, ya que tenía un puerto COM basado en el chip CH340. Para usar el firmware del enlace anterior, solo son adecuadas las tarjetas que ya tienen un puerto USB en el controlador (por ejemplo: AtMega32u4) o la comunicación a través del puerto COM no se realiza en chips de conversión de tipo FT232RL o similares, sino en microcontroladores AtMega. Por lo tanto, el firmware de la placa debe enviar los datos en formato MIDI al puerto COM, y en la computadora deberá instalar y configurar el software que interceptará estos datos y los transmitirá al puerto MIDI virtual.
El algoritmo para leer teclas y generar comandos MIDI fue el siguiente:



El programa para el controlador Arduino NANO ahora se ve así.
//    +5V
//   ST_CP  74HC595
#define latchPin      11
//   SH_CP  74HC595
#define clockPin      13
//   DS  74HC595
#define dataPin       12

//     +5V
#define latchPin_IN   9
#define clockPin_IN   10
#define dataPin_IN    8

// ,       1-16    
#define BUT_OUT0      7
#define BUT_OUT1      6
#define BUT_OUT2      5
#define BUT_OUT3      4

byte but_out[4] = {BUT_OUT0, BUT_OUT1, BUT_OUT2, BUT_OUT3};
//       
byte kbd_in[5] = {0, 0, 0, 0, 0};
byte kbd_in_new[5] = {0, 0, 0, 0, 0};

//       
byte btn_in[4] = {0, 0, 0, 0};
byte btn_in_new[4] = {0, 0, 0, 0};

//  3  -   (1 - , 0 - )
byte kbd_out = 0b11100000;

//  
void init_electronics() {
  //  ,   +5V
  //  OUTPUT
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  //  ,   +5V
  pinMode(latchPin_IN, OUTPUT);
  pinMode(clockPin_IN, OUTPUT);
  pinMode(dataPin_IN, INPUT);

  //          
  for (byte i = 0; i < 4; i++) pinMode(but_out[i], OUTPUT);
}

//      74HC595
void write_5V(byte a) {
    digitalWrite(latchPin, LOW);
    //    dataPin
    shiftOut(dataPin, clockPin, MSBFIRST, a); 
     //"" ,      
    digitalWrite(latchPin, HIGH); 
}

void read_5V(byte *btn, byte *kbd) {
  digitalWrite(clockPin_IN, HIGH);
  digitalWrite(latchPin_IN, LOW);
  digitalWrite(latchPin_IN, HIGH);
  
  //    -    
  *btn = shiftIn(dataPin_IN, clockPin_IN, LSBFIRST);
  
  //    -    
  *kbd = shiftIn(dataPin_IN, clockPin_IN, LSBFIRST);
}

void setup() {
  init_electronics();
  write_5V(kbd_out);
  Serial.begin(115200);
}

//       ,   
void read_kbd_and_btn_state(byte *btn, byte *kbd) {
 byte tmp;
  for (byte i = 0; i < 5; i++) {
    write_5V(kbd_out | (1 << i));
    read_5V(&tmp, &kbd[i]);
  }
}

void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

//     num  ,   
// 0 -  0,  0
// 1 -  0,  1
// 2 -  1,  1
// 3 -  1,  0
byte compare_bit(byte old_state, byte new_state, byte num) {
  byte tmp_old, tmp_new;
  tmp_old = (old_state >> num) & 1;
  tmp_new = (new_state >> num) & 1;
  if ((tmp_old == 0) && (tmp_new == 0)) return 0;
  if ((tmp_old == 0) && (tmp_new == 1)) return 1;
  if ((tmp_old == 1) && (tmp_new == 1)) return 2; 
  if ((tmp_old == 1) && (tmp_new == 0)) return 3;  
}

void loop() {
  read_kbd_and_btn_state(btn_in_new, kbd_in_new);
  for (byte i = 0; i < 5; i++) {
    for (byte j = 0; j < 8; j++) {
      switch (compare_bit(kbd_in[i], kbd_in_new[i], 7 - j)) {
        //  
        case 1: noteOn(0x90, 0x1D + (8 * i + j), 0x7F);
                break;
        //  
        case 2: //noteOn(0x00, 0x1D + (8 * i + j), 0x7F);
                break;
        //  
        case 3: noteOn(0x90, 0x1D + (8 * i + j), 0x00);
                break;
      }
    }
    kbd_in[i] = kbd_in_new[i];
  }
} 


No tiene sentido pintar en detalle cómo trabajar con datos MIDI, porque se puede leer aquí.

Me detendré en más detalles sobre el software para la computadora y los problemas que encontré. Surgieron problemas, simplemente debido a la falta de documentación normal para este software. Entonces, para que la computadora pueda recibir con éxito datos MIDI de un dispositivo como el mío, necesitará dos programas: loopMIDI y Serial-Midi Converter . Para Serial-MIDI Converter, también necesita instalar Java, si no está instalado en la computadora.

Iniciamos el programa loopMIDI y creamos dos puertos virtuales. Los llamé Arduino IN y Arduino OUT. Este programa será un dispositivo MIDI virtual.



A continuación, ejecute el convertidor Serial-MIDI y, al inicio, realizaremos el proceso de configuración. Desafortunadamente, debe hacer esto cada vez que lo inicia, pero no da mucho miedo, se hace literalmente con cuatro pulsaciones de teclas en el teclado. El número de puerto COM puede ser diferente; aparece en la computadora cuando se conecta la placa Arduino NANO. La velocidad del puerto se establece en el firmware Arduino NANO. Las flechas rojas indican mi configuración, en la que todo funcionó para mí.



En realidad, el proceso de configuración se ha completado y ya puede utilizar algún software que reproducirá sonidos al aceptar las pulsaciones de teclas del dispositivo. En la configuración del software, debe seleccionar "Arduino_OUT" como entrada. En la imagen a continuación, un ejemplo de configuración de Kontakt Player.



En última instancia, funciona así:


¿Que sigue? Y luego todo sucedió exactamente como esperaba: el juguete sigue siendo un juguete con exactamente todas las deficiencias que mencioné al principio. Probablemente, el niño tocará este en un zumbido, pero para un adulto, después de los teclados normales ... Es más fácil comprar cualquier teclado MIDI usado a bajo precio y será mucho mejor que este juguete. Decidí dejar este juguete como está, pero realizo algunas modificaciones:

  1. Deja el estuche original.
  2. Coloque altavoces que funcionen y haga un amplificador para ellos.
  3. Haga que funcione en el modo "juguete para niños" sin conectarse a una computadora, es decir, para que pueda reproducir sonidos por sí mismo.
  4. Haga posible conectar FootSwitch (el mismo pedal en el piano a continuación) para que pueda mantener el sonido después de soltar las teclas, como en un instrumento normal.
  5. , .
  6. , -, .



No puedo hacer la implementación de la mayoría de los puntos, mientras todos estamos juntos "en casa", ya que simplemente no tengo todos los componentes necesarios para esto en casa.

Para implementar el párrafo 3 en Internet, se encontró una solución llamada SamplerBox . La esencia del proyecto es que puede conectar cualquier teclado MIDI a la placa Raspberry Pi, que procesa comandos MIDI desde el teclado y reproduce sonidos o conmuta instrumentos, etc. Solo queda colocar la placa Raspberry Pi dentro del cuerpo del juguete, sin la posibilidad de reemplazar la tarjeta SD (sin desmontar la carcasa), configurar los botones en el cuerpo del juguete para que cambien las herramientas y esto será suficiente para dejar este proyecto en esta forma.

Pero todo esto sucederá después de que termine el período de autoaislamiento.

Espero que alguien encuentre útil mi experiencia.

All Articles