Como conectar teclado PS2 a arduino y Mostrar tecla apretada en leds??

Hola muy buenas tardes, tengo un proyecto final de electronica que me dejaron y no se por donde empezar espero que me puedan ayudar porfavor!!!!

el proyecto consiste en conectar un teclado PS2 a un arduino uno y que al aplastar cualquier tecla incluso usando el shift para ver los caracteres ocultos se muestre en una tira de 8 leds en codigo binario.

osea que cualquiera de los 256 caracteres de la tabla de codigo ASCII muestre el numero en los leds en codigo binario, osea leds prendidos y leds apagardos representando el numero correspondiente. ...
 
el teclado no usa codigo ascii aunque nuestra intuicion lo crea
usa otro protocolo buscalo como keyboard scancode
 
Busca las librerías de control del teclado, luego habría que hacer una tabla para convertirlo porque los scancodes parece que los pusieron una mañana de resaca tras una larga noche de borrachera; no tienen lógica ninguna.
 
pues peladito y en la voca lo veo dificil

debes aprender hacer las cosas y mas cuando son cosas complejas

la ventaja de arduino "para mi es una porqueria" es que esta escrito en un derivado del C
si tu buscas si la flojera no te gana, puedes buscar ejemplos escritos en C para otros micros como el AVR o los PIC
 
La ventaja de Arduino es que todo está peladito, en la boca, masticado, salivado y a media digestión.
Esa es LA ventaja de esa plataforma.
Mi recomendación es que busques el código para Arduino, es "Casi C" pero no "Ansi C".
 
ok, para que no digan que lo quiero peladito y en la boca ahí les va el código que ya he hecho, nada más que me da un error en el digitalWrite (j); del ciclo for anidado.

Código:
#define clock 3 //Este es el pin del teclado ps2 correspondiente al CLK
#define data 4  //Este es el pin del teclado ps2 correspondiente al DATA+
int teclado=0;
int j[10] ;
void setup(){
     pinMode(data, INPUT);
     pinMode(clock, OUTPUT);
     pinMode(6, OUTPUT);
     pinMode(7, OUTPUT);
     pinMode(8, OUTPUT);
     pinMode(9, OUTPUT);
     pinMode(10, OUTPUT);
     pinMode(11, OUTPUT);
     pinMode(12, OUTPUT);
     pinMode(13, OUTPUT);
}

void loop(){
  teclado = digitalRead(data);
  
   if(teclado == HIGH){
      digitalWrite(clock,HIGH);
      delay( 0.00045 ); 
   }
      else{
      for (int i=0; i<=10; i++){
        teclado=digitalRead(data);
        for (int j=0; i<=10; i++){
          digitalWrite(j[i]);
      
      }
      }
        digitalWrite(6, j[2]);
        digitalWrite(7, j[3]);
        digitalWrite(8, j[4]);
        digitalWrite(9, j[5]);
        digitalWrite(10, j[6]);
        digitalWrite(11, j[7]);
        digitalWrite(12, j[8]);
        digitalWrite(13, j[9]);
      }
}
y este es el error que me muestra:
tecladops2.ino: In function 'void loop()':
tecladops2:29: error: invalid types 'int[int]' for array subscript

Una breve explicación:
Un teclado ps2 manda 11 bits de pulso, siempre está en alto siempre y cuando no se presione ninguna tecla.
Si se presiona una tecla, los primeros dos bits no se cuentan y el último tampoco, entonces los que se toman en cuenta para crear el código binario son del 3-10

Espero que me puedan orientar, si no entienden algo pregúntenme por favor.
 
Última edición por un moderador:
revisa esto aca tienes un error

