init

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

Files at this revision

API Documentation at this revision

Comitter:
pathfindr
Date:
Tue Feb 05 14:30:57 2019 +0000
Parent:
47:cc6d4d0bf897
Child:
49:15ddd84ec9fa
Commit message:
init

Changed in this revision

NRFuart.cpp Show annotated file Show diff for this revision Revisions of this file
common.cpp Show annotated file Show diff for this revision Revisions of this file
common.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
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
states.h Show annotated file Show diff for this revision Revisions of this file
--- a/NRFuart.cpp	Mon Jan 21 19:43:17 2019 +0000
+++ b/NRFuart.cpp	Tue Feb 05 14:30:57 2019 +0000
@@ -137,7 +137,7 @@
 void NRFuart_flush() {
     if (!NRF_UART0->ENABLE) NRFuart_init_nohwfc();
     //THIS HASNT BEEN TESTED
-    char char1 = 0;
+    char char1;
     uint32_t safetycounter = 0;
     while (NRFuart_readable() && safetycounter < 10000) {
         safetycounter ++;
--- a/common.cpp	Mon Jan 21 19:43:17 2019 +0000
+++ b/common.cpp	Tue Feb 05 14:30:57 2019 +0000
@@ -12,8 +12,8 @@
         //ThisThread::sleep_for(milliseconds);
         Thread::wait(milliseconds);
         led1 = 1;
+        GLOBAL_LEDSequenceinProgress = false;
     }
-    GLOBAL_LEDSequenceinProgress = false;
 }
 void LED1blink(int count = 2, long milliseconds = 100) {
     GLOBAL_LEDSequenceinProgress = true;
@@ -30,6 +30,9 @@
     led1 = 1;
     GLOBAL_LEDSequenceinProgress = false;
 }
