init

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

Files at this revision

API Documentation at this revision

Comitter:
pathfindr
Date:
Tue Jun 25 10:40:03 2019 +0000
Parent:
53:c6942af186d7
Child:
55:0914bfcedcf8
Commit message:
latest

Changed in this revision

board.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
mbed_app.json Show annotated file Show diff for this revision Revisions of this file
modem.cpp Show annotated file Show diff for this revision Revisions of this file
modem.h Show annotated file Show diff for this revision Revisions of this file
--- a/board.h	Wed May 29 23:59:56 2019 +0000
+++ b/board.h	Tue Jun 25 10:40:03 2019 +0000
@@ -37,5 +37,5 @@
 //#define BD_PAGE_ADDRESS 0x5d000 //380928
 
 #define USERDATA_START          0x7E000 // - 8k for user data
-#define APPDATA_START           0x40000 // - 4k for app data - DEVELOPMENT
-//#define APPDATA_START           0x3D000 // - 4k for app data - PRODUCTION
\ No newline at end of file
+//#define APPDATA_START           0x40000 // - 4k for app data - DEVELOPMENT
+#define APPDATA_START           0x3D000 // - 4k for app data - PRODUCTION
\ No newline at end of file
--- a/main.cpp	Wed May 29 23:59:56 2019 +0000
+++ b/main.cpp	Tue Jun 25 10:40:03 2019 +0000
@@ -1,4 +1,4 @@
-#include "main.h"
+ #include "main.h"
 // MUST USE MBED 5.10.4   2fd0c5cfbd
 
 /*
@@ -33,6 +33,7 @@
 bool             GLOBAL_LEDSequenceinProgress                       = false;
 time_t           GLOBAL_wakeTime                                    = 0;
 char             GLOBAL_exceptionString[30];
+char             GLOBAL_exceptionStringRetainedUntilSuccess[10];
 char             GLOBAL_debug_buffer[DEBUG_BUFFERSIZE];
 char             GLOBAL_failed_broadcasts[10][160];
 bool             GLOBAL_failed_broadcast_slots[10];
@@ -46,6 +47,7 @@
 uint8_t          RET_setting_location_accuracy                      = DEFAULT_LOCATION_ACCURACY;
 uint32_t         RET_setting_location_tx_interval_mins              = DEFAULT_LOCATION_TX_INTERVAL_MINS;
 uint32_t         RET_setting_location_tx_failsafe_hrs               = DEFAULT_LOCATION_TX_FAILSAFE_HRS;
+uint32_t         RET_location_failsafe_seconds_max                  = (DEFAULT_LOCATION_TX_FAILSAFE_HRS * 3600);
 uint16_t         RET_setting_location_timeout                       = DEFAULT_LOCATION_TIMEOUT;
 uint32_t         RET_setting_activity_tx_interval_hrs               = 0;
 uint8_t          RET_setting_activity_mode                          = 1;
@@ -80,6 +82,7 @@
 bool             RET_receivedNewSettings                            = false;
 uint32_t         RET_GPSFailCount                                   = 0;
 uint32_t         RET_NetworkFailCount                               = 0;
+bool             RET_NetworkFailFlag                                = false;
 bool             RET_debug                                          = true;
 time_t           RET_debug_offat                                    = 0;
 float            RET_voltage                                        = 0.0;
@@ -88,6 +91,7 @@
 float            RET_temperature_max                                = -999.0; //Within broadcast frame. Set inital value to low
 float            RET_temperature_min                                = 999.0; //Within broadcase frame. Set inital value to high
 uint32_t         RET_modemBrownOutCountInSession                    = 0;
+time_t           RET_lastTxTime                                     = 0;
 //MOTION STATE
 bool             RET_motionTriggeredinFrame                         = false;
 bool             RET_motionStateOnInLocTXInterval                   = false;
@@ -108,43 +112,42 @@
 //EVENTS TX
 time_t           RET_eventTime_location_tx                          = 0;
 time_t           RET_eventTime_location_failsafe_tx                 = 0;
+time_t           RET_location_failsafe_seconds_count                = 0;
 time_t           RET_eventTime_environmental_tx                     = 0;
 time_t           RET_eventTime_activity_tx                          = 0;
 time_t           RET_eventTime_wakeFromDormant                      = 0;
 //BLE
-#if BLE_ENABLED
-    bool             RET_bleBroadcasting                                = false;
-    uint8_t          RET_bleAdv_flags                                   = 0;
-    char             RET_closestLocationTag_id[17];
-    int              RET_closestLocationTag_rssi                        = 999;
-    int              RET_closestBT04Tag_rssi                            = 999;
-    bool             RET_locationTag_present                            = false;
-    bool             RET_detector_present                               = false;
-    const uint8_t    bleAdv_motionTriggeredinFrame_flag                 = 0b01000000;
-    const uint8_t    bleAdv_motionState_flag                            = 0b00100000;
-    const uint8_t    bleAdv_impact_flag                                 = 0b00010000;
-    #pragma pack(1)
-    struct bleData_t {
-        uint16_t applicationSpecificId;
-        uint8_t firmware;
-        uint8_t flags;
-        uint16_t voltage;
-        uint8_t buttonpresses;
-        int16_t temperature;
-        uint8_t humidity;
-        uint8_t lux;
-        int8_t accel_x;
-        int8_t accel_y;
-        int8_t accel_z;
-        /*char id_1; //cant use this and local name as it pushes us over size limit
-        char id_2;
-        char id_3;
-        char id_4;
-        char id_5;
-        char id_6;*/
-    };
-    #pragma pack()
-#endif
+bool             RET_bleBroadcasting                                = false;
+uint8_t          RET_bleAdv_flags                                   = 0;
+char             RET_closestLocationTag_id[17];
+int              RET_closestLocationTag_rssi                        = 999;
+int              RET_closestBT04Tag_rssi                            = 999;
+bool             RET_locationTag_present                            = false;
+bool             RET_detector_present                               = false;
+const uint8_t    bleAdv_motionTriggeredinFrame_flag                 = 0b01000000;
+const uint8_t    bleAdv_motionState_flag                            = 0b00100000;
+const uint8_t    bleAdv_impact_flag                                 = 0b00010000;
+#pragma pack(1)
+struct bleData_t {
+    uint16_t applicationSpecificId;
+    uint8_t firmware;
+    uint8_t flags;
+    uint16_t voltage;
+    uint8_t buttonpresses;
+    int16_t temperature;
+    uint8_t humidity;
+    uint8_t lux;
+    int8_t accel_x;
+    int8_t accel_y;
+    int8_t accel_z;
+    /*char id_1; //cant use this and local name as it pushes us over size limit
+    char id_2;
+    char id_3;
+    char id_4;
+    char id_5;
+    char id_6;*/
+};
+#pragma pack()
 //------------------------------------------------------------------------------
 //GPIO
 //------------------------------------------------------------------------------ 
