ELEC2645 (2018/19) / Mbed 2 deprecated el17yfk

Dependencies:   mbed FXOS8700CQ mbed-rtos

Committer:
yfkwok
Date:
Sun Apr 28 18:58:10 2019 +0000
Revision:
22:f8f36e88b2ca
Parent:
12:71683453f66a
28/04/2019 - Flag reset implementation, game parameters and difficulty adjustment

Who changed what in which revision?

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