+void LED1blinkRTC(int count) {
+    RTCtick_ledflash_count = count;
+}
 void LED1errorCode(int pattern, int count) {
     GLOBAL_LEDSequenceinProgress = true;
     for (int i = 0; i < count; i++) {
@@ -46,5 +49,6 @@
 }
 void LED1off() {
     led1 = 1;
+    RTCtick_ledflash_count = 0;
     GLOBAL_LEDSequenceinProgress = false;
 }
\ No newline at end of file
--- a/common.h	Mon Jan 21 19:43:17 2019 +0000
+++ b/common.h	Tue Feb 05 14:30:57 2019 +0000
@@ -6,6 +6,7 @@
 extern DigitalOut led1;
 extern void LED1on(long milliseconds);
 extern void LED1blink(int count, long milliseconds);
+extern void LED1blinkRTC(int count);
 extern void LED1errorCode(int pattern, int count);
 extern void LED1off(void);
 
--- a/main.cpp	Mon Jan 21 19:43:17 2019 +0000
+++ b/main.cpp	Tue Feb 05 14:30:57 2019 +0000
@@ -4,15 +4,15 @@
 //FUNCTION PROTOTYPES - NEED TO ADD ALL OF THE MISSING ONES
 //------------------------------------------------------------------------------ 
 //should really add these - will just add as and when needed for now
-void event_activity_tx(uint8_t activity_mode);
+void event_activity_tx();
 
 //------------------------------------------------------------------------------
 // GLOBALS
 //------------------------------------------------------------------------------ 
+bool             GLOBAL_debugLED                     = false;
 char*            GLOBAL_defaultApi                   = "b:gps2";
 bool             GLOBAL_accel_healthy                = false;
 bool             GLOBAL_motionStopFlagTriggered      = false;
-bool             GLOBAL_debugLED                     = true;
 bool             GLOBAL_needToConfigureLis3dh        = false;
 bool             GLOBAL_registeredOnNetwork          = false;
 bool             GLOBAL_modemOn                      = false;
@@ -21,7 +21,7 @@
 char             GLOBAL_exceptionString[30];
 char             GLOBAL_debug_buffer[200];
 
-
+//SETTINGS
 int              RET_setting_firmware;
 uint32_t         RET_setting_minimumupdate_hrs;
 uint8_t          RET_setting_location_mode;
@@ -43,6 +43,7 @@
 //STATE
 uint8_t          RET_coldBoot = 1;
 bool             RET_asleep = false;
+bool             RET_busy = false;
 time_t           RET_RTCunixtime;
 bool             RET_haveSettings;
 uint8_t          RET_state;
@@ -56,6 +57,8 @@
 bool             RET_force2G;
 bool             RET_watchdogfired;
 bool             RET_receivedNewSettings;
+uint32_t         RET_GPSFailCount;
+uint32_t         RET_NetworkFailCount;
 //MOTION STATE
 bool             RET_motionTriggeredinFrame;
 bool             RET_motionTriggeredInLocTXInterval;
@@ -206,12 +209,13 @@
 //------------------------------------------------------------------------------
 // RTC TICKER
 //------------------------------------------------------------------------------ 
+uint8_t RTCtick_ledflash_count = 0;
 void RTCtick() {
     //YOU MUST NOT CALL ANY OTHER FUNCTIONS OR DEBUG FROM INSIDE HERE!!! OR IT LOCKS UP THE DEVICE, just change vars
     RET_RTCunixtime += 1;
 
     //button logic, only when device asleep
-    if (RET_asleep == true) {
+    //if (RET_asleep == true) {
         //led indicator
         //if (RET_buttonPressTime > 0 && (RET_RTCunixtime - RET_buttonPressTime) > 4) led1 = 0;
         //if (RET_buttonPressTime > 0 && (RET_RTCunixtime - RET_buttonPressTime) > 14) led1 = 1;
@@ -229,29 +233,30 @@
             RET_state = STATE_SCORCHEDEARTH;
             mainthread.release();
         } else {
-            if((RET_RTCunixtime - RET_buttonPressTime) > 1) {
-                switch (RET_buttonPressCount) {   
-                    case 1 :
-                        if(RET_state != STATE_DORMANT) {
+            if((RET_RTCunixtime - RET_buttonPressTime) > 1 && RET_buttonPressCount > 0) {
+                if(RET_busy == true) { 
+                    RTCtick_ledflash_count = 16;// 8 flashes
+                } else {
+                    switch (RET_buttonPressCount) {   
+                        case 1 :
+                            RET_state_prev = RET_state;
                             RET_state = STATE_BUTTONPRESS1;
                             mainthread.release();
-                        }
-                        break;
-                    case 3 :
-                        if(RET_state != STATE_DORMANT) {
-                            RET_state = STATE_BUTTONPRESS2;
-                            mainthread.release();
-                        }
-                        break;
-                    case 5 :
-                        if(RET_state != STATE_DORMANT) {
+                            break;
+                        case 3 :
+                            RET_state_prev = RET_state;
                             RET_state = STATE_BUTTONPRESS3;
                             mainthread.release();
-                        }
-                        break;
-                    default :
-                        //do nothing
-                        break;
+                            break;
+                        case 5 :
+                            RET_state_prev = RET_state;
+                            RET_state = STATE_BUTTONPRESS5;
+                            mainthread.release();
+                            break;
+                        default :
+                            //do nothing
+                            break;
+                    }
                 }
                 RET_SetupRunAt = 0; //allow setup to run again
                 RET_buttonPressCount = 0;
@@ -260,8 +265,15 @@
         //SETUP STATE VISUALISE
         if (!GLOBAL_LEDSequenceinProgress && RET_setupInProgress) {
             led1 = !led1; 
+        } else if (!GLOBAL_LEDSequenceinProgress && RTCtick_ledflash_count > 0) {
+            //IN OPERATION VISUALISE
+            led1 = !led1;
+            RTCtick_ledflash_count --;
+        } else if (!GLOBAL_LEDSequenceinProgress && RTCtick_ledflash_count <= 0) {
+            RTCtick_ledflash_count = 0;
+            led1 = 1; //turn off led
         }
-    }
+    //}
 }
 void resetGlobals() {
     GLOBAL_accel_healthy = false;
@@ -303,6 +315,7 @@
 void setDefaults() {
     //STATE
     RET_asleep = false;
+    RET_busy = false;
     RET_haveSettings = false;
     RET_state = STATE_SETUP;
     RET_state_prev = RET_state;
@@ -313,6 +326,8 @@
     RET_watchdogfired = false;
     RET_setupInProgress = false;
     RET_receivedNewSettings = false;
+    RET_GPSFailCount = 0;
+    RET_NetworkFailCount = 0;
     //SETTINGS
     RET_setting_firmware = 0;
     RET_setting_minimumupdate_hrs = 0;
@@ -394,10 +409,10 @@
     
     //Result
     if (test_count == test_pass) {
-        addToExceptionString("OK"); 
+        //addToExceptionString("HOK");  //dont need this, only add fails
         return true;
     } else {
-        addToExceptionString("FAIL"); 
+        addToExceptionString("HF"); 
         return false;   
     }
 }
@@ -405,9 +420,9 @@
 //------------------------------------------------------------------------------
 // MOTION FUNCS
 //------------------------------------------------------------------------------ 
-void checkMotion() {
+bool checkMotion() {
     if (lis3dh_int2) {
-        //if (GLOBAL_debugLED) LED1blink(1,50);
+        if (GLOBAL_debugLED) LED1blink(2,50);
         RET_motionTriggeredinFrame = true;
         GLOBAL_needToConfigureLis3dh = true; //interrupt has fire so need to clear it
         if (!RET_motionPendingOnState) {
@@ -417,6 +432,7 @@
             RET_motionStartTime = RET_RTCunixtime;
         }
     } else {
+        if (GLOBAL_debugLED) LED1blink(1,50);
         RET_motionTriggeredinFrame = false;
         RET_motionPendingOnState = false;
         if (!RET_motionPendingOffState) {
@@ -450,7 +466,7 @@
             RET_motionPendingOffState = false;
             RET_motionState = false;
             GLOBAL_motionStopFlagTriggered = true;
-            if (RET_setting_location_tx_failsafe_hrs > 0) {
+            if (RET_setting_activity_mode > 0 && RET_setting_location_tx_failsafe_hrs > 0) {
                 RET_motionTotalActivityHoursSincePost += ((float(RET_motionStopTime)-float(RET_motionStartTime)) / 3600.0f);
                 RET_motionTotalActivityHours += RET_motionTotalActivityHoursSincePost;
                 if (RET_setting_activity_mode == 2) {
@@ -460,6 +476,10 @@
             }
         }
     }
+    
+    if (GLOBAL_debugLED && RET_motionState == true) LED1on(1000);
+    
+    return RET_motionState;
 }
 
 //------------------------------------------------------------------------------
@@ -470,9 +490,10 @@
     int critical_fail_count = 0;
     int TEMP_a = -1; time_t TEMP_b = 0; int TEMP_c = -1; int TEMP_d = -1; int TEMP_e = -1; int TEMP_f = -1; int TEMP_g = -1; int TEMP_h = -1; int TEMP_i = -1; int TEMP_j = -1; 
     int TEMP_k = -1; int TEMP_l = -1; int TEMP_m = -1; int TEMP_n = -1; int TEMP_o = -1; int TEMP_p = -1; int TEMP_q = -1; int TEMP_r = -1; int TEMP_s = -1; int TEMP_t = -1;
-    int varTotal = 19; //change this if var number changes!!!!!!!!
+    //int varTotal = 19; //change this if var number changes!!!!!!!!
     if ( (matchCount = sscanf(settingsBuffer,"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",
     &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) ) > 0 ) {
+        
         if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "FROMSERVER: 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\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);debug_exe();}
         
@@ -512,6 +533,9 @@
             RET_SettingsGotAt = RET_RTCunixtime;
             //check for firmware update
             if (RET_setting_firmware > 0 && RET_setting_firmware != FW_VERSION) {
+                //Broadcast any activity data we have before fw update
+                event_activity_tx();
+                //prep for FW update
                 read_app_data_from_flash(&app_data);
                 clr_flag(&app_data, app_execution_flag);
                 clr_flag(&app_data, first_run_flag);
@@ -519,7 +543,7 @@
                 app_data.target_firmware_version = RET_setting_firmware;
                 write_app_data_to_flash(&app_data);
                 if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "OTA\n");debug_exe();}
-                ThisThread::sleep_for(250);
+                ThisThread::sleep_for(200);
                 system_reset();
             }
             return true;
@@ -580,7 +604,7 @@
     memset(bytestosend,0x00,sizeof(bytestosend));
     snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,v:%.2f,e:%d,z:%s.%s,c:1,s:0)\0",GLOBAL_defaultApi,FW_VERSION,voltage,timetaken,error,GLOBAL_exceptionString);
     if (modem.on(RET_force2G)) {
-        if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
+        if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,RET_setting_connection_timeout,RET_NetworkFailCount)) {
             modem.USSDmessage(bytestosend, false, 2, GLOBAL_defaultApi);
         }
     }
@@ -591,7 +615,11 @@
 // EVENTS
 //------------------------------------------------------------------------------ 
 bool event_setup(bool manualrun) {
+    if (RET_NetworkFailCount > DEFAULT_MAX_FAILED_CONNECTIONS) addToExceptionString("NF");
+    if (RET_GPSFailCount > DEFAULT_MAX_FAILED_GPS) addToExceptionString("GF");
     RET_setupInProgress = true;
+    RET_NetworkFailCount = 0;
+    RET_GPSFailCount = 0;
     bool pass = true;
     float temperature = getTemperature();
     float voltage = getBatteryV();
@@ -601,9 +629,9 @@
     if (modem.on(RET_force2G)) {
         char locString[70];
         int gpsStartTime = RET_RTCunixtime;
-        memcpy(locString, modem.getLocation(1, RET_setting_location_timeout), 70);
+        memcpy(locString, modem.getLocation(1, RET_setting_location_timeout, RET_GPSFailCount, RET_NetworkFailCount), sizeof(locString));
         int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
-        if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
+        if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,RET_setting_connection_timeout,RET_NetworkFailCount)) {
             int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for ussd response time.
             int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
             if (manualrun) addToExceptionString("MAN");
@@ -615,26 +643,26 @@
                 if (saveSettings(result) == false) {
                     //something went critically wrong getting settings 
                     pass = false;
-                    sendErrorLog("ERR:SU-IR");
+                    sendErrorLog("ERR-SU-IR");
                 }                      
             } else {
                 //Response error
-                sendErrorLog("ERR:SU-NR");
+                sendErrorLog("ERR-SU-NR");
             }
         } else {
             //FAILUREMODE modem failed to register on network
             modem.off(true);
-            if(GLOBAL_debugLED) LED1errorCode(3,10); //ERROR 3
+            LED1errorCode(3,5); //ERROR 3
             pass = false;
         }
     } else {
         //FAILUREMODE Modem failed to turn on  
         modem.off(true);
-        if(GLOBAL_debugLED) LED1errorCode(2,10); //ERROR 2
+        LED1errorCode(2,5); //ERROR 2
         pass = false;
     }
     //SEND ANY ACTIVITY DATA
-    event_activity_tx(RET_setting_activity_mode);
+    event_activity_tx();
     modem.off(true);
     
     //LOG RUN TIME - THIS MUST GO AT END AFTER WE HAVE GOT SERVER TIMESTAMP
@@ -646,15 +674,17 @@
 }
 
 void event_turnonofflog_tx(bool turnon) {
+    RET_NetworkFailCount = 0; //reset network blocker
+    RET_GPSFailCount = 0;
     float temperature = getTemperature();
     float voltage = getBatteryV();
     int connectionStartTime = RET_RTCunixtime;
     if (modem.on(RET_force2G)) {
         char locString[70];
         int gpsStartTime = RET_RTCunixtime;
-        memcpy(locString, modem.getLocation(1, RET_setting_location_timeout), 70);
+        memcpy(locString, modem.getLocation(1, RET_setting_location_timeout, RET_GPSFailCount, RET_NetworkFailCount), sizeof(locString));
         int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
-        if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
+        if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,RET_setting_connection_timeout,RET_NetworkFailCount)) {
             int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime);
             int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
             char bytestosend[160];
@@ -678,39 +708,47 @@
     float temperature = getTemperature();
     float voltage = getBatteryV();
     int selfTestResult = selfTest();
-    int connectionStartTime = RET_RTCunixtime;
-    if (RET_receivedNewSettings) {RET_receivedNewSettings = false; addToExceptionString("SR"); }
-    if (modem.on(RET_force2G)) {
-        char locString[70];
-        int gpsStartTime = RET_RTCunixtime;
-        memcpy(locString, modem.getLocation(RET_setting_location_accuracy, RET_setting_location_timeout), 70);
-        int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
-        //SEND DATA
-        if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
-            int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for ussd response time.
-            int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
-            //Check if we should wait for settings back
-            bool getSettings = true;
-            //work out if we need to get settings back
-            if (  ((RET_RTCunixtime - RET_SettingsGotAt)/3600) < RET_setting_minimumupdate_hrs  ) { getSettings = false; timetaken_total -= 10;} //remove the extra 10 seconds from times
-            char bytesToSend[160];
-            snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:loc,f:%d,t:%.1f,v:%.2f,z:LOC-%s,e:%d,y:%d,x:%d,c:1,s:%d%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,voltage,GLOBAL_exceptionString,timetaken_total,timetaken_connection,timetaken_gps,getSettings,locString);
-            char result[180];
-            snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getSettings, 2, GLOBAL_defaultApi));
-            if (result != "err") {
-                if (getSettings) {
-                    if (saveSettings(result) == false){sendErrorLog("ERR:LOC-IR");}
+    //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) {
+        if (RET_receivedNewSettings) {RET_receivedNewSettings = false; addToExceptionString("SR"); }
+        if (modem.on(RET_force2G)) {
+            char locString[70];
+            int gpsStartTime = RET_RTCunixtime;
+            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
+            int connectionStartTime = RET_RTCunixtime;
+            if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,RET_setting_connection_timeout,RET_NetworkFailCount)) {
+                int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for avg ussd response time.
+                int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
+                //Check if we should wait for settings back
+                bool getSettings = true;
+                //work out if we need to get settings back
+                if (  ((RET_RTCunixtime - RET_SettingsGotAt)/3600) < RET_setting_minimumupdate_hrs  ) { getSettings = false; timetaken_total -= 10;} //remove the extra 10 seconds from times
+                char bytesToSend[160];
+                snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:loc,f:%d,t:%.1f,v:%.2f,z:LOC-%s,e:%d,y:%d,x:%d,c:1,s:%d%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,voltage,GLOBAL_exceptionString,timetaken_total,timetaken_connection,timetaken_gps,getSettings,locString);
+                char result[180];
+                snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getSettings, 2, GLOBAL_defaultApi));
+                if (result != "err") {
+                    if (getSettings) {
+                        if (saveSettings(result) == false){sendErrorLog("ERR-LOC-IR");}
+                    }
+                } else {
+                    sendErrorLog("ERR-LOC-NR");
                 }
             } else {
-                sendErrorLog("ERR:LOC-NR");
+                //Modem fails to register on network
+                modem.off(true);
+                LED1errorCode(3,5); //ERROR 3   
             }
         } else {
+            //Modem fails to turn on
             modem.off(true);
-            if(GLOBAL_debugLED) LED1errorCode(3,10); //ERROR 3   
+            LED1errorCode(2,5); //ERROR 2
         }