@@ -217,7 +220,7 @@
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_mode:%d", RET_setting_location_mode);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_accuracy:%d", RET_setting_location_accuracy);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_tx_interval_mins:%d", RET_setting_location_tx_interval_mins);debug_exe();
-        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_tx_failsafe_hrs:%d", RET_setting_location_tx_failsafe_hrs);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_location_failsafe_seconds_max:%d", RET_location_failsafe_seconds_max);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_timeout:%d", RET_setting_location_timeout);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_activity_tx_interval_hrs:%d", RET_setting_activity_tx_interval_hrs);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_activity_mode:%d", RET_setting_activity_mode);debug_exe();        
@@ -295,6 +298,11 @@
         snprintf(GLOBAL_exceptionString+strlen(GLOBAL_exceptionString),sizeof(GLOBAL_exceptionString),".%s",value);
     }
 }
+void addToExceptionStringRetainedUntilSuccess(char* value) {
+    if(strstr(GLOBAL_exceptionStringRetainedUntilSuccess, value) == false){
+        snprintf(GLOBAL_exceptionStringRetainedUntilSuccess+strlen(GLOBAL_exceptionStringRetainedUntilSuccess),sizeof(GLOBAL_exceptionStringRetainedUntilSuccess),".%s",value);
+    }
+}
 void resetTemperatures() {
     RET_temperature_max = -999.0; //Within broadcast frame. Set inital value to low
     RET_temperature_min = 999.0; //Within broadcase frame. Set inital value to high   
@@ -320,6 +328,7 @@
 //------------------------------------------------------------------------------
 // RTC TICKER
 //------------------------------------------------------------------------------
+bool RET_flash_busy = false;
 void RTCtick() {
     //YOU MUST NOT CALL ANY OTHER FUNCTIONS OR DEBUG FROM INSIDE HERE!!! OR IT LOCKS UP THE DEVICE, just change vars & comparisons etc
     RET_RTCunixtime += 1;
@@ -344,6 +353,7 @@
         if((LPtimer.read_ms() - RET_buttonReleaseTime) > 1500 && RET_buttonPressCount > 0) {
             if(RET_busy == true) { 
                 //RTCtick_ledflash_count = 4;// 2 flashes
+                RET_flash_busy = true;
             } else {
                 RET_SetupRunAt = 0; //allow setup to run again
                 switch (RET_buttonPressCount) {   //double catches to help with debounce
@@ -374,6 +384,12 @@
         }
     }
     
+    if (RET_busy && RET_flash_busy) {
+        led1 = !led1;
+    } else {
+        RET_flash_busy = false;   
+    }
+    /*
     if(RET_debug && GLOBAL_LEDSequenceinProgress == false){
         if (RET_motionState) {
             led1 = 0;   
@@ -381,6 +397,7 @@
             led1 = 1;   
         }
     }
+    */
 }
 //------------------------------------------------------------------------------
 // GLOBALS
@@ -390,20 +407,19 @@
     RET_motionTriggeredinFrame = false;
     RET_modemBrownOutCountInSession = 0;
     RET_humidity = 99.0f;
-    memset(GLOBAL_exceptionString,0x00,sizeof(GLOBAL_exceptionString));
 }
 void healthCheck() {
     //check for watchdog fire
     if (RET_watchdogfired == true) {
         addToExceptionString("WD");
         RET_watchdogfired = false;
+        RET_haveSettings = false;
     }
     //check clock
     if(RET_haveSettings == true) {
-        if (RET_RTCunixtime < 1547678732) {
-            //go dormant for 72hrs and then resetup
+        if (RET_RTCunixtime < 1547678732 || RET_RTCunixtime > 1900000000) {
             RET_haveSettings = false; 
-            setState(STATE_DORMANT);
+            addToExceptionString("CI");
         }
     }
     //check that we have a reasonable time to loc
@@ -413,13 +429,19 @@
             if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "ERR:eventTime_location_tx is 0");debug_exe();}
             RET_haveSettings = false;
         }
