Teclado matricial para teclado midi

Saludos al foro este es mi primer mensaje :p. he estado buscando informacion de como hacer un teclado matricial que me reconozca almenos 30 teclas presionadas al tiempo (es para un proyecto midi), mediante integrados, o pic, o ambos. Intente hacerlo con unos diodos pero el voltaje se me cae, ademas de que los teclados profesionales no llevan diodos (wtf??).Alguen podria hacerme una sugerencia de como construir dicho teclado. (es de 8x8 es decir 64 teclas).

gracias
 
yo no tengo ni idea de todo esto,pero con un 555 y un condensador de un determinado valor ,y que cada tecla vaya asociada a una resistencia,para que cada una de un valor de frecuencia,si esque pueden salir mas de una frecuencia a la vez por el 555, y luego eso conectado a algo que reconozca las teclas por las distintas frecuencias... ahi llevas una idea.

se que no es muy coherente esto,y si es posible hacerlo,pero se me acaba de ocurrir.
 
Mi teclado CTK-230 si lleva diodos, separé la matriz y la conecté a un Arduino UNO y lo volví MIDI, todo usando solamente un 4094, como usé registros para almacenar las teclas podía detectar todas las que se presionaran (las 49 teclas), pero hice un desastre en el código que marea , todo por usar las Pull-Up internas en lugar de agregar los resistores, el circuito usa polling para revisar cada tecla, cuando una se detecta presionada se almacena en un registro y si anteriormente esta estaba sin presionar se envía el comando NOTE ON, luego sigue escaeando y cuando detecta que se ha liberado y el registro decía que estaba presionada es cuando se envía el comando NOTE OFF, el 4094 solo lo use para controlar las filas (o eran las columnas no me acuerdo :p), usando únicamente las señales de reloj y dato, solo ponía un bit y lo iba desplazando durante la exploración, así que las señales de latch y enable estaban activadas directamente.
En este videoapartir del 2:53 se ve una mini demostración donde se aprecia el protoboard solo con un chip, esto fue de cuando apenas había recibido el Arduino y fue lo primero que se me ocurre hacer para probarlo.
 

Adjuntos

  • CASIO CTK230 KEY MATRIX.pdf
    128.4 KB · Visitas: 43
Nuyel, muy bueno tu trabajo, tengo un yamaha psr200 y quisiera transformarlo en teclado MIDI, me podras pasar el codigo para cargar al arduino uno o poner algun videito mas detallado de como armaste todo paso a paso, me interesa mucho tu proyecto. Un saludo grande
 
Lamento decir que ando de viaje así que tanto el teclado como el Arduino están por otro lado, no tengo ni fecha para volver por ello, el código también está en la PC así que tampoco, igual habría de modificarlo y corregir, a mi se me complicó por querer usar las pull-ups internas en lugar de colocar las resistencias pull-down que hubieran facilitado el código, tendría que revisar entre los archivos que tengo en mi notebook esperando encontrar el código, pero no te lo garantizo.
 
que pena, pero bueno, por ahora empezare por armar la placa con la extension con el 4094, vere si puedo conseguir el codigo, algo de programacion conozco, pero mas que nada en visual basic. Espero que en una de esas puedas encontrar el codigo asi aprendemos de tu trabajo, igualmente un gran saludo
 
En teoría no se necesita el 4094 si se emplean los otros pines, pero eso me los dejaba libres para ocupar los análogos, por algún lado tengo un diagrama más extendido donde usaba unos 4066 para conmutar, la idea era dejar el Arduino y el circuito original en paralelo, asi no se interfería con la operación normal del teclado, veré si lo encuentro.

Otro detalle, no se usa Basic, es programado el el asesino y debe ser el Uno por que se tiene que cambiar el firmware del ATmega que controla la comunicación USB por un firmware que lo reporta como un dispositivo MIDI, del para el PC lo demás es , se instala en driver y trabaja como cualquier otro dispositivo MIDI.
 
Bueno esta era la parte importante del circuito:
Teclado.png

Respecto al código... al parecer un usuario me pidió los archivos y subí a Google Drive, te paso el link, el código en si es un desastre, usa las pullup internas así que se complicó debido a como se desplazaban los valores de las teclas, además no sabía usar Arduino ni había programado con matrices, en lugar de declarar matrices declaré variables independientes lo que lo hizo más largo que empleando un bucle con una matriz.