-    } else {
-        modem.off(true);
-        if(GLOBAL_debugLED) LED1errorCode(2,10); //ERROR 2
     }
     modem.off(true);
     //RESETS
@@ -718,38 +756,53 @@
     setEventTime_Location();
 }
 
-void event_activity_tx(uint8_t activity_mode) {
+void event_activity_log(char* eventstring) {
+    //STUB
+    return;
+}
+void event_activity_tx() {
     //SEND ACTIVITY DATA
+    
     //check we have something to send...
-    if (RET_motionTotalActivityHoursSincePost > 0.0 && activity_mode > 0) {
-        float temperature = getTemperature();
-        float voltage = getBatteryV();
-        if (modem.on(RET_force2G)) {
-            //SEND DATA
-            if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
-                char bytesToSend[160];
-                if (activity_mode == 1) {
-                    snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,t:%u,r:%.2f,h:%.2f,c:1)\0",GLOBAL_defaultApi,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours);
-                } else if (activity_mode == 2) {
-                    snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,e:%s,t:%u,r:%.2f,c:1)\0",GLOBAL_defaultApi,RET_activityData,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost);
-                }
-                char result[180];
-                bool getResponse = false;
-                snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getResponse, 2, GLOBAL_defaultApi));
-                if (result != "err") {
-                    //RESET ACTIVITY FRAME
-                    memset(RET_activityData,0,sizeof(RET_activityData));
-                    if (RET_haveSettings) { RET_motionFrameStart = RET_RTCunixtime; }
+    if (RET_motionTotalActivityHoursSincePost > 0.0f && RET_setting_activity_mode > 0) {
+        //Build data to send
+        char bytesToSend[160];
+        if (RET_setting_activity_mode == 1) {
+            snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,t:%u,r:%.2f,h:%.2f,c:1)\0",GLOBAL_defaultApi,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours);
+        } else if (RET_setting_activity_mode == 2) {
+            snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,e:%s,t:%u,r:%.2f,c:1)\0",GLOBAL_defaultApi,RET_activityData,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost);
+        }
+        
+        if (RET_NetworkFailCount <= DEFAULT_MAX_FAILED_CONNECTIONS) {
+            float temperature = getTemperature();
+            float voltage = getBatteryV();
+            if (modem.on(RET_force2G)) {
+                //SEND DATA
+                if (modem.registerOnNetwork(2,RET_setting_connection_timeout,RET_NetworkFailCount)) {
+                    char result[180];
+                    bool getResponse = false;
+                    snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getResponse, 3, GLOBAL_defaultApi));
+                    if (result != "err") {
+                        //RESET ACTIVITY FRAME
+                        memset(RET_activityData,0,sizeof(RET_activityData));
+                        if (RET_haveSettings) { RET_motionFrameStart = RET_RTCunixtime; }
+                    } else {
+                        //TODO: LETS LOG THE DATA INSTEAD   
+                        event_activity_log(bytesToSend);
+                    }
+                } else {
+                    //Modem fails to register on network
+                    modem.off(true);
                 }
             } else {
+                //Modem fails to turn on
                 modem.off(true);
-                if(GLOBAL_debugLED) LED1errorCode(3,10); //ERROR 3
             }