-        //check location failsafe tx delta is less that 2 weeks
-        long location_failsafe_tx_delta = (RET_eventTime_location_failsafe_tx - RET_RTCunixtime);
-        if (location_failsafe_tx_delta > TENDAYSINSECONDS) {
-            if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "ERR:location_failsafe_tx_delta too small");debug_exe();}
+        //check location failsafe tx is less than 2 weeks
+        if (RET_location_failsafe_seconds_max > (336 * 3600)) {
+            if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "ERR:RET_location_failsafe_seconds_max too big");debug_exe();}
             RET_haveSettings = false;
         }
     }
+    //check that we have had an attempted post within failsafe time
+    time_t timeSinceTX = (RET_RTCunixtime - RET_lastTxTime);
+    if (RET_lastTxTime > 0 && timeSinceTX > RET_location_failsafe_seconds_max) {
+        RET_haveSettings = false;
+        addToExceptionString("E1");
+    }
+    //if have settings false then rerun setup
     if (RET_haveSettings == false) {
         setState(STATE_SETUP);
     }
@@ -445,7 +467,6 @@
     if (test_count == test_pass) {
         return true;
     } else {
-        //addToExceptionString("HF"); 
         return false;   
     }
 }
@@ -488,6 +509,7 @@
 }
 void bleUpdateAndAdvertise(void)
 {
+    if (RET_setting_beacon_interval_seconds < 2) {RET_setting_beacon_interval_seconds = 2;}
     int AdvertisingInterval = (RET_setting_beacon_interval_seconds * 1000);
     bleData_t bleData;
     bleBuildData(bleData);
@@ -522,6 +544,7 @@
     RET_bleBroadcasting = false;
     if(RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "BLE Adv Stop");debug_exe();}
 }
