jueves, 14 de enero de 2016

Arduino MIDI piano LED


Arduino, MIDI, teclado, y Leds


Hola amigos!

La idea es que se enciendan los leds al compás de las notas midi y poder aprender a tocar el piano.
Para esto hace falta:
Una placa Arduino Uno (en mi caso),
Una interface USB-MIDI como el HSR 2.0,
Un opto acoplador para el HSR2.0 de la foto 2,
6 chips 74HC959,
48 LEDs de 5mm, 20 verdes para las teclas negras y 28
amarillos para las techas blancas (una blanca quedó afuera, sorry…).
Resistencias varias.
Y por supuesto un teclado que no tiene ninguna conexión con el Arduino por lo que también funciona para un piano de madera.
En mi caso utilicé un teclado del tipo “Generador de Eventos MIDI” por lo que por sí mismo no genera sonido alguno y lo tengo que conectar al PC y ejecutar algún programa DAW como el Cubase para que finalmente pueda funcionar mi teclado.

Es necesario una PC con dos puertos USB libres como mínimo.
Un USB para el Arduino que una vez cargado el sketch sólo se utiliza para alimentación, y el otro USB es para la salida MIDI al HSR2.0.
Como el Arduino no posee una interface MIDI nativa es necesario fabricar una según foto 2 y agregar la interface USB-MIDI HSR2.0.
NOTA: antes de fabricar interface óptica y usar el HSR2.0 probé SIN éxito muchos programitas como MidiYoke y otros similares.

En mi caso utilicé el programa CUBASE 7 que hay una versión libre que es útil para nuestros propósitos.
Hay muchos tutoriales en la web para aprender a usarlo.
En el Cubase se ejecuta un archivo “ .mid”, luego se silencian las pistas no deseadas.
Una vez que tenemos nuestra pista de midi elegida la copiamos en una nueva pista midi y seleccionamos el canal 2 (modificable desde el sketch) como salida donde está el HSR2.0 y el Arduino.
Se selecciona otra nueva pista en la cual vamos a ejecutar el piano o teclado. Entonces vamos a tener tres pistas en uso.

Aquí les dejo mi experiencia con la placa Arduino Uno junto con el integrado 74HC959 que es un chip que nos proporciona un registro de desplazamiento de 8 bit, ideal para este propósito.
He utilizado 6 de estos chips puestos en pares según el circuito de la foto 1.
Cada uno de los leds enciende en forma autónoma del resto y en el momento en que se hace presente la señal de la nota MIDI, pudiendo encenderse más de uno a la vez.
He utilizado como base para sostener los LEDs y los chips 74HC959 una tira de “Cable canal” que es un plástico blanco que se usa en electricidad para esconder los cables en las instalaciones eléctricas en los domicilios.
Para hacer los agujeros me resultó más simple marcar con marcador indeleble cada tecla del teclado y luego con un taladro de banco con una mecha de 5mm. De manera que los LEDs encajaran por presión sin necesidad de pegamento.

Aquí les dejo algunas fotos y videos:














Este sketch es el primer que he usado para comenzar con las pruebas. EL resto dependerá de las habilidad del programador:

 ------------------------------------------------------
/*
4 de OCTUBRE se el sketch de trabajo

no funka con dos notas a la vez

con led´s mas el 74HC595 por ahora uno sólo
para recibir datos por MIDI In
ver esquema conexion MIDI en el archivo:
   "MIDI salida del HSR al arduino.jpg"
mas el otro que falta hacer...
http://arduinobuenosaires.blogspot.com.ar/2016_01_01_archive.html

*/
int latchPin = 8; //Pin connected to ST_CP of 74HC595
int clockPin = 12; //Pin connected to SH_CP of 74HC595
int dataPin = 11; //Pin connected to DS of 74HC595
int notaled = 0; //notaled es mi varialble para las notas
int tecla = 0;

byte commandByte;
byte noteByte;
byte velocityByte;

byte noteOn = 144;

void setup(){
  Serial.begin(31250);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

}