+            modem.off(true);
         } else {
-            modem.off(true);
-            if(GLOBAL_debugLED) LED1errorCode(2,10); //ERROR 3
+            //TODO: LETS LOG THE DATA INSTEAD   
+            event_activity_log(bytesToSend);
         }
-        modem.off(true);
     }
     //RESETS
     setEventTime_Activity();
@@ -762,6 +815,7 @@
     switch(RET_state) {
         case STATE_SETUP :
         { //need the curlies to avoid "transfer of control bypass init error warning"
+            RET_busy = true;
             //check that we havent run setup too recently
             time_t setupRunAt_delta = (RET_RTCunixtime - RET_SetupRunAt);
             if (RET_SetupRunAt == 0 || setupRunAt_delta > ONEDAYINSECONDS) {
@@ -777,10 +831,12 @@
                 time_t setupCanRunAt = (RET_RTCunixtime + (ONEDAYINSECONDS - setupRunAt_delta));
                 if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"SETUP CAN RUN AGAIN @%u \n",setupCanRunAt);debug_exe();}
             }
+            RET_busy = false;
             break;
         }
         case STATE_NORMAL :
-        {            
+        {   
+            RET_busy = true;
             //LOCATION EVENT
             bool run_location_tx = false;
             switch (RET_setting_location_mode) {
@@ -800,14 +856,18 @@
                     if (GLOBAL_motionStopFlagTriggered) { run_location_tx = true; GLOBAL_motionStopFlagTriggered = false; }
                     break;
             }
-            if(RET_RTCunixtime >= RET_eventTime_location_failsafe_tx && RET_eventTime_location_failsafe_tx > 0) { run_location_tx = true; }
+            if(RET_RTCunixtime >= RET_eventTime_location_failsafe_tx && RET_eventTime_location_failsafe_tx > 0) { 
+                RET_NetworkFailCount = 0; //reset to ensure connection
+                RET_GPSFailCount = 0; // reset to ensure gps try
+                run_location_tx = true;
+            }
             if (run_location_tx) { event_location_tx(); }
             
             
             //ACTIVITY EVENT
             bool run_activity_tx = false;
             if(RET_RTCunixtime >= RET_eventTime_activity_tx && RET_eventTime_activity_tx > 0) {
-                if (RET_setting_activity_mode == 1 && RET_motionTotalActivityHoursSincePost > 0.0) {
+                if (RET_setting_activity_mode == 1 && RET_motionTotalActivityHoursSincePost > 0.0f) {
                     run_activity_tx = true;
                 }
                 if (RET_setting_activity_mode == 2 && strlen(RET_activityData) > 1) {
@@ -816,7 +876,9 @@
             }
             //If in sendevent mode, check if buffer is close to full, if so send
             if (RET_setting_activity_mode == 2 && strlen(RET_activityData) > (ACTIVITY_BUFFERSIZE-20)) { run_activity_tx = true; }
-            if (run_activity_tx) { event_activity_tx(RET_setting_activity_mode); }
+            if (run_activity_tx) { event_activity_tx(); }
+            
+            RET_busy = false;
             break;
         }
         case STATE_DORMANT :
@@ -833,29 +895,43 @@
         }
         case STATE_BUTTONPRESS1 :
         {
-            setState(STATE_NORMAL);
             if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"BUTTON PRESS 1\n");debug_exe();}
-            LED1blink(1,300);
-            break;
-        }
-        case STATE_BUTTONPRESS2 :
-        {
-            setState(STATE_NORMAL);
-            if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"BUTTON PRESS 2\n");debug_exe();}
-            LED1blink(3,300);
-            LED1on(0);
-            event_setup(true);
-            LED1off();
+            if (getBatteryV() < 2.5f) {
+                LED1blink(3,500);
+            } else if (selfTest() == false){
+                LED1blink(4,500);
+            } else {
+                if(RET_state_prev == STATE_DORMANT) {
+                    LED1on(500);
+                } else if (RET_state_prev == STATE_NORMAL) {
+                    LED1blink(2,500);
+                }
+            }
+            setState(RET_state_prev);
             break;
         }
         case STATE_BUTTONPRESS3 :
         {
-            setState(STATE_NORMAL);
-            if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"BUTTON PRESS 3\n");debug_exe();}
-            LED1blink(5,300);
-            LED1on(0);
-            event_location_tx();
-            LED1off();
+            if(RET_state_prev == STATE_DORMANT || RET_state_prev == STATE_NORMAL) {
+                if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"BUTTON PRESS 3\n");debug_exe();}
+                LED1blink(3,500);
+                LED1on(0);
+                event_setup(true);
+                LED1off();
+            }
+            setState(STATE_NORMAL); //turns device back on
+            break;
+        }
+        case STATE_BUTTONPRESS5 :
+        {
+            if(RET_state_prev == STATE_DORMANT || RET_state_prev == STATE_NORMAL) {
+                if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"BUTTON PRESS 5\n");debug_exe();}
+                LED1blink(5,500);
+                LED1on(0);
+                event_location_tx();
+                LED1off();
+            }
+            setState(STATE_NORMAL); //turns device back on
             break;  
         }
         case STATE_BUTTONHOLD :