+int blecount = 0;
 void bleAdvertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
     struct AdvertisingData_t {
         uint8_t                        length;
@@ -549,6 +572,20 @@
     char beta_location_tag_8[17] = {'0','7','e','9','9','1','d','3','b','e','b','6','4','0','4','8',0x00};
     char beta_location_tag_9[17] = {'9','5','6','3','a','0','8','6','2','1','e','8','e','c','1','4',0x00};
     
+    //RR demos
+    char beta_location_tag_10[17] = {'3','3','0','2','2','c','9','f','0','b','1','8','5','3','a','c',0x00};
+    char beta_location_tag_11[17] = {'2','5','6','c','4','0','2','b','d','c','1','4','2','5','2','7',0x00};
+    char beta_location_tag_12[17] = {'8','e','9','f','0','e','c','1','4','0','e','1','2','e','e','9',0x00};
+    char beta_location_tag_13[17] = {'8','d','6','b','8','5','e','b','8','4','6','e','e','0','0','e',0x00};
+    char beta_location_tag_14[17] = {'9','3','2','7','4','c','b','9','e','4','6','d','b','6','7','6',0x00};
+    char beta_location_tag_15[17] = {'1','a','e','3','0','7','7','f','8','f','3','a','f','7','c','1',0x00};
+    char beta_location_tag_16[17] = {'f','f','d','5','a','2','e','a','4','4','9','2','e','d','a','c',0x00};
+    char beta_location_tag_17[17] = {'f','0','e','f','2','d','8','b','f','7','6','1','3','a','1','d',0x00};
+    char beta_location_tag_18[17] = {'e','e','7','6','4','c','8','5','3','4','6','b','9','5','f','2',0x00};
+    char beta_location_tag_19[17] = {'b','b','0','3','6','7','d','b','d','a','5','b','a','5','a','5',0x00};
+    
+    blecount ++;
+    
     //Search for the manufacturer specific data with matching application-ID
     AdvertisingData_t *pAdvData;
     for (size_t index = 0; index < params->advertisingDataLen; index += (pAdvData->length + 1)) {
@@ -584,6 +621,16 @@
                     || strcmp(beacon_identifier, beta_location_tag_7) == 0
                     || strcmp(beacon_identifier, beta_location_tag_8) == 0
                     || strcmp(beacon_identifier, beta_location_tag_9) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_10) == 0 
+                    || strcmp(beacon_identifier, beta_location_tag_11) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_12) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_13) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_14) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_15) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_16) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_17) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_18) == 0
+                    || strcmp(beacon_identifier, beta_location_tag_19) == 0
                     ) {
                     //dump advertising data
                     //for (unsigned index = 0; index < params->advertisingDataLen; index++) { if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "%02x",params->advertisingData[index]);debug_exe(false);}}
@@ -593,7 +640,7 @@
                          RET_closestLocationTag_rssi = tag_rssi;
                          memcpy(RET_closestLocationTag_id, beacon_identifier, sizeof(RET_closestLocationTag_id));
                          RET_locationTag_present = true;
-                         if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Location Tag Present: %s, rssi: %d",RET_closestLocationTag_id, RET_closestLocationTag_rssi);debug_exe();}
+                         //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Location Tag: %s, rssi: %d",RET_closestLocationTag_id, RET_closestLocationTag_rssi);debug_exe();}
                     }
                 }
                 break;
@@ -629,7 +676,7 @@
                             ((params->advertisingData[19] & 0b01111111) << 8) |
                             ((params->advertisingData[20] & 0b11111111))
                         ) / 100.0;
-                     if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Humidity Tag Present: %f",RET_humidity);debug_exe();}
+                     //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Humidity Tag Present: %f",RET_humidity);debug_exe();}
                 }
                 //rssi
                 //if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"Rssi: %i", params->rssi);debug_exe();}
@@ -662,7 +709,7 @@
                 params->advertisingData[19],
                 params->advertisingData[20]);
                 //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), " Mac: [%02x%02x%02x%02x%02x%02x], rssi: %d, AType: %u, Id: %s",params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],params->rssi, pAdvData->dataType, ble_advdata);debug_exe();}
-                if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Detector @rssi: %d",params->rssi);debug_exe();}
+                //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Detector @rssi: %d",params->rssi);debug_exe();}
                 if (params->rssi >= -75) {
                     RET_detector_present = true;
                 }
@@ -674,8 +721,7 @@
 void bleConfigureScan(void)
 {
     //configure scan
-    myble.gap().setScanParams(60,30); //scan interval //scan window
-    //myble.gap().setScanParams(100,100); //scan interval //scan window
+    myble.gap().setScanParams(200,200); //scan interval //scan window
     myble.gap().startScan(bleAdvertisementCallback);
 }
 void bleStopScan(void)
@@ -726,6 +772,7 @@
                 //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MotionOn");debug_exe();}
                 RET_motionState = true;
                 RET_motionStateOnInLocTXInterval = true;
+                GLOBAL_have_GPSlocString_prev = false;
                 if (RET_motionState == false) { //If this is first after motionState 0
                     if (RET_setting_activity_mode == 2 && RET_setting_activity_tx_interval_hrs > 0) {
                         time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
@@ -778,8 +825,8 @@
         if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "PARAMS: a:%d,b:%u,c:%d,d:%d,e:%d,f:%d,g:%d,h:%d,i:%d,j:%d,k:%d,l:%d,m:%d,n:%d,o:%d,p:%d,q:%d,r:%d,s:%d,t:%d,u:%s\n",
         TEMP_a,TEMP_b,TEMP_c,TEMP_d,TEMP_e,TEMP_f,TEMP_g,TEMP_h,TEMP_i,TEMP_j,TEMP_k,TEMP_l,TEMP_m,TEMP_n,TEMP_o,TEMP_p,TEMP_q,TEMP_r,TEMP_s,TEMP_t,TEMP_u);debug_exe();}
         
-        if(TEMP_a != -1) { RET_setting_minimumupdate_hrs = TEMP_a;                      }
-        if(TEMP_b > 1552915630) {
+        if(TEMP_a > 0) { RET_setting_minimumupdate_hrs = TEMP_a;                      }
+        if(TEMP_b > 1552915630 && TEMP_b < 1900000000) {
             if (RET_RTCunixtime < 1552915630) {
                 //assume this is first proper unixtime and set
                 RET_RTCunixtime = TEMP_b;
@@ -798,30 +845,30 @@
             critical_fail_count++;
             if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "unixtime too low");debug_exe();}
         }
