init

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

Revision:
54:2840f2d50734
Parent:
53:c6942af186d7
Child:
55:0914bfcedcf8
--- 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); }