@@ -881,7 +957,6 @@
         }
         case STATE_SCORCHEDEARTH :
         {
-            LED1blink(40,50);
             if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"SCORCHED EARTH - RESETTING");debug_exe();}
             setState(STATE_SETUP); //this wont be used but just incase to kick it out of this state
             read_app_data_from_flash(&app_data);
@@ -943,16 +1018,12 @@
     if (RET_coldBoot == 1) { 
         setDefaults(); 
         //check battery
-        float voltage = getBatteryV();
-        if (voltage > 2.5f) {
-            //battery ok
-            LED1errorCode(6,2);
-        } else {
+        if (getBatteryV() < 2.5f) {
             //battery low
             LED1errorCode(10,2);
+            addToExceptionString("BA");
         }
         addToExceptionString("FR");
-        mainthread.wait(2000);
     }
     
     //MAIN LOOP
@@ -967,7 +1038,13 @@
         GLOBAL_wakeTime = RET_RTCunixtime;
         
         //check and log motion
-        if (RET_state == STATE_NORMAL) { checkMotion(); }
+        if (RET_state == STATE_NORMAL || RET_state == STATE_SETUP) { 
+            if (checkMotion() == true) {
+                //if motionstate is true, then reset network and gps fail counts, so that they are not skipped
+                RET_NetworkFailCount = 0;
+                RET_GPSFailCount = 0;
+            }
+        }
         
         //MAIN LOGIC
         if(DEBUG_ON){
@@ -981,7 +1058,7 @@
         
         /*
         if (modem.on(RET_force2G)) {
-            if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
+            if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,RET_setting_connection_timeout,RET_NetworkFailCount)) {
                 modem.USSDsend("(b:gps2,a:act,e:1.7!0.15!,t:1547937626,r:0.13,c:1)\0",2);
             }
         }
--- a/main.h	Mon Jan 21 19:43:17 2019 +0000
+++ b/main.h	Tue Feb 05 14:30:57 2019 +0000
@@ -16,7 +16,8 @@
 //------------------------------------------------------------------------------
 //DEFINES
 //------------------------------------------------------------------------------ 
-#define FW_VERSION          2
+#define FW_VERSION          4
+//#define SKU                 "GPSPLUSDEV"
 #define SKU                 "GPSPLUS"
 #define HW_MAJORREVISION    "001"
 
@@ -25,20 +26,22 @@
 #define DEBUG_ON                            1
 
 //DEFAULT SETTINGS
-#define DEFAULT_SLEEP_FRAME                 30000
+#define DEFAULT_SLEEP_FRAME                 60000
 #define DEFAULT_FORCE2G                     true
-#define DEFAULT_LOCATION_MODE               2
-#define DEFAULT_LOCATION_ACCURACY           2  // 0 = no location, 1 = cl only, 2 = gps then cl
+#define DEFAULT_LOCATION_MODE               1
+#define DEFAULT_LOCATION_ACCURACY           1  // 0 = no location, 1 = cl only, 2 = gps then cl
 #define DEFAULT_LOCATION_TX_INTERVAL_MINS   1440
 #define DEFAULT_LOCATION_TX_FAILSAFE_HRS    168
-#define DEFAULT_LOCATION_TIMEOUT            180
-#define DEFAULT_MOTION_G                    10
+#define DEFAULT_LOCATION_TIMEOUT            120
+#define DEFAULT_MOTION_G                    7
 #define DEFAULT_MOTION_START_SECONDS        120
 #define DEFAULT_MOTION_STOP_SECONDS         120
 #define DEFAULT_IMPACT_G                    127
 #define DEFAULT_CONNECTION_ATTEMPTS         1
-#define DEFAULT_CONNECTION_TIMEOUT          180
+#define DEFAULT_CONNECTION_TIMEOUT          120
 #define DEFAULT_BEACON_INTERVAL_SECONDS     20
+#define DEFAULT_MAX_FAILED_CONNECTIONS      2 //max number of failed connections before device stops broadcasting until movement detected
+#define DEFAULT_MAX_FAILED_GPS              2 //max number of failed gps searches before device stops trying gps until movement detected
 
 //CONSTS
 #define ONEDAYINSECONDS                     86400
@@ -84,7 +87,6 @@
 //#define lowByte(w) ((uint8_t) ((w) & 0xff))
 //#define highByte(w) ((uint8_t) ((w) >> 8))
 
-
 //------------------------------------------------------------------------------
 //GLOBAL VARS
 //------------------------------------------------------------------------------ 
@@ -100,7 +102,7 @@
 extern time_t GLOBAL_RTCunixtime;
 extern time_t GLOBAL_wakeTime;
 extern char GLOBAL_debug_buffer[200];
-extern bool RET_force2G;
+extern uint8_t RTCtick_ledflash_count;
 //FUNCS
 extern void watchdogKick();
 
--- a/modem.cpp	Mon Jan 21 19:43:17 2019 +0000
+++ b/modem.cpp	Tue Feb 05 14:30:57 2019 +0000
@@ -170,23 +170,23 @@
     return modemModel;
 }
 
-bool Modem::registerOnNetwork(int maxAttempts, uint32_t timeout) 
+bool Modem::registerOnNetwork(int maxAttempts, uint32_t timeout, uint32_t &BYREF_NetworkFailCount) 
 {
     //CHECK WE ARE NOT ALREADY ON NETOWRK
     if (!GLOBAL_registeredOnNetwork) {
+        //if (GLOBAL_debugLED) LED1on(0);
         int attempt = 0;
         Timer t;
         t.start();
         //DISABLE AIRPLANE MODE
         _w_disable = 1;
-        NRFuart_flush();
         while (attempt < maxAttempts) {
             watchdogKick();
             t.reset();
-            uint32_t startmillis = t.read_ms();
+            uint32_t startseconds = t.read();
             uint32_t runtime = 0;
-            while(!GLOBAL_registeredOnNetwork && runtime < timeout) {
-                runtime = (t.read_ms() - startmillis);
+            while(GLOBAL_registeredOnNetwork == false && runtime < timeout) {
+                runtime = (t.read() - startseconds);
                 ThisThread::sleep_for(1000);
                 ATsendCMD("AT+CREG?");
                 if (ATwaitForWord("+CREG: 0,5",ATTIMEOUT_VERYSHORT)) {
@@ -194,19 +194,23 @@
                     GLOBAL_registeredOnNetwork = true;
                 };
             }
-            if (!GLOBAL_registeredOnNetwork) {
+            attempt ++;
+            //if there are more attempt potential, then reset the modem
+            if (GLOBAL_registeredOnNetwork == false && attempt < maxAttempts) {
                 off(false);
                 ThisThread::sleep_for(1000);
-                on(RET_force2G);
+                on(false);
             }
-            attempt ++;
         }
         t.stop();
+        //if (GLOBAL_debugLED) LED1off();
     }
     NRFuart_flush();
-    if (GLOBAL_registeredOnNetwork) {
+    if (GLOBAL_registeredOnNetwork == true) {
+        BYREF_NetworkFailCount = 0;
         return true;
     } else {
+        BYREF_NetworkFailCount ++;
         return false;   
     }
 }
@@ -297,9 +301,9 @@
     }
 }
 
-
-char* Modem::getLocation(uint8_t accuracy, uint16_t timeout_seconds) 
+char* Modem::getLocation(uint8_t accuracy, uint16_t timeout_seconds, uint32_t &BYREF_GPSFailCount, uint32_t &BYREF_NetworkFailCount) 
 { 
+    watchdogKick();
     NRFuart_flush();
     bool haveGPSFix = false;
     bool haveCellFix = false;
@@ -307,13 +311,13 @@
     memset(locDataOut,0x00,sizeof(locDataOut));
     Timer t;
     t.start();
-    uint32_t startmillis;
+    uint32_t startseconds;
     uint32_t runtime;
-        
-    if (accuracy >= 2) {
+    
+    if (accuracy >= 2 && BYREF_GPSFailCount <= DEFAULT_MAX_FAILED_GPS) {
         //Enable External LNA power - IS DISABLED BY DEFAULT
         ATsendCMD("AT+QGPSCFG=\"lnacontrol\",1");
-        ATwaitForWord("OK",5000);
+        ATwaitForWord("OK",ATTIMEOUT_SHORT);
         
         //TURN ON GPS
         ATsendCMD("AT+QGPS=1");
@@ -321,50 +325,48 @@
         
         //TRY UNTIL TIMEOUT
         uint8_t GPS_fixstage = 0;
-        uint8_t GPS_fixcount = 0;
-        startmillis = t.read_ms();
+        //uint8_t GPS_fixcount = 0;
+        startseconds = t.read();
         runtime = 0;
-        while(!haveGPSFix && runtime < (timeout_seconds*1000)) {
-            watchdogKick();
-            ThisThread::sleep_for(5000); //this goes first
-            runtime = (t.read_ms() - startmillis);
+        while(!haveGPSFix && runtime < timeout_seconds) {
+            ThisThread::sleep_for(3000); //this goes first
+            runtime = (t.read() - startseconds);
             ATsendCMD("AT+QGPSLOC=2");
             if (ATwaitForWord("+QGPSLOC: ",ATTIMEOUT_SHORT)) {
                 GPS_fixstage = 1;
-                GPS_fixcount ++;
-                if (GPS_fixcount == 2) { //wait 10 seconds to get a better fix // need to improve this logic
-                    haveGPSFix = true;
-                } else {
-                    NRFuart_flush();   
-                }
-            } else {
-                NRFuart_flush();  
+                haveGPSFix = true;
+            }
+        }
+        
+        //STAGE 1 FIX - NOW WAIT for 5 seconds to improve fix quality // need better solution
+        if (GPS_fixstage == 1) {
+            ThisThread::sleep_for(5000);
+            ATsendCMD("AT+QGPSLOC=2");
+            if (ATwaitForWord("+QGPSLOC: ",ATTIMEOUT_SHORT)) {
+                GPS_fixstage = 2;
             }
-            if (haveGPSFix) {
-                //+QGPSLOC: 233510.0,52.55415,1.24021,1.2,59.2,2,0.00,0.0,0.0,201218,05
-                int matchCount = 0;
-                float utc;
-                float lat;
-                float lng;
-                float hdp;
-                float alt;
-                uint8_t fix;
-                float cog;
-                float spkm;
-                float spkn;
-                uint32_t date;
-                uint8_t sat;
-                
-                //Example data
-                //115757.0,52.62091,1.29536,0.8,58.2,2,0.00,0.0,0.0,211218,07
-                if (ATgetResponse('\r',ATTIMEOUT_SHORT)) { 
-                    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”:“89.0",“spd”:“0.0"}                    
-                        sprintf(locDataOut,",g:(fix:GPS,sat:%d,lat:%.6f,lng:%.6f,hdp:%.1f,spd:%.1f)\0",sat,lat,lng,hdp,spkm);
-                    }
+        }
+        
+        //STAGE 2 FIX
+        if (GPS_fixstage == 2) {
+            int matchCount = 0;
+            float utc; float lat; float lng; float hdp; float alt; uint8_t fix; float cog; float spkm; float spkn; uint32_t date; uint8_t sat;
+            
+            //Example data
+            //+QGPSLOC: 233510.0,52.55415,1.24021,1.2,59.2,2,0.00,0.0,0.0,201218,05
+            //115757.0,52.62091,1.29536,0.8,58.2,2,0.00,0.0,0.0,211218,07
+            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”:“89.0",“spd”:“0.0"}                    
+                    sprintf(locDataOut,",g:(fix:GPS,sat:%d,lat:%.6f,lng:%.6f,hdp:%.1f,spd:%.1f)\0",sat,lat,lng,hdp,spkm);
+                    haveGPSFix = true;
+                    BYREF_GPSFailCount = 0; //reset
                 }
             }
+        } else {
+            BYREF_GPSFailCount ++;       
         }
+                
         //TURN OFF GPS
         ATsendCMD("AT+QGPSEND");
         ATwaitForWord("OK",ATTIMEOUT_SHORT);
@@ -372,48 +374,45 @@
     
     //SHALL WE GET CELL LOCATION
     if (!haveGPSFix && accuracy >= 1) {
-        registerOnNetwork(2, 90000);
-        int matchCount;
-        char type[6];
-        char cellID[6];
-        char lac[6];
-        int mcc;
-        int mnc;
-        
-        startmillis = t.read_ms();
-        runtime = 0;
-        while(!haveCellFix && runtime < 15000) {
-            runtime = (t.read_ms() - startmillis);
-            ATsendCMD("AT+QENG=\"servingcell\"");
-            if (ATwaitForWord("+QENG: \"servingcell\",\"NOCONN\",",ATTIMEOUT_VERYSHORT)) {
-                if (ATgetResponse('\r',ATTIMEOUT_SHORT)) {
-                    if ((matchCount = sscanf(ATinBuffer,"\"%[^\"]\",%d,%d,%[^,],%[^,]",&type,&mcc,&mnc,&lac,&cellID)) == 5 ) {
-                        sprintf(locDataOut,",h:%s.%s.%d.%d\0",cellID,lac,mcc,mnc);
-                        //sprintf(locDataOut,",h:41806.2252.234.30\0");
-                        haveCellFix = true;
+        uint16_t cellLocateTimeout = (timeout_seconds / 2); //half the GPS timeout seems like a good rule
+        if (registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,cellLocateTimeout,BYREF_NetworkFailCount)) {
+            int matchCount; char type[6]; char cellID[6]; char lac[6]; int mcc; int mnc;
+            t.reset();
+            startseconds = t.read();
+            runtime = 0;
+            while(haveCellFix == false && runtime < 20) {
+                runtime = (t.read() - startseconds);
+                ATsendCMD("AT+QENG=\"servingcell\"");
+                if (ATwaitForWord("+QENG: \"servingcell\",\"NOCONN\",",ATTIMEOUT_VERYSHORT)) {
+                    if (ATgetResponse('\r',ATTIMEOUT_SHORT)) {
+                        if ((matchCount = sscanf(ATinBuffer,"\"%[^\"]\",%d,%d,%[^,],%[^,]",&type,&mcc,&mnc,&lac,&cellID)) == 5 ) {
+                            sprintf(locDataOut,",h:%s.%s.%d.%d\0",cellID,lac,mcc,mnc);
+                            //sprintf(locDataOut,",h:41806.2252.234.30\0");
+                            haveCellFix = true;
+                        }
                     }
                 }
             }
+                    
+            //example from mulbs
+            /*
+            2g
+            +QENG: "servingcell","NOCONN","2G",234,30,8CC,A34E,20,668,0,-80,0,5,4,26,26,1,-,-,-,-,-,-,-,-,-,"-"
+            3g
+            +QENG: "servingcell","NOCONN","3G",234,20,8A,CE735F,10588,52,-97,-99,11,25,16,128,-,-,-,-,-,"-",-
+            +QENG: "neighbourcell","2G",234,30,8CC,A34D,20,656,-89,17,17,0,0
+            +QENG: "neighbourcell","2G",234,30,8CC,678,61,686,-104,2,2,0,0
+            +QENG: "neighbourcell","2G",234,30,8CC,4303,32,676,-104,2,2,0,0
+            +QENG: "neighbourcell","2G",234,30,8CC,B2B2,16,692,-107,-1,-1,0,0
+            https://www.neilson.co.za/mobile-network-geolocation-obtaining-the-cell-ids-the-signal-strength-of-surrounding-towers-from-a-gsm-modem/
+            */
+            //ATsendCMD("AT+QENG=\"neighbourcell\"");
+            //ATwaitForWord("OK",ATTIMEOUT_LONG);
         }
-                
-        //example from mulbs
-        /*
-        2g
-        +QENG: "servingcell","NOCONN","2G",234,30,8CC,A34E,20,668,0,-80,0,5,4,26,26,1,-,-,-,-,-,-,-,-,-,"-"
-        3g
-        +QENG: "servingcell","NOCONN","3G",234,20,8A,CE735F,10588,52,-97,-99,11,25,16,128,-,-,-,-,-,"-",-
-        
-        +QENG: "neighbourcell","2G",234,30,8CC,A34D,20,656,-89,17,17,0,0
-        +QENG: "neighbourcell","2G",234,30,8CC,678,61,686,-104,2,2,0,0
-        +QENG: "neighbourcell","2G",234,30,8CC,4303,32,676,-104,2,2,0,0
-        +QENG: "neighbourcell","2G",234,30,8CC,B2B2,16,692,-107,-1,-1,0,0
-        https://www.neilson.co.za/mobile-network-geolocation-obtaining-the-cell-ids-the-signal-strength-of-surrounding-towers-from-a-gsm-modem/
-        */
-        
-        //ATsendCMD("AT+QENG=\"neighbourcell\"");
-        //ATwaitForWord("OK",ATTIMEOUT_LONG);
     }
     
