ELEC2645 (2018/19) / Mbed 2 deprecated el17yfk

Dependencies:   mbed FXOS8700CQ mbed-rtos

Committer:
yfkwok
Date:
Mon Apr 15 01:38:53 2019 +0000
Revision:
12:71683453f66a
Parent:
0:1da4db5de653
Child:
22:f8f36e88b2ca
15/4/2019 - Update animation for Bulbasaur

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 12:71683453f66a 218 }
yfkwok 12:71683453f66a 219
yfkwok 0:1da4db5de653 220 ///////////////////// private methods ////////////////////////
yfkwok 0:1da4db5de653 221
yfkwok 0:1da4db5de653 222 void Gamepad::tone_off()
yfkwok 0:1da4db5de653 223 {
yfkwok 0:1da4db5de653 224 // called after timeout
yfkwok 0:1da4db5de653 225 _buzzer->write(0.0);
yfkwok 0:1da4db5de653 226 }
yfkwok 0:1da4db5de653 227
yfkwok 0:1da4db5de653 228 void Gamepad::init_buttons()
yfkwok 0:1da4db5de653 229 {
yfkwok 0:1da4db5de653 230 // turn on pull-downs as other side of button is connected to 3V3
yfkwok 0:1da4db5de653 231 // button is 0 when not pressed and 1 when pressed
yfkwok 0:1da4db5de653 232 _button_A->mode(PullDown);
yfkwok 0:1da4db5de653 233 _button_B->mode(PullDown);
yfkwok 0:1da4db5de653 234 _button_X->mode(PullDown);
yfkwok 0:1da4db5de653 235 _button_Y->mode(PullDown);
yfkwok 0:1da4db5de653 236 _button_back->mode(PullDown);
yfkwok 0:1da4db5de653 237 _button_start->mode(PullDown);
yfkwok 0:1da4db5de653 238 _button_L->mode(PullDown);
yfkwok 0:1da4db5de653 239 _button_R->mode(PullDown);
yfkwok 0:1da4db5de653 240 _button_joystick->mode(PullDown);
yfkwok 0:1da4db5de653 241 // therefore setup rising edge interrupts
yfkwok 0:1da4db5de653 242 _button_A->rise(callback(this,&Gamepad::a_isr));
yfkwok 0:1da4db5de653 243 _button_B->rise(callback(this,&Gamepad::b_isr));
yfkwok 0:1da4db5de653 244 _button_X->rise(callback(this,&Gamepad::x_isr));
yfkwok 0:1da4db5de653 245 _button_Y->rise(callback(this,&Gamepad::y_isr));
yfkwok 0:1da4db5de653 246 _button_L->rise(callback(this,&Gamepad::l_isr));
yfkwok 0:1da4db5de653 247 _button_R->rise(callback(this,&Gamepad::r_isr));
yfkwok 0:1da4db5de653 248 _button_start->rise(callback(this,&Gamepad::start_isr));
yfkwok 0:1da4db5de653 249 _button_back->rise(callback(this,&Gamepad::back_isr));
yfkwok 0:1da4db5de653 250 _button_joystick->rise(callback(this,&Gamepad::joy_isr));
yfkwok 0:1da4db5de653 251 }
yfkwok 0:1da4db5de653 252
yfkwok 0:1da4db5de653 253 // button interrupts ISRs
yfkwok 0:1da4db5de653 254 // Each of these simply sets the appropriate event bit in the _event_state
yfkwok 0:1da4db5de653 255 // variable
yfkwok 0:1da4db5de653 256 void Gamepad::a_isr()
yfkwok 0:1da4db5de653 257 {
yfkwok 0:1da4db5de653 258 _event_state.set(A_PRESSED);
yfkwok 0:1da4db5de653 259 }
yfkwok 0:1da4db5de653 260 void Gamepad::b_isr()
yfkwok 0:1da4db5de653 261 {
yfkwok 0:1da4db5de653 262 _event_state.set(B_PRESSED);
yfkwok 0:1da4db5de653 263 }
yfkwok 0:1da4db5de653 264 void Gamepad::x_isr()
yfkwok 0:1da4db5de653 265 {
yfkwok 0:1da4db5de653 266 _event_state.set(X_PRESSED);
yfkwok 0:1da4db5de653 267 }
yfkwok 0:1da4db5de653 268 void Gamepad::y_isr()
yfkwok 0:1da4db5de653 269 {
yfkwok 0:1da4db5de653 270 _event_state.set(Y_PRESSED);
yfkwok 0:1da4db5de653 271 }
yfkwok 0:1da4db5de653 272 void Gamepad::l_isr()
yfkwok 0:1da4db5de653 273 {
yfkwok 0:1da4db5de653 274 _event_state.set(L_PRESSED);
yfkwok 0:1da4db5de653 275 }
yfkwok 0:1da4db5de653 276 void Gamepad::r_isr()
yfkwok 0:1da4db5de653 277 {
yfkwok 0:1da4db5de653 278 _event_state.set(R_PRESSED);
yfkwok 0:1da4db5de653 279 }
yfkwok 0:1da4db5de653 280 void Gamepad::back_isr()
yfkwok 0:1da4db5de653 281 {
yfkwok 0:1da4db5de653 282 _event_state.set(BACK_PRESSED);
yfkwok 0:1da4db5de653 283 }
yfkwok 0:1da4db5de653 284 void Gamepad::start_isr()
yfkwok 0:1da4db5de653 285 {
yfkwok 0:1da4db5de653 286 _event_state.set(START_PRESSED);
yfkwok 0:1da4db5de653 287 }
yfkwok 0:1da4db5de653 288 void Gamepad::joy_isr()
yfkwok 0:1da4db5de653 289 {
yfkwok 0:1da4db5de653 290 _event_state.set(JOY_PRESSED);
yfkwok 0:1da4db5de653 291 }
yfkwok 0:1da4db5de653 292
yfkwok 0:1da4db5de653 293 // get raw joystick coordinate in range -1 to 1
yfkwok 0:1da4db5de653 294 // Direction (x,y)
yfkwok 0:1da4db5de653 295 // North (0,1)
yfkwok 0:1da4db5de653 296 // East (1,0)
yfkwok 0:1da4db5de653 297 // South (0,-1)
yfkwok 0:1da4db5de653 298 // West (-1,0)
yfkwok 0:1da4db5de653 299 Vector2D Gamepad::get_coord()
yfkwok 0:1da4db5de653 300 {
yfkwok 0:1da4db5de653 301 // read() returns value in range 0.0 to 1.0 so is scaled and centre value
yfkwok 0:1da4db5de653 302 // substracted to get values in the range -1.0 to 1.0
yfkwok 0:1da4db5de653 303 float x = 2.0f*( _horiz->read() - _x0 );
yfkwok 0:1da4db5de653 304 float y = 2.0f*( _vert->read() - _y0 );
yfkwok 0:1da4db5de653 305
yfkwok 0:1da4db5de653 306 // Note: the x value here is inverted to ensure the positive x is to the
yfkwok 0:1da4db5de653 307 // right. This is simply due to how the potentiometer on the joystick
yfkwok 0:1da4db5de653 308 // I was using was connected up. It could have been corrected in hardware
yfkwok 0:1da4db5de653 309 // by swapping the power supply pins. Instead it is done in software so may
yfkwok 0:1da4db5de653 310 // need to be changed depending on your wiring setup
yfkwok 0:1da4db5de653 311
yfkwok 0:1da4db5de653 312 Vector2D coord = {-x,y};
yfkwok 0:1da4db5de653 313 return coord;
yfkwok 0:1da4db5de653 314 }
yfkwok 0:1da4db5de653 315
yfkwok 0:1da4db5de653 316 // This maps the raw x,y coord onto a circular grid.
yfkwok 0:1da4db5de653 317 // See: http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
yfkwok 0:1da4db5de653 318 Vector2D Gamepad::get_mapped_coord()
yfkwok 0:1da4db5de653 319 {
yfkwok 0:1da4db5de653 320 Vector2D coord = get_coord();
yfkwok 0:1da4db5de653 321
yfkwok 0:1da4db5de653 322 // do the transformation
yfkwok 0:1da4db5de653 323 float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
yfkwok 0:1da4db5de653 324 float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
yfkwok 0:1da4db5de653 325
yfkwok 0:1da4db5de653 326 Vector2D mapped_coord = {x,y};
yfkwok 0:1da4db5de653 327 return mapped_coord;
yfkwok 0:1da4db5de653 328 }
yfkwok 0:1da4db5de653 329
yfkwok 0:1da4db5de653 330 // this function converts the mapped coordinates into polar form
yfkwok 0:1da4db5de653 331 Polar Gamepad::get_polar()
yfkwok 0:1da4db5de653 332 {
yfkwok 0:1da4db5de653 333 // get the mapped coordinate
yfkwok 0:1da4db5de653 334 Vector2D coord = get_mapped_coord();
yfkwok 0:1da4db5de653 335
yfkwok 0:1da4db5de653 336 // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
yfkwok 0:1da4db5de653 337 // We want 0 degrees to correspond to North and increase clockwise to 359
yfkwok 0:1da4db5de653 338 // like a compass heading, so we need to swap the axis and invert y
yfkwok 0:1da4db5de653 339 float x = coord.y;
yfkwok 0:1da4db5de653 340 float y = coord.x;
yfkwok 0:1da4db5de653 341
yfkwok 0:1da4db5de653 342 float mag = sqrt(x*x+y*y); // pythagoras
yfkwok 0:1da4db5de653 343 float angle = RAD2DEG*atan2(y,x);
yfkwok 0:1da4db5de653 344 // angle will be in range -180 to 180, so add 360 to negative angles to
yfkwok 0:1da4db5de653 345 // move to 0 to 360 range
yfkwok 0:1da4db5de653 346 if (angle < 0.0f) {
yfkwok 0:1da4db5de653 347 angle+=360.0f;
yfkwok 0:1da4db5de653 348 }
yfkwok 0:1da4db5de653 349
yfkwok 0:1da4db5de653 350 // the noise on the ADC causes the values of x and y to fluctuate slightly
yfkwok 0:1da4db5de653 351 // around the centred values. This causes the random angle values to get
yfkwok 0:1da4db5de653 352 // calculated when the joystick is centred and untouched. This is also when
yfkwok 0:1da4db5de653 353 // the magnitude is very small, so we can check for a small magnitude and then
yfkwok 0:1da4db5de653 354 // set the angle to -1. This will inform us when the angle is invalid and the
yfkwok 0:1da4db5de653 355 // joystick is centred
yfkwok 0:1da4db5de653 356
yfkwok 0:1da4db5de653 357 if (mag < TOL) {
yfkwok 0:1da4db5de653 358 mag = 0.0f;
yfkwok 0:1da4db5de653 359 angle = -1.0f;
yfkwok 0:1da4db5de653 360 }
yfkwok 0:1da4db5de653 361
yfkwok 0:1da4db5de653 362 Polar p = {mag,angle};
yfkwok 0:1da4db5de653 363 return p;
yfkwok 0:1da4db5de653 364 }