Code for Doug, Elizabeth, and Maruchi's team project: a Mario Kart controller.

Dependencies:   PinDetect USBDevice mbed

Committer:
douglasc
Date:
Mon Sep 29 06:55:14 2014 +0000
Revision:
0:0c8c5c9f7586
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
douglasc 0:0c8c5c9f7586 1 /**
douglasc 0:0c8c5c9f7586 2 * Interactive Device Design, Fall 2014
douglasc 0:0c8c5c9f7586 3 * Homework 3 - Mario Kart Wii Game Controller
douglasc 0:0c8c5c9f7586 4 *
douglasc 0:0c8c5c9f7586 5 * Elizabeth Lin
douglasc 0:0c8c5c9f7586 6 * Doug Cook
douglasc 0:0c8c5c9f7586 7 * Maruchi Kim
douglasc 0:0c8c5c9f7586 8 *
douglasc 0:0c8c5c9f7586 9 * This program will setup the mbed device to act
douglasc 0:0c8c5c9f7586 10 * as a Gamecube controller by emulating a mouse
douglasc 0:0c8c5c9f7586 11 * with input data from an accelerometer. It also
douglasc 0:0c8c5c9f7586 12 * provides buttons to support other gamepad
douglasc 0:0c8c5c9f7586 13 * functions specific to Mario Kart.
douglasc 0:0c8c5c9f7586 14 *
douglasc 0:0c8c5c9f7586 15 * The Dolphin Emulator (dolphin-emu.org) can be
douglasc 0:0c8c5c9f7586 16 * configured to accept this device (a USB Mouse)
douglasc 0:0c8c5c9f7586 17 * as the joystick for an emulated Wiimote/GCPad.
douglasc 0:0c8c5c9f7586 18 *
douglasc 0:0c8c5c9f7586 19 */
douglasc 0:0c8c5c9f7586 20
douglasc 0:0c8c5c9f7586 21 #include "mbed.h"
douglasc 0:0c8c5c9f7586 22 #include "USBMouseKeyboard.h"
douglasc 0:0c8c5c9f7586 23 #include "PinDetect.h"
douglasc 0:0c8c5c9f7586 24 #include "KeyManager.h"
douglasc 0:0c8c5c9f7586 25
douglasc 0:0c8c5c9f7586 26 // **********************************************************
douglasc 0:0c8c5c9f7586 27 // constants
douglasc 0:0c8c5c9f7586 28 const int PINDETECT_SAMPLE_FREQUENCY = 20000;
douglasc 0:0c8c5c9f7586 29 const int GAIN = 15000;
douglasc 0:0c8c5c9f7586 30 const int ADAFRUIT_ACC_RANGE_MIDPOINT = 32768;
douglasc 0:0c8c5c9f7586 31 // **********************************************************
douglasc 0:0c8c5c9f7586 32
douglasc 0:0c8c5c9f7586 33 // **********************************************************
douglasc 0:0c8c5c9f7586 34 // Adafruit Accelerometer Input and calibration variables
douglasc 0:0c8c5c9f7586 35 AnalogIn xAxisIn(A2);
douglasc 0:0c8c5c9f7586 36 AnalogIn yAxisIn(A1);
douglasc 0:0c8c5c9f7586 37 AnalogIn zAxisIn(A0);
douglasc 0:0c8c5c9f7586 38 uint16_t addBias = false;
douglasc 0:0c8c5c9f7586 39 int bias = 0;
douglasc 0:0c8c5c9f7586 40 int sensitivity = 1;
douglasc 0:0c8c5c9f7586 41 float read_correct(AnalogIn input) {
douglasc 0:0c8c5c9f7586 42 float result = (float) input.read_u16();
douglasc 0:0c8c5c9f7586 43 result = result - ADAFRUIT_ACC_RANGE_MIDPOINT;
douglasc 0:0c8c5c9f7586 44 return (result - (float)bias) / (float) sensitivity;
douglasc 0:0c8c5c9f7586 45 }
douglasc 0:0c8c5c9f7586 46 // **********************************************************
douglasc 0:0c8c5c9f7586 47
douglasc 0:0c8c5c9f7586 48 // LED and Serial Interface for 'Ready' feedback and debugging
douglasc 0:0c8c5c9f7586 49 DigitalOut greenLed(LED2);
douglasc 0:0c8c5c9f7586 50 Serial pc(USBTX, USBRX);
douglasc 0:0c8c5c9f7586 51
douglasc 0:0c8c5c9f7586 52 // **********************************************************
douglasc 0:0c8c5c9f7586 53 // minimum function for unsigned 16-bit integers
douglasc 0:0c8c5c9f7586 54 uint16_t min(uint16_t a, uint16_t b) {
douglasc 0:0c8c5c9f7586 55 return (a < b) ? a : b;
douglasc 0:0c8c5c9f7586 56 }
douglasc 0:0c8c5c9f7586 57 // **********************************************************
douglasc 0:0c8c5c9f7586 58
douglasc 0:0c8c5c9f7586 59 int main() {
douglasc 0:0c8c5c9f7586 60 // Perform accelerometer calibration at startup
douglasc 0:0c8c5c9f7586 61 // (assume the accelerometer is flat and
douglasc 0:0c8c5c9f7586 62 // face-down on a level surface).
douglasc 0:0c8c5c9f7586 63 greenLed = 1;
douglasc 0:0c8c5c9f7586 64 uint16_t initialX = xAxisIn.read_u16();
douglasc 0:0c8c5c9f7586 65 uint16_t correctX = 32768;
douglasc 0:0c8c5c9f7586 66 bias = initialX - correctX;
douglasc 0:0c8c5c9f7586 67 sensitivity = (zAxisIn.read_u16() - 32768 - bias);
douglasc 0:0c8c5c9f7586 68 greenLed = 0;
douglasc 0:0c8c5c9f7586 69
douglasc 0:0c8c5c9f7586 70 // Keyboard init and config
douglasc 0:0c8c5c9f7586 71 USBMouseKeyboard key_mouse = USBMouseKeyboard(ABS_MOUSE);
douglasc 0:0c8c5c9f7586 72 KeyManager keys = KeyManager();
douglasc 0:0c8c5c9f7586 73 PinDetect buttonA(D7);
douglasc 0:0c8c5c9f7586 74 PinDetect buttonB(D6);
douglasc 0:0c8c5c9f7586 75 buttonA.mode(PullUp);
douglasc 0:0c8c5c9f7586 76 buttonB.mode(PullUp);
douglasc 0:0c8c5c9f7586 77 buttonA.setSampleFrequency( PINDETECT_SAMPLE_FREQUENCY );
douglasc 0:0c8c5c9f7586 78 buttonA.attach_asserted(&keys, &KeyManager::keyAOn);
douglasc 0:0c8c5c9f7586 79 buttonA.attach_deasserted(&keys, &KeyManager::keyAOff);
douglasc 0:0c8c5c9f7586 80 buttonB.setSampleFrequency( PINDETECT_SAMPLE_FREQUENCY );
douglasc 0:0c8c5c9f7586 81 buttonB.attach_asserted(&keys, &KeyManager::keyBOn);
douglasc 0:0c8c5c9f7586 82 buttonB.attach_deasserted(&keys, &KeyManager::keyBOff);
douglasc 0:0c8c5c9f7586 83
douglasc 0:0c8c5c9f7586 84 // analog-in to joystick calculation variables
douglasc 0:0c8c5c9f7586 85 uint16_t xAxis;
douglasc 0:0c8c5c9f7586 86 uint16_t yAxis;
douglasc 0:0c8c5c9f7586 87 uint16_t xCenter = (X_MAX_ABS - X_MIN_ABS)/2;
douglasc 0:0c8c5c9f7586 88 uint16_t yCenter = (Y_MAX_ABS - Y_MIN_ABS)/2;
douglasc 0:0c8c5c9f7586 89 uint32_t xOrigin = xCenter;
douglasc 0:0c8c5c9f7586 90 uint32_t yOrigin = yCenter;
douglasc 0:0c8c5c9f7586 91 uint16_t lastXAxis = 0;
douglasc 0:0c8c5c9f7586 92 uint16_t lastYAxis = 0;
douglasc 0:0c8c5c9f7586 93
douglasc 0:0c8c5c9f7586 94 while(1) {
douglasc 0:0c8c5c9f7586 95 xAxis = min(floor(.5*lastXAxis + .5*(uint16_t)(floor(atan(read_correct(xAxisIn)/read_correct(yAxisIn))*GAIN)+xOrigin)),X_MAX_ABS);
douglasc 0:0c8c5c9f7586 96 yAxis = floor(.5*lastYAxis + .5*(uint16_t)(-1*floor(atan(read_correct(zAxisIn)/read_correct(yAxisIn))*GAIN)+yOrigin));
douglasc 0:0c8c5c9f7586 97 lastXAxis = xAxis;
douglasc 0:0c8c5c9f7586 98 lastYAxis = yAxis;
douglasc 0:0c8c5c9f7586 99 key_mouse.move(xAxis, yAxis);
douglasc 0:0c8c5c9f7586 100
douglasc 0:0c8c5c9f7586 101 // read button pads
douglasc 0:0c8c5c9f7586 102 if (keys.keysPressed()) {
douglasc 0:0c8c5c9f7586 103 key_mouse.keyDown(keys.getCharacter());
douglasc 0:0c8c5c9f7586 104 } else {
douglasc 0:0c8c5c9f7586 105 key_mouse.keyUp();
douglasc 0:0c8c5c9f7586 106 }
douglasc 0:0c8c5c9f7586 107 }
douglasc 0:0c8c5c9f7586 108 }