Joe Shotton / ll16j23s_test_docs

Files at this revision

API Documentation at this revision

Comitter:
eencae
Date:
Mon Feb 06 19:33:29 2017 +0000
Parent:
2:ea5538fcfe2f
Child:
4:bafb7f483e93
Commit message:
Removed LCD from library and merged in joystick methods (untested)

Changed in this revision

Gamepad.cpp Show annotated file Show diff for this revision Revisions of this file
Gamepad.h Show annotated file Show diff for this revision Revisions of this file
--- a/Gamepad.cpp	Sat Feb 04 16:21:19 2017 +0000
+++ b/Gamepad.cpp	Mon Feb 06 19:33:29 2017 +0000
@@ -10,7 +10,6 @@
     led_5 = new PwmOut(PTC4);
     led_6 = new PwmOut(PTD3);
 
-    lcd = new N5110(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
     joystick = new Joystick(PTB10,PTB11,PTC16);
 
     button_A = new InterruptIn(PTB9);
@@ -21,6 +20,10 @@
     button_start = new InterruptIn(PTC5);
     button_L = new InterruptIn(PTB18);
     button_R = new InterruptIn(PTB3);
+    button_joystick = new InterruptIn(PTC16);
+    
+    vert = new AnalogIn(PTB10);
+    horiz = new AnalogIn(PTB11);
 
     buzzer = new PwmOut(PTC10);
     pot = new AnalogIn(PTB2);
@@ -32,7 +35,7 @@
 Gamepad::~Gamepad()
 {
     delete led_1,led_2,led_3,led_4,led_5,led_6;
-    delete lcd,joystick,button_A,button_B;
+    delete button_A,button_B,button_joystick,vert,horiz;
     delete button_X, button_Y, button_back, button_start;
     delete button_L, button_R, buzzer, pot, timeout;
 }
@@ -42,13 +45,17 @@
 void Gamepad::init()
 {
     lcd->init();
-    joystick->init();
     leds_off();
+    
+    // read centred values of joystick
+    _x0 = horiz->read();
+    _y0 = vert->read();
 
     buzzer->period(1.0/1000.0);  // 1 kHz
 
     // clear all flags
-    a_flag=0,b_flag=0,x_flag=0,y_flag=0,l_flag=0,r_flag=0,back_flag=0,start_flag=0;
+    a_flag=0,b_flag=0,x_flag=0,y_flag=0,joy_flag=0;
+    l_flag=0,r_flag=0,back_flag=0,start_flag=0;
 
 }
 
@@ -182,6 +189,63 @@
         return false;
     }
 }
+
+bool Gamepad::joystick_pressed()
+{
+    // ISR must have been triggered
+    if (joy_flag) {
+        joy_flag = 0;  // clear flag
+        return true;
+    } else {
+        return false;
+    }
+}
+
+// this method gets the magnitude of the joystick movement
+float Gamepad::get_mag()
+{
+    Polar p = get_polar();
+    return p.mag;
+}
+
+// this method gets the angle of joystick movement (0 to 360, 0 North)
+float Gamepad::get_angle()
+{
+    Polar p = get_polar();
+    return p.angle;
+}
+
+Direction Joystick::get_direction()
+{
+    float angle = get_angle();  // 0 to 360, -1 for centred
+
+    Direction d;
+    // partition 360 into segments and check which segment the angle is in
+    if (angle < 0.0f) {
+        d = CENTRE;   // check for -1.0 angle
+    } else if (angle < 22.5f) {  // then keep going in 45 degree increments
+        d = N;
+    } else if (angle < 67.5f) {
+        d = NE;
+    } else if (angle < 112.5f) {
+        d = E;
+    } else if (angle < 157.5f) {
+        d = SE;
+    } else if (angle < 202.5f) {
+        d = S;
+    } else if (angle < 247.5f) {
+        d = SW;
+    } else if (angle < 292.5f) {
+        d = W;
+    } else if (angle < 337.5f) {
+        d = NW;
+    } else {
+        d = N;
+    }
+
+    return d;
+}
+
 ///////////////////// private methods ////////////////////////
 
 void Gamepad::tone_off()
@@ -201,6 +265,7 @@
     button_start->mode(PullDown);
     button_L->mode(PullDown);
     button_R->mode(PullDown);
+    button_joystick->mode(PullDown);
     // therefore setup rising edge interrupts
     button_A->rise(callback(this,&Gamepad::a_isr));
     button_B->rise(callback(this,&Gamepad::b_isr));
@@ -210,6 +275,7 @@
     button_R->rise(callback(this,&Gamepad::r_isr));
     button_start->rise(callback(this,&Gamepad::start_isr));
     button_back->rise(callback(this,&Gamepad::back_isr));
+    button_joystick->rise(callback(this,&Gamepad::joy_isr));
 }
 
 // button interrupts ISRs
