Final version

Dependencies:   mbed SparkfunAnalogJoystick LSM9DS1_Library_cal PinDetect

Files at this revision

API Documentation at this revision

Comitter:
kzar
Date:
Tue Dec 11 21:22:01 2018 +0000
Parent:
1:0ec1b59239f2
Commit message:
ye

Changed in this revision

LSM9DS1_Library_cal.lib Show annotated file Show diff for this revision Revisions of this file
SparkfunAnalogJoystick.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM9DS1_Library_cal.lib	Tue Dec 11 21:22:01 2018 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/4180_1/code/LSM9DS1_Library_cal/#36abf8e18ade
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SparkfunAnalogJoystick.lib	Tue Dec 11 21:22:01 2018 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/a/code/SparkfunAnalogJoystick/#2b40241a7675
--- a/main.cpp	Wed Dec 05 20:53:45 2018 +0000
+++ b/main.cpp	Tue Dec 11 21:22:01 2018 +0000
@@ -3,26 +3,23 @@
 
 #include "mbed.h"
 #include "PinDetect.h"
+#include "SparkfunAnalogJoystick.h"
+#include "LSM9DS1.h"
+#define PI 3.14159
 
+#define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA.
+// Construct serial objects
 Serial pc(USBTX, USBRX);
 Serial esp(p28, p27); // tx, rx
-
-
 // Standard Mbed LED definitions
 DigitalOut  led1(LED1);
 DigitalOut  led2(LED2);
-DigitalOut  led3(LED3);
-DigitalOut  led4(LED4);
-
-// Push button used for testing
-PinDetect pb1(p21);
-void pushed();
-
-/*
-char ssid[32] = "hsd";     // enter WiFi router ssid inside the quotes
-char pwd [32] = "austin123"; // enter WiFi router password inside the quotes
-*/
-
+// Joystick for control
+SparkfunAnalogJoystick joystick(p18, p19, p20);
+// Construct imu object
+LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);//sda, scl
+// function for geting mag heading
+float calc_heading(float mx, float my);
 
 // things for sending/receiving data over serial
 volatile int tx_in=0;
@@ -34,172 +31,192 @@
 char rx_buffer[buffer_size+1];
 void Tx_interrupt();
 void Rx_interrupt();
-void read_line();
+//void read_line();
 
 int DataRX;
 int update;
 char cmdbuff[1024];
 char replybuff[4096];
-char webdata[4096]; // This may need to be bigger depending on WEB browser used
+char webdata[4096];     // This may need to be bigger depending on WEB browser used
 char webbuff[4096];     // Currently using 1986 characters, Increase this if more web page data added
-void SendCMD(),getreply();
+void SendCMD();
+//void getreply();
 void getConnection();   // Sets up a connection with the car server
 char rx_line[1024];
-int port        =80;  // set server port
-int SERVtimeout =5;    // set server timeout in seconds in case link breaks.
-
-
+int port = 80;          // set server port
+int SERVtimeout = 5;    // set server timeout in seconds in case link breaks.
 
 int main()
 {
     pc.baud(9600);
     esp.baud(9600);
-    led1=1,led2=0,led3=0, led4=0;
+
+    // Init leds
+    led1=0,led2=0;
+    
     // Setup a serial interrupt function to receive data
     esp.attach(&Rx_interrupt, Serial::RxIrq);
     // Setup a serial interrupt function to transmit data
     esp.attach(&Tx_interrupt, Serial::TxIrq);
-    // Attach isr to pushbutton
-    pb1.mode(PullUp);
-    pb1.attach_asserted(&pushed);
-
+    
     // Get connection to server
     getConnection();
     
-    update = 0;
-    // Everything is interrupt driven, infinite loop
-    while(1) {
-        
-        pushed();
-        
-        //Send all car vals+
-        if (update) {
-            // Send led for testing 
-            
-            
-            // Reset update flag
-            update = 0;
+    // Set up the imu
+    IMU.begin();
+    if (!IMU.begin()) {
+        pc.printf("Failed to communicate with LSM9DS1.\n");
+    }
+    IMU.calibrate(1);
+    IMU.calibrateMag(0);
+    float forward, current, diff;
+    float servo_x;
+    //initial heading calc, need to rotate by 360 degrees.
+    while(!IMU.magAvailable(X_AXIS));
+    IMU.readMag();
+    forward = calc_heading(IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my));
+    
+    // Variables used for joystick
+    float lm, rm;
+    float x, y;
+    
+    while (1) {
+        // Update the motor speeds
+            // Get x and y
+            x = joystick.xAxis();
+            y = joystick.yAxis();
+            // Get the angle of direction
+        // Determine which direction (straight, complete turn, or in a coordinate quadrant)
+        // straight (set motor speed directly to y
+        if (x < .1 && x > -.1) {
+            lm = (y);
+            rm = (-1*y);\
+        }
+        // Complete turn (set outside motor directly to x)
+        else if ( y < .1 && y > -.1) {
+            if (x > 0) {
+                lm = (x);
+                rm = (0);
+            } else {
+                lm = (0);
+                rm = (x);  
+            }  
         }
         
+        // Update the servo   
+        while(!IMU.magAvailable(X_AXIS));
+        IMU.readMag();
+        current = calc_heading(IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my));
+        // diff is the final difference from forward direction in [-180, 180] range
+        // this needs to     be normalized to [0, 1] while only keeping [-45, 45]
+        diff = fmod((forward - current + 180), 360) - 180;
+        diff = (diff < -180) ? (diff + 360) : diff;
+        servo_x = (diff / 90.0) + 0.45;
+        
+        // Send the updated value of the motors and servos
+        sprintf(cmdbuff, "cl:send(\"<l=%f,r=%f,x=%f>\")\r\n)", lm, rm, servo_x);
+
+        SendCMD();
+        wait(0.18);
+        led1=!led1;
     }
 }
 
