Snake vs Block Game to be run upon K64F.

Dependencies:   mbed

Committer:
AhmedPlaymaker
Date:
Tue Apr 30 08:32:30 2019 +0000
Revision:
61:f3c402bc2ad0
Parent:
51:387249f9b333
Child:
62:ebf6ecf8a6d5
Fixed an issue with the gamepad library that made it remember the previous button pressed, also removed pad.init() because of this

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AhmedPlaymaker 0:4b15c2d4aa58 1 #include "Gamepad.h"
AhmedPlaymaker 0:4b15c2d4aa58 2
AhmedPlaymaker 0:4b15c2d4aa58 3 #include "mbed.h"
AhmedPlaymaker 0:4b15c2d4aa58 4
AhmedPlaymaker 0:4b15c2d4aa58 5 //////////// constructor/destructor ////////////
AhmedPlaymaker 0:4b15c2d4aa58 6 Gamepad::Gamepad()
AhmedPlaymaker 0:4b15c2d4aa58 7 :
AhmedPlaymaker 0:4b15c2d4aa58 8 _led1(new PwmOut(PTA1)),
AhmedPlaymaker 0:4b15c2d4aa58 9 _led2(new PwmOut(PTA2)),
AhmedPlaymaker 0:4b15c2d4aa58 10 _led3(new PwmOut(PTC2)),
AhmedPlaymaker 0:4b15c2d4aa58 11 _led4(new PwmOut(PTC3)),
AhmedPlaymaker 0:4b15c2d4aa58 12 _led5(new PwmOut(PTC4)),
AhmedPlaymaker 0:4b15c2d4aa58 13 _led6(new PwmOut(PTD3)),
AhmedPlaymaker 0:4b15c2d4aa58 14
AhmedPlaymaker 0:4b15c2d4aa58 15 _button_A(new InterruptIn(PTB9)),
AhmedPlaymaker 0:4b15c2d4aa58 16 _button_B(new InterruptIn(PTD0)),
AhmedPlaymaker 0:4b15c2d4aa58 17 _button_X(new InterruptIn(PTC17)),
AhmedPlaymaker 0:4b15c2d4aa58 18 _button_Y(new InterruptIn(PTC12)),
AhmedPlaymaker 0:4b15c2d4aa58 19 _button_L(new InterruptIn(PTB18)),
AhmedPlaymaker 0:4b15c2d4aa58 20 _button_R(new InterruptIn(PTB3)),
AhmedPlaymaker 0:4b15c2d4aa58 21 _button_back(new InterruptIn(PTB19)),
AhmedPlaymaker 0:4b15c2d4aa58 22 _button_start(new InterruptIn(PTC5)),
AhmedPlaymaker 0:4b15c2d4aa58 23 _button_joystick(new InterruptIn(PTC16)),
AhmedPlaymaker 0:4b15c2d4aa58 24
AhmedPlaymaker 0:4b15c2d4aa58 25 _vert(new AnalogIn(PTB10)),
AhmedPlaymaker 0:4b15c2d4aa58 26 _horiz(new AnalogIn(PTB11)),
AhmedPlaymaker 0:4b15c2d4aa58 27
AhmedPlaymaker 0:4b15c2d4aa58 28 _buzzer(new PwmOut(PTC10)),
AhmedPlaymaker 0:4b15c2d4aa58 29 _pot(new AnalogIn(PTB2)),
AhmedPlaymaker 0:4b15c2d4aa58 30
AhmedPlaymaker 0:4b15c2d4aa58 31 _timeout(new Timeout()),
AhmedPlaymaker 0:4b15c2d4aa58 32
AhmedPlaymaker 0:4b15c2d4aa58 33 _event_state(0),
AhmedPlaymaker 0:4b15c2d4aa58 34
AhmedPlaymaker 0:4b15c2d4aa58 35 _x0(0),
AhmedPlaymaker 0:4b15c2d4aa58 36 _y0(0)
AhmedPlaymaker 0:4b15c2d4aa58 37 {}
AhmedPlaymaker 0:4b15c2d4aa58 38
AhmedPlaymaker 0:4b15c2d4aa58 39 Gamepad::~Gamepad()
AhmedPlaymaker 0:4b15c2d4aa58 40 {
AhmedPlaymaker 0:4b15c2d4aa58 41 delete _led1,_led2,_led3,_led4,_led5,_led6;
AhmedPlaymaker 0:4b15c2d4aa58 42 delete _button_A,_button_B,_button_joystick,_vert,_horiz;
AhmedPlaymaker 0:4b15c2d4aa58 43 delete _button_X,_button_Y,_button_back,_button_start;
AhmedPlaymaker 0:4b15c2d4aa58 44 delete _button_L,_button_R, _buzzer, _pot, _timeout;
AhmedPlaymaker 0:4b15c2d4aa58 45 }
AhmedPlaymaker 0:4b15c2d4aa58 46
AhmedPlaymaker 0:4b15c2d4aa58 47 ///////////////// public methods /////////////////
AhmedPlaymaker 0:4b15c2d4aa58 48
AhmedPlaymaker 0:4b15c2d4aa58 49 void Gamepad::init()
AhmedPlaymaker 0:4b15c2d4aa58 50 {
AhmedPlaymaker 0:4b15c2d4aa58 51 leds_off();
AhmedPlaymaker 0:4b15c2d4aa58 52 init_buttons();
AhmedPlaymaker 0:4b15c2d4aa58 53
AhmedPlaymaker 0:4b15c2d4aa58 54 // read centred values of joystick
AhmedPlaymaker 0:4b15c2d4aa58 55 _x0 = _horiz->read();
AhmedPlaymaker 0:4b15c2d4aa58 56 _y0 = _vert->read();
AhmedPlaymaker 0:4b15c2d4aa58 57
AhmedPlaymaker 0:4b15c2d4aa58 58 // clear all flags
AhmedPlaymaker 0:4b15c2d4aa58 59 _event_state = 0;
AhmedPlaymaker 0:4b15c2d4aa58 60 }
AhmedPlaymaker 0:4b15c2d4aa58 61
AhmedPlaymaker 0:4b15c2d4aa58 62 void Gamepad::leds_off()
AhmedPlaymaker 0:4b15c2d4aa58 63 {
AhmedPlaymaker 0:4b15c2d4aa58 64 leds(0.0);
AhmedPlaymaker 0:4b15c2d4aa58 65 }
AhmedPlaymaker 0:4b15c2d4aa58 66
AhmedPlaymaker 0:4b15c2d4aa58 67 void Gamepad::leds_on()
AhmedPlaymaker 0:4b15c2d4aa58 68 {
AhmedPlaymaker 0:4b15c2d4aa58 69 leds(1.0);
AhmedPlaymaker 0:4b15c2d4aa58 70 }
AhmedPlaymaker 0:4b15c2d4aa58 71
AhmedPlaymaker 0:4b15c2d4aa58 72 void Gamepad::leds(float val) const
AhmedPlaymaker 0:4b15c2d4aa58 73 {
AhmedPlaymaker 0:4b15c2d4aa58 74 if (val < 0.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 75 val = 0.0f;
AhmedPlaymaker 0:4b15c2d4aa58 76 }
AhmedPlaymaker 0:4b15c2d4aa58 77 if (val > 1.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 78 val = 1.0f;
AhmedPlaymaker 0:4b15c2d4aa58 79 }
AhmedPlaymaker 0:4b15c2d4aa58 80
AhmedPlaymaker 0:4b15c2d4aa58 81 // leds are active-low, so subtract from 1.0
AhmedPlaymaker 0:4b15c2d4aa58 82 // 0.0 corresponds to fully-off, 1.0 to fully-on
AhmedPlaymaker 0:4b15c2d4aa58 83 val = 1.0f - val;
AhmedPlaymaker 0:4b15c2d4aa58 84
AhmedPlaymaker 0:4b15c2d4aa58 85 _led1->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 86 _led2->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 87 _led3->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 88 _led4->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 89 _led5->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 90 _led6->write(val);
AhmedPlaymaker 0:4b15c2d4aa58 91 }
AhmedPlaymaker 0:4b15c2d4aa58 92
AhmedPlaymaker 0:4b15c2d4aa58 93 void Gamepad::led(int n,float val) const
AhmedPlaymaker 0:4b15c2d4aa58 94 {
AhmedPlaymaker 0:4b15c2d4aa58 95 // ensure they are within vlaid range
AhmedPlaymaker 0:4b15c2d4aa58 96 if (val < 0.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 97 val = 0.0f;
AhmedPlaymaker 0:4b15c2d4aa58 98 }
AhmedPlaymaker 0:4b15c2d4aa58 99 if (val > 1.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 100 val = 1.0f;
AhmedPlaymaker 0:4b15c2d4aa58 101 }
AhmedPlaymaker 0:4b15c2d4aa58 102
AhmedPlaymaker 0:4b15c2d4aa58 103 switch (n) {
AhmedPlaymaker 0:4b15c2d4aa58 104
AhmedPlaymaker 0:4b15c2d4aa58 105 // check for valid LED number and set value
AhmedPlaymaker 0:4b15c2d4aa58 106
AhmedPlaymaker 0:4b15c2d4aa58 107 case 1:
AhmedPlaymaker 0:4b15c2d4aa58 108 _led1->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 109 break;
AhmedPlaymaker 0:4b15c2d4aa58 110 case 2:
AhmedPlaymaker 0:4b15c2d4aa58 111 _led2->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 112 break;
AhmedPlaymaker 0:4b15c2d4aa58 113 case 3:
AhmedPlaymaker 0:4b15c2d4aa58 114 _led3->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 115 break;
AhmedPlaymaker 0:4b15c2d4aa58 116 case 4:
AhmedPlaymaker 0:4b15c2d4aa58 117 _led4->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 118 break;
AhmedPlaymaker 0:4b15c2d4aa58 119 case 5:
AhmedPlaymaker 0:4b15c2d4aa58 120 _led5->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 121 break;
AhmedPlaymaker 0:4b15c2d4aa58 122 case 6:
AhmedPlaymaker 0:4b15c2d4aa58 123 _led6->write(1.0f-val); // active-low so subtract from 1
AhmedPlaymaker 0:4b15c2d4aa58 124 break;
AhmedPlaymaker 0:4b15c2d4aa58 125
AhmedPlaymaker 0:4b15c2d4aa58 126 }
AhmedPlaymaker 0:4b15c2d4aa58 127 }
AhmedPlaymaker 0:4b15c2d4aa58 128
AhmedPlaymaker 0:4b15c2d4aa58 129 float Gamepad::read_pot() const
AhmedPlaymaker 0:4b15c2d4aa58 130 {
AhmedPlaymaker 0:4b15c2d4aa58 131 return _pot->read();
AhmedPlaymaker 0:4b15c2d4aa58 132 }
AhmedPlaymaker 0:4b15c2d4aa58 133
AhmedPlaymaker 0:4b15c2d4aa58 134 void Gamepad::tone(float frequency, float duration)
AhmedPlaymaker 0:4b15c2d4aa58 135 {
AhmedPlaymaker 0:4b15c2d4aa58 136 _buzzer->period(1.0f/frequency);
AhmedPlaymaker 0:4b15c2d4aa58 137 _buzzer->write(0.5); // 50% duty cycle - square wave
AhmedPlaymaker 0:4b15c2d4aa58 138 _timeout->attach(callback(this, &Gamepad::tone_off), duration );
AhmedPlaymaker 0:4b15c2d4aa58 139 }
AhmedPlaymaker 0:4b15c2d4aa58 140
AhmedPlaymaker 0:4b15c2d4aa58 141 bool Gamepad::check_event(GamepadEvent const id)
AhmedPlaymaker 0:4b15c2d4aa58 142 {
AhmedPlaymaker 0:4b15c2d4aa58 143 // Check whether event flag is set
AhmedPlaymaker 0:4b15c2d4aa58 144 if (_event_state[id]) {
AhmedPlaymaker 61:f3c402bc2ad0 145 _event_state = 0;
AhmedPlaymaker 61:f3c402bc2ad0 146 //_event_state.reset(id); // clear flag
AhmedPlaymaker 0:4b15c2d4aa58 147 return true;
AhmedPlaymaker 0:4b15c2d4aa58 148 } else {
AhmedPlaymaker 0:4b15c2d4aa58 149 return false;
AhmedPlaymaker 0:4b15c2d4aa58 150 }
AhmedPlaymaker 0:4b15c2d4aa58 151 }
AhmedPlaymaker 0:4b15c2d4aa58 152
AhmedPlaymaker 0:4b15c2d4aa58 153 // this method gets the magnitude of the joystick movement
AhmedPlaymaker 0:4b15c2d4aa58 154 float Gamepad::get_mag()
AhmedPlaymaker 0:4b15c2d4aa58 155 {
AhmedPlaymaker 0:4b15c2d4aa58 156 Polar p = get_polar();
AhmedPlaymaker 0:4b15c2d4aa58 157 return p.mag;
AhmedPlaymaker 0:4b15c2d4aa58 158 }
AhmedPlaymaker 0:4b15c2d4aa58 159
AhmedPlaymaker 0:4b15c2d4aa58 160 // this method gets the angle of joystick movement (0 to 360, 0 North)
AhmedPlaymaker 0:4b15c2d4aa58 161 float Gamepad::get_angle()
AhmedPlaymaker 0:4b15c2d4aa58 162 {
AhmedPlaymaker 0:4b15c2d4aa58 163 Polar p = get_polar();
AhmedPlaymaker 0:4b15c2d4aa58 164 return p.angle;
AhmedPlaymaker 0:4b15c2d4aa58 165 }
AhmedPlaymaker 0:4b15c2d4aa58 166
AhmedPlaymaker 0:4b15c2d4aa58 167 Direction Gamepad::get_direction()
AhmedPlaymaker 0:4b15c2d4aa58 168 {
AhmedPlaymaker 0:4b15c2d4aa58 169 float angle = get_angle(); // 0 to 360, -1 for centred
AhmedPlaymaker 0:4b15c2d4aa58 170
AhmedPlaymaker 0:4b15c2d4aa58 171 Direction d;
AhmedPlaymaker 0:4b15c2d4aa58 172 // partition 360 into segments and check which segment the angle is in
AhmedPlaymaker 0:4b15c2d4aa58 173 if (angle < 0.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 174 d = CENTRE; // check for -1.0 angle
AhmedPlaymaker 0:4b15c2d4aa58 175 } else if (angle < 22.5f) { // then keep going in 45 degree increments
AhmedPlaymaker 0:4b15c2d4aa58 176 d = N;
AhmedPlaymaker 0:4b15c2d4aa58 177 } else if (angle < 67.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 178 d = NE;
AhmedPlaymaker 0:4b15c2d4aa58 179 } else if (angle < 112.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 180 d = E;
AhmedPlaymaker 0:4b15c2d4aa58 181 } else if (angle < 157.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 182 d = SE;
AhmedPlaymaker 0:4b15c2d4aa58 183 } else if (angle < 202.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 184 d = S;
AhmedPlaymaker 0:4b15c2d4aa58 185 } else if (angle < 247.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 186 d = SW;
AhmedPlaymaker 0:4b15c2d4aa58 187 } else if (angle < 292.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 188 d = W;
AhmedPlaymaker 0:4b15c2d4aa58 189 } else if (angle < 337.5f) {
AhmedPlaymaker 0:4b15c2d4aa58 190 d = NW;
AhmedPlaymaker 0:4b15c2d4aa58 191 } else {
AhmedPlaymaker 0:4b15c2d4aa58 192 d = N;
AhmedPlaymaker 0:4b15c2d4aa58 193 }
AhmedPlaymaker 0:4b15c2d4aa58 194
AhmedPlaymaker 0:4b15c2d4aa58 195 return d;
AhmedPlaymaker 0:4b15c2d4aa58 196 }
AhmedPlaymaker 0:4b15c2d4aa58 197
AhmedPlaymaker 0:4b15c2d4aa58 198 ///////////////////// private methods ////////////////////////
AhmedPlaymaker 0:4b15c2d4aa58 199
AhmedPlaymaker 0:4b15c2d4aa58 200 void Gamepad::tone_off()
AhmedPlaymaker 0:4b15c2d4aa58 201 {
AhmedPlaymaker 0:4b15c2d4aa58 202 // called after timeout
AhmedPlaymaker 0:4b15c2d4aa58 203 _buzzer->write(0.0);
AhmedPlaymaker 0:4b15c2d4aa58 204 }
AhmedPlaymaker 0:4b15c2d4aa58 205
AhmedPlaymaker 0:4b15c2d4aa58 206 void Gamepad::init_buttons()
AhmedPlaymaker 0:4b15c2d4aa58 207 {
AhmedPlaymaker 0:4b15c2d4aa58 208 // turn on pull-downs as other side of button is connected to 3V3
AhmedPlaymaker 0:4b15c2d4aa58 209 // button is 0 when not pressed and 1 when pressed
AhmedPlaymaker 0:4b15c2d4aa58 210 _button_A->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 211 _button_B->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 212 _button_X->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 213 _button_Y->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 214 _button_back->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 215 _button_start->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 216 _button_L->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 217 _button_R->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 218 _button_joystick->mode(PullDown);
AhmedPlaymaker 0:4b15c2d4aa58 219 // therefore setup rising edge interrupts
AhmedPlaymaker 0:4b15c2d4aa58 220 _button_A->rise(callback(this,&Gamepad::a_isr));
AhmedPlaymaker 0:4b15c2d4aa58 221 _button_B->rise(callback(this,&Gamepad::b_isr));
AhmedPlaymaker 0:4b15c2d4aa58 222 _button_X->rise(callback(this,&Gamepad::x_isr));
AhmedPlaymaker 0:4b15c2d4aa58 223 _button_Y->rise(callback(this,&Gamepad::y_isr));
AhmedPlaymaker 0:4b15c2d4aa58 224 _button_L->rise(callback(this,&Gamepad::l_isr));
AhmedPlaymaker 0:4b15c2d4aa58 225 _button_R->rise(callback(this,&Gamepad::r_isr));
AhmedPlaymaker 0:4b15c2d4aa58 226 _button_start->rise(callback(this,&Gamepad::start_isr));
AhmedPlaymaker 0:4b15c2d4aa58 227 _button_back->rise(callback(this,&Gamepad::back_isr));
AhmedPlaymaker 0:4b15c2d4aa58 228 _button_joystick->rise(callback(this,&Gamepad::joy_isr));
AhmedPlaymaker 0:4b15c2d4aa58 229 }
AhmedPlaymaker 0:4b15c2d4aa58 230
AhmedPlaymaker 0:4b15c2d4aa58 231 // button interrupts ISRs
AhmedPlaymaker 0:4b15c2d4aa58 232 // Each of these simply sets the appropriate event bit in the _event_state
AhmedPlaymaker 0:4b15c2d4aa58 233 // variable
AhmedPlaymaker 0:4b15c2d4aa58 234 void Gamepad::a_isr()
AhmedPlaymaker 0:4b15c2d4aa58 235 {
AhmedPlaymaker 0:4b15c2d4aa58 236 _event_state.set(A_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 237 }
AhmedPlaymaker 0:4b15c2d4aa58 238 void Gamepad::b_isr()
AhmedPlaymaker 0:4b15c2d4aa58 239 {
AhmedPlaymaker 0:4b15c2d4aa58 240 _event_state.set(B_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 241 }
AhmedPlaymaker 0:4b15c2d4aa58 242 void Gamepad::x_isr()
AhmedPlaymaker 0:4b15c2d4aa58 243 {
AhmedPlaymaker 0:4b15c2d4aa58 244 _event_state.set(X_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 245 }
AhmedPlaymaker 0:4b15c2d4aa58 246 void Gamepad::y_isr()
AhmedPlaymaker 0:4b15c2d4aa58 247 {
AhmedPlaymaker 0:4b15c2d4aa58 248 _event_state.set(Y_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 249 }
AhmedPlaymaker 0:4b15c2d4aa58 250 void Gamepad::l_isr()
AhmedPlaymaker 0:4b15c2d4aa58 251 {
AhmedPlaymaker 0:4b15c2d4aa58 252 _event_state.set(L_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 253 }
AhmedPlaymaker 0:4b15c2d4aa58 254 void Gamepad::r_isr()
AhmedPlaymaker 0:4b15c2d4aa58 255 {
AhmedPlaymaker 0:4b15c2d4aa58 256 _event_state.set(R_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 257 }
AhmedPlaymaker 0:4b15c2d4aa58 258 void Gamepad::back_isr()
AhmedPlaymaker 0:4b15c2d4aa58 259 {
AhmedPlaymaker 0:4b15c2d4aa58 260 _event_state.set(BACK_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 261 }
AhmedPlaymaker 0:4b15c2d4aa58 262 void Gamepad::start_isr()
AhmedPlaymaker 0:4b15c2d4aa58 263 {
AhmedPlaymaker 0:4b15c2d4aa58 264 _event_state.set(START_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 265 }
AhmedPlaymaker 0:4b15c2d4aa58 266 void Gamepad::joy_isr()
AhmedPlaymaker 0:4b15c2d4aa58 267 {
AhmedPlaymaker 0:4b15c2d4aa58 268 _event_state.set(JOY_PRESSED);
AhmedPlaymaker 0:4b15c2d4aa58 269 }
AhmedPlaymaker 0:4b15c2d4aa58 270
AhmedPlaymaker 0:4b15c2d4aa58 271 // get raw joystick coordinate in range -1 to 1
AhmedPlaymaker 0:4b15c2d4aa58 272 // Direction (x,y)
AhmedPlaymaker 0:4b15c2d4aa58 273 // North (0,1)
AhmedPlaymaker 0:4b15c2d4aa58 274 // East (1,0)
AhmedPlaymaker 0:4b15c2d4aa58 275 // South (0,-1)
AhmedPlaymaker 0:4b15c2d4aa58 276 // West (-1,0)
AhmedPlaymaker 0:4b15c2d4aa58 277 Vector2D Gamepad::get_coord()
AhmedPlaymaker 0:4b15c2d4aa58 278 {
AhmedPlaymaker 0:4b15c2d4aa58 279 // read() returns value in range 0.0 to 1.0 so is scaled and centre value
AhmedPlaymaker 0:4b15c2d4aa58 280 // substracted to get values in the range -1.0 to 1.0
AhmedPlaymaker 0:4b15c2d4aa58 281 float x = 2.0f*( _horiz->read() - _x0 );
AhmedPlaymaker 0:4b15c2d4aa58 282 float y = 2.0f*( _vert->read() - _y0 );
AhmedPlaymaker 0:4b15c2d4aa58 283
AhmedPlaymaker 0:4b15c2d4aa58 284 // Note: the x value here is inverted to ensure the positive x is to the
AhmedPlaymaker 0:4b15c2d4aa58 285 // right. This is simply due to how the potentiometer on the joystick
AhmedPlaymaker 0:4b15c2d4aa58 286 // I was using was connected up. It could have been corrected in hardware
AhmedPlaymaker 0:4b15c2d4aa58 287 // by swapping the power supply pins. Instead it is done in software so may
AhmedPlaymaker 0:4b15c2d4aa58 288 // need to be changed depending on your wiring setup
AhmedPlaymaker 0:4b15c2d4aa58 289
AhmedPlaymaker 0:4b15c2d4aa58 290 Vector2D coord = {-x,y};
AhmedPlaymaker 0:4b15c2d4aa58 291 return coord;
AhmedPlaymaker 0:4b15c2d4aa58 292 }
AhmedPlaymaker 0:4b15c2d4aa58 293
AhmedPlaymaker 0:4b15c2d4aa58 294 // This maps the raw x,y coord onto a circular grid.
AhmedPlaymaker 0:4b15c2d4aa58 295 // See: http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
AhmedPlaymaker 0:4b15c2d4aa58 296 Vector2D Gamepad::get_mapped_coord()
AhmedPlaymaker 0:4b15c2d4aa58 297 {
AhmedPlaymaker 0:4b15c2d4aa58 298 Vector2D coord = get_coord();
AhmedPlaymaker 0:4b15c2d4aa58 299
AhmedPlaymaker 0:4b15c2d4aa58 300 // do the transformation
AhmedPlaymaker 0:4b15c2d4aa58 301 float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
AhmedPlaymaker 0:4b15c2d4aa58 302 float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
AhmedPlaymaker 0:4b15c2d4aa58 303
AhmedPlaymaker 0:4b15c2d4aa58 304 Vector2D mapped_coord = {x,y};
AhmedPlaymaker 0:4b15c2d4aa58 305 return mapped_coord;
AhmedPlaymaker 0:4b15c2d4aa58 306 }
AhmedPlaymaker 0:4b15c2d4aa58 307
AhmedPlaymaker 0:4b15c2d4aa58 308 // this function converts the mapped coordinates into polar form
AhmedPlaymaker 0:4b15c2d4aa58 309 Polar Gamepad::get_polar()
AhmedPlaymaker 0:4b15c2d4aa58 310 {
AhmedPlaymaker 0:4b15c2d4aa58 311 // get the mapped coordinate
AhmedPlaymaker 0:4b15c2d4aa58 312 Vector2D coord = get_mapped_coord();
AhmedPlaymaker 0:4b15c2d4aa58 313
AhmedPlaymaker 0:4b15c2d4aa58 314 // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
AhmedPlaymaker 0:4b15c2d4aa58 315 // We want 0 degrees to correspond to North and increase clockwise to 359
AhmedPlaymaker 0:4b15c2d4aa58 316 // like a compass heading, so we need to swap the axis and invert y
AhmedPlaymaker 0:4b15c2d4aa58 317 float x = coord.y;
AhmedPlaymaker 0:4b15c2d4aa58 318 float y = coord.x;
AhmedPlaymaker 0:4b15c2d4aa58 319
AhmedPlaymaker 0:4b15c2d4aa58 320 float mag = sqrt(x*x+y*y); // pythagoras
AhmedPlaymaker 0:4b15c2d4aa58 321 float angle = RAD2DEG*atan2(y,x);
AhmedPlaymaker 0:4b15c2d4aa58 322 // angle will be in range -180 to 180, so add 360 to negative angles to
AhmedPlaymaker 0:4b15c2d4aa58 323 // move to 0 to 360 range
AhmedPlaymaker 0:4b15c2d4aa58 324 if (angle < 0.0f) {
AhmedPlaymaker 0:4b15c2d4aa58 325 angle+=360.0f;
AhmedPlaymaker 0:4b15c2d4aa58 326 }
AhmedPlaymaker 0:4b15c2d4aa58 327
AhmedPlaymaker 0:4b15c2d4aa58 328 // the noise on the ADC causes the values of x and y to fluctuate slightly
AhmedPlaymaker 0:4b15c2d4aa58 329 // around the centred values. This causes the random angle values to get
AhmedPlaymaker 0:4b15c2d4aa58 330 // calculated when the joystick is centred and untouched. This is also when
AhmedPlaymaker 0:4b15c2d4aa58 331 // the magnitude is very small, so we can check for a small magnitude and then
AhmedPlaymaker 0:4b15c2d4aa58 332 // set the angle to -1. This will inform us when the angle is invalid and the
AhmedPlaymaker 0:4b15c2d4aa58 333 // joystick is centred
AhmedPlaymaker 0:4b15c2d4aa58 334
AhmedPlaymaker 0:4b15c2d4aa58 335 if (mag < TOL) {
AhmedPlaymaker 0:4b15c2d4aa58 336 mag = 0.0f;
AhmedPlaymaker 0:4b15c2d4aa58 337 angle = -1.0f;
AhmedPlaymaker 0:4b15c2d4aa58 338 }
AhmedPlaymaker 0:4b15c2d4aa58 339
AhmedPlaymaker 0:4b15c2d4aa58 340 Polar p = {mag,angle};
AhmedPlaymaker 0:4b15c2d4aa58 341 return p;
AhmedPlaymaker 0:4b15c2d4aa58 342 }