for (int i=0; i<=10; i++){
teclado=digitalRead(data);
for (int j=0; i<=10; i++){
digitalWrite(j);

declaras j pero incrementas i eso es un problema

pero mas arriba declaras j como una variable global eso tambien es un error por que declaras j 2 veces
 
muchas gracias por el comentario ya le e arreglado unas cosas aqui esta el codigo

Código:
#define clock 3 //Este es el pin del teclado ps2 correspondiente al CLK
#define data 4  //Este es el pin del teclado ps2 correspondiente al DATA+
int teclado=0;
void setup(){
     pinMode(data, INPUT);
     pinMode(clock, OUTPUT);
     pinMode(6, OUTPUT);
     pinMode(7, OUTPUT);
     pinMode(8, OUTPUT);
     pinMode(9, OUTPUT);
     pinMode(10, OUTPUT);
     pinMode(11, OUTPUT);
     pinMode(12, OUTPUT);
     pinMode(13, OUTPUT);
}

void loop(){
  teclado = digitalRead(data);
  
   if(teclado == HIGH){
      digitalWrite(clock,HIGH);
      //delay( 0.00045 ); 
   }
      else{
      for (int i=0; i<=10; i++){
        teclado=digitalRead(data);
        for (int j=0; j<=10; j++){
          digitalWrite(j[i]=teclado);
      
      }
      }
        digitalWrite(6, j[2]);
        digitalWrite(7, j[3]);
        digitalWrite(8, j[4]);
        digitalWrite(9, j[5]);
        digitalWrite(10, j[6]);
        digitalWrite(11, j[7]);
        digitalWrite(12, j[8]);
        digitalWrite(13, j[9]);
      }
}

y aqui esta el error que me da :
tecladops2_1.ino: In function 'void loop()':
tecladops2_1:28: error: invalid types 'int[int]' for array subscript
tecladops2_1:32: error: 'j' was not declared in this scope
 
j=teclado

esto no es valido

por que j no es un array es solo 1 entero

cuando declaras int j;
solo ocupas 1 solo entero

pero si declaras int j[10]; es un array de 10 enteros

ojo con eso

piensa mas en ese for

yo no declararia los enteros dentro del for
declararia los enteros afuera del loop

es lo malo del aurdino hiso un C todo raro y los que publican en internet no son muy buenos programadores tambien ojo con las publicaciones de internet
 
gracias TRILO-BITE e checado mi codigo y tenias razon ya lo e arreglado y el codigo me quedo muy biien y compila bien el problema es que no me cacha bien el tren de pulsos que proviene del teclado y pues me muestra un codigo binario que no correponde con el de la tecla presionada no se si sea porque el tiempo que estoy manejando entra cada iteracion sea muy chico.

el maestro nos dijo que el teclado mandaba los pulsos cada 45 nanosegundos pero creo que esta mal porque por ahy lei que eran otros tiempos, que me podrian decir al respecto?
otra duda es que los foquitos del teclado prenden al principio y se apagan y si presiono el block mayus no prende el foco del teclado que debe ni cuando presiono el blockeo del teclado numerico que sera?

aqui esta el codigo
Código:
#define clock 3 //Este es el pin del teclado ps2 correspondiente al CLK
#define data 4  //Este es el pin del teclado ps2 correspondiente al DATA+
int teclado=0;
int vector[10] ;
void setup(){
     pinMode(data, INPUT);
     pinMode(clock, OUTPUT);
     pinMode(6, OUTPUT);
     pinMode(7, OUTPUT);
     pinMode(8, OUTPUT);
     pinMode(9, OUTPUT);
     pinMode(10, OUTPUT);
     pinMode(11, OUTPUT);
     pinMode(12, OUTPUT);
     pinMode(13, OUTPUT);
}

void loop(){
  teclado = digitalRead(data);
  
   if(teclado == HIGH){
      digitalWrite(clock,HIGH);
      //delay(  ); 
   }
      else{
      for (int i=0; i<11; i++){
        delay( 0.00045 );
        teclado=digitalRead(data);
        vector[i]=teclado;
    
      }
       
     
      }
          if(vector[1] == 0)
        digitalWrite(6, LOW);
        else
       digitalWrite(6, HIGH);
       
       if(vector[2] == 0)
        digitalWrite(7, LOW);
       else
       digitalWrite(7, HIGH);
       
       if(vector[3] == 0)
        digitalWrite(8, LOW);
       else
       digitalWrite(8, HIGH);
       
       if(vector[4] == 0)
        digitalWrite(9, LOW);
       else
       digitalWrite(9, HIGH);
       
       if(vector[5] == 0)
        digitalWrite(10, LOW);
       else
       digitalWrite(10, HIGH);
       
       if(vector[6] == 0)
        digitalWrite(11, LOW);
       else
       digitalWrite(11, HIGH);
       
       if(vector[7] == 0)
        digitalWrite(12, LOW);
       else
       digitalWrite(12, HIGH);
       
       if(vector[8] == 0)
        digitalWrite(13, LOW);
       else
       digitalWrite(13, HIGH);
}
 
ahi te fallo nunca he leido un teclado PS2 ese era un proyecto que tenia pero por falta de tiempo no lo he podido empezar

pero toda lectura se basa en emular la forma de onda de cualquier dispositivo ejemplo
I2c ,SPI , UART ,etc.

que un micro tenga el hardware especial para leer esos dispositivos no es obligatorio usarlos se pueden hacer por software.

el teclado PS2 debes emular su reloj

primero que nada leer, leer mucho sobre los protocolos que vallas a emular "son casi todos en ingles"
http://www.computer-engineering.org/ps2protocol/

despues emular la forma de onda o WAVEFORM
waveform1.jpg


y revisar en un osciloscopio que salga dicha forma de onda parecida o similar
luego los tiempos de comunicacion no son tan obligatorios aveces pueden ir mas lento o mas rapido
pero repito AVECES

yo veo que el PS2 envia una trama de bits por cada pulso de reloj
waveform3.jpg

lo que yo haria

es bueno viendo la forma de onda del HOST
es enviar un pulso bajo "indica que la trama inicia"
y con el mismo pin que yo inicie el pulso empiezo a leer 10 bits de reloj osea 10 pulsos
y con el pin de DATA leer los bits que tienen informacion

ahi usaria un INT16 en el caso de arduino un INT

y al leer iria rotando los datos que van entrando
ejemplo:

int leer;
char clk;
for(clk=0;clk!=11;clk++)
{
leer+=leer<<clk;
}

algo asi bueno pude que mi algoritmo tenga error pero la idea es leer y por cada bit que valla entrando que se valla acomodando en el entero ;)

suerte
 
Última edición:
Perdon pero solo entendi la mitad de lo que dijiste.
osciloscopio no tengo acceso a ninguno.
y segun yo eso es lo que estoy haciendo con mi codigo leo lo que entra por el data con un ciclo for y lo guardo en en vector y luego pues leo el vector para prender los leds.

la verdad e leido mucho ya del protocolo, mas omenos lo entiendo pero es la primera vez que nos dan electronica asi que solo emos visto lo basico y aun no comprendo unas cosas
 
no eso no es un vector es un ARRAY un array no es lo que necesitas

ejemplos de ARRAY o ARREGLOS

char letras[10];
int numeros[10];

matrices:

char letras [1][3];
int numeros [2][3];

y lo que estas haciendo es algo incorrecto por leemos 1 bit por cada pulso de reloj
y lo estas guardado en 1 Byte es decir no vamos a leer nada util.

y perdon por decir de los 10 bits ahi estoy mal podemos descartar el Start , stop parity y ACK
eso no nos es muy util.

lo util son los 8 bits que vienen del teclado

el algoritmo es el siguiente:

mantener el alto "1" el CLK para el teclado

cuando yo quiera leer el teclado hago esto:
mandar en estado bajo el CLK del teclado y enseguida poner el pin de CLK en modo entrada

contar los pulsos del reloj que entren "bueno creo que el teclado crea el reloj por lo que vi"
e ir contando los pulos

pulso 0 inicio
pulso 1 al 8 DATOS
pulso 9 al 11 cosas

y se vuelve a repetir

entonces NO usar ni WHILE ni FOR por que eso nosatoraria el micro y eso no queremos


no se como se declare el bucle infinito en el ARDUNIO pero lo pondre asi

bucle
{
if(clk==1)//leemos si el pin CLK entra puslo
{
reloj++;
if(reloj>=12)//nos aseguramos que lleguen 11 pulsos
{
reloj=0;
if(reloj==0)
{
//START
}
}
}

if(reloj>=1 && reloj<=9) //leemos los 8 bits
{
dato=dato<<reloj-1; //por cada pulso metemos en el byte para irlo acomodando recuerda que el byte

//es 7-0 por eso le resto 1 por que acomodaria de 8-1 la funcion que uso es ROTAR

}

//hacer algo con el BYTE dato nose imprimirlo compararlo nose

if(dato==TU NUMERO)
{
//la tecla fue " la letra que lea"
}



}//fin del bucle


asi como esta el codigo me daria errores pero mas o menos asi seria la idea es que estudies la funcion de ROTAR se escribe asi >> y <<
su sintaxis es :

numero= numero<<X;

donde numero es la variable que desplazas 1 bit a la izquierda o a la derecha << o >>
y la X indica cuantos BITS lo desplazare

ejemplo:

numero=1;
numero=numero<<4;

desplaze numero 4 veces a la izq si valia 1 ahora vale 8
visto en modo binario
00000001
00001000


por eso cuando leemos de bit en bit los acomodamos en el BYTE

tenemos el BYTE vacio
00000000

y digamos que leimos:
1
0
1
1
0
0
1
1
los vamos acomodando con rotar a la izq
asi empezamos
00000000

los vamos rotando de 1 en 1
00000001
00000010
00000101
00001011
00010110
00101100
01011001

hasta obtener algo asi:

10110011

suerte y a repasar mucho
 
Última edición:
Muchas gracias si le entendi a tu codigo lo malo es que tampoco se muy bien como pasarlo a codigo arduino tendre que leer y buscar mas al respecto pero me sirvio mucho
 
mira es que tampoco debes depender de arduino , de pic ,AVR o lo que fuese

yo lo escribi en ANSI C

es lo malo cuando entiendan el ANSI C puden tener un 98% de compatibilidad los codigos escritos y pueden ser usados en cualquier micro y cualquier compilador
 
si es lo que dije el arduino no es la piedra angular solo debes aprender en ANSI C
el ANSI C te va a funcionar en cualquier plataforma ya sea Arduino , pic ,etc.
 
Oye TRILO-BYTE ya se que es mucho pedir pero crees que me podrias ayudar, y facilitarme el codigo que nesecito en C o ansi C de tal manera que solo lo meta en el arduino y al ejecutarlo haga lo que deseo.

esque ya no se que hacer y nesecito entregarlo este lunes y creo que no me da tiempo de hacerlo yo solo,
ya se que estos foros son para resolver dudas y no para hacernos todo el trabajo pero estoy desesperado y como no entiendo de C o ANSI C pues no sabria ni que hacer solo se un poquito del codigo nativo de arduino
 
pues mira ando atorado en un proyecto ayudo para salir de mis bloqueos mentales
asi que tienes todo el domingo para salir.

digo la inspiracion sale cuando dejas el proyecto a un lado yo te di algo que se me ocurrio derrepente que podria funcionar obviamente tiene errores solo es pulir el codigo.

pero no cierres tu mente al arduino busca ayuda en Todopic.ar o revisa sus foros los programadores son muy buenos sobretodo un tal SUKY.

busca sus algoritmos ellos programan normalmente en CCS para pic pero el 90% funciona en cualquier microcontrolador.

busca varios caminos para salir del bache ;) el problema de arduino es que hacen cosas medio raras por que muchos de ellos no saben programar y no saben electronica.

te sugiero eso que revises esos foros y buscale conectar un pic y un teclado en CCS
aunque no sea un arduino y no sea el lenguaje del arduino lo que importa es el ALGORITMO y sobre todo como lo resolvieron.

suerte
 
Atrás
Arriba