4180 weather balloon logging and cutdown system

Dependencies:   GPS MPL3115A2 SDFileSystem mbed-rtos mbed

Fork of WeatherBalloon4180 by Chad Miller

Committer:
Gjika
Date:
Mon Dec 07 19:02:21 2015 +0000
Revision:
6:d61e7eeabcac
Parent:
5:c3e1fc7fa00d
Final version of 4180 weather balloon

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:6b7345059afe 1 #include "mbed.h"
cmiller86 2:21e4b9092bb2 2 #include "rtos.h"
cmiller86 2:21e4b9092bb2 3
simon 0:6b7345059afe 4 #include "GPS.h"
cmiller86 5:c3e1fc7fa00d 5 #include "MPL3115A2.h"
cmiller86 2:21e4b9092bb2 6 #include "SDFileSystem.h"
simon 0:6b7345059afe 7
cmiller86 3:b490294520d5 8 #define PC_DEBUG
cmiller86 3:b490294520d5 9
cmiller86 5:c3e1fc7fa00d 10 /*
cmiller86 5:c3e1fc7fa00d 11 * You must define the minimum and maximum latitudes
cmiller86 5:c3e1fc7fa00d 12 * and longitudes yourself in these four macros.
cmiller86 5:c3e1fc7fa00d 13 *
cmiller86 5:c3e1fc7fa00d 14 * For reference: the coordinates right outide Van Leer
cmiller86 5:c3e1fc7fa00d 15 * (Fishbowl) are:
cmiller86 5:c3e1fc7fa00d 16 *
cmiller86 5:c3e1fc7fa00d 17 * Longitude = -140.400406
cmiller86 5:c3e1fc7fa00d 18 * Latitude = 33.772503
cmiller86 5:c3e1fc7fa00d 19 */
cmiller86 5:c3e1fc7fa00d 20 #define MIN_LATITUDE -145
cmiller86 5:c3e1fc7fa00d 21 #define MAX_LATITUDE -135
cmiller86 5:c3e1fc7fa00d 22 #define MIN_LONGITUDE 28
cmiller86 5:c3e1fc7fa00d 23 #define MAX_LONGITUDE 38
cmiller86 5:c3e1fc7fa00d 24
simon 0:6b7345059afe 25 Serial pc(USBTX, USBRX);
cmiller86 2:21e4b9092bb2 26 SDFileSystem sd(p5, p6, p7, p8, "sd");
simon 0:6b7345059afe 27 GPS gps(p9, p10);
cmiller86 2:21e4b9092bb2 28
cmiller86 2:21e4b9092bb2 29 AnalogIn temp1(p18);
cmiller86 2:21e4b9092bb2 30 AnalogIn temp2(p19);
cmiller86 2:21e4b9092bb2 31 AnalogIn temp3(p20);
cmiller86 2:21e4b9092bb2 32
cmiller86 5:c3e1fc7fa00d 33 DigitalIn dtmf1(p11);
cmiller86 5:c3e1fc7fa00d 34 DigitalIn dtmf2(p12);
cmiller86 5:c3e1fc7fa00d 35 DigitalIn dtmf3(p13);
cmiller86 5:c3e1fc7fa00d 36 DigitalIn log_switch(p21);
cmiller86 2:21e4b9092bb2 37
Gjika 1:2c4f640a8104 38 DigitalOut led1(LED1);
cmiller86 5:c3e1fc7fa00d 39 DigitalOut led2(LED2);
cmiller86 5:c3e1fc7fa00d 40 DigitalOut relay(p14);
cmiller86 2:21e4b9092bb2 41
cmiller86 5:c3e1fc7fa00d 42 I2C i2c(p28, p27);
cmiller86 5:c3e1fc7fa00d 43 MPL3115A2 altimeter(&i2c, &pc);
cmiller86 5:c3e1fc7fa00d 44
cmiller86 5:c3e1fc7fa00d 45 bool attempted = false, cutdown = false, gps_locked = false;
cmiller86 5:c3e1fc7fa00d 46 bool log_open = log_switch;
cmiller86 3:b490294520d5 47 float tempF1, tempF2, tempF3;
Gjika 6:d61e7eeabcac 48 float analog1, analog2;
cmiller86 2:21e4b9092bb2 49
cmiller86 2:21e4b9092bb2 50 FILE *sdout;
cmiller86 3:b490294520d5 51 Timer t;
cmiller86 3:b490294520d5 52 Mutex log_mutex;
simon 0:6b7345059afe 53
cmiller86 5:c3e1fc7fa00d 54 Altitude alt_altitude;
cmiller86 5:c3e1fc7fa00d 55 Temperature alt_temperature;
cmiller86 5:c3e1fc7fa00d 56 Pressure alt_pressure;
cmiller86 5:c3e1fc7fa00d 57
cmiller86 2:21e4b9092bb2 58 void init()
cmiller86 2:21e4b9092bb2 59 {
cmiller86 2:21e4b9092bb2 60 t.start();
cmiller86 3:b490294520d5 61
cmiller86 3:b490294520d5 62 led1 = 0;
cmiller86 2:21e4b9092bb2 63 relay = 0;
cmiller86 2:21e4b9092bb2 64
cmiller86 5:c3e1fc7fa00d 65 altimeter.init();
cmiller86 5:c3e1fc7fa00d 66 altimeter.setOffsetAltitude(0);
cmiller86 5:c3e1fc7fa00d 67 altimeter.setOffsetTemperature(0);
cmiller86 5:c3e1fc7fa00d 68 altimeter.setOffsetPressure(0);
cmiller86 5:c3e1fc7fa00d 69
cmiller86 2:21e4b9092bb2 70 mkdir("/sd/weather_balloon", 0777);
cmiller86 2:21e4b9092bb2 71 }
cmiller86 2:21e4b9092bb2 72
cmiller86 4:ebf8c354c758 73 void update_gps(void const *args)
cmiller86 2:21e4b9092bb2 74 {
cmiller86 3:b490294520d5 75 while(true)
cmiller86 2:21e4b9092bb2 76 {
cmiller86 5:c3e1fc7fa00d 77 gps_locked = gps.sample();
cmiller86 5:c3e1fc7fa00d 78 led1 = gps_locked;
Gjika 1:2c4f640a8104 79
cmiller86 3:b490294520d5 80 Thread::wait(250);
cmiller86 3:b490294520d5 81 }
cmiller86 3:b490294520d5 82 }
cmiller86 3:b490294520d5 83
cmiller86 4:ebf8c354c758 84 void update_temperature(void const *args)
cmiller86 3:b490294520d5 85 {
Gjika 6:d61e7eeabcac 86 float tempC1;
cmiller86 3:b490294520d5 87
cmiller86 3:b490294520d5 88 while(true)
cmiller86 3:b490294520d5 89 {
cmiller86 2:21e4b9092bb2 90 tempC1 = ((temp1 * 3.3) - 0.600) * 100.0;
cmiller86 2:21e4b9092bb2 91 tempF1 = (9.0 * tempC1) / 5.0 + 32;
Gjika 6:d61e7eeabcac 92 analog1 = (temp2);
Gjika 6:d61e7eeabcac 93 analog2 = (temp3);
Gjika 1:2c4f640a8104 94
cmiller86 3:b490294520d5 95 Thread::wait(250);
cmiller86 3:b490294520d5 96 }
cmiller86 3:b490294520d5 97 }
cmiller86 3:b490294520d5 98
cmiller86 5:c3e1fc7fa00d 99 void update_altimeter(void const *args)
cmiller86 5:c3e1fc7fa00d 100 {
cmiller86 5:c3e1fc7fa00d 101 while(true)
cmiller86 5:c3e1fc7fa00d 102 {
cmiller86 5:c3e1fc7fa00d 103 altimeter.readAltitude(&alt_altitude);
cmiller86 5:c3e1fc7fa00d 104 altimeter.readTemperature(&alt_temperature);
cmiller86 5:c3e1fc7fa00d 105
cmiller86 5:c3e1fc7fa00d 106 altimeter.setModeStandby();
cmiller86 5:c3e1fc7fa00d 107 altimeter.setModeBarometer();
cmiller86 5:c3e1fc7fa00d 108 altimeter.setModeActive();
cmiller86 5:c3e1fc7fa00d 109 altimeter.readPressure(&alt_pressure);
cmiller86 5:c3e1fc7fa00d 110
cmiller86 5:c3e1fc7fa00d 111 altimeter.setModeStandby();
cmiller86 5:c3e1fc7fa00d 112 altimeter.setModeAltimeter();
cmiller86 5:c3e1fc7fa00d 113 altimeter.setModeActive();
cmiller86 5:c3e1fc7fa00d 114
cmiller86 5:c3e1fc7fa00d 115 Thread::wait(250);
cmiller86 5:c3e1fc7fa00d 116 }
cmiller86 5:c3e1fc7fa00d 117 }
cmiller86 5:c3e1fc7fa00d 118
cmiller86 4:ebf8c354c758 119 void write_to_log(void const *args)
cmiller86 3:b490294520d5 120 {
cmiller86 3:b490294520d5 121 while(true)
cmiller86 3:b490294520d5 122 {
cmiller86 5:c3e1fc7fa00d 123 if(log_switch)
cmiller86 5:c3e1fc7fa00d 124 {
cmiller86 5:c3e1fc7fa00d 125 log_mutex.lock();
cmiller86 5:c3e1fc7fa00d 126
cmiller86 5:c3e1fc7fa00d 127 if(!log_open)
cmiller86 5:c3e1fc7fa00d 128 {
cmiller86 5:c3e1fc7fa00d 129 sdout = fopen("/sd/weather_balloon/log.txt", "a");
cmiller86 5:c3e1fc7fa00d 130 log_open = true;
cmiller86 5:c3e1fc7fa00d 131 }
cmiller86 5:c3e1fc7fa00d 132
cmiller86 5:c3e1fc7fa00d 133 fprintf(sdout, "----- %f -----\r\n", t.read());
cmiller86 5:c3e1fc7fa00d 134 fprintf(sdout, "Long = %f\r\nLati = %f\r\n", gps.longitude, gps.latitude);
Gjika 6:d61e7eeabcac 135 fprintf(sdout, "Temp1 = %f\r\nAnalog1 = %f\r\nAnalog2 = %f\r\n", tempF1, analog1, analog2);
cmiller86 5:c3e1fc7fa00d 136 fprintf(sdout, "Altitude = %s ft, offset = 0x%X\r\n", alt_altitude.print(), altimeter.offsetAltitude());
Gjika 6:d61e7eeabcac 137 //fprintf(sdout, "Temperature = %s deg F, offset = 0x%X\r\n", alt_temperature.print(), altimeter.offsetTemperature());
cmiller86 5:c3e1fc7fa00d 138 //fprintf(sdout, "Pressure = %s Pa, offset = 0x%X\r\n", alt_pressure.print(), altimeter.offsetPressure());
cmiller86 5:c3e1fc7fa00d 139 fprintf(sdout, dtmf1 ? "DTMF 1 = True\r\n" : "DTMF 1 = False\r\n");
cmiller86 5:c3e1fc7fa00d 140 fprintf(sdout, dtmf2 ? "DTMF 2 = True\r\n" : "DTMF 2 = False\r\n");
cmiller86 5:c3e1fc7fa00d 141 fprintf(sdout, dtmf3 ? "DTMF 3 = True\r\n" : "DTMF 3 = False\r\n");
cmiller86 5:c3e1fc7fa00d 142
cmiller86 5:c3e1fc7fa00d 143 #ifdef PC_DEBUG
cmiller86 5:c3e1fc7fa00d 144 pc.printf("----- %f -----\r\n", t.read());
cmiller86 5:c3e1fc7fa00d 145 pc.printf("Long = %f\r\nLati = %f\r\n", gps.longitude, gps.latitude);
Gjika 6:d61e7eeabcac 146 pc.printf("Temp1 = %f\r\nAnalog1 = %f\r\nAnalog2 = %f\r\n", tempF1, analog1, analog2);
cmiller86 5:c3e1fc7fa00d 147 pc.printf("Altitude = %s ft, offset = 0x%X\r\n", alt_altitude.print(), altimeter.offsetAltitude());
Gjika 6:d61e7eeabcac 148 //pc.printf("Temperature = %s deg F, offset = 0x%X\r\n", alt_temperature.print(), altimeter.offsetTemperature());
cmiller86 5:c3e1fc7fa00d 149 //pc.printf("Pressure = %s Pa, offset = 0x%X\r\n", alt_pressure.print(), altimeter.offsetPressure());
cmiller86 5:c3e1fc7fa00d 150 pc.printf(dtmf1 ? "DTMF 1 = True\r\n" : "DTMF 1 = False\r\n");
cmiller86 5:c3e1fc7fa00d 151 pc.printf(dtmf2 ? "DTMF 2 = True\r\n" : "DTMF 2 = False\r\n");
cmiller86 5:c3e1fc7fa00d 152 pc.printf(dtmf3 ? "DTMF 3 = True\r\n" : "DTMF 3 = False\r\n");
cmiller86 5:c3e1fc7fa00d 153 #endif
cmiller86 5:c3e1fc7fa00d 154
cmiller86 5:c3e1fc7fa00d 155 log_mutex.unlock();
cmiller86 5:c3e1fc7fa00d 156
cmiller86 5:c3e1fc7fa00d 157 Thread::wait(1000);
cmiller86 5:c3e1fc7fa00d 158 }
cmiller86 5:c3e1fc7fa00d 159 else
cmiller86 5:c3e1fc7fa00d 160 {
cmiller86 5:c3e1fc7fa00d 161 if(log_open)
cmiller86 5:c3e1fc7fa00d 162 {
cmiller86 5:c3e1fc7fa00d 163 fclose(sdout);
cmiller86 5:c3e1fc7fa00d 164 log_open = false;
cmiller86 5:c3e1fc7fa00d 165 }
cmiller86 5:c3e1fc7fa00d 166 }
cmiller86 2:21e4b9092bb2 167
cmiller86 5:c3e1fc7fa00d 168 led2 = log_switch;
cmiller86 3:b490294520d5 169 }
cmiller86 3:b490294520d5 170 }
cmiller86 3:b490294520d5 171
cmiller86 5:c3e1fc7fa00d 172 bool gps_out_of_bounds()
cmiller86 5:c3e1fc7fa00d 173 {
cmiller86 5:c3e1fc7fa00d 174 static int count = 0;
cmiller86 5:c3e1fc7fa00d 175
cmiller86 5:c3e1fc7fa00d 176 if(gps_locked)
cmiller86 5:c3e1fc7fa00d 177 {
cmiller86 5:c3e1fc7fa00d 178 if(count > 10)
cmiller86 5:c3e1fc7fa00d 179 {
cmiller86 5:c3e1fc7fa00d 180 count = 0;
cmiller86 5:c3e1fc7fa00d 181 return gps.latitude < MIN_LATITUDE
cmiller86 5:c3e1fc7fa00d 182 || gps.latitude > MAX_LATITUDE
cmiller86 5:c3e1fc7fa00d 183 || gps.longitude < MIN_LONGITUDE
cmiller86 5:c3e1fc7fa00d 184 || gps.longitude > MAX_LONGITUDE;
cmiller86 5:c3e1fc7fa00d 185 }
cmiller86 5:c3e1fc7fa00d 186 else
cmiller86 5:c3e1fc7fa00d 187 {
cmiller86 5:c3e1fc7fa00d 188 count++;
cmiller86 5:c3e1fc7fa00d 189 return false;
cmiller86 5:c3e1fc7fa00d 190 }
cmiller86 5:c3e1fc7fa00d 191 }
cmiller86 5:c3e1fc7fa00d 192 else
cmiller86 5:c3e1fc7fa00d 193 return false;
cmiller86 5:c3e1fc7fa00d 194 }
cmiller86 5:c3e1fc7fa00d 195
cmiller86 4:ebf8c354c758 196 void check_cutdown(void const *args)
cmiller86 3:b490294520d5 197 {
cmiller86 3:b490294520d5 198 while(true)
cmiller86 3:b490294520d5 199 {
cmiller86 5:c3e1fc7fa00d 200 if(t.read() >= 7200 || dtmf1 || alt_altitude.altitude() > 100000 || gps_out_of_bounds())
cmiller86 2:21e4b9092bb2 201 cutdown = true;
Gjika 1:2c4f640a8104 202
cmiller86 2:21e4b9092bb2 203 if(cutdown && !attempted)
cmiller86 2:21e4b9092bb2 204 {
cmiller86 3:b490294520d5 205 log_mutex.lock();
cmiller86 5:c3e1fc7fa00d 206
cmiller86 5:c3e1fc7fa00d 207 if(log_switch && log_open)
cmiller86 5:c3e1fc7fa00d 208 {
cmiller86 5:c3e1fc7fa00d 209 fprintf(sdout, "Cutdown Started = %f\r\n", t.read());
cmiller86 5:c3e1fc7fa00d 210
cmiller86 5:c3e1fc7fa00d 211 #ifdef PC_DEBUG
cmiller86 5:c3e1fc7fa00d 212 pc.printf("Cutdown Started = %f\r\n", t.read());
cmiller86 5:c3e1fc7fa00d 213 #endif
cmiller86 5:c3e1fc7fa00d 214 }
cmiller86 5:c3e1fc7fa00d 215
cmiller86 3:b490294520d5 216 log_mutex.unlock();
cmiller86 2:21e4b9092bb2 217
cmiller86 2:21e4b9092bb2 218 relay = 1;
cmiller86 5:c3e1fc7fa00d 219 Thread::wait(20000);
cmiller86 2:21e4b9092bb2 220 relay = 0;
cmiller86 2:21e4b9092bb2 221
cmiller86 3:b490294520d5 222 log_mutex.lock();
cmiller86 5:c3e1fc7fa00d 223
cmiller86 5:c3e1fc7fa00d 224 if(log_switch && log_open)
cmiller86 5:c3e1fc7fa00d 225 {
cmiller86 5:c3e1fc7fa00d 226 fprintf(sdout, "Cutdown Ended = %f\r\n", t.read());
cmiller86 5:c3e1fc7fa00d 227
cmiller86 5:c3e1fc7fa00d 228 #ifdef PC_DEBUG
cmiller86 5:c3e1fc7fa00d 229 pc.printf("Cutdown Ended = %f\r\n", t.read());
cmiller86 5:c3e1fc7fa00d 230 #endif
cmiller86 5:c3e1fc7fa00d 231 }
cmiller86 5:c3e1fc7fa00d 232
cmiller86 3:b490294520d5 233 log_mutex.unlock();
cmiller86 2:21e4b9092bb2 234
cmiller86 2:21e4b9092bb2 235 attempted = true;
simon 0:6b7345059afe 236 }
cmiller86 3:b490294520d5 237
cmiller86 3:b490294520d5 238 Thread::wait(100);
simon 0:6b7345059afe 239 }
cmiller86 2:21e4b9092bb2 240 }
cmiller86 3:b490294520d5 241
cmiller86 3:b490294520d5 242 int main()
cmiller86 3:b490294520d5 243 {
cmiller86 4:ebf8c354c758 244 init();
cmiller86 4:ebf8c354c758 245
cmiller86 3:b490294520d5 246 Thread gps_thread(update_gps);
cmiller86 3:b490294520d5 247 Thread temperature_thread(update_temperature);
cmiller86 5:c3e1fc7fa00d 248 Thread altimeter_thread(update_altimeter);
cmiller86 3:b490294520d5 249 Thread log_thread(write_to_log);
cmiller86 3:b490294520d5 250 Thread cutdown_thread(check_cutdown);
cmiller86 5:c3e1fc7fa00d 251
cmiller86 5:c3e1fc7fa00d 252 while(true);
cmiller86 3:b490294520d5 253 }