Demo program for LCD and Joystick

Dependents:   ELEC2645_Race_Collision

Committer:
eencae
Date:
Fri Dec 11 12:25:25 2020 +0000
Revision:
0:be41a15e7a86
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 0:be41a15e7a86 1 #include "Joystick.h"
eencae 0:be41a15e7a86 2
eencae 0:be41a15e7a86 3 Joystick::Joystick(PinName vertPin,PinName horizPin)
eencae 0:be41a15e7a86 4 {
eencae 0:be41a15e7a86 5 vert = new AnalogIn(vertPin);
eencae 0:be41a15e7a86 6 horiz = new AnalogIn(horizPin);
eencae 0:be41a15e7a86 7 }
eencae 0:be41a15e7a86 8
eencae 0:be41a15e7a86 9 void Joystick::init()
eencae 0:be41a15e7a86 10 {
eencae 0:be41a15e7a86 11 // read centred values of joystick
eencae 0:be41a15e7a86 12 _x0 = horiz->read();
eencae 0:be41a15e7a86 13 _y0 = vert->read();
eencae 0:be41a15e7a86 14
eencae 0:be41a15e7a86 15 // this assumes that the joystick is centred when the init function is called
eencae 0:be41a15e7a86 16 // if perfectly centred, the pots should read 0.5, but this may
eencae 0:be41a15e7a86 17 // not be the case and x0 and y0 will be used to calibrate readings
eencae 0:be41a15e7a86 18 }
eencae 0:be41a15e7a86 19
eencae 0:be41a15e7a86 20 Direction Joystick::get_direction()
eencae 0:be41a15e7a86 21 {
eencae 0:be41a15e7a86 22 float angle = get_angle(); // 0 to 360, -1 for centred
eencae 0:be41a15e7a86 23
eencae 0:be41a15e7a86 24 Direction d;
eencae 0:be41a15e7a86 25 // partition 360 into segments and check which segment the angle is in
eencae 0:be41a15e7a86 26 if (angle < 0.0f) {
eencae 0:be41a15e7a86 27 d = CENTRE; // check for -1.0 angle
eencae 0:be41a15e7a86 28 } else if (angle < 22.5f) { // then keep going in 45 degree increments
eencae 0:be41a15e7a86 29 d = N;
eencae 0:be41a15e7a86 30 } else if (angle < 67.5f) {
eencae 0:be41a15e7a86 31 d = NE;
eencae 0:be41a15e7a86 32 } else if (angle < 112.5f) {
eencae 0:be41a15e7a86 33 d = E;
eencae 0:be41a15e7a86 34 } else if (angle < 157.5f) {
eencae 0:be41a15e7a86 35 d = SE;
eencae 0:be41a15e7a86 36 } else if (angle < 202.5f) {
eencae 0:be41a15e7a86 37 d = S;
eencae 0:be41a15e7a86 38 } else if (angle < 247.5f) {
eencae 0:be41a15e7a86 39 d = SW;
eencae 0:be41a15e7a86 40 } else if (angle < 292.5f) {
eencae 0:be41a15e7a86 41 d = W;
eencae 0:be41a15e7a86 42 } else if (angle < 337.5f) {
eencae 0:be41a15e7a86 43 d = NW;
eencae 0:be41a15e7a86 44 } else {
eencae 0:be41a15e7a86 45 d = N;
eencae 0:be41a15e7a86 46 }
eencae 0:be41a15e7a86 47
eencae 0:be41a15e7a86 48 return d;
eencae 0:be41a15e7a86 49 }
eencae 0:be41a15e7a86 50
eencae 0:be41a15e7a86 51 // this method gets the magnitude of the joystick movement
eencae 0:be41a15e7a86 52 float Joystick::get_mag()
eencae 0:be41a15e7a86 53 {
eencae 0:be41a15e7a86 54 Polar p = get_polar();
eencae 0:be41a15e7a86 55 return p.mag;
eencae 0:be41a15e7a86 56 }
eencae 0:be41a15e7a86 57
eencae 0:be41a15e7a86 58 // this method gets the angle of joystick movement (0 to 360, 0 North)
eencae 0:be41a15e7a86 59 float Joystick::get_angle()
eencae 0:be41a15e7a86 60 {
eencae 0:be41a15e7a86 61 Polar p = get_polar();
eencae 0:be41a15e7a86 62 return p.angle;
eencae 0:be41a15e7a86 63 }
eencae 0:be41a15e7a86 64
eencae 0:be41a15e7a86 65 // get raw joystick coordinate in range -1 to 1
eencae 0:be41a15e7a86 66 // Direction (x,y)
eencae 0:be41a15e7a86 67 // North (0,1)
eencae 0:be41a15e7a86 68 // East (1,0)
eencae 0:be41a15e7a86 69 // South (0,-1)
eencae 0:be41a15e7a86 70 // West (-1,0)
eencae 0:be41a15e7a86 71 Vector2D Joystick::get_coord()
eencae 0:be41a15e7a86 72 {
eencae 0:be41a15e7a86 73 // read() returns value in range 0.0 to 1.0 so is scaled and centre value
eencae 0:be41a15e7a86 74 // substracted to get values in the range -1.0 to 1.0
eencae 0:be41a15e7a86 75 float x = 2.0f*( horiz->read() - _x0 );
eencae 0:be41a15e7a86 76 float y = 2.0f*( vert->read() - _y0 );
eencae 0:be41a15e7a86 77
eencae 0:be41a15e7a86 78 // Note: the values are negated so positive is up and right.
eencae 0:be41a15e7a86 79 Vector2D coord = {-x,y};
eencae 0:be41a15e7a86 80 return coord;
eencae 0:be41a15e7a86 81 }
eencae 0:be41a15e7a86 82
eencae 0:be41a15e7a86 83 // This maps the raw x,y coord onto a circular grid.
eencae 0:be41a15e7a86 84 // See: http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
eencae 0:be41a15e7a86 85 Vector2D Joystick::get_mapped_coord()
eencae 0:be41a15e7a86 86 {
eencae 0:be41a15e7a86 87 Vector2D coord = get_coord();
eencae 0:be41a15e7a86 88
eencae 0:be41a15e7a86 89 // do the transformation
eencae 0:be41a15e7a86 90 float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
eencae 0:be41a15e7a86 91 float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
eencae 0:be41a15e7a86 92
eencae 0:be41a15e7a86 93 Vector2D mapped_coord = {x,y};
eencae 0:be41a15e7a86 94 return mapped_coord;
eencae 0:be41a15e7a86 95 }
eencae 0:be41a15e7a86 96
eencae 0:be41a15e7a86 97 // this function converts the mapped coordinates into polar form
eencae 0:be41a15e7a86 98 Polar Joystick::get_polar()
eencae 0:be41a15e7a86 99 {
eencae 0:be41a15e7a86 100 // get the mapped coordinate
eencae 0:be41a15e7a86 101 Vector2D coord = get_mapped_coord();
eencae 0:be41a15e7a86 102
eencae 0:be41a15e7a86 103 // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
eencae 0:be41a15e7a86 104 // We want 0 degrees to correspond to North and increase clockwise to 359
eencae 0:be41a15e7a86 105 // like a compass heading, so we need to swap the axis and invert y
eencae 0:be41a15e7a86 106 float x = coord.y;
eencae 0:be41a15e7a86 107 float y = coord.x;
eencae 0:be41a15e7a86 108
eencae 0:be41a15e7a86 109 float mag = sqrt(x*x+y*y); // pythagoras
eencae 0:be41a15e7a86 110 float angle = RAD2DEG*atan2(y,x);
eencae 0:be41a15e7a86 111 // angle will be in range -180 to 180, so add 360 to negative angles to
eencae 0:be41a15e7a86 112 // move to 0 to 360 range
eencae 0:be41a15e7a86 113 if (angle < 0.0f) {
eencae 0:be41a15e7a86 114 angle+=360.0f;
eencae 0:be41a15e7a86 115 }
eencae 0:be41a15e7a86 116
eencae 0:be41a15e7a86 117 // the noise on the ADC causes the values of x and y to fluctuate slightly
eencae 0:be41a15e7a86 118 // around the centred values. This causes the random angle values to get
eencae 0:be41a15e7a86 119 // calculated when the joystick is centred and untouched. This is also when
eencae 0:be41a15e7a86 120 // the magnitude is very small, so we can check for a small magnitude and then
eencae 0:be41a15e7a86 121 // set the angle to -1. This will inform us when the angle is invalid and the
eencae 0:be41a15e7a86 122 // joystick is centred
eencae 0:be41a15e7a86 123
eencae 0:be41a15e7a86 124 if (mag < TOL) {
eencae 0:be41a15e7a86 125 mag = 0.0f;
eencae 0:be41a15e7a86 126 angle = -1.0f;
eencae 0:be41a15e7a86 127 }
eencae 0:be41a15e7a86 128
eencae 0:be41a15e7a86 129 Polar p = {mag,angle};
eencae 0:be41a15e7a86 130 return p;
eencae 0:be41a15e7a86 131 }