-        if(TEMP_c != -1) { RET_setting_firmware = TEMP_c;                               } else { RET_setting_firmware = -1;}
-        if(TEMP_d != -1) { setState(TEMP_d);                                            } else { setState(STATE_NORMAL);}
-        if(TEMP_e != -1) { RET_setting_location_mode = TEMP_e;                          }
+        if(TEMP_c > 0) { RET_setting_firmware = TEMP_c;                               } else { RET_setting_firmware = -1;}
+        if(TEMP_d > -1) { setState(TEMP_d);                                           } else { setState(STATE_NORMAL);}
+        if(TEMP_e > 0) { RET_setting_location_mode = TEMP_e;                          }
             if(RET_setting_location_mode > 4) {RET_setting_location_mode = DEFAULT_LOCATION_MODE;}
-        if(TEMP_f != -1) { RET_setting_location_accuracy = TEMP_f;                      }
+        if(TEMP_f > 0) { RET_setting_location_accuracy = TEMP_f;                      }
             if(RET_setting_location_accuracy > 3) {RET_setting_location_accuracy = DEFAULT_LOCATION_ACCURACY;}
-        if(TEMP_g != -1) { RET_setting_location_tx_interval_mins = TEMP_g;              }
-        if(TEMP_h != -1) { RET_setting_location_tx_failsafe_hrs = TEMP_h;               }
+        if(TEMP_g > 0) { RET_setting_location_tx_interval_mins = TEMP_g;              }
+        if(TEMP_h > 0) { RET_setting_location_tx_failsafe_hrs = TEMP_h;               }
             if(RET_setting_location_tx_failsafe_hrs > 504) {RET_setting_location_tx_failsafe_hrs = DEFAULT_LOCATION_TX_FAILSAFE_HRS;}
-        if(TEMP_i != -1) { RET_setting_location_timeout = TEMP_i;                       }
+        if(TEMP_i > 0) { RET_setting_location_timeout = TEMP_i;                       }
             if(RET_setting_location_timeout < 60 || RET_setting_location_timeout > 300) {RET_setting_location_timeout = DEFAULT_LOCATION_TIMEOUT;}
-        if(TEMP_j != -1) { RET_setting_activity_tx_interval_hrs = TEMP_j;               }
-        if(TEMP_k != -1) { RET_setting_environmental_tx_interval_mins = TEMP_k;         }
-        if(TEMP_l != -1) { RET_setting_motion_g = TEMP_l;                               }
+        if(TEMP_j > -1) { RET_setting_activity_tx_interval_hrs = TEMP_j;               }
+        if(TEMP_k > -1) { RET_setting_environmental_tx_interval_mins = TEMP_k;         }
+        if(TEMP_l > 0) { RET_setting_motion_g = TEMP_l;                               }
             if(RET_setting_motion_g < 4 || RET_setting_motion_g > 127) {RET_setting_motion_g = DEFAULT_MOTION_G;}
-        if(TEMP_m != -1) { RET_setting_motion_start_seconds = TEMP_m;                   }
-        if(TEMP_n != -1) { RET_setting_motion_stop_seconds = TEMP_n;                    }
-        if(TEMP_o != -1) { RET_setting_impact_g = TEMP_o;                               }
-        if(TEMP_p != -1) { RET_setting_impact_alert = TEMP_p;                           }
-        if(TEMP_q != -1) { RET_setting_connection_timeout = TEMP_q;                     }
+        if(TEMP_m > -1) { RET_setting_motion_start_seconds = TEMP_m;                   }
+        if(TEMP_n > -1) { RET_setting_motion_stop_seconds = TEMP_n;                    }
+        if(TEMP_o > -1) { RET_setting_impact_g = TEMP_o;                               }
+        if(TEMP_p > -1) { RET_setting_impact_alert = TEMP_p;                           }
+        if(TEMP_q > -1) { RET_setting_connection_timeout = TEMP_q;                     }
             if(RET_setting_connection_timeout < 60 || RET_setting_connection_timeout > 240) { RET_setting_connection_timeout = DEFAULT_CONNECTION_TIMEOUT; }
