How to Use MBED as a mouse
.from: http://mbed.org/cookbook/Slingshot
Check this in action!
So now you can kill pigs with a real USB Slingshot, by combining the two totally different worlds of carpentry and embedded systems!
XXXXXXXXXXXXXXXXXXXXXXXX main.cpp XXXXXXXXXXXXXXXXXXXXXXXXXXX
/* mbed USB Slingshot,
*
* Copyright (c) 2010-2011 mbed.org, MIT License
*
* smokrani, sford
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "mbed.h"
#include "USBMouse.h"
#include "ADXL345.h"
// Physical interfaces
USBMouse mouse;
ADXL345 accelerometer(p5, p6, p7, p8);
AnalogIn stretch_sensor(p15);
BusOut leds(LED1, LED2, LED3, LED4);
// Return slingshot angle in radians, up > 0 > down
float get_angle() {
int readings[3];
accelerometer.getOutput(readings);
float x = (int16_t)readings[0];
float z = (int16_t)readings[2];
return atan(z / x);
}
// Return normalised stretch value based on bounds of all readings seen
float get_stretch() {
static float min_strength = 0.7;
static float max_strength = 0.7;
float current_strength = stretch_sensor.read();
if(current_strength > max_strength) { max_strength = current_strength; }
if(current_strength < min_strength) { min_strength = current_strength; }
float stretch = (current_strength - min_strength) / (max_strength - min_strength);
return 1.0 - stretch;
}
// move mouse to a location relative to the start point, stepping as needed
void move_mouse(int x, int y) {
const int STEP = 10;
static int current_x = 0;
static int current_y = 0;
int move_x = x - current_x;
int move_y = y - current_y;
// Move the mouse, in steps of max step size to ensure it is picked up by OS
while(move_x > STEP) { mouse.move(STEP, 0); move_x -= STEP; }
while(move_x < -STEP) { mouse.move(-STEP, 0); move_x += STEP; }
while(move_y > STEP) { mouse.move(0, STEP); move_y -= STEP; }
while(move_y < -STEP) { mouse.move(0, -STEP); move_y += STEP; }
mouse.move(move_x, move_y);
current_x = x;
current_y = y;
}
template <class T>
T filter(T* array, int len, T value) {
T mean = 0.0;
for(int i = 0; i<len - 1; i++) {
mean += array[i + 1];
array[i] = array[i + 1];
}
mean += value;
array[len - 1] = value;
return mean / (T)len;
}
typedef enum {
WAITING = 2,
AIMING = 4,
FIRING = 8
} state_t;
int main() {
leds = 1;
// setup accelerometer
accelerometer.setPowerControl(0x00);
accelerometer.setDataFormatControl(0x0B);
accelerometer.setDataRate(ADXL345_3200HZ);
accelerometer.setPowerControl(0x08);
state_t state = WAITING;
Timer timer;
float angles[8] = {0};
float stretches[8] = {0};
while(1) {
// get the slingshot parameters
float this_stretch = get_stretch();
float this_angle = get_angle();
// apply some filtering
float stretch = filter(stretches, 8, this_stretch);
float angle = filter(angles, 8, this_angle);
leds = state;
// act based on the current state
switch (state) {
case WAITING:
if(stretch > 0.5) { // significant stretch, considered starting
mouse.press(MOUSE_LEFT);
state = AIMING;
}
break;
case AIMING:
if(stretch - this_stretch > 0.1) { // rapid de-stretch, considered a fire
mouse.release(MOUSE_LEFT);
move_mouse(0, 0);
timer.start();
state = FIRING;
} else {
int x = 0.0 - cos(angle) * stretch * 200;
int y = sin(angle) * stretch * 200;
move_mouse(x, y);
}
break;
case FIRING:
if(timer > 3.0) {
timer.stop();
timer.reset();
state = WAITING;
}
break;
};
wait(0.01);
}
}
XXXXXXXXXXXXXXXXXXXXXXXX test.cpp XXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "mbed.h"
#include "USBMouse.h"
#include "ADXL345.h"
USBMouse mouse;
ADXL345 acc(p5, p6, p7, p8);
AnalogIn strength(p15);
int main() {
//Initialize accelerometer
acc.setPowerControl(0x00);
acc.setDataFormatControl(0x0B);
acc.setDataRate(ADXL345_3200HZ);
acc.setPowerControl(0x08);
while (1) {
int readings[3];
acc.getOutput(readings); // test accelerometer
printf("acc: %i, %i, %i\r\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
uint16_t str = strength.read_u16(); // test stretch sensor
printf("strength: %d\r\n", str);
mouse.move(10, 10); // test USB relative mouse
wait(0.1);
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Here is the pinout table:
ADXL345 Signal Name | mbed pin |
---|---|
Vcc | Vout |
Gnd | Gnd |
SDA | p5 |
SDO | p6 |
SCL | p7 |
CS | p8 |
Stretch sensor | mbed pin |
One extremity | Vout |
The other | p15 |
USB connector | mbed pin |
Vcc | Vin |
Gnd | Gnd |
D+ | D+ |
D- | D- |
No comments:
Post a Comment