Demo program for LCD and Joystick

Dependents:   ELEC2645_Race_Collision

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Joystick.cpp Source File

Joystick.cpp

00001 #include "Joystick.h"
00002 
00003 Joystick::Joystick(PinName vertPin,PinName horizPin)
00004 {
00005     vert = new AnalogIn(vertPin);
00006     horiz = new AnalogIn(horizPin);
00007 }
00008 
00009 void Joystick::init()
00010 {
00011     // read centred values of joystick
00012     _x0 = horiz->read();
00013     _y0 = vert->read();
00014 
00015     // this assumes that the joystick is centred when the init function is called
00016     // if perfectly centred, the pots should read 0.5, but this may
00017     // not be the case and x0 and y0 will be used to calibrate readings
00018 }
00019 
00020 Direction Joystick::get_direction()
00021 {
00022     float angle = get_angle();  // 0 to 360, -1 for centred
00023 
00024     Direction d;
00025     // partition 360 into segments and check which segment the angle is in
00026     if (angle < 0.0f) {
00027         d = CENTRE;   // check for -1.0 angle
00028     } else if (angle < 22.5f) {  // then keep going in 45 degree increments
00029         d = N;
00030     } else if (angle < 67.5f) {
00031         d = NE;
00032     } else if (angle < 112.5f) {
00033         d = E;
00034     } else if (angle < 157.5f) {
00035         d = SE;
00036     } else if (angle < 202.5f) {
00037         d = S;
00038     } else if (angle < 247.5f) {
00039         d = SW;
00040     } else if (angle < 292.5f) {
00041         d = W;
00042     } else if (angle < 337.5f) {
00043         d = NW;
00044     } else {
00045         d = N;
00046     }
00047 
00048     return d;
00049 }
00050 
00051 // this method gets the magnitude of the joystick movement
00052 float Joystick::get_mag()
00053 {
00054     Polar p = get_polar();
00055     return p.mag;
00056 }
00057 
00058 // this method gets the angle of joystick movement (0 to 360, 0 North)
00059 float Joystick::get_angle()
00060 {
00061     Polar p = get_polar();
00062     return p.angle;
00063 }
00064 
00065 // get raw joystick coordinate in range -1 to 1
00066 // Direction (x,y)
00067 // North     (0,1)
00068 // East      (1,0)
00069 // South     (0,-1)
00070 // West      (-1,0)
00071 Vector2D Joystick::get_coord()
00072 {
00073     // read() returns value in range 0.0 to 1.0 so is scaled and centre value
00074     // substracted to get values in the range -1.0 to 1.0
00075     float x = 2.0f*( horiz->read() - _x0 );
00076     float y = 2.0f*( vert->read() - _y0 );
00077 
00078     // Note: the values are negated so positive is up and right.
00079     Vector2D coord = {-x,y};
00080     return coord;
00081 }
00082 
00083 // This maps the raw x,y coord onto a circular grid.
00084 // See:  http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
00085 Vector2D Joystick::get_mapped_coord()
00086 {
00087     Vector2D coord = get_coord();
00088 
00089     // do the transformation
00090     float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
00091     float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
00092 
00093     Vector2D mapped_coord = {x,y};
00094     return mapped_coord;
00095 }
00096 
00097 // this function converts the mapped coordinates into polar form
00098 Polar Joystick::get_polar()
00099 {
00100     // get the mapped coordinate
00101     Vector2D coord = get_mapped_coord();
00102 
00103     // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
00104     // We want 0 degrees to correspond to North and increase clockwise to 359
00105     // like a compass heading, so we need to swap the axis and invert y
00106     float x = coord.y;
00107     float y = coord.x;
00108 
00109     float mag = sqrt(x*x+y*y);  // pythagoras
00110     float angle = RAD2DEG*atan2(y,x);
00111     // angle will be in range -180 to 180, so add 360 to negative angles to
00112     // move to 0 to 360 range
00113     if (angle < 0.0f) {
00114         angle+=360.0f;
00115     }
00116 
00117     // the noise on the ADC causes the values of x and y to fluctuate slightly
00118     // around the centred values. This causes the random angle values to get
00119     // calculated when the joystick is centred and untouched. This is also when
00120     // the magnitude is very small, so we can check for a small magnitude and then
00121     // set the angle to -1. This will inform us when the angle is invalid and the
00122     // joystick is centred
00123 
00124     if (mag < TOL) {
00125         mag = 0.0f;
00126         angle = -1.0f;
00127     }
00128 
00129     Polar p = {mag,angle};
00130     return p;
00131 }