27 November 2023

Game Controller: Five Night's at Freddy's

Vision & Disclaimer 

For the final project I decided to create a game controller for Five Nights at Freddy's. Taking into consideration the gameplay and theming I decided to turn the laptop the player uses in-game into the controller in an attempt to better immerse the player in the gameplay. One of the biggest challenges I faced was realizing that FnAF isn't actually played using any hotkeys or keyboard controls and is only controlled using the mouse. Given that, I must state as a disclaimer, that I found external code that takes keyboard commands and converts it into mouse movements on the screen, thus emulating how FnAF could be played with only the keyboard.

Controller Description

 With that sorted, here's the description for the actual controller. The "laptop" would sit on the player's lap or on the desk in front of them and then be controlled using the various sensors. When the "laptop" is opened, the laptop in game is opened to view the cameras, and then using the potentiometer and the position switch the player can cycle through each of the cameras; closing the laptop of course closes it in game as well. The position switch is used to control the doors while the "laptop" is closed, and the potentiometer and photoresistor work in tandem to turn the lights on and off depending on brightness and position of the potentiometer.

Peer Question

Although the player would be looking at the actual computer screen most times do you think more visual aids on the controller itself would be useful?












#include <bluefruit.h>
#include <Adafruit_TinyUSB.h>
#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>

//HID report descriptor using TinyUSB's template
//Single report (no ID) descriptor
uint8_t const desc_hid_report[] =
{
  TUD_HID_REPORT_DESC_KEYBOARD()
};

// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
//https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h


float y; //CPB Accelerometer
bool computerOpen = false; //check if screen is opened
bool leftDoorClosed = false; // check if left door is closed
bool rightDoorClosed = false; // check if right door is closed

//Check if cameras are active
bool cam0 = false;
bool cam1 = false;
bool cam2 = false;
bool cam3 = false;
bool cam4 = false;
bool cam5 = false;
bool cam6 = false;
bool cam7 = false;
bool cam8 = false;
bool cam9 = false;
bool cam1A = false;
bool cam2B = false;
//check if lights are on
bool leftLight = false;
bool rightLight = false;
void setup() {
  CircuitPlayground.begin();
  usb_hid.begin();
  pinMode(CPLAY_SLIDESWITCHPIN, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP); //Toggle Switch input 1
  pinMode(A5, INPUT_PULLUP);//Toggle Switch input 2
  Serial.begin(115200);

  delay(1000);

}

