Abstract

Traditional gamepads typically require a T.V. screen or a monitor that is propped up on a stand. With handheld devices such as smartphones however, require you to hold onto the display itself. The player to either has to prop up the phone on the table or settle for on screen displays that lack the tactile feedback that physical buttons have. The VPad utilizes Google’s open-source VR platform Cardboard to give gamers an affordable VR gaming experience. The VPad will interface via Bluetooth to a computer and the rendered frames in the computer will then be streamed to the android smartphone. Headtracking is also implemented to complete the whole VR experience. The incorporation of these systems in a gamepad will prove to be invaluable in certain game genres like racing games. The user can coast through a race track while looking around and enjoy amazing scenery that accompanies the skyline. This effectively provides an affordable solution to players who want to experience VR gaming.

The Problem

Today, many gamers wish to experience the awesome vr gameplay, but are restricted by certain problems.. Phones need to be propped up in order to use a gamepad, but with the VPad, this is not a requirement. Gamepads that work with today's VRs such as Oculus cost more than $100 usually, but the VPad is affordable and can be easily implemented and ran on any VR and game.

Details

Game Engine: Unity

We made a driving simulator in Unity to demo the VPAD. We used Unity's graphics engine to render the car and race track and used Unity's physics engine to implement the driving mechanics. Since the focus is on the VPAD controller, we will not go into the technical details of how c# code in Unity works. For the friction, we adjusted the center of mass to be low as possible and increased the stiffness off the wheel colliders to match the terrain we imported. I used lerping and clamping to fix the driving wheel's rotation. To parse the data from serial monitor, we used a SerialPort and connected to the right port to read a line. After that, the string was parsed and broken down based on whenever there were spaces between the number and the next value. Since the values from the analog stick varied from 510 to 530, we set a thresholds for an idle joystick so the car would not rotate while there was no user. The push buttons were connected to digital pins, so we only needed to detect if data read from the pin was HIGH or LOW and start accelerating or decelerating based on the user's presses.A copy of the C# code is included in the Google Drive files found below. ThingSpeak: In the Unity code, we tracked the amount of times each button on the controller is pressed and automatically upload the data to ThingSpeak at the end of each session. ThingSpeak servers will then display a graph that logs the user's stats.

VR Technology: Samsung Gear VR and Trinus

Some may argue that the Samsung Gear VR used in the demo contradicts our philosophy of creating a cheap VR gaming solution, especially considering that Samsung's Gear VR costs around $200 alone and requires a $600 smartphone to operate. This is a valid point, however, we do want to point out that our implementation of the VPAD works just as well with any Smartphone that is compatible with Google Cardboard. Google Cardboard can be found on Amazon for as low as $6. This is made possible through an Android App called Trinus, Trinus acts as a bridge between the computer and smartphone. The app streams anything that is displayed on the computer's screen to the smartphone via Wi-Fi and sends data from the Gyro and Accelerometer in the phone to the computer, this is how headtracking is implemented. The "3D" effect is created by rendering two images that are slightly offset from one another and presenting one image to each eye. The stereoscopic images tricks our brain into thinking that we are perceiving depth.

VPad Controller: Arduino

The controller itself runs on Arduino. We are using two Arduino Unos along with an Analog stick, two buttons, two Bluetooth modules and a battery pack. The Arduino code and circuitry diagrams will also be included in the image gallery above.

The Analog stick outputs two analog signals, one for the x direction and one for the y direction. The signals range from 0 to 1023 with 0 corresponding to the left direction, 1023 to the right direction and the 500-520 mark being the idle or neutral state. With this information, we mapped out the ranges that is outputted from the serial monitor to the corresponding steering directions in the Unity code.

The two buttons are simply connected in series with a resistor and connected to two digital pins that output a simple on or off state. Again, the state of the two buttons are outputted in the serial monitor to Unity and the green and blue buttons were matched to the gas and reverse functions respectively.

The implementation of Bluetooth has allowed us to go completely wireless which is critical to the immersive VR experience because the user will no longer have orientation constraints that are placed by wires. If there were wires involved, for example, doing a full body 360 degree turn will wrap the wires around the user's body. Needless to say, this will ruin the whole experience. We used two HC-05 that were paired up in a Master and Slave relationship with the Master on the controller transmitting data and the Slave on the other Arduino that is hooked up to a computer to read the transmitted information.

Arduino code for the transmitter:

#include <SoftwareSerial.h>
  // Define buttons to use
   int vertical = 0;
   int horizontal = 0;
   int selectA, selectB;

   const int buttonB = 8;
   SoftwareSerial  BTSerial(12, 13); //RX TX
// variable to hold the state of the buttons