-        if(TEMP_r != -1) { RET_setting_beacon_interval_seconds = TEMP_r;                }
-        if(TEMP_s != -1) { RET_setting_beacon_scan = TEMP_s;                            }
-        if(TEMP_t != -1) { RET_setting_activity_mode = TEMP_t;                          }
+        if(TEMP_r > -1) { RET_setting_beacon_interval_seconds = TEMP_r;                }
+        if(TEMP_s > -1) { RET_setting_beacon_scan = TEMP_s;                            }
+        if(TEMP_t > -1) { RET_setting_activity_mode = TEMP_t;                          }
         if(TEMP_u[0] != 0x00 && TEMP_u[1] != 0x00 && TEMP_u[2] != 0x00) { strcpy(RET_pf_identifier,TEMP_u);                      }
 
         if (critical_fail_count == 0) { 
@@ -868,10 +915,13 @@
         RET_eventTime_location_tx = (RET_RTCunixtime + (RET_setting_location_tx_interval_mins * 60));
         if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "EVTSET - LOC TX @ %u, MODE %d",RET_eventTime_location_tx, RET_setting_location_mode);debug_exe();}
     }
-    if(RET_setting_location_tx_failsafe_hrs > 0) { 
-        RET_eventTime_location_failsafe_tx = (RET_RTCunixtime + (RET_setting_location_tx_failsafe_hrs * 3600));
-        if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "EVTSET - LOC FS TX @ %u",RET_eventTime_location_failsafe_tx);debug_exe();}
+    if(RET_setting_location_tx_failsafe_hrs > 0 && RET_setting_location_tx_failsafe_hrs <= 168) { 
+        RET_location_failsafe_seconds_max = (RET_setting_location_tx_failsafe_hrs * 3600);
+        if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "EVTSET - LOC FS TX %u s",RET_location_failsafe_seconds_max);debug_exe();}
+    } else {
+        RET_location_failsafe_seconds_max = (DEFAULT_LOCATION_TX_FAILSAFE_HRS * 3600);
     }
+    RET_eventTime_location_failsafe_tx = (RET_RTCunixtime + RET_location_failsafe_seconds_max);
 }
 void setEventTime_Activity() {
     if(RET_setting_activity_tx_interval_hrs > 0) { 
@@ -1059,6 +1109,7 @@
     #if BLE_ENABLED
         bleStopAdvertising();
     #endif
+    RET_lastTxTime = RET_RTCunixtime;
     //check if we have any outstanding to send
     failed_broadcasts_tx();
     bool selfTestResult = selfTest();
@@ -1071,6 +1122,7 @@
     RET_locationTag_present = false;
     RET_detector_present = false;
     #if BLE_ENABLED
+        blecount = 0;
         if (RET_setting_beacon_scan == 1 && RET_setting_location_mode != LOCATION_MODE_REALTIME) {
             LowPowerTimer bleScan_t;
             bleScan_t.start();
@@ -1085,10 +1137,11 @@
                 //Scan for 10 seconds
                 bleConfigureScan();
                 bleScan_startmillis = bleScan_t.read_ms();
-                while (bleScan_runtime < 10000 && RET_detector_present == false) {
+                while (bleScan_runtime < 20000 && RET_detector_present == false) {
                     bleScan_runtime = (bleScan_t.read_ms() - bleScan_startmillis);
                     myble.waitForEvent(); // low power wait for event
                 }
+                if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "BLECount: %d",blecount);debug_exe();}
                 if (RET_locationTag_present && RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "LocationTag: %s, rssi: %d",RET_closestLocationTag_id, RET_closestLocationTag_rssi);debug_exe();}
             }
             bleScan_t.stop();
@@ -1100,14 +1153,14 @@
         }
     #endif
     
-    
     if (skipTX == false || failsafe == true) {
         //Set any network or GPS fail flags
-        if (RET_NetworkFailCount > DEFAULT_MAX_FAILED_CONNECTIONS) addToExceptionString("NF");
-        if (RET_GPSFailCount > DEFAULT_MAX_FAILED_GPS) addToExceptionString("GF");
-        //lets check to see if we've had repeated comms failings in this location, if so dont bother trying. reset by movment and timeout
+        if (RET_NetworkFailCount > DEFAULT_MAX_FAILED_CONNECTIONS) {RET_NetworkFailFlag = true;}
+        if (RET_GPSFailCount > DEFAULT_MAX_FAILED_GPS) {addToExceptionString("GF");}
+        //lets check to see if we've had repeated comms failings in this location, if so dont bother trying. reset by movment and failsafe
         if (RET_NetworkFailCount <= DEFAULT_MAX_FAILED_CONNECTIONS) {
-            if (RET_receivedNewSettings) {RET_receivedNewSettings = false; addToExceptionString("SR"); }
+            if (RET_NetworkFailFlag) {RET_NetworkFailFlag = false; addToExceptionString("NF");}
+            if (RET_receivedNewSettings) {RET_receivedNewSettings = false; addToExceptionString("SR");}
             if (modem.on(RET_force2G)) {
                 char locString[70];
                 int gpsStartTime = RET_RTCunixtime;
@@ -1124,7 +1177,6 @@
                         memcpy(locString, modem.getLocation(RET_setting_location_accuracy, RET_setting_location_timeout, RET_GPSFailCount, RET_NetworkFailCount), sizeof(locString));
                     }
                 }
-                
                 int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
                 
                 //SEND DATA
@@ -1143,7 +1195,7 @@
                     if (getSettings == true && strcmp(result, "sendokrecfail") == 0) {
                         //send ok but receive fail
                         if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"USSD Send Ok but Rec fail");debug_exe();}