Hay muchas mejoras que se pueden hacer respecto a eso, te dejo un código reducido para emplear matrices, pero no garantizo que funcione, al menos compila pero no tengo mi Arduino para ni el teclado para probar.
Código:
/* Arduino USB MIDI demo */

#define D        0x80 //Comando desactivar nota
#define A        0x90 //Comando activar nota
#define PITCH    0xE0 //Comando para Pitch
#define Sustain  0x40 //Perdal de Sustain
unsigned int pitchWheel    = 0x2000; //Variable de para pitch wheel
unsigned int pitchRegister = 0x01FF; //Registro del pitch

/* Definiciones de notas */
#define nC2   0x24 //Octava 2
#define nC3   0x30 //Octava 3
#define nC4   0x3C //Octava 4 Valor de Do central
#define nC5   0x48 //Octava 5
#define nC6   0x54 //Octava 6Do final alto
unsigned char base = nC2;  //Octava base del teclado (nota más grave), cambiarlo permite correr las notas una octava

/* Pines Matriz*/
#define KI0 2
#define KI1 3
#define KI2 4
#define KI3 5
#define KI4 6
#define KI5 7
#define KI6 8

/* Pines Latch */
#define clock  9
#define data  10

/* Registro de Matriz*/
unsigned char KO[8] = {0,0,0,0,0,0,0,0};

unsigned char IndexKO = 0; //Indice de salidas
unsigned char IndexKI = 0; //indice de entradas

unsigned char Key = 0;     //Filtro de tecla
unsigned char velocidad = 127; //volumen de teclas
boolean sustain = false;
unsigned char N = 0x24;
/* Formato para enviar el comando [comando][canal][dato1][dato2] */
void nota(char comando, char canal, char dato1) //dato 2 es velocidad de la nota
{
  Serial.write(comando);
  Serial.write(canal);
  Serial.write(dato1);
  Serial.write(velocidad);
}
void Control(unsigned char control, unsigned char canal, unsigned char valor)
{
  Serial.write(0xB0); //Modo de Control
  Serial.write(canal);
  Serial.write(control);
  Serial.write(valor);
}

