Final project for ECE 4180.

Dependencies:   GPS SDFileSystem mbed-rtos mbed MPL3115A2

Fork of GPS_HelloWorld by kris gjika

Revision:
5:c3e1fc7fa00d
Parent:
4:ebf8c354c758
--- a/main.cpp	Tue Nov 17 07:22:32 2015 +0000
+++ b/main.cpp	Tue Dec 01 20:38:27 2015 +0000
@@ -2,10 +2,26 @@
 #include "rtos.h"
 
 #include "GPS.h"
+#include "MPL3115A2.h"
 #include "SDFileSystem.h"
 
 #define PC_DEBUG
 
+/*
+ * You must define the minimum and maximum latitudes
+ * and longitudes yourself in these four macros.
+ *
+ * For reference: the coordinates right outide Van Leer
+ * (Fishbowl) are:
+ *
+ * Longitude = -140.400406
+ * Latitude  = 33.772503
+ */
+#define MIN_LATITUDE  -145
+#define MAX_LATITUDE  -135
+#define MIN_LONGITUDE 28
+#define MAX_LONGITUDE 38
+
 Serial pc(USBTX, USBRX);
 SDFileSystem sd(p5, p6, p7, p8, "sd");
 GPS gps(p9, p10);
@@ -14,18 +30,30 @@
 AnalogIn temp2(p19);
 AnalogIn temp3(p20);
 
-DigitalIn dtmf(p11);
+DigitalIn dtmf1(p11);
+DigitalIn dtmf2(p12);
+DigitalIn dtmf3(p13);
+DigitalIn log_switch(p21);
 
 DigitalOut led1(LED1);
-DigitalOut relay(p8);
+DigitalOut led2(LED2);
+DigitalOut relay(p14);
 
-bool attempted = false, cutdown = false;
+I2C i2c(p28, p27);
+MPL3115A2 altimeter(&i2c, &pc);
+
+bool attempted = false, cutdown = false, gps_locked = false;
+bool log_open = log_switch;
 float tempF1, tempF2, tempF3;
 
 FILE *sdout;
 Timer t;
 Mutex log_mutex;
 
+Altitude alt_altitude;
+Temperature alt_temperature;
+Pressure alt_pressure;
+
 void init()
 {
     t.start();
@@ -33,18 +61,20 @@
     led1  = 0;
     relay = 0;
     
+    altimeter.init();
+    altimeter.setOffsetAltitude(0);
+    altimeter.setOffsetTemperature(0);
+    altimeter.setOffsetPressure(0);
+    
     mkdir("/sd/weather_balloon", 0777);
-    sdout = fopen("/sd/weather_balloon/log.txt", "w");
 }
 
 void update_gps(void const *args)
 {
     while(true)
     {
-        gps.sample();
-        
-        if(!gps.longitude)
-            led1 = 1;
+        gps_locked = gps.sample();
+        led1       = gps_locked;
         
         Thread::wait(250);
     }
@@ -67,51 +97,140 @@
     }
 }
 
