PhysComp Final Project Documentation

Apex Legends Motion Controller

Concept: A handheld motion controller that replaces the mouse functions in Apex Legends.

Hardware: I used the Arduino Micro for it's native usb functions with a MPU 6050 accelerometer to mimic the movements of a mouse and control the camera movement. There are 3 buttons: one to control aiming, one to control shooting, and a button to turn around 180 degrees. When the game is not open, it can also just function as a mouse and control the cursor. Since it is just replacing the mouse it also functions in other games as well.

Final Product: 

Video 1

Video 2

Code
 ---------------------------------------------------
#include <MPU6050.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <Mouse.h>
#include <Keyboard.h>
 
MPU6050 mpu;
int16_t ax, ay, az, gx, gy, gz;
int16_t accx, accy, accz;
int vx, vy;
int TRIGGER_BUTTON = 5;
int AIM_BUTTON = 6;
int TURN_BUTTON = 8;
int lastTurnPushed = 0;
bool weaponModeOn = true;
float angle;
 
//code for smoothing input
int readIndex = 0;
const int numReadings = 20;
int angleReadings[numReadings];
int total = 0;
float averageAngle = 0.0;
 
 
int oldZ = 0;
int newZ = 0;
 
void setup() {
  Serial.begin(115200);
  Wire.begin();
  mpu.initialize();
  if (!mpu.testConnection()) {
    while (1);
  }
  pinMode(TRIGGER_BUTTON, INPUT_PULLUP);
  pinMode(AIM_BUTTON, INPUT_PULLUP);
  pinMode(TURN_BUTTON, INPUT_PULLUP);
 
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    angleReadings[thisReading] = 0;
  }
}
 
void loop() {
 
  int triggerPushed = digitalRead(TRIGGER_BUTTON);
  int aimPushed = digitalRead(AIM_BUTTON);
  int turnPushed = digitalRead(TURN_BUTTON);
 
  total = total - angleReadings[readIndex];
  angleReadings[readIndex] = angle;
  total = total + angleReadings[readIndex];
  readIndex = readIndex + 1;
  if (readIndex >= numReadings) {
    readIndex = 0;
  }
 
 
  if (triggerPushed == HIGH) {
    if (Mouse.isPressed()) {
      Mouse.release();
    }
  } else {
    Serial.println("trigger pushed");
    Mouse.press();
  }

  if (aimPushed == HIGH) {
    if (Mouse.isPressed(MOUSE_RIGHT)) {
      Mouse.release(MOUSE_RIGHT);
    }
  } else {
    Serial.println("aim pushed");
    Mouse.press(MOUSE_RIGHT);
  }

  if (turnPushed == HIGH) {
    if (turnPushed != lastTurnPushed){
      for(int i = 0; i < 32trrrr; i++){
        Mouse.move(50,0);
      }
    }
  }
  lastTurnPushed = turnPushed;
 
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  mpu.getAcceleration(&accx, &accy, &accz);
 
  oldZ = newZ;
  vx = (gx + 900) / 150; // "+300" because the x axis of gyroscope give values about -350 while it's not moving. Change this value if you get something different using the TEST code, chacking if there are values far from zero.
  vy = -(gz + 230) / 150; // same here about "-100"
 
    Mouse.move(vx, vy);
  Serial.println(vx);

  angle = atan2((float) ay, (float) ~ax) * (180.0 / PI);
 
  delay(20);
} 

Comments

Popular posts from this blog

Feeling Patterns Assignment #1

Hypercinema Week #4

PhysComp Week #1