Wednesday, November 13, 2013

Nes Controller Pad Bluethoot Hack (En Construccion)

Voy a comenzar un proyecto basado en el mando controlador de la consola Nintendo N.E.S
Primero conectaremos el pad al osciloscopio y veremos como funciona la comunicacion mando-consola.
Conectaremos en los pines de clock, latch y data1.
La primera Captura es sin ningun boton presionado:
La primera señal que encontramos en la imagen es la linea de Clock, que separa cada bit de informacion de la señal de datos.
Luego tenemos la linea de datos, que a cada pulso negativo de Clock, transmite un bit reflejando el estado de cada boton. Un estado alto representa un boton sin presionar y un estado bajo representa un boton presionado.
Y por ultimo la linea Latch que sirve para que el  integrado del pad lea el estado de los botones y los transmita por la linea de datos.
Y despues presionando un par de botones.
 Vemos como cuando se presiona un boton genera un pulso negativo en la linea de datos, en la posicion que le corresponde a cada boton. de izquierda a derecha: A, B, Select, Start,Up, Down, Left, Right.
Aqui tenemos el interior del mando:


El integrado que se encarga de realizar la comunicacion es un MC14021BCP Download Datasheet.
Para leer el estad del mando utilizare un ATTiny84 de atmel.
Instalamos el core tiny-arduino y configuraremos los timers del microcontrolador para emular la comunicacion con la nintendo y transmitir el estado de los botones a traves de un modulo bluethoot.
El codigo es el siguiente:

--------------------------Begin Code--------------------------------------------

#include <SoftwareSerial.h>
SoftwareSerial mySerial(8, 7); // RX, TX

int i=0;
int botones = 0;

void setup() {
  DDRA = (1<<DDA0) | (1<<DDA1) | (1<<DDA2) | (0<<DDA3) | (1<<DDA7);  
  startTimer();
  mySerial.begin(9600);
  mySerial.println("Hello, world?"); 

}

 void startTimer() {
    cli();           // disable all interrupts

    TCCR1A = 0;
    TCCR1B = 0;
    TCCR1C = 0; 
    TCNT1  = 0;

    OCR1A = 10;     // compare  register.
    TCCR1B = (1 << WGM12) | (2 << CS10);    // CTC mode and 256 prescaler 
    TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt

    sei();             // enable all interrupts
  }

  ISR(TIM1_COMPA_vect) { 
    PORTA =  PORTA ^ B00000001;  // invierte el pin de salida
    i++;
    PORTA = PORTA ^ B00000001;  // invierte el pin de salida
    if(i==8){
      PORTA = PORTA ^  B00000010;  // invierte el pin de salida
      for(i=0;i<1;i++);
      i=0;
      PORTA = PORTA ^ B00000010;  
      comunica();
      botones =  0;    
    }
   botones = botones << 1;
   botones = botones + !digitalRead(3);
   }
  
  void comunica(){
   if((botones&128)==128) mySerial.println("A");  //Boton A
   if((botones&64)==64) mySerial.println("B");    //Boton B
   if((botones&32)==32) mySerial.println("E");    //Select
   if((botones&16)==16) mySerial.println("T");    //start
   if((botones&8)==8) mySerial.println("U");      //UP
   if((botones&4)==4) mySerial.println("D");      //Down
   if((botones&2)==2) mySerial.println("L");      //Left
   if((botones&1)==1) mySerial.println("R");      //Right
   
   //mySerial.println(botones);
  }
   
 void loop(){  }

---------------------------END CODE-----------------------------------

Al final del codigo vemos donde manda una letra para cada boton presionado.
Los timers se han configurado para leer el mando a la misma velocidad que si estubiera conectado a la consola.
Configuramos el modulo bluethoot en android y instalamos algun programa de terminal para conectarnos en la conexion serie.
Podemos comprobar como cada vez que presionamos cualquier boton del mando, imprime una letra en la conexion serie.
Falta por crear un programa que transforme la salida serie en teclas presionadas en el dispositivo.
EN CONSTRUCCION....

No comments:

Post a Comment