-void pushed()
+// Gets magnetic heading
+float calc_heading(float mx, float my)
 {
-    strcpy(cmdbuff,"cl:send(\"flip_led1\")\r\n");
-    SendCMD();
-    //getreply();
-    wait(.1);  
+    // touchy trig stuff to use arctan to get compass heading (scale is 0..360)
+    mx = -mx;
+    float heading;
+    if (my == 0.0)
+        heading = (mx < 0.0) ? 180.0 : 0.0;
+    else
+        heading = atan2(mx, my)*360.0/(2.0*PI);
+    heading -= DECLINATION; //correct for geo location
+    if(heading>180.0) heading = heading - 360.0;
+    else if(heading<-180.0) heading = 360.0 + heading;
+    else if(heading<0.0) heading = 360.0  + heading;
+
+    // pc.printf("Magnetic Heading: %f degrees\n\r",heading);
+    return heading;
 }
 
+
 // Sets up connection with car server
 void getConnection()
-{
+{   
     // Reset the ESP8266
     pc.printf("++++++++++ Resetting ESP ++++++++++\r\n");
     strcpy(cmdbuff,"node.restart()\r\n");
     SendCMD();
-    wait(2);
-    getreply();
+    wait(1);
     
     // Disconncet from any potential connections
     strcpy(cmdbuff,"wifi.sta.disconnect()\r\n");
     SendCMD();
-    getreply();
-    wait(2);     
+    wait(1);     
     // Set mode (STATION)
     strcpy(cmdbuff,"wifi.setmode(wifi.STATION)\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
+    //getreply();
+    wait(1); 
     // Connect to car server
     strcpy(cmdbuff,"wifi.sta.config(\"Marlon's iPhone\", \"feelsbadman\")\r\n");
     SendCMD();
-    getreply();
-    wait(2);
+    wait(1);
     // Connect to server
     strcpy(cmdbuff,"wifi.sta.connect()\r\n");
     SendCMD();
-    getreply();
-    wait(2);
+    wait(1);
     
     strcpy(cmdbuff,"print(\"Looking for a connection\")\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
+    wait(1); 
     
     strcpy(cmdbuff,"tmr.alarm(1,2000,1, function()\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
+    wait(1); 
     
     strcpy(cmdbuff,"if(wifi.sta.getip()~=nil) then\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
+    wait(1); 
     
     strcpy(cmdbuff,"tmr.stop(1)\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
+    wait(1); 
     // Print out controller ip address
     strcpy(cmdbuff,"print(\"Connected!\")\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
+    wait(1); 
     // Print out controller ip address
     strcpy(cmdbuff,"print(\"Client IP Address: \",wifi.sta.getip())\r\n");
     SendCMD();
-    getreply();
-    wait(5); 
+    wait(1);
     // Create connetion
     strcpy(cmdbuff,"cl=net.createConnection(net.TCP, 0)\r\n");
     SendCMD();
-    getreply();
-    wait(2);
+    wait(1);
     // Connect the connection
     strcpy(cmdbuff,"cl:connect(80, \"192.168.4.1\")\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
-    
-//    strcpy(cmdbuff,"tmr.alarm(2, 5000, 1, function()\r\n");
-//    SendCMD();
-//    getreply();
-//    wait(2);
-//    
-//    strcpy(cmdbuff,"cl:send(\"Hello World!\")\r\n");
-//    SendCMD();
-//    getreply();
-//    wait(2);
-//    
-//    strcpy(cmdbuff,"end)\r\n");
-//    SendCMD();
-//    getreply();
-//    wait(2);
-    
-    
-    // Print out controller ip address
+    wait(1);
+   
     strcpy(cmdbuff,"else\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
-    // Print out controller ip address
+    wait(1);
+    
     strcpy(cmdbuff,"print(\"Connecting...\")\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
-    // Print out controller ip address
+    wait(1); 
+    
     strcpy(cmdbuff,"end\r\n");
     SendCMD();
-    getreply();
-    wait(2);
-    // Print out controller ip address
+    wait(1);
+    
     strcpy(cmdbuff,"end)\r\n");
     SendCMD();
-    getreply();
-    wait(2); 
-    
+    //getreply();
+    wait(5); 
 }
 
 
@@ -240,40 +257,40 @@
 
 
 // Get Command and ESP status replies
-void getreply()
-{
-    read_line();
-    sscanf(rx_line,replybuff);
-}
+//void getreply()
+//{
+//    read_line();
+//    sscanf(rx_line,replybuff);
+//}
 
 // FUNCTIONS BELOW ARE FOR RX AND TX INTERUPTS (NOT WEB STUFF)
  
 // Read a line from the large rx buffer from rx interrupt routine
-void read_line() {
-    int i;
-    i = 0;
-// Start Critical Section - don't interrupt while changing global buffer variables
-    NVIC_DisableIRQ(UART1_IRQn);
-// Loop reading rx buffer characters until end of line character
-    while ((i==0) || (rx_line[i-1] != '\r')) {
-// Wait if buffer empty
-        if (rx_in == rx_out) {
-// End Critical Section - need to allow rx interrupt to get new characters for buffer
-            NVIC_EnableIRQ(UART1_IRQn);
-            while (rx_in == rx_out) {
-            }
-// Start Critical Section - don't interrupt while changing global buffer variables
-            NVIC_DisableIRQ(UART1_IRQn);
-        }
-        rx_line[i] = rx_buffer[rx_out];
-        i++;
-        rx_out = (rx_out + 1) % buffer_size;
-    }
-// End Critical Section
-    NVIC_EnableIRQ(UART1_IRQn);
-    rx_line[i-1] = 0;
-    return;
-}
+//void read_line() {
+//    int i;
+//    i = 0;
+//// Start Critical Section - don't interrupt while changing global buffer variables
+//    NVIC_DisableIRQ(UART1_IRQn);
+//// Loop reading rx buffer characters until end of line character
+//    while ((i==0) || (rx_line[i-1] != '\r')) {
+//// Wait if buffer empty
+//        if (rx_in == rx_out) {
+//// End Critical Section - need to allow rx interrupt to get new characters for buffer
+//            NVIC_EnableIRQ(UART1_IRQn);
+//            while (rx_in == rx_out) {
+//            }
+//// Start Critical Section - don't interrupt while changing global buffer variables
+//            NVIC_DisableIRQ(UART1_IRQn);
+//        }
+//        rx_line[i] = rx_buffer[rx_out];
+//        i++;
+//        rx_out = (rx_out + 1) % buffer_size;
+//    }
+//// End Critical Section
+//    NVIC_EnableIRQ(UART1_IRQn);
+//    rx_line[i-1] = 0;
+//    return;
+//}
  
  
 // Interupt Routine to read in data from serial port
@@ -285,8 +302,8 @@
     while ((esp.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
         rx_buffer[rx_in] = esp.getc();
 // Uncomment to Echo to USB serial to watch data flow
-        pc.putc(rx_buffer[rx_in]);
-        rx_in = (rx_in + 1) % buffer_size;
+//        pc.putc(rx_buffer[rx_in]);
+//        rx_in = (rx_in + 1) % buffer_size;
     }
     //led3=0;
     return;