Code for Doug, Elizabeth, and Maruchi's team project: a Mario Kart controller.
Dependencies: PinDetect USBDevice mbed
Revision 0:0c8c5c9f7586, committed 2014-09-29
- Comitter:
- douglasc
- Date:
- Mon Sep 29 06:55:14 2014 +0000
- Commit message:
- initial commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/KeyManager.h Mon Sep 29 06:55:14 2014 +0000
@@ -0,0 +1,91 @@
+/**
+ * Class KeyManager
+ *
+ * This class tracks the state of the four input
+ * buttons and returns state information and
+ * mappings.
+ *
+ */
+
+#ifndef KEYMANAGER
+#define KEYMANAGER
+
+#include <string>
+#include <ctype.h>
+
+class KeyManager {
+private:
+ // key definitions
+ bool keyA;
+ bool keyB;
+ bool keyC;
+ bool keyZ;
+
+public:
+
+ // constructor
+ KeyManager() {
+ keyA = false;
+ keyB = false;
+ keyC = false;
+ keyZ = false;
+ }
+
+ // DEBUG: return the status of which keys are pressed
+ char* getStatusString() {
+ std::string status = "the following keys are pressed:";
+ if (keyA) {
+ status += " A";
+ }
+ if (keyB) {
+ status += " B";
+ }
+ if (keyC) {
+ status += " C";
+ }
+ if (keyZ) {
+ status += " Z";
+ }
+ status += "\n";
+ return (char*)status.c_str();
+ }
+
+ // map the current code to its character
+ char getCharacter() {
+ if (keyA) {
+ return 'a';
+ }
+ if (keyB) {
+ return 'b';
+ }
+ if (keyC) {
+ return 'c';
+ }
+ if (keyZ) {
+ return 'z';
+ }
+ return '?';
+ }
+
+ // check whether any of the character keys or the space
+ // key are pressed
+ bool keysPressed() {
+ if (keyA || keyB || keyC || keyZ) {
+ return true;
+ }
+ return false;
+ }
+
+ // Interrupt callback functions
+ void keyAOn() { keyA = true; }
+ void keyAOff() { keyA = false; }
+ void keyBOn() { keyB = true; }
+ void keyBOff() { keyB = false; }
+ void keyCOn() { keyC = true; }
+ void keyCOff() { keyC = false; }
+ void keyZOn() { keyZ = true; }
+ void keyZOff() { keyZ = false; }
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PinDetect.lib Mon Sep 29 06:55:14 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/douglasc/code/PinDetect/#74bc6d7814e9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice.lib Mon Sep 29 06:55:14 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/douglasc/code/USBDevice/#283b977e638d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Sep 29 06:55:14 2014 +0000
@@ -0,0 +1,108 @@
+/**
+ * Interactive Device Design, Fall 2014
+ * Homework 3 - Mario Kart Wii Game Controller
+ *
+ * Elizabeth Lin
+ * Doug Cook
+ * Maruchi Kim
+ *
+ * This program will setup the mbed device to act
+ * as a Gamecube controller by emulating a mouse
+ * with input data from an accelerometer. It also
+ * provides buttons to support other gamepad
+ * functions specific to Mario Kart.
+ *
+ * The Dolphin Emulator (dolphin-emu.org) can be
+ * configured to accept this device (a USB Mouse)
+ * as the joystick for an emulated Wiimote/GCPad.
+ *
+ */
+
+#include "mbed.h"
+#include "USBMouseKeyboard.h"
+#include "PinDetect.h"
+#include "KeyManager.h"
+
+// **********************************************************
+// constants
+const int PINDETECT_SAMPLE_FREQUENCY = 20000;
+const int GAIN = 15000;
+const int ADAFRUIT_ACC_RANGE_MIDPOINT = 32768;
+// **********************************************************
+
+// **********************************************************
+// Adafruit Accelerometer Input and calibration variables
+AnalogIn xAxisIn(A2);
+AnalogIn yAxisIn(A1);
+AnalogIn zAxisIn(A0);
+uint16_t addBias = false;
+int bias = 0;
+int sensitivity = 1;
+float read_correct(AnalogIn input) {
+ float result = (float) input.read_u16();
+ result = result - ADAFRUIT_ACC_RANGE_MIDPOINT;
+ return (result - (float)bias) / (float) sensitivity;
+}
+// **********************************************************
+
+// LED and Serial Interface for 'Ready' feedback and debugging
+DigitalOut greenLed(LED2);
+Serial pc(USBTX, USBRX);
+
+// **********************************************************
+// minimum function for unsigned 16-bit integers
+uint16_t min(uint16_t a, uint16_t b) {
+ return (a < b) ? a : b;
+}
+// **********************************************************
+
+int main() {
+ // Perform accelerometer calibration at startup
+ // (assume the accelerometer is flat and
+ // face-down on a level surface).
+ greenLed = 1;
+ uint16_t initialX = xAxisIn.read_u16();
+ uint16_t correctX = 32768;
+ bias = initialX - correctX;
+ sensitivity = (zAxisIn.read_u16() - 32768 - bias);
+ greenLed = 0;
+
+ // Keyboard init and config
+ USBMouseKeyboard key_mouse = USBMouseKeyboard(ABS_MOUSE);
+ KeyManager keys = KeyManager();
+ PinDetect buttonA(D7);
+ PinDetect buttonB(D6);
+ buttonA.mode(PullUp);
+ buttonB.mode(PullUp);
+ buttonA.setSampleFrequency( PINDETECT_SAMPLE_FREQUENCY );
+ buttonA.attach_asserted(&keys, &KeyManager::keyAOn);
+ buttonA.attach_deasserted(&keys, &KeyManager::keyAOff);
+ buttonB.setSampleFrequency( PINDETECT_SAMPLE_FREQUENCY );
+ buttonB.attach_asserted(&keys, &KeyManager::keyBOn);
+ buttonB.attach_deasserted(&keys, &KeyManager::keyBOff);
+
+ // analog-in to joystick calculation variables
+ uint16_t xAxis;
+ uint16_t yAxis;
+ uint16_t xCenter = (X_MAX_ABS - X_MIN_ABS)/2;
+ uint16_t yCenter = (Y_MAX_ABS - Y_MIN_ABS)/2;
+ uint32_t xOrigin = xCenter;
+ uint32_t yOrigin = yCenter;
+ uint16_t lastXAxis = 0;
+ uint16_t lastYAxis = 0;
+
+ while(1) {
+ xAxis = min(floor(.5*lastXAxis + .5*(uint16_t)(floor(atan(read_correct(xAxisIn)/read_correct(yAxisIn))*GAIN)+xOrigin)),X_MAX_ABS);
+ yAxis = floor(.5*lastYAxis + .5*(uint16_t)(-1*floor(atan(read_correct(zAxisIn)/read_correct(yAxisIn))*GAIN)+yOrigin));
+ lastXAxis = xAxis;
+ lastYAxis = yAxis;
+ key_mouse.move(xAxis, yAxis);
+
+ // read button pads
+ if (keys.keysPressed()) {
+ key_mouse.keyDown(keys.getCharacter());
+ } else {
+ key_mouse.keyUp();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Sep 29 06:55:14 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1 \ No newline at end of file