void setup();
void loop();
void SSClear()
{
  digitalWrite(data, HIGH);
  for(int i = 0; i < 8; i++){
  digitalWrite(clock, LOW);
  digitalWrite(clock, HIGH);
  }
  IndexKO = 0;
}
void Next()
{
  if (IndexKO == 0)
  {
    digitalWrite(clock, LOW);
    digitalWrite(data, LOW);
    digitalWrite(clock, HIGH);
    digitalWrite(data, HIGH);
  }
  else
  {
    digitalWrite(clock, LOW);
    digitalWrite(clock, HIGH);
  }
  IndexKO++;
  if (IndexKO == 8){IndexKO = 0;}
}
void setup() 
{
  pinMode(KI0, INPUT_PULLUP);
  pinMode(KI1, INPUT_PULLUP);
  pinMode(KI2, INPUT_PULLUP);
  pinMode(KI3, INPUT_PULLUP);
  pinMode(KI4, INPUT_PULLUP);
  pinMode(KI5, INPUT_PULLUP);
  pinMode(KI6, INPUT_PULLUP);

  pinMode(data, OUTPUT);
  pinMode(clock, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  SSClear();
  delay(1000);
  digitalWrite(13, LOW);
  KO[IndexKO] = 0;
}

void Scan() //Funcion para escanear la matriz y enviar las notas
{
  /**********************************************************************
  *                          Escaneo De Matriz                          *
  **********************************************************************/
  while(1)
  {
    
    Next(); //Inicio de escaneo
    N = base;
    IndexKI = 0x40;
    Key = KO[IndexKO] & IndexKI; //Reconocimiento para KI0
    if (digitalRead(KI0) == LOW) 
    {
      if (Key == 0){nota(A, 1, N); KO[IndexKO] |= IndexKI;}
    }
    else
    {
      if (Key != 0){nota(D, 1, N); KO[IndexKO] &= ~IndexKI;}
    }
    N += 8;
    IndexKI = IndexKI >> 1;
    Key = KO[IndexKO] & IndexKI; //Reconocimiento para KI1
    if (digitalRead(KI1) == LOW) 
    {
      if (Key == 0){nota(A, 1, N); KO[IndexKO] |= IndexKI;}
    }
    else
    {
      if (Key != 0){nota(D, 1, N); KO[IndexKO] &= ~IndexKI;}
    }
     N += 8;
    IndexKI = IndexKI >> 1;
    Key = KO[IndexKO] & IndexKI; //Reconocimiento para KI2
    if (digitalRead(KI2) == LOW) 
    {
      if (Key == 0){nota(A, 1, N); KO[IndexKO] |= IndexKI;}
    }
    else
    {
      if (Key != 0){nota(D, 1, N); KO[IndexKO] &= ~IndexKI;}
    }
    N += 8;
    IndexKI = IndexKI >> 1;
    Key = KO[IndexKO] & IndexKI; //Reconocimiento para KI3
    if (digitalRead(KI3) == LOW) 
    {
      if (Key == 0){nota(A, 1, N); KO[IndexKO] |= IndexKI;}
    }
    else
    {
      if (Key != 0){nota(D, 1, N); KO[IndexKO] &= ~IndexKI;}
    }
     N += 8;
    IndexKI = IndexKI >> 1;
    Key = KO[IndexKO] & IndexKI; //Reconocimiento para KI4
    if (digitalRead(KI4) == LOW) 
    {
      if (Key == 0){nota(A, 1, N); KO[IndexKO] |= IndexKI;}
    }
    else
    {
      if (Key != 0){nota(D, 1, N); KO[IndexKO] &= ~IndexKI;}
    }
    N += 8;
    IndexKI = IndexKI >> 1;
    Key = KO[IndexKO] & IndexKI; //Reconocimiento para KI5
    if (digitalRead(KI5) == LOW) 
    {
      if (Key == 0){nota(A, 1, N); KO[IndexKO] |= IndexKI;}
    }
    else
    {
      if (Key != 0){nota(D, 1, N); KO[IndexKO] &= ~IndexKI;}
    }
     N += 8;
    IndexKI = IndexKI >> 1;
    Key = KO[IndexKO] & IndexKI; //Reconocimiento para KI6
    if (digitalRead(KI6) == LOW) 
    {
      if (Key == 0){nota(A, 1, N); KO[IndexKO] |= IndexKI;}
    }
    else
    {
      if (Key != 0){nota(D, 1, N); KO[IndexKO] &= ~IndexKI;}
    }
    
    //Romper en index 7
    if(IndexKO == 7) break;
  }
}

void pitchControl()
{
  unsigned int Analogo;
  unsigned int tolerancia;
  unsigned char LSB;
  unsigned char MSB;
  Analogo = analogRead(A1);
  tolerancia = Analogo & 0x1E0;
  if (pitchRegister != tolerancia)
  {
    pitchRegister = tolerancia;
    Analogo = Analogo - 511;
    Analogo = Analogo * 15;
    pitchWheel = 0x2000 + Analogo;
    LSB = pitchWheel & 0x7F;
    MSB = (pitchWheel >> 7) & 0x7F;
    Serial.write(PITCH);
    Serial.write(1);
    Serial.write(LSB);
    Serial.write(MSB);
    /*Serial.print("Rueda: ");
    Serial.println(pitchWheel);
    Serial.print("MSB Hex: ");
    Serial.print(MSB, HEX);
    Serial.print(" LSB Hex: ");
    Serial.println(LSB, HEX);*/
  }
} 
void loop()
{
  int Analogo;
  Analogo = analogRead (A0); //Lectura de velocidad
  velocidad = Analogo / 8;   //Conversion de 10 a 7 bits
  Scan();                    //Escaneo de matriz*/
  //pitchControl();            //Lectura del control de pitch
}

Otra nota, los valores de KIx y KOx son según el diagrama de la matriz en mi teclado, el PDF con ese diagrama está más arriba. Suerte con intentarlo.


Aclaración extra:
Si bien se usan comando según el estándar MIDI, no se usa la velocidad MIDI que es a 31250baud como en el ejemplo MIDI del Arduino, es por motivos del firmware en el ATmega que controla la comunicación USB que funciona a 115,2KBaud/s, si planean usarlo con un dispositivo MIDI certificado tienen que cambiar la velocidad.
 
Última edición:
Nuyel, muchas gracias por molestarte en responder, voy a revisar tranquilo la info y el archivo comprimido que subiste, mas la info del codigo modificado, para ver lo que puedo hacer. Recien estoy en los comienzos en el tema programacion de microcontroladores, mi unica experiencia hasta ahora es la programacion de una placa similar a Pinguino con pic18f2550, que la estoy usando para correr un simulador de carreras de automoviles. Con arduino son mis primeros pasos. Mil gracias, seguramente te estare molestando nuevamente en cualquier momento, un saludo grande
 
Atrás
Arriba