+    t.stop();
+    
     //RETURN
     if (accuracy == 0) {
         sprintf(locDataOut,"\0");
--- a/modem.h	Mon Jan 21 19:43:17 2019 +0000
+++ b/modem.h	Tue Feb 05 14:30:57 2019 +0000
@@ -24,11 +24,11 @@
             void off(bool soft);
              
             //funcs
-            bool registerOnNetwork(int maxAttempts, uint32_t timeout);
+            bool registerOnNetwork(int maxAttempts, uint32_t timeout, uint32_t &BYREF_NetworkFailCount);
             bool USSDsend(char* message, int maxAttempts);
             char* USSDreceive(int messageIndex);
             char* USSDmessage(char* message, bool needResponse, int maxAttempts, char* api);
-            char* getLocation(uint8_t accuracy, uint16_t timeout_seconds); //accuracy is 1,2,3   low, med, high
+            char* getLocation(uint8_t accuracy, uint16_t timeout_seconds, uint32_t &BYREF_GPSFailCount, uint32_t &BYREF_NetworkFailCount); //accuracy is 1,2
             long long getIMEI(void);
             char* getModemModel(void);
             
--- a/states.h	Mon Jan 21 19:43:17 2019 +0000
+++ b/states.h	Tue Feb 05 14:30:57 2019 +0000
@@ -2,7 +2,7 @@
 #define STATE_NORMAL             1
 #define STATE_DORMANT            99
 #define STATE_BUTTONPRESS1       81
-#define STATE_BUTTONPRESS2       82
-#define STATE_BUTTONPRESS3       83
+#define STATE_BUTTONPRESS3       82
+#define STATE_BUTTONPRESS5       83
 #define STATE_BUTTONHOLD         89
 #define STATE_SCORCHEDEARTH      90
\ No newline at end of file