Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 00023 #include "mbed.h" 00024 #include "USBMouse.h" 00025 #include "ADXL345.h" 00026 00027 // Physical interfaces 00028 USBMouse mouse; 00029 ADXL345 accelerometer(p5, p6, p7, p8); 00030 AnalogIn stretch_sensor(p15); 00031 BusOut leds(LED1, LED2, LED3, LED4); 00032 00033 // Return slingshot angle in radians, up > 0 > down 00034 float get_angle() { 00035 int readings[3]; 00036 accelerometer.getOutput(readings); 00037 float x = (int16_t)readings[0]; 00038 float z = (int16_t)readings[2]; 00039 return atan(z / x); 00040 } 00041 00042 // Return normalised stretch value based on bounds of all readings seen 00043 float get_stretch() { 00044 static float min_strength = 0.7; 00045 static float max_strength = 0.7; 00046 float current_strength = stretch_sensor.read(); 00047 if(current_strength > max_strength) { max_strength = current_strength; } 00048 if(current_strength < min_strength) { min_strength = current_strength; } 00049 float stretch = (current_strength - min_strength) / (max_strength - min_strength); 00050 return 1.0 - stretch; 00051 } 00052 00053 // move mouse to a location relative to the start point, stepping as needed 00054 void move_mouse(int x, int y) { 00055 const int STEP = 10; 00056 static int current_x = 0; 00057 static int current_y = 0; 00058 00059 int move_x = x - current_x; 00060 int move_y = y - current_y; 00061 00062 // Move the mouse, in steps of max step size to ensure it is picked up by OS 00063 while(move_x > STEP) { mouse.move(STEP, 0); move_x -= STEP; } 00064 while(move_x < -STEP) { mouse.move(-STEP, 0); move_x += STEP; } 00065 while(move_y > STEP) { mouse.move(0, STEP); move_y -= STEP; } 00066 while(move_y < -STEP) { mouse.move(0, -STEP); move_y += STEP; } 00067 mouse.move(move_x, move_y); 00068 00069 current_x = x; 00070 current_y = y; 00071 } 00072 00073 template <class T> 00074 T filter(T* array, int len, T value) { 00075 T mean = 0.0; 00076 for(int i = 0; i<len - 1; i++) { 00077 mean += array[i + 1]; 00078 array[i] = array[i + 1]; 00079 } 00080 mean += value; 00081 array[len - 1] = value; 00082 return mean / (T)len; 00083 } 00084 00085 typedef enum { 00086 WAITING = 2, 00087 AIMING = 4, 00088 FIRING = 8 00089 } state_t; 00090 00091 int main() { 00092 leds = 1; 00093 00094 // setup accelerometer 00095 accelerometer.setPowerControl(0x00); 00096 accelerometer.setDataFormatControl(0x0B); 00097 accelerometer.setDataRate(ADXL345_3200HZ); 00098 accelerometer.setPowerControl(0x08); 00099 00100 state_t state = WAITING; 00101 Timer timer; 00102 00103 float angles[8] = {0}; 00104 float stretches[8] = {0}; 00105 00106 while(1) { 00107 00108 // get the slingshot parameters 00109 float this_stretch = get_stretch(); 00110 float this_angle = get_angle(); 00111 00112 // apply some filtering 00113 float stretch = filter(stretches, 8, this_stretch); 00114 float angle = filter(angles, 8, this_angle); 00115 00116 leds = state; 00117 00118 // act based on the current state 00119 switch (state) { 00120 case WAITING: 00121 if(stretch > 0.5) { // significant stretch, considered starting 00122 mouse.press(MOUSE_LEFT); 00123 state = AIMING; 00124 } 00125 break; 00126 00127 case AIMING: 00128 if(stretch - this_stretch > 0.1) { // rapid de-stretch, considered a fire 00129 mouse.release(MOUSE_LEFT); 00130 move_mouse(0, 0); 00131 timer.start(); 00132 state = FIRING; 00133 } else { 00134 int x = 0.0 - cos(angle) * stretch * 200; 00135 int y = sin(angle) * stretch * 200; 00136 move_mouse(x, y); 00137 } 00138 break; 00139 00140 case FIRING: 00141 if(timer > 3.0) { 00142 timer.stop(); 00143 timer.reset(); 00144 state = WAITING; 00145 } 00146 break; 00147 }; 00148 00149 wait(0.01); 00150 } 00151 }
Generated on Tue Jul 12 2022 13:23:58 by