void checkMIDI(){
  do{
    if (Serial.available()){
      commandByte = Serial.read();//read first byte
      noteByte = Serial.read();//read next byte
      velocityByte = Serial.read();//read final byte
      if (commandByte == noteOn)//if note on message
        //check if note == 60 and velocity > 0
        if (noteByte == 60 && velocityByte > 0){
          tecla = 60;
        }
        if (noteByte == 61 && velocityByte > 0){
          tecla = 61;
        }
        if (noteByte == 62 && velocityByte > 0){
         tecla = 62;
        }
        if (noteByte == 63 && velocityByte > 0){
          tecla = 63;
        }
        if (noteByte == 64 && velocityByte > 0){
          tecla = 64;
        }
        if (noteByte == 65 && velocityByte > 0){
          tecla = 65;
        }
        if (noteByte == 66 && velocityByte > 0){
          tecla = 66;
        }
        if (noteByte == 67 && velocityByte > 0){
          tecla = 67;
        }
        if (noteByte == 68 && velocityByte > 0){
          tecla = 68;
        }
    }
  }
  while (Serial.available() > 24);//when three bytes available
}
   
void loop(){
  checkMIDI();
    int bitToSet = tecla - 59;
    registerWrite(bitToSet, HIGH);
   
  }
 
void registerWrite(int whichPin, int whichState) {
  byte bitsToSend = 0;
  digitalWrite(latchPin, LOW);
  bitWrite(bitsToSend, whichPin, whichState);
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
  digitalWrite(latchPin, HIGH);

delay(100);
 
 
  //estas cuatro lineas son para APAGAR los LED's
   // tecla = 19;
    //registerWrite(bitToSet, LOW);
    //bitsToSend = 19;
    //digitalWrite(latchPin, HIG);
    //shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
    //digitalWrite(latchPin, HIGH);
  
   
}

------------------------------------------------------------------------------------

Este sketch es el segundo que he usado para comenzar:

*
OK OK con 3 led´s en los PIN 13,7,2
enciende y apagan OK OK

para recibir datos por MIDI In
ver la pag. para copiar  el esquema
OK OK
ver esquema archivo:
   "MIDI salida del HSR al arduino.jpg"
http://arduinobuenosaires.blogspot.com.ar/2016_01_01_archive.html

*/
byte commandByte;
byte noteByte;
byte velocityByte;
byte noteOn = 144;

void setup(){
  Serial.begin(31250);
  pinMode(13,OUTPUT);  //SI
  digitalWrite(13,LOW); //arranca apagado
       pinMode(12,OUTPUT);
  digitalWrite(12,LOW);
       pinMode(8,OUTPUT);
  digitalWrite(8,LOW);
       pinMode(7,OUTPUT); //SI
  digitalWrite(7,LOW);
       pinMode(4,OUTPUT);
  digitalWrite(4,LOW);
       pinMode(2,OUTPUT); //SI
  digitalWrite(2,LOW);
}
void checkMIDI(){
  do{
    if (Serial.available()){
      commandByte = Serial.read();//read first byte
      noteByte = Serial.read();//read next byte
      velocityByte = Serial.read();//read final byte
      if (commandByte == noteOn)//if note on message
        if (noteByte == 60 && velocityByte > 0){
          digitalWrite(13,HIGH);} //prende el led
        if (noteByte == 61 && velocityByte > 0){
          digitalWrite(12,HIGH);}//prende el led  
        if (noteByte == 62 && velocityByte > 0){
          digitalWrite(8,HIGH);}//prende el led 
        if (noteByte == 62 && velocityByte > 0){
          digitalWrite(7,HIGH);}//prende el led     
        if (noteByte == 64 && velocityByte > 0){
          digitalWrite(4,HIGH);}//prende el led   
        if (noteByte == 64 && velocityByte > 0){
          digitalWrite(2,HIGH);}//prende el led
    }
  }
  while (Serial.available() > 24);//when three bytes available
}
void loop(){
  checkMIDI();
  delay(20);
  if (commandByte == 128 && noteByte == 60) (digitalWrite(13,LOW)); //apaga el LED
  if (commandByte == 128 && noteByte == 62) (digitalWrite(7,LOW)); //apaga el LED
  if (commandByte == 128 && noteByte == 64) (digitalWrite(2,LOW)); //apaga el LED
}
















2 comentarios:

  1. Este comentario ha sido eliminado por un administrador del blog.

    ResponderEliminar
  2. Hola,impresionante tu proyecto
    Necesitaría hacer algo parecido con 20 salidas a 5 v
    Podrías ayudarme?
    Gracias

    ResponderEliminar