Control the wondrous spinning-frog game of Zuma's Revenge with a rotating chair and an Airzooka. Maps compass rotation, flex sensor and push button input to USB actions to control Zuma's Revenge (http://www.popcap.com/games/zumas-revenge/online)

Dependencies:   LSM303DLHC mbed

Note that content for USB HID and USB Device is actually from the USBDevice mbed library. However, we made a couple of small changes to this library (allowing USB clicks at a particular location) that required us to break it off from the main project if we wanted to publish without pushing upstream.

Committer:
andrewhead
Date:
Mon Sep 29 01:12:20 2014 +0000
Revision:
0:4df415dde990
Initial Commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewhead 0:4df415dde990 1 #include "mbed.h"
andrewhead 0:4df415dde990 2 #include "LSM303DLHC.h"
andrewhead 0:4df415dde990 3 #include "USBMouseKeyboard.h"
andrewhead 0:4df415dde990 4
andrewhead 0:4df415dde990 5
andrewhead 0:4df415dde990 6 USBMouseKeyboard mouseKeyboard(ABS_MOUSE);
andrewhead 0:4df415dde990 7 LSM303DLHC compass(PTC11, PTC10);
andrewhead 0:4df415dde990 8 InterruptIn switchButton(D13);
andrewhead 0:4df415dde990 9 AnalogIn fireButton(A0);
andrewhead 0:4df415dde990 10
andrewhead 0:4df415dde990 11
andrewhead 0:4df415dde990 12 const float FLEX_THRESHOLD = .6;
andrewhead 0:4df415dde990 13 float lastFlexValue = 0;
andrewhead 0:4df415dde990 14 bool spaceHit = false;
andrewhead 0:4df415dde990 15
andrewhead 0:4df415dde990 16
andrewhead 0:4df415dde990 17 void hitSpace(void) {
andrewhead 0:4df415dde990 18 /* Register trigger that the SPACE control button has been hit */
andrewhead 0:4df415dde990 19 spaceHit = true;
andrewhead 0:4df415dde990 20 }
andrewhead 0:4df415dde990 21
andrewhead 0:4df415dde990 22
andrewhead 0:4df415dde990 23 bool wasFlexReleased(void) {
andrewhead 0:4df415dde990 24 /* Check to see whether the flex sensor was released according to predetermined threshold. */
andrewhead 0:4df415dde990 25 bool released = false;
andrewhead 0:4df415dde990 26 float flexValue = fireButton.read();
andrewhead 0:4df415dde990 27 if ((lastFlexValue > FLEX_THRESHOLD) && (flexValue < FLEX_THRESHOLD)) {
andrewhead 0:4df415dde990 28 released = true;
andrewhead 0:4df415dde990 29 }
andrewhead 0:4df415dde990 30 lastFlexValue = flexValue;
andrewhead 0:4df415dde990 31 return released;
andrewhead 0:4df415dde990 32 }
andrewhead 0:4df415dde990 33
andrewhead 0:4df415dde990 34
andrewhead 0:4df415dde990 35 int main(void) {
andrewhead 0:4df415dde990 36
andrewhead 0:4df415dde990 37 /* Variables for sensing orientation */
andrewhead 0:4df415dde990 38 int16_t x_center = (X_MAX_ABS - X_MIN_ABS)/2;
andrewhead 0:4df415dde990 39 int16_t y_center = (Y_MAX_ABS - Y_MIN_ABS)/2;
andrewhead 0:4df415dde990 40 float xRot, yRot, nullRot;
andrewhead 0:4df415dde990 41 int16_t xPos, yPos;
andrewhead 0:4df415dde990 42
andrewhead 0:4df415dde990 43 /* When the switch button is hit, register SPACE getting hit */
andrewhead 0:4df415dde990 44 switchButton.fall(&hitSpace);
andrewhead 0:4df415dde990 45
andrewhead 0:4df415dde990 46 while (1) {
andrewhead 0:4df415dde990 47 /* This loop just checks sensors and maps them to keyboard and mouse motions that
andrewhead 0:4df415dde990 48 will accurately enough control the game that has been opened in a browser
andrewhead 0:4df415dde990 49 and centered in the middle of the screen. */
andrewhead 0:4df415dde990 50
andrewhead 0:4df415dde990 51 /* Detect rotation from the compass. We don't care about several compass variables,
andrewhead 0:4df415dde990 52 (the ones returned into the nullRot variable) so we just pass in an unused variable. */
andrewhead 0:4df415dde990 53 /* The x and y that we compute don't appear to be perfectly accurate mappings to the
andrewhead 0:4df415dde990 54 rotating compass -- the radius of the circle changes as one rotates. But the
andrewhead 0:4df415dde990 55 heuristic effect we get below is good enough for playing Zuma. */
andrewhead 0:4df415dde990 56 compass.read(&nullRot, &nullRot, &nullRot, &xRot, &yRot, &nullRot);
andrewhead 0:4df415dde990 57 xPos = x_center + int16_t(xRot * 12000);
andrewhead 0:4df415dde990 58 yPos = y_center + int16_t(yRot * 12000);
andrewhead 0:4df415dde990 59
andrewhead 0:4df415dde990 60 /* Move the mouse to a rotated position on a circle centered at the middle of the screen */
andrewhead 0:4df415dde990 61 mouseKeyboard.move(xPos, yPos);
andrewhead 0:4df415dde990 62
andrewhead 0:4df415dde990 63 /* Check on flex sensor to see if ball was fired */
andrewhead 0:4df415dde990 64 bool fired = wasFlexReleased();
andrewhead 0:4df415dde990 65 if (fired) {
andrewhead 0:4df415dde990 66 mouseKeyboard.click(xPos, yPos, MOUSE_LEFT);
andrewhead 0:4df415dde990 67 }
andrewhead 0:4df415dde990 68
andrewhead 0:4df415dde990 69 /* Check to see if button for hitting SPACE was triggered */
andrewhead 0:4df415dde990 70 if (spaceHit == true) {
andrewhead 0:4df415dde990 71 mouseKeyboard.printf(" ");
andrewhead 0:4df415dde990 72 spaceHit = false;
andrewhead 0:4df415dde990 73 }
andrewhead 0:4df415dde990 74
andrewhead 0:4df415dde990 75 /* Put a healthy amount of space between each iteration */
andrewhead 0:4df415dde990 76 wait_ms(10);
andrewhead 0:4df415dde990 77 }
andrewhead 0:4df415dde990 78 }