20 April 2025

Doom Controller Final Project - Austin Frunk and Brayan Soto


 Doom Controller



This controller is based on a skull motif that we feel is appropriate for the world of doom. In essence doom has always been an outlier in many ways and in its tone even dating back to the original doom game it has always been along the rock and heavy metal genres. We thought a skull motif was perfect for this world and we went further to stylize the skull fully as a hand drawn sketched style to make it our own as the skull is a scanned skull that is available publicly. Carving out the top of the skull to house the wires was something we focused on as well. 

Inputs - Outputs:

Accelerometer - WASD Keys

Microphone - Space Key

Unconventional Switch - Ctrl Key

The design of the controller thematically uses an unconventional switch to allow the player to fire by clicking the jaw. This gives feedback to the player on when the fire happens physically. Not only that the design allows the player to interact with the controller on a personal level that allows feedback by speaking into the controller and it responding in game. It is designed to allow you to be immersed in the world of doom and feel like you actively contributing to the metal power fantasy that is doom classic. 

What other doom style mechanics could you see out of controller out of this? Do you think we succeeded in design?

Video:



What we did:

Austin- Initial psudo code and coding of the controller, wiring of the controller, Playtesting

Brayan - Code Review, Playtesting, Print and Post Processing of Controller, Design of controller concept.

Code:

#include <Adafruit_CircuitPlayground.h>

#include <Keyboard.h>


const uint8_t BUTTON_PIN   = A3;  //pin for jaw


const float ACCEL_THRESHOLD   = 1.0;    // tilt sensitivity

const int   SOUND_THRESHOLD   = 10;    // microphone trigger level


bool lastState = HIGH;


void setup() {

  // Initialize Circuit Playground and Keyboard

  CircuitPlayground.begin();

  pinMode(BUTTON_PIN, INPUT_PULLUP);

  Keyboard.begin();

}


void loop() {


  //ACCELEROMETER - ARROW KEYS


  float x = CircuitPlayground.motionX();  // X tilt

  float y = CircuitPlayground.motionY();  // Y tilt



  // Up arrow for positive Y

  if (y > ACCEL_THRESHOLD) {

    Keyboard.press(KEY_UP_ARROW);

  } else {

    Keyboard.release(KEY_UP_ARROW);

  }


  // Down arrow for negative Y

  if (y < -ACCEL_THRESHOLD) {

    Keyboard.press(KEY_DOWN_ARROW);

  } else {

    Keyboard.release(KEY_DOWN_ARROW);

  }


  // Right arrow for positive X

  if (x > ACCEL_THRESHOLD) {

    Keyboard.press(KEY_RIGHT_ARROW);

  } else {

    Keyboard.release(KEY_RIGHT_ARROW);

  }


  // Left arrow for negative X

  if (x < -ACCEL_THRESHOLD) {

    Keyboard.press(KEY_LEFT_ARROW);

  } else {

    Keyboard.release(KEY_LEFT_ARROW);

  }



  // SOUND SENSOR - SPACE KEY


  int soundLevel = CircuitPlayground.soundSensor();


  if (soundLevel > SOUND_THRESHOLD) {

    Keyboard.press(' ');  // Press the space character

  } else {

    Keyboard.release(' '); 

  }


  // JAW CIRCUIT - LEFT CTRL

  

  bool currentState = digitalRead(BUTTON_PIN);


  if (currentState != lastState) {          // state changed?

    if (currentState == LOW) {              // switch just pressed

      Keyboard.press(KEY_LEFT_CTRL);                  // send any key you like

    } else {                                // switch just released

      Keyboard.release(KEY_LEFT_CTRL);

    }

    lastState = currentState;               // remember for next loop

  }


  delay(100);  // 100ms

}

Schematic:


Other Photos








 


No comments:

Post a Comment

Note: Only a member of this blog may post a comment.