4180 weather balloon logging and cutdown system

Dependencies:   GPS MPL3115A2 SDFileSystem mbed-rtos mbed

Fork of WeatherBalloon4180 by Chad Miller

main.cpp

Committer:
Gjika
Date:
2015-12-07
Revision:
6:d61e7eeabcac
Parent:
5:c3e1fc7fa00d

File content as of revision 6:d61e7eeabcac:

#include "mbed.h"
#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);

AnalogIn temp1(p18);
AnalogIn temp2(p19);
AnalogIn temp3(p20);

DigitalIn dtmf1(p11);
DigitalIn dtmf2(p12);
DigitalIn dtmf3(p13);
DigitalIn log_switch(p21);

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut relay(p14);

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;
float analog1, analog2;

FILE *sdout;
Timer t;
Mutex log_mutex;

Altitude alt_altitude;
Temperature alt_temperature;
Pressure alt_pressure;

void init()
{
    t.start();
    
    led1  = 0;
    relay = 0;
    
    altimeter.init();
    altimeter.setOffsetAltitude(0);
    altimeter.setOffsetTemperature(0);
    altimeter.setOffsetPressure(0);
    
    mkdir("/sd/weather_balloon", 0777);
}

void update_gps(void const *args)
{
    while(true)
    {
        gps_locked = gps.sample();
        led1       = gps_locked;
        
        Thread::wait(250);
    }
}

void update_temperature(void const *args)
{
    float tempC1;
    
    while(true)
    {
        tempC1 = ((temp1 * 3.3) - 0.600) * 100.0;
        tempF1 = (9.0 * tempC1) / 5.0 + 32;
        analog1 = (temp2);
        analog2 = (temp3);
        
        Thread::wait(250);
    }
}

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)
    {
        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\nAnalog1 = %f\r\nAnalog2 = %f\r\n", tempF1, analog1, analog2);
            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\nAnalog1 = %f\r\nAnalog2 = %f\r\n", tempF1, analog1, analog2);
            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;
            }
        }
        
        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() >= 7200 || dtmf1 || alt_altitude.altitude() > 100000 || gps_out_of_bounds())
            cutdown = true;

        if(cutdown && !attempted)
        {
            log_mutex.lock();
            
            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(20000);
            relay = 0;
            
            log_mutex.lock();
            
            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;
        }
        
        Thread::wait(100);
    }
}

int main()
{
    init();
    
    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);
}