Brandon Yee / Mbed 2 deprecated Slingshot

Dependencies:   ADXL345 DebounceIn USBDevice mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed USB Slingshot, 
00002  *
00003  * Copyright (c) 2010-2011 mbed.org, MIT License
00004  * 
00005  * smokrani, sford
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00008  * and associated documentation files (the "Software"), to deal in the Software without
00009  * restriction, including without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00011  * Software is furnished to do so, subject to the following conditions:
00012  * 
00013  *  The above copyright notice and this permission notice shall be included in all copies or
00014  * substantial portions of the Software.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00017  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00018  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00021  
00022  Edited to use slider/pushbutton input instead of stretch sensor by Joshua Schrader and Brandon Yee, 2012
00023  
00024  */
00025 
00026 #include "DebounceIn.h"
00027 #include "mbed.h"
00028 #include "USBMouse.h"
00029 #include "ADXL345.h"
00030 
00031 USBMouse mouse;
00032 ADXL345 accelerometer(p5, p6, p7, p8);
00033 AnalogIn stretch_sensor(p15);
00034 DebounceIn button(p13);
00035 float str;
00036 int push;
00037 BusOut leds(LED1, LED2, LED3, LED4);
00038 
00039 // Return slingshot angle in radians, up > 0 > down
00040 float get_angle() {
00041     int readings[3];
00042     accelerometer.getOutput(readings);
00043     float x = (int16_t)readings[0];
00044     float z = (int16_t)readings[2];
00045     return atan(z / x);    
00046 }
00047 
00048 // Return normalised stretch value based on bounds of all readings seen
00049 float get_stretch() {
00050     static float min_strength = 0.7;
00051     static float max_strength = 0.7;
00052     float current_strength = stretch_sensor.read();
00053     if(current_strength > max_strength) { max_strength = current_strength; }
00054     if(current_strength < min_strength) { min_strength = current_strength; }
00055     float stretch = (current_strength - min_strength) / (max_strength - min_strength);
00056     return 1.0 - stretch;
00057 }
00058 
00059 // move mouse to a location relative to the start point, stepping as needed
00060 void move_mouse(int x, int y) {
00061     const int STEP = 10;
00062     static int current_x = 0;
00063     static int current_y = 0;
00064     
00065     int move_x = x - current_x;
00066     int move_y = y - current_y; 
00067 
00068     // Move the mouse, in steps of max step size to ensure it is picked up by OS
00069     while(move_x > STEP) { mouse.move(STEP, 0); move_x -= STEP; }
00070     while(move_x < -STEP) { mouse.move(-STEP, 0); move_x += STEP; }
00071     while(move_y > STEP) { mouse.move(0, STEP); move_y -= STEP; }
00072     while(move_y < -STEP) { mouse.move(0, -STEP); move_y += STEP; }
00073     mouse.move(move_x, move_y);
00074     
00075     current_x = x;
00076     current_y = y;
00077 }
00078 
00079 template <class T>
00080 T filter(T* array, int len, T value) {
00081     T mean = 0.0;
00082     for(int i = 0; i<len - 1; i++) {
00083         mean += array[i + 1];
00084         array[i] = array[i + 1];
00085     }
00086     mean += value;
00087     array[len - 1] = value;
00088     return mean / (T)len;
00089 }
00090 
00091 typedef enum {
00092     WAITING = 2,
00093     AIMING = 4,
00094     FIRING = 8
00095 } state_t;
00096 
00097 int main() {
00098     leds = 1;
00099 
00100     // setup accelerometer
00101     accelerometer.setPowerControl(0x00);
00102     accelerometer.setDataFormatControl(0x0B);
00103     accelerometer.setDataRate(ADXL345_3200HZ);
00104     accelerometer.setPowerControl(0x08);
00105 
00106     state_t state = WAITING;    
00107     Timer timer;
00108 
00109     float angles[8] = {0};
00110     
00111     while(1) {        
00112     
00113         // Check button        
00114         push = !button;
00115 
00116         // get the slingshot parameters
00117         float stretch = get_stretch();
00118         float this_angle = get_angle();
00119 
00120         // apply some filtering
00121         float angle = filter(angles, 8, this_angle);
00122             
00123         leds = state;
00124                 
00125         // act based on the current state
00126         switch (state) {
00127             case WAITING:
00128                 if(stretch > 0.2) {             // significant stretch, considered starting 
00129                     mouse.press(MOUSE_LEFT);
00130                     state = AIMING;
00131                 }
00132                 break;
00133 
00134             case AIMING:
00135                 if(push) { // push button while aiming, considered a fire
00136                     mouse.release(MOUSE_LEFT);
00137                     move_mouse(0, 0);
00138                     timer.start();
00139                     wait(1);
00140                     state = FIRING;
00141                 } else {    //incrementally move mouse
00142                     int x = 0.0 - cos(angle) * stretch * 40;
00143                     int y = sin(angle) * stretch * 40;
00144                     move_mouse(x, y);
00145                 }
00146                 break;
00147 
00148             case FIRING:
00149                 push = !button; //update button
00150                 if(push) {      // if pushed, return to ready
00151                     timer.stop();
00152                     timer.reset();
00153                     state = WAITING;
00154                     wait(.5);
00155                 }      
00156                 break;
00157         };
00158         
00159         wait(0.01);
00160     }
00161 }