@@ -244,4 +310,81 @@
 void Gamepad::start_isr()
 {
     start_flag=1;
+}
+void Gamepad::joy_isr()
+{
+    joy_flag=1;
+}
+
+// get raw joystick coordinate in range -1 to 1
+// Direction (x,y)
+// North     (0,1)
+// East      (1,0)
+// South     (0,-1)
+// West      (-1,0)
+Vector2D Gamepad::get_coord()
+{
+    // read() returns value in range 0.0 to 1.0 so is scaled and centre value
+    // substracted to get values in the range -1.0 to 1.0
+    float x = 2.0f*( horiz->read() - _x0 );
+    float y = 2.0f*( vert->read() - _y0 );
+
+    // Note: the x value here is inverted to ensure the positive x is to the
+    // right. This is simply due to how the potentiometer on the joystick
+    // I was using was connected up. It could have been corrected in hardware
+    // by swapping the power supply pins. Instead it is done in software so may
+    // need to be changed depending on your wiring setup
+
+    Vector2D coord = {-x,y};
+    return coord;
+}
+
+// This maps the raw x,y coord onto a circular grid.
+// See:  http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
+Vector2D Gamepad::get_mapped_coord()
+{
+    Vector2D coord = get_coord();
+
+    // do the transformation
+    float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
+    float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
+
+    Vector2D mapped_coord = {x,y};
+    return mapped_coord;
+}
+
+// this function converts the mapped coordinates into polar form
+Polar Gamepad::get_polar()
+{
+    // get the mapped coordinate
+    Vector2D coord = get_mapped_coord();
+
+    // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
+    // We want 0 degrees to correspond to North and increase clockwise to 359
+    // like a compass heading, so we need to swap the axis and invert y
+    float x = coord.y;
+    float y = coord.x;
+
+    float mag = sqrt(x*x+y*y);  // pythagoras
+    float angle = RAD2DEG*atan2(y,x);
+    // angle will be in range -180 to 180, so add 360 to negative angles to
+    // move to 0 to 360 range
+    if (angle < 0.0f) {
+        angle+=360.0f;
+    }
+
+    // the noise on the ADC causes the values of x and y to fluctuate slightly
+    // around the centred values. This causes the random angle values to get
+    // calculated when the joystick is centred and untouched. This is also when
+    // the magnitude is very small, so we can check for a small magnitude and then
+    // set the angle to -1. This will inform us when the angle is invalid and the
+    // joystick is centred
+
+    if (mag < TOL) {
+        mag = 0.0f;
+        angle = -1.0f;
+    }
+
+    Polar p = {mag,angle};
+    return p;
 }
\ No newline at end of file
--- a/Gamepad.h	Sat Feb 04 16:21:19 2017 +0000
+++ b/Gamepad.h	Mon Feb 06 19:33:29 2017 +0000
@@ -2,8 +2,31 @@
 #define GAMEPAD_H
 
 #include "mbed.h"
-#include "N5110.h"
-#include "Joystick.h"
+
+#define TOL 0.1f
+#define RAD2DEG 57.2957795131f
+
+enum Direction {
+    CENTRE,  // 0
+    N,       // 1
+    NE,      // 2
+    E,       // 3
+    SE,      // 4
+    S,       // 5
+    SW,      // 6
+    W,       // 7
+    NW      // 8
+};
+
+struct Vector2D {
+    float x;
+    float y;
+};
+
+struct Polar {
+    float mag;
+    float angle;
+};
 
 class Gamepad
 {
@@ -12,8 +35,6 @@
 
     Gamepad();
     ~Gamepad();
-    N5110 *lcd;
-    Joystick *joystick;
 
     void init();
     void leds_on();
@@ -32,6 +53,12 @@
     bool back_pressed();
     bool start_pressed();
 
+    bool joystick_pressed();
+    float get_mag();
+    float get_angle();
+    Direction get_direction();    // N,NE,E,SE etc.
+
+
 private:
 
     PwmOut *led_1;
@@ -44,11 +71,15 @@
     InterruptIn *button_A;
     InterruptIn *button_B;
     InterruptIn *button_X;
-    InterruptIn *button_Y;  // changed pin
+    InterruptIn *button_Y;
     InterruptIn *button_back;
     InterruptIn *button_start;
     InterruptIn *button_L;
     InterruptIn *button_R;
+    InterruptIn *button_joystick;
+
+    AnalogIn *vert;
+    AnalogIn *horiz;
 
     PwmOut *buzzer;
     AnalogIn *pot;
@@ -57,6 +88,7 @@
 
     void init_buttons();
     void tone_off();
+
     void a_isr();
     void b_isr();
     void x_isr();
@@ -65,8 +97,20 @@
     void r_isr();
     void back_isr();
     void start_isr();
+    void joy_isr();
+    
+    Vector2D get_coord();         // cartesian co-ordinates x,y
+    Vector2D get_mapped_coord();  // x,y mapped to circle
+    Direction get_direction();    // N,NE,E,SE etc.
+    Polar get_polar();            // mag and angle in struct form
 
-    bool a_flag,b_flag,x_flag,y_flag,l_flag,r_flag,back_flag,start_flag;
+    bool a_flag,b_flag,x_flag,y_flag,l_flag,r_flag,back_flag,start_flag,joy_flag;
+    
+      // centred x,y values    
+    float _x0;
+    float _y0;
+
+
 
 };