-                        //sendErrorLog("ERR-LOC-NR");
+                        sendErrorLog("ERR-LOC-NR");
                     } else if (strcmp(result, "sendok") == 0) {
                         //do nothing
                     } else if (strcmp(result, "sendfail") == 0) {
@@ -1265,14 +1317,18 @@
                     if (GLOBAL_motionStopFlagTriggered) { GLOBAL_motionStopFlagTriggered = false; run_location_tx = true; }
                     break;
             }
-            if(RET_RTCunixtime >= RET_eventTime_location_failsafe_tx && RET_eventTime_location_failsafe_tx > 0) { 
+            if(run_location_tx == false && RET_location_failsafe_seconds_count >= RET_location_failsafe_seconds_max) { 
+                RET_location_failsafe_seconds_count = 0; //reset
                 RET_NetworkFailCount = 0; //reset to ensure connection
                 RET_GPSFailCount = 0; // reset to ensure gps try
                 addToExceptionString("FS");
                 updateBatteryV();
                 event_location_tx(true);
             } else {
-                if (run_location_tx) { updateBatteryV(); event_location_tx(false); }
+                if (run_location_tx) { 
+                    updateBatteryV(); 
+                    event_location_tx(false); 
+                }
             }
             
             //ACTIVITY EVENT
@@ -1415,7 +1471,7 @@
     //INIT
     LED1off();
     ThisThread::sleep_for(2000); //Initial pause, this is needed for softdevice to init, dont remove!! If we dont have this we get crashes
-    watchdog.configure(300.0); //5 mins //Do not set to less than 4500ms or can cause issues with softdevice
+    watchdog.configure(400.0); //6.6 mins //Do not set to less than 4500ms or can cause issues with softdevice
     modem.off(false);
     RTCticker.attach(&RTCtick, 1.0);
     LPtimer.start();
@@ -1431,15 +1487,19 @@
         switch(NRF_POWER->RESETREAS) {
             case 0x00000001  :
                 if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:HW\n");debug_exe();}
+                addToExceptionString("RH");
             break;
             case 0x00000002  :
                 if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:WD\n");debug_exe();}
+                addToExceptionString("WD");
             break;
             case 0x00000004  :
                 if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:SW\n");debug_exe();}
+                addToExceptionString("RS");
             break;
             case 0x00000008  :
                 if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:LU\n");debug_exe();}
+                addToExceptionString("RL");
             break;            
         }
         NRF_POWER->RESETREAS = 0xffffffff;
@@ -1474,7 +1534,7 @@
         //MAIN LOGIC
         if(RET_debug){
             if (RET_state != 99) {
-                debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d, S:%d, SET:%d, MF:%d, MS:%d, MTX:%d, %u, L:%u, LFS:%u, A:%u", FW_VERSION, RET_state, RET_haveSettings, RET_motionTriggeredinFrame, RET_motionState, RET_motionStateOnInLocTXInterval, RET_RTCunixtime,RET_eventTime_location_tx,RET_eventTime_location_failsafe_tx,RET_eventTime_activity_tx);debug_exe();
+                debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d, S:%d, SET:%d, MF:%d, MS:%d, MTX:%d, %u, L:%u, FSC:%u FSM:%u, FST:%u, A:%u", FW_VERSION, RET_state, RET_haveSettings, RET_motionTriggeredinFrame, RET_motionState, RET_motionStateOnInLocTXInterval, RET_RTCunixtime,RET_eventTime_location_tx,RET_location_failsafe_seconds_count,RET_location_failsafe_seconds_max,RET_eventTime_location_failsafe_tx,RET_eventTime_activity_tx);debug_exe();
                 debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "ACT M:%d, HsP:%.2f, Ht:%.2f, D:%s",RET_setting_activity_mode,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours,RET_activityData);debug_exe();
             } else {
                 debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d, S:%d, WAKE@:%u\n", FW_VERSION, RET_state, RET_eventTime_wakeFromDormant);debug_exe();
@@ -1517,6 +1577,8 @@
         #endif
         
         //PRE-SLEEP ACTIONS
+        RET_location_failsafe_seconds_count += (DEFAULT_SLEEP_FRAME / 1000);
+        memset(GLOBAL_exceptionString,0x00,sizeof(GLOBAL_exceptionString));
         LED1off();
         modem.off(GLOBAL_modemOn); //HARD OR SOFT SHUT DOWN - DEPENDING ON modemOn state
         if (GLOBAL_needToConfigureLis3dh) { lis3dh_configureForSleep(RET_setting_motion_g,RET_setting_impact_g); }
--- a/main.h	Wed May 29 23:59:56 2019 +0000
+++ b/main.h	Tue Jun 25 10:40:03 2019 +0000
@@ -16,7 +16,7 @@
 //------------------------------------------------------------------------------
 //FW DETAILS
 //------------------------------------------------------------------------------ 
-#define FW_VERSION          328
+#define FW_VERSION          26
 //#define SKU                 "GPSPLUSDEV"
 #define SKU                 "GPSPLUS"
 #define HW_MAJORREVISION    "001"
@@ -118,7 +118,8 @@
 extern char GLOBAL_debug_buffer[DEBUG_BUFFERSIZE];
 extern char GLOBAL_GPSlocString_prev[70];
 extern bool GLOBAL_have_GPSlocString_prev;
+extern char GLOBAL_exceptionStringRetainedUntilSuccess[10];
 //FUNCS
 extern void watchdogKick();
-
+extern void addToExceptionString(char* value);
 #endif
\ No newline at end of file
--- a/mbed_app.json	Wed May 29 23:59:56 2019 +0000
+++ b/mbed_app.json	Tue Jun 25 10:40:03 2019 +0000
@@ -23,6 +23,8 @@
             "platform.sys-stats-enabled": false
         },
         "NRF52_DK": {
+            "target.mbed_app_start": "0x3E000",
+            "target.bootloader_img": null,
             "target.OUTPUT_EXT": "bin",
             "target.uart_hwfc": 0,
             "nordic.uart_0_fifo_size": 1024,
--- a/modem.cpp	Wed May 29 23:59:56 2019 +0000
+++ b/modem.cpp	Tue Jun 25 10:40:03 2019 +0000
@@ -52,8 +52,10 @@
     }
 }
 
