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

Dependencies:   PinDetect USBDevice mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /**
00002  * Interactive Device Design, Fall 2014
00003  * Homework 3 - Mario Kart Wii Game Controller
00004  *
00005  * Elizabeth Lin
00006  * Doug Cook
00007  * Maruchi Kim
00008  *
00009  * This program will setup the mbed device to act
00010  * as a Gamecube controller by emulating a mouse
00011  * with input data from an accelerometer. It also
00012  * provides buttons to support other gamepad
00013  * functions specific to Mario Kart.
00014  *
00015  * The Dolphin Emulator (dolphin-emu.org) can be
00016  * configured to accept this device (a USB Mouse)
00017  * as the joystick for an emulated Wiimote/GCPad.
00018  *
00019  */
00020 
00021 #include "mbed.h"
00022 #include "USBMouseKeyboard.h"
00023 #include "PinDetect.h"
00024 #include "KeyManager.h"
00025 
00026 // **********************************************************
00027 // constants
00028 const int PINDETECT_SAMPLE_FREQUENCY = 20000;
00029 const int GAIN = 15000;
00030 const int ADAFRUIT_ACC_RANGE_MIDPOINT = 32768;
00031 // **********************************************************
00032 
00033 // **********************************************************
00034 // Adafruit Accelerometer Input and calibration variables
00035 AnalogIn xAxisIn(A2);
00036 AnalogIn yAxisIn(A1);
00037 AnalogIn zAxisIn(A0);
00038 uint16_t addBias = false;
00039 int bias = 0;
00040 int sensitivity = 1;
00041 float read_correct(AnalogIn input) {
00042     float result = (float) input.read_u16();
00043     result = result - ADAFRUIT_ACC_RANGE_MIDPOINT;
00044     return (result - (float)bias) / (float) sensitivity;
00045 }
00046 // **********************************************************
00047 
00048 // LED and Serial Interface for 'Ready' feedback and debugging
00049 DigitalOut greenLed(LED2);
00050 Serial pc(USBTX, USBRX);
00051 
00052 // **********************************************************
00053 // minimum function for unsigned 16-bit integers
00054 uint16_t min(uint16_t a, uint16_t b) {
00055         return (a < b) ? a : b;
00056 }
00057 // **********************************************************
00058 
00059 int main() {
00060     // Perform accelerometer calibration at startup
00061     // (assume the accelerometer is flat and
00062     // face-down on a level surface).
00063     greenLed = 1;
00064     uint16_t initialX = xAxisIn.read_u16();
00065     uint16_t correctX = 32768;
00066     bias = initialX - correctX;
00067     sensitivity = (zAxisIn.read_u16() - 32768 - bias);
00068     greenLed = 0;
00069 
00070     // Keyboard init and config
00071     USBMouseKeyboard key_mouse = USBMouseKeyboard(ABS_MOUSE);
00072     KeyManager keys = KeyManager();
00073     PinDetect buttonA(D7);
00074     PinDetect buttonB(D6);
00075     buttonA.mode(PullUp);
00076     buttonB.mode(PullUp);
00077     buttonA.setSampleFrequency( PINDETECT_SAMPLE_FREQUENCY );
00078     buttonA.attach_asserted(&keys, &KeyManager::keyAOn);
00079     buttonA.attach_deasserted(&keys, &KeyManager::keyAOff);
00080     buttonB.setSampleFrequency( PINDETECT_SAMPLE_FREQUENCY );
00081     buttonB.attach_asserted(&keys, &KeyManager::keyBOn);
00082     buttonB.attach_deasserted(&keys, &KeyManager::keyBOff);
00083 
00084     // analog-in to joystick calculation variables
00085     uint16_t xAxis;
00086     uint16_t yAxis;
00087     uint16_t xCenter = (X_MAX_ABS - X_MIN_ABS)/2;
00088     uint16_t yCenter = (Y_MAX_ABS - Y_MIN_ABS)/2;
00089     uint32_t xOrigin = xCenter;
00090     uint32_t yOrigin = yCenter;
00091     uint16_t lastXAxis = 0;
00092     uint16_t lastYAxis = 0;
00093 
00094     while(1) {
00095         xAxis = min(floor(.5*lastXAxis + .5*(uint16_t)(floor(atan(read_correct(xAxisIn)/read_correct(yAxisIn))*GAIN)+xOrigin)),X_MAX_ABS);
00096         yAxis = floor(.5*lastYAxis + .5*(uint16_t)(-1*floor(atan(read_correct(zAxisIn)/read_correct(yAxisIn))*GAIN)+yOrigin));
00097         lastXAxis = xAxis;
00098         lastYAxis = yAxis;
00099         key_mouse.move(xAxis, yAxis);
00100 
00101         // read button pads
00102         if (keys.keysPressed()) {
00103             key_mouse.keyDown(keys.getCharacter());
00104         } else {
00105             key_mouse.keyUp();
00106         }
00107     }
00108 }