4180 weather balloon logging and cutdown system
Dependencies: GPS MPL3115A2 SDFileSystem mbed-rtos mbed
Fork of WeatherBalloon4180 by
main.cpp@5:c3e1fc7fa00d, 2015-12-01 (annotated)
- Committer:
- cmiller86
- Date:
- Tue Dec 01 20:38:27 2015 +0000
- Revision:
- 5:c3e1fc7fa00d
- Parent:
- 4:ebf8c354c758
- Child:
- 6:d61e7eeabcac
Last requirements added
Who changed what in which revision?
User | Revision | Line number | New 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; |
cmiller86 | 2:21e4b9092bb2 | 48 | |
cmiller86 | 2:21e4b9092bb2 | 49 | FILE *sdout; |
cmiller86 | 3:b490294520d5 | 50 | Timer t; |
cmiller86 | 3:b490294520d5 | 51 | Mutex log_mutex; |
simon | 0:6b7345059afe | 52 | |
cmiller86 | 5:c3e1fc7fa00d | 53 | Altitude alt_altitude; |
cmiller86 | 5:c3e1fc7fa00d | 54 | Temperature alt_temperature; |
cmiller86 | 5:c3e1fc7fa00d | 55 | Pressure alt_pressure; |
cmiller86 | 5:c3e1fc7fa00d | 56 | |
cmiller86 | 2:21e4b9092bb2 | 57 | void init() |
cmiller86 | 2:21e4b9092bb2 | 58 | { |
cmiller86 | 2:21e4b9092bb2 | 59 | t.start(); |
cmiller86 | 3:b490294520d5 | 60 | |
cmiller86 | 3:b490294520d5 | 61 | led1 = 0; |
cmiller86 | 2:21e4b9092bb2 | 62 | relay = 0; |
cmiller86 | 2:21e4b9092bb2 | 63 | |
cmiller86 | 5:c3e1fc7fa00d | 64 | altimeter.init(); |
cmiller86 | 5:c3e1fc7fa00d | 65 | altimeter.setOffsetAltitude(0); |
cmiller86 | 5:c3e1fc7fa00d | 66 | altimeter.setOffsetTemperature(0); |
cmiller86 | 5:c3e1fc7fa00d | 67 | altimeter.setOffsetPressure(0); |
cmiller86 | 5:c3e1fc7fa00d | 68 | |
cmiller86 | 2:21e4b9092bb2 | 69 | mkdir("/sd/weather_balloon", 0777); |
cmiller86 | 2:21e4b9092bb2 | 70 | } |
cmiller86 | 2:21e4b9092bb2 | 71 | |
cmiller86 | 4:ebf8c354c758 | 72 | void update_gps(void const *args) |
cmiller86 | 2:21e4b9092bb2 | 73 | { |
cmiller86 | 3:b490294520d5 | 74 | while(true) |
cmiller86 | 2:21e4b9092bb2 | 75 | { |
cmiller86 | 5:c3e1fc7fa00d | 76 | gps_locked = gps.sample(); |
cmiller86 | 5:c3e1fc7fa00d | 77 | led1 = gps_locked; |
Gjika | 1:2c4f640a8104 | 78 | |
cmiller86 | 3:b490294520d5 | 79 | Thread::wait(250); |
cmiller86 | 3:b490294520d5 | 80 | } |
cmiller86 | 3:b490294520d5 | 81 | } |
cmiller86 | 3:b490294520d5 | 82 | |
cmiller86 | 4:ebf8c354c758 | 83 | void update_temperature(void const *args) |
cmiller86 | 3:b490294520d5 | 84 | { |
cmiller86 | 3:b490294520d5 | 85 | float tempC1, tempC2, tempC3; |
cmiller86 | 3:b490294520d5 | 86 | |
cmiller86 | 3:b490294520d5 | 87 | while(true) |
cmiller86 | 3:b490294520d5 | 88 | { |
cmiller86 | 2:21e4b9092bb2 | 89 | tempC1 = ((temp1 * 3.3) - 0.600) * 100.0; |
cmiller86 | 2:21e4b9092bb2 | 90 | tempC2 = ((temp2 * 3.3) - 0.600) * 100.0; |
cmiller86 | 2:21e4b9092bb2 | 91 | tempC3 = ((temp3 * 3.3) - 0.600) * 100.0; |
cmiller86 | 2:21e4b9092bb2 | 92 | tempF1 = (9.0 * tempC1) / 5.0 + 32; |
cmiller86 | 2:21e4b9092bb2 | 93 | tempF2 = (9.0 * tempC2) / 5.0 + 32; |
cmiller86 | 2:21e4b9092bb2 | 94 | tempF3 = (9.0 * tempC3) / 5.0 + 32; |
Gjika | 1:2c4f640a8104 | 95 | |
cmiller86 | 3:b490294520d5 | 96 | Thread::wait(250); |
cmiller86 | 3:b490294520d5 | 97 | } |
cmiller86 | 3:b490294520d5 | 98 | } |
cmiller86 | 3:b490294520d5 | 99 | |
cmiller86 | 5:c3e1fc7fa00d | 100 | void update_altimeter(void const *args) |
cmiller86 | 5:c3e1fc7fa00d | 101 | { |
cmiller86 | 5:c3e1fc7fa00d | 102 | while(true) |
cmiller86 | 5:c3e1fc7fa00d | 103 | { |
cmiller86 | 5:c3e1fc7fa00d | 104 | altimeter.readAltitude(&alt_altitude); |
cmiller86 | 5:c3e1fc7fa00d | 105 | altimeter.readTemperature(&alt_temperature); |
cmiller86 | 5:c3e1fc7fa00d | 106 | |
cmiller86 | 5:c3e1fc7fa00d | 107 | altimeter.setModeStandby(); |
cmiller86 | 5:c3e1fc7fa00d | 108 | altimeter.setModeBarometer(); |
cmiller86 | 5:c3e1fc7fa00d | 109 | altimeter.setModeActive(); |
cmiller86 | 5:c3e1fc7fa00d | 110 | altimeter.readPressure(&alt_pressure); |
cmiller86 | 5:c3e1fc7fa00d | 111 | |
cmiller86 | 5:c3e1fc7fa00d | 112 | altimeter.setModeStandby(); |
cmiller86 | 5:c3e1fc7fa00d | 113 | altimeter.setModeAltimeter(); |
cmiller86 | 5:c3e1fc7fa00d | 114 | altimeter.setModeActive(); |
cmiller86 | 5:c3e1fc7fa00d | 115 | |
cmiller86 | 5:c3e1fc7fa00d | 116 | Thread::wait(250); |
cmiller86 | 5:c3e1fc7fa00d | 117 | } |
cmiller86 | 5:c3e1fc7fa00d | 118 | } |
cmiller86 | 5:c3e1fc7fa00d | 119 | |
cmiller86 | 4:ebf8c354c758 | 120 | void write_to_log(void const *args) |
cmiller86 | 3:b490294520d5 | 121 | { |
cmiller86 | 3:b490294520d5 | 122 | while(true) |
cmiller86 | 3:b490294520d5 | 123 | { |
cmiller86 | 5:c3e1fc7fa00d | 124 | if(log_switch) |
cmiller86 | 5:c3e1fc7fa00d | 125 | { |
cmiller86 | 5:c3e1fc7fa00d | 126 | log_mutex.lock(); |
cmiller86 | 5:c3e1fc7fa00d | 127 | |
cmiller86 | 5:c3e1fc7fa00d | 128 | if(!log_open) |
cmiller86 | 5:c3e1fc7fa00d | 129 | { |
cmiller86 | 5:c3e1fc7fa00d | 130 | sdout = fopen("/sd/weather_balloon/log.txt", "a"); |
cmiller86 | 5:c3e1fc7fa00d | 131 | log_open = true; |
cmiller86 | 5:c3e1fc7fa00d | 132 | } |
cmiller86 | 5:c3e1fc7fa00d | 133 | |
cmiller86 | 5:c3e1fc7fa00d | 134 | fprintf(sdout, "----- %f -----\r\n", t.read()); |
cmiller86 | 5:c3e1fc7fa00d | 135 | fprintf(sdout, "Long = %f\r\nLati = %f\r\n", gps.longitude, gps.latitude); |
cmiller86 | 5:c3e1fc7fa00d | 136 | fprintf(sdout, "Temp1 = %f\r\nTemp2 = %f\r\nTemp3 = %f\r\n", -tempF1, -tempF2, -tempF3); |
cmiller86 | 5:c3e1fc7fa00d | 137 | fprintf(sdout, "Altitude = %s ft, offset = 0x%X\r\n", alt_altitude.print(), altimeter.offsetAltitude()); |
cmiller86 | 5:c3e1fc7fa00d | 138 | fprintf(sdout, "Temperature = %s deg F, offset = 0x%X\r\n", alt_temperature.print(), altimeter.offsetTemperature()); |
cmiller86 | 5:c3e1fc7fa00d | 139 | //fprintf(sdout, "Pressure = %s Pa, offset = 0x%X\r\n", alt_pressure.print(), altimeter.offsetPressure()); |
cmiller86 | 5:c3e1fc7fa00d | 140 | fprintf(sdout, dtmf1 ? "DTMF 1 = True\r\n" : "DTMF 1 = False\r\n"); |
cmiller86 | 5:c3e1fc7fa00d | 141 | fprintf(sdout, dtmf2 ? "DTMF 2 = True\r\n" : "DTMF 2 = False\r\n"); |
cmiller86 | 5:c3e1fc7fa00d | 142 | fprintf(sdout, dtmf3 ? "DTMF 3 = True\r\n" : "DTMF 3 = False\r\n"); |
cmiller86 | 5:c3e1fc7fa00d | 143 | |
cmiller86 | 5:c3e1fc7fa00d | 144 | #ifdef PC_DEBUG |
cmiller86 | 5:c3e1fc7fa00d | 145 | pc.printf("----- %f -----\r\n", t.read()); |
cmiller86 | 5:c3e1fc7fa00d | 146 | pc.printf("Long = %f\r\nLati = %f\r\n", gps.longitude, gps.latitude); |
cmiller86 | 5:c3e1fc7fa00d | 147 | pc.printf("Temp1 = %f\r\nTemp2 = %f\r\nTemp3 = %f\r\n", -tempF1, -tempF2, -tempF3); |
cmiller86 | 5:c3e1fc7fa00d | 148 | pc.printf("Altitude = %s ft, offset = 0x%X\r\n", alt_altitude.print(), altimeter.offsetAltitude()); |
cmiller86 | 5:c3e1fc7fa00d | 149 | pc.printf("Temperature = %s deg F, offset = 0x%X\r\n", alt_temperature.print(), altimeter.offsetTemperature()); |
cmiller86 | 5:c3e1fc7fa00d | 150 | //pc.printf("Pressure = %s Pa, offset = 0x%X\r\n", alt_pressure.print(), altimeter.offsetPressure()); |
cmiller86 | 5:c3e1fc7fa00d | 151 | pc.printf(dtmf1 ? "DTMF 1 = True\r\n" : "DTMF 1 = False\r\n"); |
cmiller86 | 5:c3e1fc7fa00d | 152 | pc.printf(dtmf2 ? "DTMF 2 = True\r\n" : "DTMF 2 = False\r\n"); |
cmiller86 | 5:c3e1fc7fa00d | 153 | pc.printf(dtmf3 ? "DTMF 3 = True\r\n" : "DTMF 3 = False\r\n"); |
cmiller86 | 5:c3e1fc7fa00d | 154 | #endif |
cmiller86 | 5:c3e1fc7fa00d | 155 | |
cmiller86 | 5:c3e1fc7fa00d | 156 | log_mutex.unlock(); |
cmiller86 | 5:c3e1fc7fa00d | 157 | |
cmiller86 | 5:c3e1fc7fa00d | 158 | Thread::wait(1000); |
cmiller86 | 5:c3e1fc7fa00d | 159 | } |
cmiller86 | 5:c3e1fc7fa00d | 160 | else |
cmiller86 | 5:c3e1fc7fa00d | 161 | { |
cmiller86 | 5:c3e1fc7fa00d | 162 | if(log_open) |
cmiller86 | 5:c3e1fc7fa00d | 163 | { |
cmiller86 | 5:c3e1fc7fa00d | 164 | fclose(sdout); |
cmiller86 | 5:c3e1fc7fa00d | 165 | log_open = false; |
cmiller86 | 5:c3e1fc7fa00d | 166 | } |
cmiller86 | 5:c3e1fc7fa00d | 167 | } |
cmiller86 | 2:21e4b9092bb2 | 168 | |
cmiller86 | 5:c3e1fc7fa00d | 169 | led2 = log_switch; |
cmiller86 | 3:b490294520d5 | 170 | } |
cmiller86 | 3:b490294520d5 | 171 | } |
cmiller86 | 3:b490294520d5 | 172 | |
cmiller86 | 5:c3e1fc7fa00d | 173 | bool gps_out_of_bounds() |
cmiller86 | 5:c3e1fc7fa00d | 174 | { |
cmiller86 | 5:c3e1fc7fa00d | 175 | static int count = 0; |
cmiller86 | 5:c3e1fc7fa00d | 176 | |
cmiller86 | 5:c3e1fc7fa00d | 177 | if(gps_locked) |
cmiller86 | 5:c3e1fc7fa00d | 178 | { |
cmiller86 | 5:c3e1fc7fa00d | 179 | if(count > 10) |
cmiller86 | 5:c3e1fc7fa00d | 180 | { |
cmiller86 | 5:c3e1fc7fa00d | 181 | count = 0; |
cmiller86 | 5:c3e1fc7fa00d | 182 | return gps.latitude < MIN_LATITUDE |
cmiller86 | 5:c3e1fc7fa00d | 183 | || gps.latitude > MAX_LATITUDE |
cmiller86 | 5:c3e1fc7fa00d | 184 | || gps.longitude < MIN_LONGITUDE |
cmiller86 | 5:c3e1fc7fa00d | 185 | || gps.longitude > MAX_LONGITUDE; |
cmiller86 | 5:c3e1fc7fa00d | 186 | } |
cmiller86 | 5:c3e1fc7fa00d | 187 | else |
cmiller86 | 5:c3e1fc7fa00d | 188 | { |
cmiller86 | 5:c3e1fc7fa00d | 189 | count++; |
cmiller86 | 5:c3e1fc7fa00d | 190 | return false; |
cmiller86 | 5:c3e1fc7fa00d | 191 | } |
cmiller86 | 5:c3e1fc7fa00d | 192 | } |
cmiller86 | 5:c3e1fc7fa00d | 193 | else |
cmiller86 | 5:c3e1fc7fa00d | 194 | return false; |
cmiller86 | 5:c3e1fc7fa00d | 195 | } |
cmiller86 | 5:c3e1fc7fa00d | 196 | |
cmiller86 | 4:ebf8c354c758 | 197 | void check_cutdown(void const *args) |
cmiller86 | 3:b490294520d5 | 198 | { |
cmiller86 | 3:b490294520d5 | 199 | while(true) |
cmiller86 | 3:b490294520d5 | 200 | { |
cmiller86 | 5:c3e1fc7fa00d | 201 | if(t.read() >= 7200 || dtmf1 || alt_altitude.altitude() > 100000 || gps_out_of_bounds()) |
cmiller86 | 2:21e4b9092bb2 | 202 | cutdown = true; |
Gjika | 1:2c4f640a8104 | 203 | |
cmiller86 | 2:21e4b9092bb2 | 204 | if(cutdown && !attempted) |
cmiller86 | 2:21e4b9092bb2 | 205 | { |
cmiller86 | 3:b490294520d5 | 206 | log_mutex.lock(); |
cmiller86 | 5:c3e1fc7fa00d | 207 | |
cmiller86 | 5:c3e1fc7fa00d | 208 | if(log_switch && log_open) |
cmiller86 | 5:c3e1fc7fa00d | 209 | { |
cmiller86 | 5:c3e1fc7fa00d | 210 | fprintf(sdout, "Cutdown Started = %f\r\n", t.read()); |
cmiller86 | 5:c3e1fc7fa00d | 211 | |
cmiller86 | 5:c3e1fc7fa00d | 212 | #ifdef PC_DEBUG |
cmiller86 | 5:c3e1fc7fa00d | 213 | pc.printf("Cutdown Started = %f\r\n", t.read()); |
cmiller86 | 5:c3e1fc7fa00d | 214 | #endif |
cmiller86 | 5:c3e1fc7fa00d | 215 | } |
cmiller86 | 5:c3e1fc7fa00d | 216 | |
cmiller86 | 3:b490294520d5 | 217 | log_mutex.unlock(); |
cmiller86 | 2:21e4b9092bb2 | 218 | |
cmiller86 | 2:21e4b9092bb2 | 219 | relay = 1; |
cmiller86 | 5:c3e1fc7fa00d | 220 | Thread::wait(20000); |
cmiller86 | 2:21e4b9092bb2 | 221 | relay = 0; |
cmiller86 | 2:21e4b9092bb2 | 222 | |
cmiller86 | 3:b490294520d5 | 223 | log_mutex.lock(); |
cmiller86 | 5:c3e1fc7fa00d | 224 | |
cmiller86 | 5:c3e1fc7fa00d | 225 | if(log_switch && log_open) |
cmiller86 | 5:c3e1fc7fa00d | 226 | { |
cmiller86 | 5:c3e1fc7fa00d | 227 | fprintf(sdout, "Cutdown Ended = %f\r\n", t.read()); |
cmiller86 | 5:c3e1fc7fa00d | 228 | |
cmiller86 | 5:c3e1fc7fa00d | 229 | #ifdef PC_DEBUG |
cmiller86 | 5:c3e1fc7fa00d | 230 | pc.printf("Cutdown Ended = %f\r\n", t.read()); |
cmiller86 | 5:c3e1fc7fa00d | 231 | #endif |
cmiller86 | 5:c3e1fc7fa00d | 232 | } |
cmiller86 | 5:c3e1fc7fa00d | 233 | |
cmiller86 | 3:b490294520d5 | 234 | log_mutex.unlock(); |
cmiller86 | 2:21e4b9092bb2 | 235 | |
cmiller86 | 2:21e4b9092bb2 | 236 | attempted = true; |
simon | 0:6b7345059afe | 237 | } |
cmiller86 | 3:b490294520d5 | 238 | |
cmiller86 | 3:b490294520d5 | 239 | Thread::wait(100); |
simon | 0:6b7345059afe | 240 | } |
cmiller86 | 2:21e4b9092bb2 | 241 | } |
cmiller86 | 3:b490294520d5 | 242 | |
cmiller86 | 3:b490294520d5 | 243 | int main() |
cmiller86 | 3:b490294520d5 | 244 | { |
cmiller86 | 4:ebf8c354c758 | 245 | init(); |
cmiller86 | 4:ebf8c354c758 | 246 | |
cmiller86 | 3:b490294520d5 | 247 | Thread gps_thread(update_gps); |
cmiller86 | 3:b490294520d5 | 248 | Thread temperature_thread(update_temperature); |
cmiller86 | 5:c3e1fc7fa00d | 249 | Thread altimeter_thread(update_altimeter); |
cmiller86 | 3:b490294520d5 | 250 | Thread log_thread(write_to_log); |
cmiller86 | 3:b490294520d5 | 251 | Thread cutdown_thread(check_cutdown); |
cmiller86 | 5:c3e1fc7fa00d | 252 | |
cmiller86 | 5:c3e1fc7fa00d | 253 | while(true); |
cmiller86 | 3:b490294520d5 | 254 | } |