altos: Log in-flight data for MicroPeak
[fw/altos] / src / micropeak / ao_micropeak.c
index 6ceec3b5164aa97e559a83fe0bfac31675435007..525cfa42bfe529f14fd7c49647048ca65ba2d58b 100644 (file)
@@ -47,6 +47,15 @@ ao_pa_get(void)
 #define GROUND_AVG_SHIFT       4
 #define GROUND_AVG             (1 << GROUND_AVG_SHIFT)
 
+/* Pressure change (in Pa) to detect boost */
+#define BOOST_DETECT           120     /* 10m at sea level, 12m at 2000m */
+
+/* Wait after power on before doing anything to give the user time to assemble the rocket */
+#define BOOST_DELAY            AO_SEC_TO_TICKS(30)
+
+/* Pressure change (in Pa) to detect landing */
+#define LAND_DETECT            12      /* 1m at sea level, 1.2m at 2000m */
+
 static void
 ao_compute_height(void)
 {
@@ -56,18 +65,40 @@ ao_compute_height(void)
 }
 
 #if !HAS_EEPROM
+
+#define PA_GROUND_OFFSET       0
+#define PA_MIN_OFFSET          4
+#define N_SAMPLES_OFFSET       8
+#define STARTING_LOG_OFFSET    10
+#define MAX_LOG_OFFSET         512
+
+static uint16_t ao_log_offset = STARTING_LOG_OFFSET;
+
 void
 ao_save_flight(void)
 {
-       ao_eeprom_write(0, &pa_ground, sizeof (pa_ground));
-       ao_eeprom_write(sizeof (pa_ground), &pa_min, sizeof (pa_min));
+       uint16_t        n_samples = (ao_log_offset - STARTING_LOG_OFFSET) / sizeof (uint16_t);
+       ao_eeprom_write(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground));
+       ao_eeprom_write(PA_MIN_OFFSET, &pa_min, sizeof (pa_min));
+       ao_eeprom_write(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples));
 }
 
 void
 ao_restore_flight(void)
 {
-       ao_eeprom_read(0, &pa_ground, sizeof (pa_ground));
-       ao_eeprom_read(sizeof (pa_ground), &pa_min, sizeof (pa_min));
+       ao_eeprom_read(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground));
+       ao_eeprom_read(PA_MIN_OFFSET, &pa_min, sizeof (pa_min));
+}
+
+void
+ao_log_micro(void)
+{
+       uint16_t        low_bits = pa;
+
+       if (ao_log_offset < MAX_LOG_OFFSET) {
+               ao_eeprom_write(ao_log_offset, &low_bits, sizeof (low_bits));
+               ao_log_offset += sizeof (low_bits);
+       }
 }
 #endif
 
@@ -101,6 +132,8 @@ main(void)
 #endif
        ao_restore_flight();
        ao_compute_height();
+       /* Give the person a second to get their finger out of the way */
+       ao_delay(AO_MS_TO_TICKS(1000));
        ao_report_altitude();
        
        ao_spi_init();
@@ -115,6 +148,7 @@ main(void)
                ao_log_micro_dump();
 #endif 
 
+       ao_delay(BOOST_DELAY);
        /* Wait for motion, averaging values to get ground pressure */
        time = ao_time();
        ao_pa_get();
@@ -122,23 +156,20 @@ main(void)
        sample_count = 0;
        for (;;) {
                time += SAMPLE_SLEEP;
-               ao_delay_until(time);
                if (sample_count == 0)
-                       ao_led_on(AO_LED_BLUE);
+                       ao_led_on(AO_LED_REPORT);
+               ao_delay_until(time);
                ao_pa_get();
                if (sample_count == 0)
-                       ao_led_off(AO_LED_BLUE);
+                       ao_led_off(AO_LED_REPORT);
                pa_avg = pa_avg - (pa_avg >> FILTER_SHIFT) + pa;
                pa_diff = pa_ground - pa_avg;
-               if (pa_diff < 0)
-                       pa_diff = -pa_diff;
 
-               /* about 2 meters at sea level, more if you're higher */
-               if (pa_diff > (24 << FILTER_SHIFT))
+               /* Check for a significant pressure change */
+               if (pa_diff > (BOOST_DETECT << FILTER_SHIFT))
                        break;
 
                if (sample_count < GROUND_AVG * 2) {
-                       ao_led_off(AO_LED_BLUE);
                        if (sample_count < GROUND_AVG)
                                pa_sum += pa;
                        ++sample_count;
@@ -165,12 +196,15 @@ main(void)
                time += SAMPLE_SLEEP;
                ao_delay_until(time);
                if ((sample_count & 3) == 0)
-                       ao_led_on(AO_LED_BLUE);
+                       ao_led_on(AO_LED_REPORT);
                ao_pa_get();
                if ((sample_count & 3) == 0)
-                       ao_led_off(AO_LED_BLUE);
+                       ao_led_off(AO_LED_REPORT);
 #if HAS_EEPROM
                ao_log_micro_data(AO_LOG_MICRO_DATA | pa);
+#else
+               if (sample_count & 1)
+                       ao_log_micro();
 #endif
                pa_avg = pa_avg - (pa_avg >> FILTER_SHIFT) + pa;
                if (pa_avg < pa_min)
@@ -178,8 +212,9 @@ main(void)
 
                if (sample_count == (GROUND_AVG - 1)) {
                        pa_diff = pa_interval_max - pa_interval_min;
-                       /* About 1m at sea level */
-                       if (pa_diff < (12 << FILTER_SHIFT))
+
+                       /* Check to see if the pressure is now stable */
+                       if (pa_diff < (LAND_DETECT << FILTER_SHIFT))
                                break;
                        sample_count = 0;
                        pa_interval_min = pa_avg;