-int Modem::ATwaitForWordOrWord(char* word1, char* word2, uint32_t timeout)
+/*
+bool Modem::ATwaitForWordOrBO(char* word1, uint32_t timeout)
 {
+      char* word2 = "RDY\r";
       int targetIndex1 = 0;
       int targetIndex2 = 0;
       bool havefullmatch1 = false;
@@ -105,7 +107,18 @@
       }
       t.stop();
       t.reset();
+      
+      //if bool response
+      if (havefullmatch1) {
+        return true;
+      }
+      else {
+        addToExceptionStringRetainedUntilSuccess("BO");
+        return false;
+      }
+      
     
+      //if int response
       if (havefullmatch1) {
             return 1;
       }
@@ -116,6 +129,7 @@
             return 0;
       }
 }
+*/
 
 
 bool Modem::ATgetResponse(char terminator, uint32_t timeout) 
@@ -562,20 +576,19 @@
             ATwaitForWord("OK",ATTIMEOUT_SHORT);
             ATsendCMD("AT+QGPSLOC=2");
             if (ATwaitForWord("+QGPSLOC: ",ATTIMEOUT_SHORT)) {
-                haveGPSFix = true;
-                GPS_fixstage = 1;
-                GPS_fixloopcount ++;
                 int matchCount = 0;
                 if (ATgetResponse('\r',ATTIMEOUT_VERYSHORT)) { 
                     if ((matchCount = sscanf(ATinBuffer,"%f,%f,%f,%f,%f,%d,%f,%f,%f,%d,%d",&utc,&lat,&lng,&hdp,&alt,&fix,&cog,&spkm,&spkn,&date,&sat)) == 11 ) {
                         //{“fix”:“GPS”,“sat”:“9",“lat”:“52.913254",“lng”:“-1.455289",“hdp”:“2.0",“spd”:“0.0"}                    
                         haveGPSFix = true;
+                        GPS_fixstage = 1;
+                        GPS_fixloopcount ++;
                         if (accuracy > 2) {
-                            if (hdp <= 1.8) {
+                            if (hdp <= 1.8f) {
                                 GPS_fixstage = 2;
                             }
                         } else {
-                            if (GPS_fixloopcount >= 1) {
+                            if (GPS_fixloopcount > 2) {
                                 GPS_fixstage = 2;
                             }
                         }
--- a/modem.h	Wed May 29 23:59:56 2019 +0000
+++ b/modem.h	Tue Jun 25 10:40:03 2019 +0000
@@ -37,7 +37,7 @@
             //AT
             void ATsendCMD(char* cmd);
             bool ATwaitForWord(char* word, uint32_t timeout);
-            int ATwaitForWordOrWord(char* word1, char* word2, uint32_t timeout);
+            bool ATwaitForWordOrBO(char* word1, uint32_t timeout);
             bool ATgetResponse(char terminator, uint32_t timeout);
         private: