Posted on Aug 21, 2011

RoboTouch iPad Controller

Using an Arduino, I hacked my old NES controller to control micro servos with custom conductive arms that simulate touches to the screen of my iPad. The servos are attached to the screen with mini suction cups on a custom aluminum bracket and can be easily positioned for any game.

I basically wanted to play my favorite iPad game (Reckless Racing) with my NES controller and didn’t want to hack a solution via dock port.

Schematic:
RoboTouch Schematic

Arduino Sketch:

 /*
 RoboTouch iPad Controller
 
 Translates button presses on a Nintendo controller to "button" presses
 from grounded servo "fingers"
 
 created 201103
 by Joven 
 
 */
 
 #include <Servo.h>      // include the servo library

 Servo servo1Motor;       // creates an instances of the servo object to control a servo
 Servo servo2Motor; 
 Servo servo3Motor; 

 // NES Controller
 byte controller_data = 0;
 int clock = 2; // set the clock pin
 int latch = 3; // set the latch pin
 int datin = 4;// set the data in pin
 
 // Robo Finger Servos
 int servo1Pin = 9;  
 int servo2Pin = 10; 
 int servo3Pin = 11; 
 
 // Config
 long randNumber;
 int timeDelay = 100;

 void setup() { 
    // Attach Servos
    servo1Motor.attach(servo1Pin);
    servo2Motor.attach(servo2Pin);
    servo3Motor.attach(servo3Pin);
    
    // Start Serial for debug
    Serial.begin(57600);
    
    // NES Data Pins
    pinMode(latch,OUTPUT);
    pinMode(clock,OUTPUT);
    pinMode(datin,INPUT);
    digitalWrite(latch,HIGH);
    digitalWrite(clock,HIGH);
 } 
  
 // CONTROLLER READ 
 void controllerRead() {
    controller_data = 0;
    digitalWrite(latch,LOW);
    digitalWrite(clock,LOW);
    digitalWrite(latch,HIGH);
    delayMicroseconds(2);
    digitalWrite(latch,LOW);
    controller_data = digitalRead(datin);
    for (int i = 1; i <= 7; i ++) {
    digitalWrite(clock,HIGH);
    delayMicroseconds(2);
    controller_data = controller_data << 1;
    controller_data = controller_data + digitalRead(datin) ;
    delayMicroseconds(4);
    digitalWrite(clock,LOW);
    }
 }

 void loop() 
 { 
    controllerRead();
    
    // Output Raw Data
    Serial.println(int(controller_data));
    
    // Button Left
    if (int(controller_data) == 253 || int(controller_data) == 125) {
      // Arm Down
      servo1Motor.write(80); 
    } else {
      // Arm Up
      servo1Motor.write(90);
    }  
    
    // Button Right
    if (int(controller_data) == 254 || int(controller_data) == 126) {
      servo2Motor.write(80); 
    } else {
      servo2Motor.write(90);
    }  
    
    // Button A
    if (int(controller_data) <= 127 && int(controller_data) >= 125) {
      servo3Motor.write(80); 
    } else {
      servo3Motor.write(90);
    }   

    delay(timeDelay);
 }

Resources:

My previous project decoding the NES controller: RetroGamer Drive

Micro Servo