//=========================================================
//=======  SETUP
//=========================================================
void setup()
{
   BTSerial.begin(9600);
   pinMode(buttonB, INPUT);  
   pinMode(2, INPUT);
   pinMode(8, INPUT);
   Serial.begin(9600);  // turn on the serial communication

}

//=========================================================
//======= MAIN LOOP
//=========================================================
void loop()
{

  vertical = analogRead(1); // will be 0-1023
  horizontal = analogRead(0); // will be 0-1023
  selectA = digitalRead(2); // will be HIGH (1) if not pressed, and LOW (0) if pressed
  selectB = digitalRead(8);
  // print out the values

   serialToUnity();

}


//=========================================================
//======= Serial Communication to unity
//=========================================================
void serialToUnity()
{
    String output = "";
    //if(output == "") {
      // Serial.print(vertical, DEC);
    //}
    //else {
      BTSerial.print(vertical, DEC) + BTSerial.print(" ");
      Serial.print(vertical, DEC) + Serial.print(" ");
    //}
    //if(Serial.peek() == -1) {
        BTSerial.print(horizontal, DEC) + BTSerial.print(" ");
        Serial.print(horizontal, DEC) + Serial.print(" ");

        if(selectA == LOW) {
          BTSerial.print("A ");
          Serial.print("A ");
        }
        else {
          BTSerial.print("C ");
          Serial.print("C ");
        }

        if(selectB == LOW) {
          BTSerial.print("B");
          Serial.print("B");
        }
        else {
          BTSerial.print("D");
          Serial.print("D");
        }
    //}
    //else {
      //Serial.print(horizontal, DEC) + Serial.print(" ");
    //}

    //if(selectA == HIGH)
    //{ output += " A";}
    //if(selectB == LOW)
    //{ output += " B";}

      BTSerial.println("");
      Serial.println("");

    Serial.flush();
    delay(100);

}

Arduino code for receiver:

#include <SoftwareSerial.h>
SoftwareSerial  BTSerial(2, 3); //RX TX
String inData;
void setup() {
  BTSerial.begin(9600); //begin bluetooth communication
  Serial.begin(9600); //begin serial communication
}

void loop() {
  if (BTSerial.available()) {
    char received = (char) BTSerial.read(); //reads single character at a time

        // Process message when new line character is recieved
        if (received == '\n')
        {
            Serial.println(inData);

            inData = ""; // Clear recieved buffer
        } else {
              inData += received; 
        }
  }
}

Since the Arduinos are powered via USB, a power bank that is used to charge smartphones can be repurposed and used as the power for the controller. The power bank even has a battery level indicator to tell us when to charge the Vpad. We used a double sided tape to tape the controller onto the Arduino Uno and with that, we have a completely wireless controller.

Files https://drive.google.com/folderview?id=0B5oquuFspmWoN1h6R1ZIdjhBNlU&usp=sharing

ThingSpeak https://thingspeak.com/channels/69685

Videos Intro: https://www.youtube.com/watch?v=eKC0J13TJbQ Final: https://www.youtube.com/watch?v=aeN0Aisppvk

Google Doc version: https://docs.google.com/document/d/1ssZ1BxdQpgPH0yRaRq9vAdIHnbqf3kUEDp5Zgvh5CA4/edit?usp=sharing

Closing

The beauty of the VPad is that it is made with technology that is readily available. The Arduinos, battery pack, analog stick, buttons and Google Cardboard can all be purchased at low prices from various online retailers. The computer and smartphone on the other hand, are products that are common in every house hold. Ultimately, we wish to show that you don't need to spend hundreds of dollars to experience the latest and coolest technology that the modern world has to offer.

Share this project:
×

Updates

Richard Zheng posted an update

Finally, as we approached the final stages of development for our project, we decided to incorporate the "internet" element of this project. We added code into our driving simulator that provides statistical data to thingspeak, which included data like how many times each button was pressed.

Log in or sign up for Devpost to join the conversation.

Richard Zheng posted an update

Our project reached a significant milestone when we received the Samsung Gear VR and a Galaxy Note 4 from Sid. By that time, the major bugs with transmitting data between the controller and the computer were fixed and the wiring for the controller was fully optimized.

Log in or sign up for Devpost to join the conversation.

Richard Zheng posted an update

One bug that we had to deal with throughout the development process were the mechanics and physics in the driving simulator that we made. For example, the coefficient of friction between the wheels and the road was too low, making steering at certain speeds very difficult to control.

Log in or sign up for Devpost to join the conversation.

Richard Zheng posted an update

After days of intensive testing, we finally got our bluetooth modules to pair. So far, getting the modules to pair was the biggest struggle of this project. For example, the original bluetooth modules that we had decided to pair with another group's bluetooth module and started sending data to their serial monitors. Fortunately, the ever resourceful TA's of ESE 111 bestowed upon us a new paired bluetooth module and saved our project.

Log in or sign up for Devpost to join the conversation.