+void update_altimeter(void const *args)
+{
+    while(true)
+    {
+        altimeter.readAltitude(&alt_altitude);
+        altimeter.readTemperature(&alt_temperature);
+        
+        altimeter.setModeStandby();
+        altimeter.setModeBarometer();
+        altimeter.setModeActive();
+        altimeter.readPressure(&alt_pressure);
+        
+        altimeter.setModeStandby();
+        altimeter.setModeAltimeter();
+        altimeter.setModeActive();
+        
+        Thread::wait(250);
+    }
+}
+
 void write_to_log(void const *args)
 {
     while(true)
     {
-        log_mutex.lock();
-        
-        fprintf(sdout, "----- %f -----\n\r", t.read());
-        fprintf(sdout, "Long = %f\n\rLati = %f\n\r", gps.longitude, gps.latitude);
-        fprintf(sdout, "Temp1 = %f\n\rTemp2 = %f\n\rTemp3 = %f\n\r", tempF1, tempF2, tempF3);
-        fprintf(sdout, dtmf ? "DTMF = True\n\r" : "DTMF = False\n\r");
+        if(log_switch)
+        {
+            log_mutex.lock();
+            
+            if(!log_open)
+            {
+                sdout    = fopen("/sd/weather_balloon/log.txt", "a");
+                log_open = true;
+            }
+            
+            fprintf(sdout, "----- %f -----\r\n", t.read());
+            fprintf(sdout, "Long = %f\r\nLati = %f\r\n", gps.longitude, gps.latitude);
+            fprintf(sdout, "Temp1 = %f\r\nTemp2 = %f\r\nTemp3 = %f\r\n", -tempF1, -tempF2, -tempF3);
+            fprintf(sdout, "Altitude = %s ft, offset = 0x%X\r\n", alt_altitude.print(), altimeter.offsetAltitude());
+            fprintf(sdout, "Temperature = %s deg F, offset = 0x%X\r\n", alt_temperature.print(), altimeter.offsetTemperature());
+            //fprintf(sdout, "Pressure = %s Pa, offset = 0x%X\r\n", alt_pressure.print(), altimeter.offsetPressure());
+            fprintf(sdout, dtmf1 ? "DTMF 1 = True\r\n" : "DTMF 1 = False\r\n");
+            fprintf(sdout, dtmf2 ? "DTMF 2 = True\r\n" : "DTMF 2 = False\r\n");
+            fprintf(sdout, dtmf3 ? "DTMF 3 = True\r\n" : "DTMF 3 = False\r\n");
+            
+            #ifdef PC_DEBUG
+            pc.printf("----- %f -----\r\n", t.read());
+            pc.printf("Long = %f\r\nLati = %f\r\n", gps.longitude, gps.latitude);
+            pc.printf("Temp1 = %f\r\nTemp2 = %f\r\nTemp3 = %f\r\n", -tempF1, -tempF2, -tempF3);
+            pc.printf("Altitude = %s ft, offset = 0x%X\r\n", alt_altitude.print(), altimeter.offsetAltitude());
+            pc.printf("Temperature = %s deg F, offset = 0x%X\r\n", alt_temperature.print(), altimeter.offsetTemperature());
+            //pc.printf("Pressure = %s Pa, offset = 0x%X\r\n", alt_pressure.print(), altimeter.offsetPressure());
+            pc.printf(dtmf1 ? "DTMF 1 = True\r\n" : "DTMF 1 = False\r\n");
+            pc.printf(dtmf2 ? "DTMF 2 = True\r\n" : "DTMF 2 = False\r\n");
+            pc.printf(dtmf3 ? "DTMF 3 = True\r\n" : "DTMF 3 = False\r\n");
+            #endif
+            
+            log_mutex.unlock();
+            
+            Thread::wait(1000);
+        }
+        else
+        {
+            if(log_open)
+            {
+                fclose(sdout);
+                log_open = false;
+            }
+        }
         
-        #ifdef PC_DEBUG
-        pc.printf("----- %f -----\n\r", t.read());
-        pc.printf("Long = %f\n\rLati = %f\n\r", gps.longitude, gps.latitude);
-        pc.printf("Temp1 = %f\n\rTemp2 = %f\n\rTemp3 = %f\n\r", tempF1, tempF2, tempF3);
-        pc.printf(dtmf ? "DTMF = True\n\r" : "DTMF = False\n\r");
-        #endif
-        
-        log_mutex.unlock();
-        
-        Thread::wait(1000);
+        led2 = log_switch;
     }
 }
 
+bool gps_out_of_bounds()
+{
+    static int count = 0;
+    
+    if(gps_locked)
+    {
+        if(count > 10)
+        {
+            count = 0;
+            return    gps.latitude  < MIN_LATITUDE
+                   || gps.latitude  > MAX_LATITUDE
+                   || gps.longitude < MIN_LONGITUDE
+                   || gps.longitude > MAX_LONGITUDE;
+        }
+        else
+        {
+            count++;
+            return false;
+        }
+    }
+    else
+        return false;
+}
+
 void check_cutdown(void const *args)
 {
     while(true)
     {
-        if(t.read() >= 20 || dtmf)
+        if(t.read() >= 7200 || dtmf1 || alt_altitude.altitude() > 100000 || gps_out_of_bounds())
             cutdown = true;
 
         if(cutdown && !attempted)
         {
             log_mutex.lock();
-            pc.printf("Cutdown Started = %f\n\r", t.read());
-            fprintf(sdout, "Cutdown Started = %f\n\r", t.read());
+            
+            if(log_switch && log_open)
+            {
+                fprintf(sdout, "Cutdown Started = %f\r\n", t.read());
+                
+                #ifdef PC_DEBUG
+                pc.printf("Cutdown Started = %f\r\n", t.read());
+                #endif
+            }
+            
             log_mutex.unlock();
             
             relay = 1;
-            Thread::wait(200000);
+            Thread::wait(20000);
             relay = 0;
             
             log_mutex.lock();
-            pc.printf("Cutdown Ended = %f\n\r", t.read());
-            fprintf(sdout, "Cutdown Ended = %f\n\r", t.read());
+            
+            if(log_switch && log_open)
+            {
+                fprintf(sdout, "Cutdown Ended = %f\r\n", t.read());
+                
+                #ifdef PC_DEBUG
+                pc.printf("Cutdown Ended = %f\r\n", t.read());
+                #endif
+            }
+                        
             log_mutex.unlock();
             
             attempted = true;
@@ -127,6 +246,9 @@
     
     Thread gps_thread(update_gps);
     Thread temperature_thread(update_temperature);
+    Thread altimeter_thread(update_altimeter);
     Thread log_thread(write_to_log);
     Thread cutdown_thread(check_cutdown);
+    
+    while(true);
 }