void loop() {
  uint8_t const report_id = 0;  //unsigned 8bit (1 byte) int
  uint8_t modifier = 0;         //used by libraries to save space
  uint8_t keycode[6] = { 0, 0 };   //normal int is 16 bit (4 bytes)

    y = CircuitPlayground.motionY() * -1; //Accelerometer Y value
    int toggleValue1 = analogRead(A1); //toggle switch 1 output
    int toggleValue2 = analogRead(A5); //toggle switch 2 output
    int knobValue = analogRead(A3); //potentiometer values
    int brightness = analogRead(A4); //Photoresistor value
  if(digitalRead(CPLAY_SLIDESWITCHPIN))
  {
    Serial.println(y);
  //Opens and closes computer screen
   if(y > 7.2  && computerOpen == false)
   {
    computerOpen = true;
    keycode[0] = HID_KEY_SPACE;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(50);
    usb_hid.keyboardRelease(0);
    }
   if(y < 4 && computerOpen == true)
   {
    computerOpen = false;
    keycode[0] = HID_KEY_SPACE;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(50);
    usb_hid.keyboardRelease(0);
   }

   //controls left and right doors
   //Left Door close
   if (toggleValue1 >= 900 && toggleValue2 <= 350 && computerOpen == false && leftDoorClosed == false) {
    keycode[0] = HID_KEY_Q;
    leftDoorClosed = true;
    rightDoorClosed = false;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(5);
    usb_hid.keyboardRelease(0);
  }
  //Do nothing if both doors open and switch in middle
  if (toggleValue1 >= 900 && toggleValue2 >= 900 && computerOpen == false) {
    keycode[0] = HID_NULL_STATE;
    leftDoorClosed = false;
    rightDoorClosed = false;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(5);
    usb_hid.keyboardRelease(0);
  }
  //Right Door close
  if (toggleValue2 >= 900 && toggleValue1 <= 350 && computerOpen == false && rightDoorClosed == false) {
    keycode[0] = HID_KEY_P;
    leftDoorClosed = false;
    rightDoorClosed = true;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(5);
    usb_hid.keyboardRelease(0);
  }


  //Controls left and right lights
  //Left light on
   if(knobValue < 500 && brightness >= 850 && computerOpen == false && leftLight == false)
   {
    keycode[1] = HID_KEY_A;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(75);
    leftLight = true;
    usb_hid.keyboardRelease(0);
   }
   //Right light on
    if(knobValue > 600 && brightness >= 850 && computerOpen == false && rightLight == false)
   {
    keycode[1] = HID_KEY_L;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(75);
    rightLight = true;
    usb_hid.keyboardRelease(0);
   }
   //left light off
    if(knobValue < 500 && brightness <= 750 && computerOpen == false && leftLight == true)
   {
    keycode[1] = HID_KEY_A;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(75);
    leftLight = false;
    usb_hid.keyboardRelease(0);
   }
   //Right light off
    if(knobValue > 600 && brightness < 750 && computerOpen == false && rightLight == true)
   {
    keycode[0] = HID_KEY_L;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(75);
    rightLight = false;
    usb_hid.keyboardRelease(0);
   }
   
  //If statements for Num Pad to select cameras
   if(knobValue <=99 && knobValue > 10 && computerOpen == true && cam0 == false)
   {
    cam0 = true;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_0;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue <=199 && knobValue >99 && computerOpen == true && cam1 == false)
   {
    cam0 = false;
    cam1 = true;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_1;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue <=299 && knobValue >199 && computerOpen == true && cam2 == false)
   {
    cam0 = false;
    cam1 = true;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_2;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue <=399 && knobValue >299 && computerOpen == true && cam3 == false)
   {
    cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = true;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_3;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue <=499 && knobValue >399 && computerOpen == true && cam4 == false)
   {
    cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = true;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_4;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue <=599 && knobValue >499 && computerOpen == true && cam5 == false)
   {
    cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = true;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_5;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue <=699 && knobValue >599 && computerOpen == true && cam6 == false)
   {
    cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = true;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_6;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue <=799 && knobValue >699 && computerOpen == true && cam7 == false)
   {
    cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = true;
    cam8 = false;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_7;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue <=899 && knobValue >799 && computerOpen == true && cam8 == false)
   {
    cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = true;
    cam9 = false;
    keycode[0] = HID_KEY_KEYPAD_8;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(knobValue >=900 && computerOpen == true && cam9 == false)
   {
    cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = true;
    keycode[0] = HID_KEY_KEYPAD_9;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   if(toggleValue1 >= 900 && toggleValue2 <= 200 && computerOpen == true && knobValue < 20)
   {
      cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    cam1A = true;
    cam2B = false;
    keycode[0] = HID_KEY_1;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
      if(toggleValue2 >= 900 && toggleValue1 <= 200 && computerOpen == true && knobValue < 20)
   {
    cam0 = false;
    cam1 = false;
    cam2 = false;
    cam3 = false;
    cam4 = false;
    cam5 = false;
    cam6 = false;
    cam7 = false;
    cam8 = false;
    cam9 = false;
    cam1A = false;
    cam2B = true;
     keycode[0] = HID_KEY_2;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);
   }
   }
}

Game Controller: Ender Lilies

 My controller was a bit of a scope failure on my end, it was too ambitious for someone as novice as me in terms of almost every aspect in its creation. Despite this I'm quite satisfied with how it turned out, generally speaking. The controller's design revolves around two halves, the flower, which controls command inputs, and the sword, which controls general movement around the game world, as well as healing.

Turning the sword handle either way will move the character in a certain direction, either left or right. Pushing the sword up or down will either use a healing prayer, if you push it upwards, or cause the player to look down. The latter input was chosen over other inputs because it allows the player to slam attack, which while awkward in this setup, is possible and necessary to advance in certain parts of the game.

The flower controls inputs based off of gesture, moving your hand in certain ways in front of the flower opposite the sword will cause one of several inputs to occur, jump, attack, dodge, and interact. These are all the inputs necessary to advance in the game, up to the point where I've actually played it. They include jumping, attacking, blocking/dodging, and interact/hook. These inputs are the bare minimum necessary to advance, with perhaps the exception of switching spirit sets over. This would have been controlled with other sensors initially, though this was found to be unfeasible as it was outside of my programming capabilities. Moreover the flower covers proved too much for the sensors to handle, so the final version needed its sensor mounted on the exterior.

Conceptually the sword is supposed to represent the knight, who is the guiding spirit that follows your character throughout the game, providing useful advice and encouraging your character as she travels. The flowers are meant to resemble the healing lilies found throughout the game, as well as tie back into the game's namesake. They also represent the player character, who is a young girl of upstanding purity, hence the white coloration. The game also sees the player control various spirits, who do all of the actual combat for you, so moving your hand around is comparable to commanding the spirits as you fight, and is actually the part of the controller I would most like to expand on given the opportunity.

I would like to ask of reviewers what I could do to make the inputs feel smoother, as it is somewhat awkward to control inputs through hand movement, and it can get tiring at times. So I would like to know if the gesture controls are acceptable or if they need refining/replacing. I would also like to know if more feedback would be necessary, the switch and potentiometer feel fine already, in that regard, so I would mostly be looking for suggestions when relating to the sensor(s).

I also would've liked to add a few buttons, one on the pommel for switching spirits, and either one or several on the handguard for using the several other minor spirits you can take with you, though the latter would also be possible if I were to better acquaintance myself with using multiple sensors.




#include <Adafruit_APDS9960.h>

#include <Keyboard.h>
#include <KeyboardLayout.h>
#include <Keyboard_da_DK.h>
#include <Keyboard_de_DE.h>
#include <Keyboard_es_ES.h>
#include <Keyboard_fr_FR.h>
#include <Keyboard_it_IT.h>
#include <Keyboard_sv_SE.h>


#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>

//Setup sensors, currently only 1
Adafruit_APDS9960 apds;

void setup() {
  // put your setup code here, to run once:

  //Begin CircuitPlayground, followed by apds1
  Serial.begin(9600);
  delay(100);
  apds.begin();

  //Enable proximity and gesture detection for apds1
  apds.enableProximity(true);
  apds.enableGesture(true);
  apds.setProximityInterruptThreshold(0, 255);


  //Setup Pins
  pinMode(A1,INPUT);
  pinMode(9,INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);

}

void loop() {
  // put your main code here, to run repeatedly:

  //Setup Variables
  int turnVariable = analogRead(A1);
  int switchVariable1 = digitalRead(9);
  int switchVariable2 = digitalRead(10);

  //Serial.println(turnVariable);
  //First, we do the if statements for the switch(up/down input)
  if(switchVariable1 == 1 && switchVariable2 == 0)
  {
    Keyboard.release('w');
    Keyboard.press('s');
    delay(1);
  }

  if(switchVariable1 == 0 && switchVariable2 == 1)
  {
    /*Keyboard.release('s');
    Keyboard.press('w');*/
    Keyboard.println(',');
    delay(1);
  }

  if(switchVariable1 != 0 && switchVariable2 != 0)
  {
    Keyboard.release('w');
    Keyboard.release('s');
    delay(1);
  }

  //Next, are the switch statements for the potetiometer (left/right)
  if(turnVariable <= 350)
  {
    Keyboard.release('a');
    Keyboard.press('d');
    delay(1);
  }

  if(turnVariable >= 550)
  {
    Keyboard.release('d');
    Keyboard.press('a');
    delay(1);
  }

  if(turnVariable < 550 && turnVariable > 350)
  {
    Keyboard.release('a');
    Keyboard.release('d');
    delay(1);
  }
  uint8_t gesture = apds.readGesture();
    if(gesture == APDS9960_DOWN)
    {
      Keyboard.println("C");
      delay(25);
    }
    if(gesture == APDS9960_UP)
    {
      Keyboard.println("X");
      delay(25);
    }
    if(gesture == APDS9960_LEFT)
    {
      Keyboard.println("Z");
      delay(25);
    }
    if(gesture == APDS9960_RIGHT)
    {
      Keyboard.println("V");
      delay(25);
    }

  uint8_t proximityData = apds.readProximity();
  Serial.println(proximityData);

}

 








"Nidhogg" Rapier Controller








 My controller is modeled after a traditional rapier and is intended to be used to play the fencing game "Nidhogg." In Nidhogg, you are locked in a fencing duel with a computer or another player. The mechanics are rather basic. They involve changing your stance by pressing the up and down buttons, moving left and right, and attacking from whichever stance you have chosen. I believe that this simplicity in the controls is what gives the game its depth. The game is rather small, so it wasn’t able to take off, but this game’s fast-paced combat allows for a fun experience.

I wanted to capture Nidhogg’s fast-paced gameplay with a controller modeled after a rapier since it’s a fencing game. I like to imagine two players dueling at an arcade cabinet with a controller similar to the one I have created. To use it, you simply tilt in the directions to move left and right, raise your sword, and thrust. At first, it feels a bit weird to use in a 2D environment, but after playing around, you kind of get the hang of the weird controls.

There are definitely some ways I wish I could have improved on the design, the main one being a fully Bluetooth/wireless setup. Currently, the circuit playground is separate from the controller, with the motion sensors being what make up the controller; however, in my original sketch, I wanted to have the circuit playground inside of the controller as well. In order to make it fully wireless, there would also need to be room for a battery as well, so I would’ve needed a larger-sized controller. This would give more room and would make it feel more natural to hold. 

One question I have is how I would go about adding this space and where to put the inner components. Would simply increasing the height of the hand guard suffice, or should the entire controller size be increased?

Code:

// Full orientation sensing using NXP/Madgwick/Mahony and a range of 9-DoF
// sensor sets.
// You *must* perform a magnetic calibration before this code will work.
//
// To view this data, use the Arduino Serial Monitor to watch the
// scrolling angles, or run the OrientationVisualiser example in Processing.
// Based on  https://github.com/ /NXPMotionSense with adjustments
// to Adafruit Sensor interface and SensorLab

#include <Adafruit_SensorLab.h>
#include <Adafruit_Sensor_Calibration.h>
#include <Adafruit_AHRS.h>
#include "Adafruit_TinyUSB.h"
#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>

uint8_t const desc_hid_report[] = {
  TUD_HID_REPORT_DESC_KEYBOARD()
};

Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);

// pick your filter! slower == better quality output
Adafruit_NXPSensorFusion filter;  // slowest
//Adafruit_Madgwick filter;  // faster than NXP
//Adafruit_Mahony filter;  // fastest

#define FILTER_UPDATE_RATE_HZ 100
uint32_t timestamp;

Adafruit_SensorLab lab;
Adafruit_Sensor *accelerometer, *gyroscope, *magnetometer;

#if defined(ADAFRUIT_SENSOR_CALIBRATION_USE_EEPROM)
Adafruit_Sensor_Calibration_EEPROM cal;
#else
Adafruit_Sensor_Calibration_SDFat cal;
#endif

const int debounce = 100;
const int thresh = 500;

void setup() {
  //keyboard
  CircuitPlayground.begin();
  usb_hid.begin();

  Serial.begin(115200);
  while (!Serial) yield();

  Serial.println(F("Sensor Lab - IMU AHRS!"));
  lab.begin();

  if (!cal.begin()) {
    Serial.println("Failed to initialize calibration helper");
  } else if (!cal.loadCalibration()) {
    Serial.println("No calibration loaded/found");
  }

  Serial.println("Looking for a magnetometer");
  magnetometer = lab.getMagnetometer();
  if (!magnetometer) {
    Serial.println(F("Could not find a magnetometer!"));
    while (1) yield();
  }

  Serial.println("Looking for a gyroscope");
  gyroscope = lab.getGyroscope();
  if (!gyroscope) {
    Serial.println(F("Could not find a gyroscope!"));
    while (1) yield();
  }

  Serial.println("Looking for a accelerometer");
  accelerometer = lab.getAccelerometer();
  if (!accelerometer) {
    Serial.println(F("Could not find a accelerometer!"));
    while (1) yield();
  }

  accelerometer->printSensorDetails();
  gyroscope->printSensorDetails();
  magnetometer->printSensorDetails();

  filter.begin(FILTER_UPDATE_RATE_HZ);
  timestamp = millis();

  Wire.setClock(400000);  // 400KHz


}


void loop() {

  uint8_t const report_id = 0;
  uint8_t const modifier = 0;
  uint8_t keycode[6] = { 0 };

  float roll, pitch, heading;
  float gx, gy, gz;

  if ((millis() - timestamp) < (1000 / FILTER_UPDATE_RATE_HZ)) {
    return;
  }
  timestamp = millis();
  // Read the motion sensors
  sensors_event_t accel, gyro, mag;
  accelerometer->getEvent(&accel);
  gyroscope->getEvent(&gyro);
  magnetometer->getEvent(&mag);
  //Serial.print("I2C took "); Serial.print(millis()-timestamp); Serial.println(" ms");

  cal.calibrate(mag);
  cal.calibrate(accel);
  cal.calibrate(gyro);
  // Gyroscope needs to be converted from Rad/s to Degree/s
  // the rest are not unit-important
  gx = gyro.gyro.x * SENSORS_RADS_TO_DPS;
  gy = gyro.gyro.y * SENSORS_RADS_TO_DPS;
  gz = gyro.gyro.z * SENSORS_RADS_TO_DPS;

  // Update the SensorFusion filter
  filter.update(gx, gy, gz,
                accel.acceleration.x, accel.acceleration.y, accel.acceleration.z,
                mag.magnetic.x, mag.magnetic.y, mag.magnetic.z);
  //Serial.print("Update took "); Serial.print(millis()-timestamp); Serial.println(" ms");

  /*Serial.print("Raw: ");
  Serial.print(accel.acceleration.x, 4);
  Serial.print(", ");
  Serial.print(accel.acceleration.y, 4);
  Serial.print(", ");
  Serial.print(accel.acceleration.z, 4);
  Serial.print(", ");
  Serial.print(gx, 4);
  Serial.print(", ");
  Serial.print(gy, 4);
  Serial.print(", ");
  Serial.print(gz, 4);
  Serial.print(", ");
  Serial.print(mag.magnetic.x, 4);
  Serial.print(", ");
  Serial.print(mag.magnetic.y, 4);
  Serial.print(", ");
  Serial.print(mag.magnetic.z, 4);
  Serial.println("");*/

  // print the heading, pitch and roll
  roll = filter.getRoll();
  pitch = filter.getPitch();
  heading = filter.getYaw();
 /* Serial.print("Orientation: ");
  Serial.print(heading);
  Serial.print(" ");
  Serial.print(pitch);
  Serial.print(" ");
  Serial.println(roll);
  Serial.print("Took ");
  Serial.print(millis() - timestamp);
  Serial.println(" ms");*/



  if (roll > 0 && digitalRead(CPLAY_SLIDESWITCHPIN))  //move left
  {
    keycode[0] = HID_KEY_A;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(debounce);
    usb_hid.keyboardRelease(0);
    Serial.print("Roll: (should be greater than 0): ");
    Serial.print(roll);
    Serial.println("");

  }
  delay(debounce);

  if (roll < 0 && digitalRead(CPLAY_SLIDESWITCHPIN))  //move right
  {
    keycode[0] = HID_KEY_D;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(debounce);
    usb_hid.keyboardRelease(0);
    Serial.print("Roll: (should be less than 0): ");
    Serial.print(roll);
    Serial.println("");

  }
  delay(debounce);

  if (pitch < 0 && digitalRead(CPLAY_SLIDESWITCHPIN))  //raise stance up
  {
    keycode[0] = HID_KEY_W;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(debounce);
    usb_hid.keyboardRelease(0);
    Serial.print("Pitch: Should be < 0): ");
    Serial.print(pitch);
    Serial.println("");

  }
  delay(debounce);
  if (pitch > 0 && pitch < 30 && digitalRead(CPLAY_SLIDESWITCHPIN))  //lower stance down
  {
    keycode[0] = HID_KEY_S;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(debounce);
    usb_hid.keyboardRelease(0);
    Serial.print("Pitch: Should be between 0 and 30): ");
    Serial.print(pitch);
    Serial.println("");
  }
  delay(debounce);
  if (accel.acceleration.z > 1 && digitalRead(CPLAY_SLIDESWITCHPIN))  // thrust
  {
    keycode[0] = HID_KEY_F;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(10);
    usb_hid.keyboardRelease(0);

    Serial.print("Accel: Should be greater than 10 ): ");
    Serial.print(accel.acceleration.z, 4);
    Serial.println("");
  }
  delay(debounce);
}

Video:

https://youtu.be/Wxp7VUb9rM0