The HexiHeart is a demo project product that takes advantage of many of the onboard Hexiwear sensors and capabilities to create a multifunctional fitness and safety watch.

Dependencies:   FXAS21002 FXOS8700 Hexi_KW40Z Hexi_OLED_SSD1351 MAXIM W25Q64FVSSIG HTU21D MPL3115A2 TSL2561

Fork of HexiHeart_Alex by Hexiwear_zeta

Files at this revision

API Documentation at this revision

Comitter:
nbaker
Date:
Mon Mar 26 00:29:18 2018 +0000
Parent:
9:d2e39ee9fedd
Child:
11:ccda4d44bd8e
Commit message:
Added final fall mode (full sequential fall algorithm), including alert screen and dismiss alert screen. Added FAP (Fall Alert Protection) to main screen. fixed "aggressive Haptic" problem by using a Ticker to turn off Haptic instead of RTOS.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Tue Mar 06 00:22:47 2018 +0000
+++ b/main.cpp	Mon Mar 26 00:29:18 2018 +0000
@@ -13,6 +13,10 @@
 Function and interupt routines
 Display data screen update routines
 
+v2.09 - Added final fall mode (full sequential fall algorithm), including alert screen 
+and dismiss alert screen.  Added FAP (Fall Alert Protection) to main screen. fixed "aggressive Haptic" problem by using a Ticker to 
+turn off Haptic instead of RTOS timer.
+
 v2.08 - Fixed impact detect functionality, all fall detect parameters are now adjustable, 
 added motion detect function, incorporated new heat index calc, increased font by 20% for time/date. 
 Added SW and power resetting to initialize sensors in known state.
@@ -46,7 +50,7 @@
 
 
 // Definitions
-#define SW_Ver          2.08    // For displaying software version
+#define SW_Ver          2.09    // For displaying software version
 #define LED_ON          0
 #define LED_OFF         1
 #define SCRN_TIME       10.0
@@ -64,6 +68,7 @@
 //#define MPL3115A2_I2C_ADDRESS_  ? // 
 
 void StartHaptic(void);
+void Haptic_Off_(void); // added by NRB
 void StartHaptic(int x);
 void StopHaptic(void const *n);
 void error_screen(void);  // display error screen 
@@ -85,17 +90,26 @@
 void Disable_Heart_Rate();
 void Led_Zone_Indicator();
 void Heat_Index_Calculation();
-void fall_config(uint8_t); 
-void gyro_sensor_config(uint8_t);
+void fall_config(uint8_t);         //function call to setup fall detecting modes
+void accel_sensor_config(uint8_t); 
+void gyro_sensor_config(uint8_t); 
 void light_config(uint8_t); 
 void press_config(uint8_t); 
-void fall_detect(void);
-void fall_det_end(void);
-void fall_detect_off(void);
-void impact_detect(void);
-void motion_detect();
+void fall_detect(void);         // Interupt routine
+void fall_detect_debug(void);   // Interupt routine
+void fall_det_end(void);        // Interupt routine
+void fall_det_end_debug(void);  // Interupt routine
+void chkfall(void);             // Routine used with Ticker 
+void interupt_off(void);
+void clear_fall(void);          // Routine used with Ticker
+void impact_detect(void);       // Interupt routine
+void impact_detect_debug(void); // Interupt routine
+void motion_detect();           // Interupt routine
+void motion_detect_debug();     // Interupt routine
+void chkmotion(void);           // Routine used with Ticker
+void chk_help_needed(void);      // Routine used with Ticker
 void MAX30101_test_config(uint8_t);
-
+void Send_Alert(uint8_t);    // fuction to store and send alert
 
 // *****************  Global variables  ***********************
 char text_1[20];            // Text buffer - Do we need more?
@@ -108,18 +122,21 @@
 bool OLED_ON = 1;           // Turn OLED power on/off
 bool Fall_Alert = 1;        // Initialize as no active alert
 bool Panic_Alert = 0;       // Initialize as no active alert
-uint8_t Fall_Alert_Mode = 4;   // Initialize with fall alert mode on
+uint8_t Fall_Alert_Mode = 5;   // Initialize with fall alert mode on
 bool Heart_Rate_Mode = 0;   // Initialize with Heart rate off
 float Accel_Mag=0.0;        // Vector magnitude calculated from sensor data
 float Accel_Data[3];        // Accel Data from sensor
 float Accel_Data_Event[3];  // Accel Data from sensor at interupt
+float Fall_Event_Data[7];   // Fall event Data ff-value, ff-time, impact-value, 4byte timestamp
 float Gyro_Mag=0.0;         // Vector magnitude calculated from sensor data
-float Gyro_Data[3];         // Gyro data from sensor
-float Fall_Thresh=0.5;      // Initialize Fall detect Threshold
-float Impact_Thresh=3.0;    // Initialize Impact detect Threshold
-float Movement_Thresh=50.0; // Initialize Movement detect Threshold
+float Gyro_Data[3];             // Gyro data from sensor
+float Fall_Thresh=0.5;          // Initialize Free-Fall detect Threshold as being <= 0.5g
+float Fall_Impact_Max_Wait_Time=2.0;// maximum wait time from end of fall detect to impact detect 
+float Impact_Thresh=3.0;        // Initialize Impact detect Threshold
+float Movement_Thresh=50.0;     // Initialize Movement detect Threshold
 float Min_Movement_Time=5.0;    // Initialize Movement minimum movement time to 5 sec
 float Min_Movement_duration=60.0;    // Initialize Movement min-movement testing duration to 60 sec
+float Do_You_Need_Help_Time=10.0; // Time to dismiss "Do you need Help" screen
 uint8_t Current_Zone = 1;
 uint8_t Prev_Zone = 1;
 uint8_t Heart_Rate = 100;
@@ -203,6 +220,10 @@
 
 //***************** Tickers and Timers *****************
 Ticker Screen_Timer;// use ticker to turn off OLED
+Timer f_time; // Timer used to measure fall 
+Ticker chk_fall; // Ticker used to check on active fall
+Ticker chk_motion; // Ticker used to check on post fall motion
+Ticker Haptic_Timer;
 
 void timout_timer(){ // turn off display mode
 #ifdef Debug    // in debug keep screens on for demo  
@@ -272,6 +293,9 @@
             case 6: {// Panic Alert
                 StartHaptic();
                 Panic_Alert = !Panic_Alert;
+                if(Panic_Alert == 1){
+                Send_Alert(0); // send/store alert type zero
+                }//endif
                 update_display();
                 break;
             }
@@ -373,19 +397,19 @@
                 break;
             }
             
-            case 41: {//Fall mode 0,1,2,3,4
-            // 0=nothing, 1=fall_only, 2=impact only, 3=motion_only, 4=all
+            case 41: {//Fall mode 0,1,2,3,4,5
+            // 0=nothing, 1=fall_only, 2=impact only, 3=motion_only, 4=all, 5=main sequence
                 StartHaptic();
                 Fall_Alert_Mode++;
-                if(Fall_Alert_Mode > 4){
+                if(Fall_Alert_Mode > 5){
                 Fall_Alert_Mode = 0;
                 }//endif
                 update_display();
                 __disable_irq();    // Disable all Interrupts
                 fall_config(10);  // reset accel sensor
-                gyro_sensor_config(10);  // reset gyro sensor  
+                //gyro_sensor_config(10);  // reset gyro sensor  
                 wait(0.1);
-                gyro_sensor_config(Fall_Alert_Mode);  // leave gyro sensor active
+                //gyro_sensor_config(Fall_Alert_Mode);  // leave gyro sensor active
                 fall_config(Fall_Alert_Mode);
                 wait(0.1);
                 __enable_irq();     // Enable all Interrupts
@@ -608,19 +632,19 @@
                 update_display();
                 break;
             }
-            case 41: {//Fall mode 0,1,2,3
-            // 0=nothing, 1=fall_only, 2=impact only, 3=motion_only, 4=all
+            case 41: {//Fall mode 0,1,2,3,4,5
+            // 0=nothing, 1=fall_only, 2=impact only, 3=motion_only, 4=all, 5=main sequence
                 StartHaptic();
                 Fall_Alert_Mode--;
-                if(Fall_Alert_Mode > 3){// should be 0xff if decr from zero
-                Fall_Alert_Mode = 3;
+                if(Fall_Alert_Mode > 5){// should be 0xff if decr from zero
+                Fall_Alert_Mode = 5;
                 }  //endif
                 update_display();
                 __disable_irq();    // Disable all Interrupts
                 fall_config(10);  // reset accel sensor
-                gyro_sensor_config(10);  // reset gyro sensor  
+                //gyro_sensor_config(10);  // reset gyro sensor  
                 wait(0.1);
-                gyro_sensor_config(Fall_Alert_Mode);  // leave gyro sensor active
+                //gyro_sensor_config(Fall_Alert_Mode);  // leave gyro sensor active
                 fall_config(Fall_Alert_Mode);
                 wait(0.1);
                 __enable_irq();     // Enable all Interrupts
@@ -715,12 +739,13 @@
             case 2: {// Fall Alert option
                 StartHaptic();
                 if(Fall_Alert == 1){
-                    Accel_INT1.fall(&fall_detect_off); // turn off Accel sensor's int#1 calls interupt routine
                     Fall_Alert = 0;
+                    fall_config(0); // configure sensors for standby
                     }
                 else{     
-                    Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
+                    //Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
                     Fall_Alert = 1;
+                    fall_config(Fall_Alert_Mode); // configure sensors for current fall mode
                     }
                 update_display();
                 break;
@@ -842,7 +867,13 @@
                     //do nothing for now
                 break;
             }         
-            
+            case 47: {// Fall-Detected screen "are you ok?"
+                StartHaptic();
+                Send_Alert(1); // send/store alert type one
+                Screen_Num = 48;  //Change to screen 48 (send alert screen)
+                update_display();
+                break;
+            }     
              case 71: {// BLE
                 StartHaptic();
                 Screen_Num = 72;  //Change to screen 72
@@ -1054,7 +1085,24 @@
                 Screen_Num = 45;  //Change to screen 45
                 update_display();
                 break;
-            }             
+            }         
+            case 47: {// Fall-detected screen
+                StartHaptic();
+                Led_clk1 = 0;  // Turn off LED1, on docking station
+                Led_clk2 = 0;  // Turn off LED2, on docking station
+                Screen_Num = 0;  //Change to screen 0
+                update_display();
+                break;
+            }      
+            case 48: {// Sending Fall-Alert screen
+                StartHaptic();
+                Led_clk1 = 0;  // Turn off LED1, on docking station
+                Led_clk2 = 0;  // Turn off LED2, on docking station
+                // stop/dismiss alert
+                Screen_Num = 0;  //Change to screen 0
+                update_display();
+                break;
+            }       
                           
              case 71: {// BLE
                 StartHaptic();
@@ -1094,8 +1142,9 @@
 {
 //   set_time(1256729737);  // Set RTC time to Wed, 28 Oct 2009 11:35:37
  //  set_time((Year-1970)*365*24*3600+(days of this year)*24*3600+(hr)*3600 + (min)*60 + (Sec) - fudge factor);  // Set RTC time to Mon, 19 Feb 2018 10:00
-  // set_time(48*365*24*3600 + 61*24*3600 + 10*3600-4);  // Set RTC time to Mon, 19 Feb 2018 10:00
-    set_time((2018-1970)*365.25f*24*3600 + (31+28+1-1)*24*3600 + (16)*3600 + (5)*60+ (1) + 38);  // Set RTC time
+  //set_time(48*365*24*3600 + 61*24*3600 + 10*3600-4);  // Set RTC time to Mon, 19 Feb 2018 10:00
+   //set_time((2018-1970)*365.25f*24*3600 + (31+28+1-1)*24*3600 + (16)*3600 + (5)*60+ (1) + 38);  // Set RTC time to 3/01/2018 16:04:20
+    set_time((2018-1970)*365.25f*24*3600 + (31+28+26-1)*24*3600 + (10)*3600 + (0)*60+ (0) + 28);  // Set RTC time to 3/26/2018 10:00:00
     RED_Led = LED_OFF;
     GRN_Led = LED_OFF;
     BLU_Led = LED_OFF;
@@ -1115,8 +1164,8 @@
     wait(0.2);      // how long should we wait for sensors to power up?
         
     oled.FillScreen(COLOR_BLACK); // Clear screen 
-    fall_config(10);            // SW reset accell sensor 
-    gyro_sensor_config(10);     // SW reset gyro sensor 
+    fall_config(10);            // SW reset accell and gyro sensor 
+ //   gyro_sensor_config(10);     // SW reset gyro sensor 
     press_config(0);            // put pressure sensor into 2uA standby, we're not using it
     MAX30101_test_config(10);   // SW reset accell sensor 
     oled.FillScreen(COLOR_BLACK); // Clear screen 
@@ -1127,14 +1176,14 @@
  
 // **************  configure sensor modules  ******************
 
-//    accel.accel_config();   // original configure accel sensor  
+    //accel.accel_config();   // original configure accel sensor  
     fall_config(Fall_Alert_Mode); // configure sensor (I2C1) for current fall mode
-    //Fall_Alert_Mode: 0=none, 1=fall_only, 2=impact only, 3=motion_only, 4=all
-//   gyro.gyro_config();    // original configure gyro sensor
-    gyro_sensor_config(Fall_Alert_Mode);  // configure gyro sensor (I2C1) 0=standby, 1=active, 2=interupt set up
-//    mag.mag_config();     // we don't need mag 
-//    light_config(0);      // config TSL2561 ambient light sensor (I2C0) for lowest power - cycling PowerEn should have reset it to state
-//    Configure HTU21(Temp/Hum)? No need, it seems to draw 0.02uA when not being activly read over data bus
+    //Fall_Alert_Mode: 0=none, 1=fall_only, 2=impact only, 3=motion_only, 4=all three, 5=full sequencial
+    //gyro.gyro_config();    // original configure gyro sensor
+    //gyro_sensor_config(Fall_Alert_Mode);  // configure gyro sensor (I2C1) 0=standby, 1=active, 2=interupt set up (now setup in fall_config())
+    //mag.mag_config();     // we don't need mag 
+    //light_config(0);      // config TSL2561 ambient light sensor (I2C0) for lowest power - cycling PowerEn should have reset it to state
+    //Configure HTU21(Temp/Hum)? No need, it seems to draw 0.02uA when not being activly read over data bus
 
 //   need to configure MAX30101 at some point
    // MAX30101_test_config(0);
@@ -1148,11 +1197,11 @@
  //   kw40z_device.attach_buttonSlide(&ButtonSlide);
 
 // ***** attaching interupts to functions *********
-    Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
-    Accel_INT2.fall(&impact_detect); //Accel sensor's int#2 calls interupt routine
-    Gyro_INT1.fall(&motion_detect); // Gyro sensor's int#1 (PTD1) calls interupt routine
-    //Gyro_INT2.fall(&motion_detect); // Gyro sensor's int#2 (PTC18) calls interupt routine
-    //HR_INT1.fall(&some_HR_read_function_yet_to_be_named); // MAX30101 - Heart rate sensor's interupt
+    //Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 (PTC1) calls interupt routine (now setup in fall_config())
+    //Accel_INT2.fall(&impact_detect); //Accel sensor's int#2 (PTD13) calls interupt routine(now setup in fall_config())
+    //Gyro_INT1.fall(&motion_detect); // Gyro sensor's int#1 (PTD1) calls interupt routine (now setup in fall_config())
+    //Gyro_INT2.fall(&motion_detect); // Gyro sensor's int#2 (PTC18) calls interupt routine (not used)
+    //HR_INT1.fall(&some_HR_read_function_yet_to_be_named); // MAX30101 - Heart rate sensor's interupt (PTB18)
 
 // **** Get OLED Class Default Text Properties ****************
     oled_text_properties_t textProperties = {0};
@@ -1264,6 +1313,21 @@
             oled.Label((uint8_t *)"BT",40,80);  //Display "BT" at x,y
             textProperties.fontColor = COLOR_WHITE;
             oled.SetTextProperties(&textProperties);  
+            
+            textProperties.fontColor = COLOR_GRAY;
+            if(Fall_Alert == 1){
+                textProperties.fontColor = COLOR_GREEN; // is Fall protection on?
+            }
+            if(Fall_Alert == 1 && Led_clk1 == 1){
+                textProperties.fontColor = COLOR_YELLOW; // is Fall detected? 
+            }       
+            if(Fall_Alert == 1 && Led_clk1 == 1 && Led_clk2 == 1){
+                textProperties.fontColor = COLOR_RED; // is impact detected? 
+            }       
+            oled.SetTextProperties(&textProperties); 
+            oled.Label((uint8_t *)"FAP",1,0);  //Display "FAP" at x,y
+            textProperties.fontColor = COLOR_WHITE;
+            oled.SetTextProperties(&textProperties);
            
 // added real time and date information            
             char buffer[32];
@@ -1306,16 +1370,17 @@
             oled.FillScreen(COLOR_BLACK); // Clear screen
             oled.Label((uint8_t *)"Fall Alert",20,5); // Display at x,y
             oled.Label((uint8_t *)"Protection",15,20);  
+            oled.Label((uint8_t *)"FAP",15,40); 
             if (Fall_Alert == 1){  
            
             textProperties.fontColor = COLOR_GREEN; 
             oled.SetTextProperties(&textProperties);
-            oled.Label((uint8_t *)" On ",32,40);   
+            oled.Label((uint8_t *)" On ",42,40);   
             }
             else {               
             textProperties.fontColor = COLOR_GRAY;
             oled.SetTextProperties(&textProperties);
-            oled.Label((uint8_t *)" Off ",30,40);  
+            oled.Label((uint8_t *)" Off ",40,40);  
         
                 } 
             textProperties.fontColor = COLOR_WHITE; 
@@ -1531,23 +1596,23 @@
             textProperties.fontColor = COLOR_GREEN;
             oled.SetTextProperties(&textProperties);
             sprintf(text_1," %i ",Fall_Alert_Mode);
-            oled.Label((uint8_t *)text_1,35,20);// text_1 at x,y
+            oled.Label((uint8_t *)text_1,36,20);// text_1 at x,y
             textProperties.fontColor = COLOR_GRAY;
-            if(Fall_Alert_Mode == 1 || Fall_Alert_Mode == 4){
+            if(Fall_Alert_Mode == 1 || Fall_Alert_Mode >= 4){
                 textProperties.fontColor = COLOR_GREEN;
             }
             oled.SetTextProperties(&textProperties);
             sprintf(text_1," %1.2f g  ",Fall_Thresh);
             oled.Label((uint8_t *)text_1,35,35);// text_1 at x,y
             textProperties.fontColor = COLOR_GRAY;
-            if(Fall_Alert_Mode == 2 || Fall_Alert_Mode == 4){
+            if(Fall_Alert_Mode == 2 || Fall_Alert_Mode >= 4){
                 textProperties.fontColor = COLOR_GREEN;
             }
             oled.SetTextProperties(&textProperties);
             sprintf(text_1," %2.2f g  ",Impact_Thresh);
             oled.Label((uint8_t *)text_1,35,50);// text_1 at x,y
             textProperties.fontColor = COLOR_GRAY;
-            if(Fall_Alert_Mode == 3 || Fall_Alert_Mode == 4){
+            if(Fall_Alert_Mode == 3 || Fall_Alert_Mode >= 4){
                 textProperties.fontColor = COLOR_GREEN;
             }
             oled.SetTextProperties(&textProperties);
@@ -2016,6 +2081,44 @@
             oled.SetTextProperties(&textProperties);
             break;
         }//end case 46   
+        
+        case 47: { //Post fall "are you OK?" screen
+            oled.FillScreen(COLOR_BLACK);
+            textProperties.fontColor = COLOR_RED;
+            oled.SetTextProperties(&textProperties);
+            oled.Label((uint8_t *)"Fall Detected!", 5, 5);
+            textProperties.font = OpenSans_12x18_Regular;  //  Max Width of Character  = 12px, Max Height of Character = 18px 
+            textProperties.fontColor = COLOR_WHITE;
+            oled.SetTextProperties(&textProperties); 
+            oled.Label((uint8_t *)"Do you need", 5, 20);
+            oled.Label((uint8_t *)"Help?", 10, 35);
+            //oled.Label((uint8_t *)"+",85,15); // "*" at x,y
+            //oled.Label((uint8_t *)"-",85,60); // "*" at x,y
+            oled.Label((uint8_t *)"No",10,75); // Display "Back" at x,y
+            oled.Label((uint8_t *)"YES!",60,75);  //Display "Next" at x,y
+            textProperties.font = OpenSans_10x15_Regular;  //  Max Width of Character  = 10px, Max Height of Character = 15px 
+            textProperties.fontColor = COLOR_WHITE;
+            oled.SetTextProperties(&textProperties);
+            break;
+        }//end case 47   
+        
+        case 48: { //Sending Fall alert screen
+            oled.FillScreen(COLOR_BLACK);
+            textProperties.fontColor = COLOR_RED;
+            oled.SetTextProperties(&textProperties);
+            oled.Label((uint8_t *)"Fall Detected!", 5, 5);
+            textProperties.font = OpenSans_12x18_Regular;  //  Max Width of Character  = 12px, Max Height of Character = 18px 
+            textProperties.fontColor = COLOR_WHITE;
+            oled.SetTextProperties(&textProperties); 
+            oled.Label((uint8_t *)"Sending", 20, 40);
+            oled.Label((uint8_t *)"Alert", 25, 55);
+            oled.Label((uint8_t *)"Dismiss?",5,75); // Display "Back" at x,y
+            //oled.Label((uint8_t *)"YES!",60,80);  //Display "Next" at x,y
+            textProperties.font = OpenSans_10x15_Regular;  //  Max Width of Character  = 10px, Max Height of Character = 15px 
+            textProperties.fontColor = COLOR_WHITE;
+            oled.SetTextProperties(&textProperties);
+            break;
+        }//end case 48
 
 #endif  // end of non-production/debug version code
 
@@ -2083,12 +2186,17 @@
 ******************************************************************************/
 void StartHaptic(void)
 {
-    hapticTimer.start(30);  // was originaly 50, then 30 
+    Haptic_Timer.attach(&Haptic_Off_,(0.05));
+   // hapticTimer.start(30);  // was originaly 50, then 30 
     /* this 30 value seems to not work after Neil added a global 
     __disable_irq() and __enable_irq() for the update_display() functions on 2/18/18
     */
     haptic = 1;
 }
+void Haptic_Off_(void)
+{
+    haptic = 0;
+    }
 
 /*****************************************************************************
 Name: StartHaptic
@@ -2465,12 +2573,12 @@
 }
 
 /*****************************************************************************
-Name: fall_detect()
-Purpose: Interupt rutine called when accelerometer IC has detected a free-fall >= 0.5g
-
+Name: fall_detect_debug()
+Purpose: Debug Interupt routine called when accelerometer IC has detected a 
+free-fall (accel <= 0.5g)
+Inputs: interupt1 of accel sensor
 ******************************************************************************/
-
-void fall_detect(){// fall detect interupt rutine
+void fall_detect_debug(){// fall detect interupt routine
 if(Fall_Alert == 1){
  accel.acquire_accel_data_g(Accel_Data_Event);
 // for now just turn on display and give haptic feedback
@@ -2493,39 +2601,40 @@
     oled.Label((uint8_t *)text_1,2,5);// text_1 at x,y
 
     BLU_Led = LED_ON;  // LEDs default to on, need to turn off
-    Led_clk2 = 1;  // Turn LED2 on docking station on
-    haptic = 1;
-    Accel_INT1.rise(&fall_det_end); // Accel sensor's int#1 calls interupt routine
+    Led_clk1 = 1;  // Turn on LED1, on docking station
+    StartHaptic();
+ //   haptic = 1;
+    Accel_INT1.rise(&fall_det_end_debug); // reset accel sensor's int#1 to active high and proper int routine
 //__enable_irq();     // Enable all Interrupts
 }// end if     
-}//end fall_detect interupt routine
-
+}//end fall_detect_debug interupt routine
 
-void fall_detect_off(){// fall detect interupt rutine
-// for now just turn on display and give haptic feedback
-}//end fall_detect_off interupt routine
-  
-void fall_det_end(){
+/*****************************************************************************
+Name: fall_det_end_debug()
+Purpose: Debug interupt routine called when accelerometer IC has detected that the 
+free-fall acceleration has ended (accel now >0.5g)
+Inputs: interupt1 of accel sensor
+******************************************************************************/
+void fall_det_end_debug(){
     haptic = 0;         // Turn off Haptic
     BLU_Led = LED_OFF;  // Turn off HexiHeart Blue LED
-    Led_clk2 = 0;       // Turn off LED2 on docking station on
+    Led_clk1 = 0;       // Turn off LED1, on docking station
     fall_config(21);    // reads interrupts to clear old interupt
  //   oled.Label((uint8_t *)"                         ",05,70); // clear display at x,y
-    Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
-}    //end fall_det_end interupt routine
+    Accel_INT1.fall(&fall_detect_debug); // reset accel sensor's int#1 to active low and proper int routine
+}    //end fall_det_end_debug interupt routine
 
 /*****************************************************************************
-Name: impact_detect()
-Purpose: Interupt rutine called when accelerometer IC has detected a vector
+Name: impact_detect_debug()
+Purpose: Debug Interupt routine called when accelerometer IC has detected a vector
 magnitude acceleration >= 3.0g
-
+Inputs: interupt2 of accel sensor
 ******************************************************************************/
-      
-void impact_detect(){
+void impact_detect_debug(){
  if(Fall_Alert == 1){
     accel.acquire_accel_data_g(Accel_Data_Event);
     haptic = 1;
-    Led_clk3 = 1;  // Turn LED2 on docking station on
+    Led_clk2 = 1;  // Turn LED2 on docking station on
 
     Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED
         if (OLED_ON == 0) {
@@ -2542,23 +2651,24 @@
         sprintf(text_1,"Impact:%2.2fg",Accel_Mag);
         oled.Label((uint8_t *)text_1,3,20);// text_1 at x,y
         wait(0.1);
-        Led_clk3 = 0;  // Turn LED2 off docking station on
+        Led_clk2 = 0;  // Turn LED2 off docking station on
         haptic = 0;
  }// end if     
-}//end impact_detect interupt routine
+}//end impact_detect_debug interupt routine
 
 /*****************************************************************************
-Name: motion_detect()
-Purpose: Interupt rutine called when gyro IC has detected motion >= 50 deg/sec
+Name: motion_detect_debug()
+Purpose: Debug Interupt routine called when gyro IC has detected motion >= 50 deg/sec
 in order to see if fall-impact resulted in motion-less person.
+Inputs: interupt1 of gyro sensor
 ******************************************************************************/
-void motion_detect(){
+void motion_detect_debug(){
  float Gyro_Data_Event[3]; // store right away to see what it was
  if(Fall_Alert == 1 && Fall_Alert_Mode > 2){// only service interupt if automatic fall detect is selected by user
     gyro.acquire_gyro_data_dps(Gyro_Data_Event);
     Gyro_Mag = (abs(Gyro_Data_Event[0])+abs(Gyro_Data_Event[1])+abs(Gyro_Data_Event[2]));
     haptic = 1;
-    Led_clk1 = 1;  // Turn LED1 on docking station on
+    Led_clk3 = 1;  // Turn on LED3, on docking station
 
     Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED
         if (OLED_ON == 0) {
@@ -2572,21 +2682,374 @@
         }  // endif         
         sprintf(text_1,"Motion:%4.0f d/s",Gyro_Mag);
         oled.Label((uint8_t *)text_1,3,20);// text_1 at x,y
+        gyro_sensor_config(13); // reset motion counter
         wait(0.1);
-        Led_clk1 = 0;  // Turn LED1 off docking station on
+        Led_clk3 = 0;  // Turn LED3 off docking station on
         haptic = 0;
  }// end if     
+}//end motion_detect_debug interupt routine
+
+//********** Full sequential fall interup routines below *********************
+/*****************************************************************************
+Name: fall_detect()
+Purpose: Interupt routine called when accelerometer IC has detected a 
+free-fall (accel <= 0.5g)
+Inputs: interupt1 of accel sensor
+******************************************************************************/
+void fall_detect(){// fall detect interupt routine
+if(Fall_Alert == 1 && Led_clk2 == 0){// are we looking for falls? Have we already det impact?
+ accel.acquire_accel_data_g(Accel_Data_Event);
+    f_time.reset(); 
+    f_time.start(); //start measuring fall time
+    for (int i=0; i<7; i++){
+        Fall_Event_Data[i] = 0; // clear any old information
+    }//end for loop
+
+//    Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED
+    //time_t seconds = time(NULL);
+    //store time into Fall_Event_Data buffer
+    Fall_Event_Data[0] = 2*sqrt(((Accel_Data_Event[0]*Accel_Data_Event[0])+(Accel_Data_Event[1]*Accel_Data_Event[1])+(Accel_Data_Event[2]*Accel_Data_Event[2])));
+    Led_clk1 = 1;  // Turn on LED1, on docking station
+    //Led_clk2 = 0;  // Turn off LED2, on docking station
+    Accel_INT1.rise(&fall_det_end); // look for end of fall by reseting accel sensor's int#1 to active high
+ //   Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
+    Accel_INT2.fall(&impact_detect); //Start looking for vector impacts
+ //   Gyro_INT1.fall(&motion_detect); // Gyro sensor's int#1 (PTD1) calls interupt routine
+    chk_fall.attach(&chkfall,(0.5)); //initialize ticker to check for end of fall every half second
+ 
+}// end if     
+}//end fall_detect interupt routine
+
+
+/*****************************************************************************
+Name: chkfall()
+Purpose: Ticker interupt routine called every 0.5 Seconds (after a free-fall has been detected)
+to check to see if we've missed the interupt indicating the free-fall event is over.
+Inputs: chk_fall Ticker
+******************************************************************************/
+void chkfall(){// Ticker fall-end detect routine to see if we missed interupt
+    if(Accel_INT1 == 0){//fall still active
+        accel.acquire_accel_data_g(Accel_Data_Event);
+        Accel_Mag = 2*sqrt(((Accel_Data_Event[0]*Accel_Data_Event[0])+(Accel_Data_Event[1]*Accel_Data_Event[1])+(Accel_Data_Event[2]*Accel_Data_Event[2])));
+        if (Accel_Mag < Fall_Event_Data[0]){
+            Fall_Event_Data[0] = Accel_Mag;// if fall is less than previous re-store value
+        }//endif  
+    }//endif
+    else{//fall interupt off
+        f_time.stop(); // stop fall timer
+        chk_fall.detach(); //stop ticker, interupt caught end of fall
+        chk_fall.attach(&clear_fall,(2.0)); //initialize ticker to check no impact in 2 seconds
+        Accel_INT1.fall(NULL); // turn off accel sensor's int#1
+    }//end else
+    
+}//end chkfall ticker interupt routine
+
+/*****************************************************************************
+Name: interupt_off()
+Purpose: Interupts are supposed to be turned off by using "Int_name.fall(NULL);", but
+that doesn't seem to work. 
+******************************************************************************/
+void interupt_off(){// turn off an interupt by substituting this one
+// Do nothing 
+}//end interupt_off  routine
+
+
+/*****************************************************************************
+Name: fall_det_end()
+Purpose: Interupt routine called when accelerometer IC has detected that the 
+free-fall acceleration has ended (accel now >0.5g)
+Inputs: interupt1 of accel sensor
+******************************************************************************/
+void fall_det_end(){    // accel detected end of free-fall
+    f_time.stop();      // stop fall timer
+    chk_fall.detach();  //stop ticker, interupt caught end of fall
+    chk_fall.attach(&clear_fall,(Fall_Impact_Max_Wait_Time)); //initialize ticker to check no impact in 2 seconds
+   // fall_config(21);    // reads interrupts to clear old interupt
+    Accel_INT1.fall(NULL); // Turn off accel sensor's int#1 
+}    //end fall_det_end interupt routine
+
+
+/*****************************************************************************
+Name: clear_fall()
+Purpose: Ticker interupt routine called to clear/cancel fall detection routine if 
+no impact was detected withing 2.0 seconds after the free-fall event
+Inputs: chk_fall Ticker
+******************************************************************************/
+void clear_fall(){// Ticker routine to clear_fall detect routine if no impact in 2.0 seconds after free-fall event is over
+    if(Led_clk2 == 1){// have we detected an impact?
+     chk_fall.detach(); //just stop ticker
+    }//endif
+    else{
+     Accel_INT1.fall(&fall_detect); // reset accel sensor's int#1 to active low and reset for next fall
+     Accel_INT2.fall(NULL); //Stop looking for vector impacts, 
+     Led_clk1 = 0;       // Turn off LED1, on docking station
+    }//end else
+}//end clear_fall ticker interupt routine
+
+
+/*****************************************************************************
+Name: impact_detect()
+Purpose: Interupt routine called when accelerometer IC has detected a vector
+magnitude acceleration >= 3.0g
+Inputs: interupt2 of accel sensor
+******************************************************************************/
+void impact_detect(){// we may detect multiple impacts, this needs to work from last impact detected
+ if(Fall_Alert == 1){
+    f_time.stop(); // stop fall timer
+    accel.acquire_accel_data_g(Accel_Data_Event);
+    chk_fall.detach();  //detach/stop ticker, impact was detected
+    wait(0.1);
+    Fall_Event_Data[1] = f_time;// store free-fall time
+    Led_clk2 = 1;  // Turn on LED2, on docking station
+    gyro_sensor_config(13); // reset motion counter
+    Gyro_INT1.fall(&motion_detect);     // Start looking for motion
+    chk_motion.attach(&chkmotion,(Min_Movement_duration)); //initialize ticker to check for motion during Min_Movement_duration
+ }  // endif    
+    Accel_Mag = 2*sqrt(((Accel_Data_Event[0]*Accel_Data_Event[0])+(Accel_Data_Event[1]*Accel_Data_Event[1])+(Accel_Data_Event[2]*Accel_Data_Event[2])));
+    if(Accel_Mag>Fall_Event_Data[2]){
+        Fall_Event_Data[2] = Accel_Mag; // if impact accel is higher than last measured, update
+    }//endif
+    //wait(0.1);
+    //Led_clk3 = 1;  // Turn on LED3, on docking station  - we're looking for motion  
+}//end impact_detect interupt routine
+
+/*****************************************************************************
+Name: motion_detect()
+Purpose: Interupt routine called when gyro IC has detected motion >= 50 deg/sec
+in order to see if fall-impact resulted in motion-less person.
+Inputs: interupt1 of gyro sensor
+******************************************************************************/
+void motion_detect(){// 2 seconds of motion was detected
+ chk_motion.detach(); //stop ticker, we've detected motion        
+    Accel_INT1.fall(&fall_detect);   // Accel sensor's int#1 calls interupt routine
+    Accel_INT2.fall(NULL);    //Reset for next event
+    Gyro_INT1.fall(NULL);     //Reset for next event
+        //wait(0.1);
+        Led_clk1 = 0;  // Turn off LED1, on docking station
+        Led_clk2 = 0;  // Turn off LED2, on docking station
+
 }//end motion_detect interupt routine
 
+
+/*****************************************************************************
+Name: chkmotion()
+Purpose: Ticker interupt routine called when 60sec window has elapsed without 
+2seconds of motion being detected.
+Inputs: chk_motion Ticker
+******************************************************************************/
+void chkmotion(){// if we got here we didn't detect motion
+    //
+    chk_motion.detach(); //stop ticker
+    Screen_Num = 47;  //Change to screen 47 (Fall diag screen)
+    Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED
+        if (OLED_ON == 0) {
+        OLED_ON = 1; // Screen was off, set to On          
+         }  // endif 
+        update_display(); //
+        chk_motion.attach(&chk_help_needed,(Do_You_Need_Help_Time)); //initialize ticker to send automatic alert 
+        haptic = 1;
+        wait(0.2);// very aggressive hapic
+        haptic = 0;
+        wait(0.2);
+        haptic = 1;
+        wait(0.2);// very aggressive hapic
+        haptic = 0;
+        wait(0.2);
+        haptic = 1;
+        wait(0.2);// very aggressive hapic
+        haptic = 0;
+        
+    }//end of chkmotion ticker interupt routine
+    
+/*****************************************************************************
+Name: chk_help_needed()
+Purpose: Ticker interupt routine called when X sec window has elapsed without 
+user dimissing "Are you OK" screen, sends automatic alert. 
+Inputs: chk_motion Ticker
+******************************************************************************/    
+void chk_help_needed(){// Were they able to dismiss on their own?
+    //
+    chk_motion.detach(); //stop ticker
+    if (Screen_Num == 47){// are we still on screen 47?
+        Screen_Num = 48;  //Change to screen 48 and send alert
+        Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED to keep it on 
+        if (OLED_ON == 0) {
+        OLED_ON = 1; // Screen was off, set to On        
+        }  // endif 
+        update_display();
+        oled_text_properties_t textProperties = {0};
+        oled.GetTextProperties(&textProperties);
+        textProperties.fontColor = COLOR_RED;
+        oled.SetTextProperties(&textProperties);
+        oled.Label((uint8_t *)"No responce!", 5, 20);
+        textProperties.fontColor = COLOR_WHITE;
+        oled.SetTextProperties(&textProperties);
+        Send_Alert(2); // send alert type two     
+        haptic = 1;
+        wait(0.5);// very aggressive hapic
+        haptic = 0;
+        wait(0.2);
+        haptic = 1;
+        wait(0.5);// very aggressive hapic
+        haptic = 0;
+        wait(0.2);
+        haptic = 1;
+        wait(0.5);// very aggressive hapic
+        haptic = 0;
+    }  // endif   
+
+    }//end of chkmotion ticker interupt routine
+    
+    
+/*****************************************************************************
+Name: Send_Alert()
+Purpose: routine used to store and send alert
+Inputs: int value from 0 to 256
+0=Panic, 1=Fall+asked for help, 2=Fall+No responce, 3=?
+Returns: None
+******************************************************************************/
+void Send_Alert(uint8_t Num){
+    
+    // store alert
+    // transmit alert
+    
+    }//end Send_Alert routine
+
 /*****************************************************************************
 Name: fall_config()
+Purpose: routine used to set accelerometer and gyro sensors' internal registers for chip
+level interrupts
+Inputs: int value from 0 to 256
+Returns: None
+******************************************************************************/
+void fall_config(uint8_t Num){ // this is more than just accel config
+// use case switches here to configure for 
+switch(Num) {           
+                case 0: {// put in standby
+                    accel_sensor_config(0); // set accel sensor to standby
+                    /*For lowest accel power ~2uA in standby mode */
+                    gyro_sensor_config(0); // set gyro sensor to standby
+                    /*For lowest gyro power ~2.8uA in standby mode */
+                    Accel_INT1.fall(NULL); // Turn off Accel sensor's int#1
+                    Accel_INT2.fall(NULL); // Turn off Accel sensor's int#2
+                    Gyro_INT1.fall(NULL); // Turn off Gyro sensor's int#1 
+                    break;      
+                }// end of case 0
+                
+                case 1: {// configure for free-fall int only
+                    accel_sensor_config(1); // set accel sensor for free-fall
+                    gyro_sensor_config(0); // set gyro sensor to standby
+                    Accel_INT1.fall(NULL); // Turn off Accel sensor's int#1
+                    Accel_INT2.fall(NULL); // Turn off Accel sensor's int#2
+                    Gyro_INT1.fall(NULL); // Turn off Gyro sensor's int#1 
+                    
+                    Accel_INT1.fall(&fall_detect_debug); // Accel sensor's int#1 calls interupt routine
+                    break;
+                }// end of case 1
+                
+                case 2: {// configure for vector impact only
+                    accel_sensor_config(2); // set accel sensor vector impact only
+                    gyro_sensor_config(0); // set gyro sensor to standby
+                    Accel_INT1.fall(NULL); // Turn off Accel sensor's int#1
+                   // Accel_INT2.fall(NULL); // Turn off Accel sensor's int#2
+                    Gyro_INT1.fall(NULL); // Turn off Gyro sensor's int#1
+                    Accel_INT2.fall(&impact_detect_debug); //Accel sensor's int#2 calls interupt routine
+                    
+                    break;
+                }// end of case 2    
+     
+                case 3: {// configure for motion int only
+                    accel_sensor_config(0); // set accel sensor vector impact only
+                    gyro_sensor_config(3); // set gyro sensor to standby
+                    Accel_INT1.fall(NULL); // Turn off Accel sensor's int#1
+                    Accel_INT2.fall(NULL); // Turn off Accel sensor's int#2
+                    Gyro_INT1.fall(&motion_detect_debug); // Gyro sensor's int#1 (PTD1) calls interupt routine
+                    break;
+                }// end of case 3           
+                                            
+                 case 4: {// configure FFMT for free-fall event AND config for vector impact   
+                    accel_sensor_config(4); // set accel sensor Free-fall and vector impact
+                    gyro_sensor_config(3); // set gyro sensor motion
+                    Accel_INT1.fall(&fall_detect_debug); // Accel sensor's int#1 calls interupt routine
+                    Accel_INT2.fall(&impact_detect_debug); //Accel sensor's int#2 calls interupt routine
+                    Gyro_INT1.fall(&motion_detect_debug); // Gyro sensor's int#1 (PTD1) calls interupt routine
+                    break;
+                }// end of case 4
+                
+                case 5: {// configure for sequential free-fall, vector impact then motion  
+                    accel_sensor_config(4); // set accel sensor Free-fall and vector impact
+                    gyro_sensor_config(3); // set gyro sensor motion
+                    Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
+                    Accel_INT2.fall(NULL); //Accel sensor's int#2 calls interupt routine
+                    Gyro_INT1.fall(NULL); // Gyro sensor's int#1 (PTD1) calls interupt routine
+                    break;
+                }// end of case 4
+                       
+                case 10: {// reset IC 
+                    accel_sensor_config(10); // reset accel sensor 
+                    gyro_sensor_config(10); // reset gyro sensor 
+                    break;
+                }// end case 10      
+                
+                case 11: {// wake both sensors for simple data read, they were in stanby
+                    accel_sensor_config(11); // set accel sensor active for read
+                    gyro_sensor_config(11); // set accel sensor active for read
+                    break;
+                }// end of case 11 
+                
+                case 12: {// put into standby for low power
+                    accel_sensor_config(12); // set accel sensor to standby
+                    gyro_sensor_config(12); // set gyro sensor to standby
+                    break;
+                }// end of case 112             
+                
+                case 20: {// read INT_Source to clear VECM int, shouldn't have to do this
+            // This was not working for me but it was due to me using the wrong FXOS8700_I2C_ADDRESS_
+                    char d[2];//, data_byte_[1]; 
+                    d[0] = 0x0c;  // 0x0c is INT_Source Reg
+                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_,d,1,true); // "true" is needed to prevent stop
+                    wait(0.01);
+                    if(i2c_bus1.read(FXOS8700_I2C_ADDRESS_,d,1) == 1){ // read Who am I Reg for debug
+                    sprintf(text_1," INT_Read_Err ");
+                    oled.Label((uint8_t *)text_1,5,50); // Display error at x,y 
+                    wait(1);  // wait 1 seconds
+                    }//endif
+                    break;
+                }// end of case 20 
+                
+                   case 21: {// read A_FFMT_SRC reg to clear FFMT int, shouldn't have to do this
+            // This was not working for me but it was due to me using the wrong FXOS8700_I2C_ADDRESS_
+                    char d[2];//, data_byte_[1]; 
+                    d[0] = 0x16;  // 0x16 is A_FFMT_SRC Reg
+                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_,d,1,true); // "true" is needed to prevent stop
+                    wait(0.01);
+                    if(i2c_bus1.read(FXOS8700_I2C_ADDRESS_,d,1) == 1){ // read Who am I Reg for debug
+                    sprintf(text_1," INT_Read_Err ");
+                    oled.Label((uint8_t *)text_1,5,50); // Display error at x,y 
+                    wait(1);  // wait 1 seconds
+                    }//endif
+                    break;
+                }// end of case 21 
+                
+                default: {
+                    oled.Label((uint8_t *)" Mode? ",30,60); // Display "mode" at x,y
+                    // unknown config
+                    break;
+                } 
+}// end switch                
+
+}// end Fall_config
+
+
+/*****************************************************************************
+Name: accel_sensor_config()
 Purpose: Used to set accelerometer IC's internal registers to set up chip level
 interrupts
 Inputs: int value from 0 to 256
 Returns: None
 ******************************************************************************/
       
-void fall_config(uint8_t Num){ // this is more than just accel config
+void accel_sensor_config(uint8_t Num){ 
 // use case switches here to configure for 
 switch(Num) {           
                 case 0: {// put in standby
@@ -2958,7 +3421,7 @@
                         oled.Label((uint8_t *)" Reset error ",30,05); // Display "error" at x,y 
                         wait(3.0); // display for 3 seconds
                     }//end if    
-                    oled.Label((uint8_t *)"Acc_Reset",20,60); // Display "reset" at x,y
+                   // oled.Label((uint8_t *)"Acc_Reset",20,60); // Display "reset" at x,y
                     break;
                 }// end case 10      
                 
@@ -3023,7 +3486,7 @@
                 } 
 }// end switch                
 
-}// end Fall_config
+}// end accel_sensor_cconfig
 
 /*****************************************************************************
 Name: gyro_sensor_config()
@@ -3040,7 +3503,7 @@
                     /*For lowest power ~2.8uA in standby mode */
                     char d[2];
                     d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
-                    d[1] = 0x08;                                      //Puts device in standby mode
+                    d[1] = 0b00001100;                                //puts device in standby mode and leaves ODR set to 100Hz
                     if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
                         oled.Label((uint8_t *)"gyr_err0a",20,45); // Display "error" at x,y 
                         wait(3.0); // display for 3 seconds
@@ -3048,7 +3511,7 @@
                     break;    
                 }// end of case 0  
                 
-                case 1: {// Fall_Alert mode=1 or 2, put in active mode se we can read gyro measurments
+                case 1: {// Fall_Alert mode=1, put in active mode se we can read gyro measurments
                     char d[2];
                     d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
                     d[1] = 0x00;                                      //Puts device in standby mode  
@@ -3071,30 +3534,7 @@
                     break;
                 }// end of case 1
                 
-                case 2: {// Fall_Alert mode=1 or 2, put in active mode se we can read gyro measurments
-                    char d[2];
-                    d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
-                    d[1] = 0x00;                                      //Puts device in standby mode  
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err2a",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if   
-                    d[0] = FXAS21002_CTRL_REG0;                       //CTRL_REG0=0x0d
-                    d[1] = 0x00;                                       //sets FS =+/- 2000 dps
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err2b",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if  
-                    d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
-                    d[1] = 0x0e;                                       //0x0e puts device in active mode with ODR = 100Hz
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err2c",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if  
-                    break;
-                }// end of case 2
-                
-                case 3: {// Fall_Alert mode 3 or 4,  set up interupt, put in active mode
+                case 3: {// Fall_Alert mode 3,  set up interupt, put in active mode
                     char d[2];
                     d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
                     d[1] = 0x00;                                      //0x08 puts device in standby mode  
@@ -3162,78 +3602,7 @@
                         wait(3.0); // display for 3 seconds
                     }//end if  
                     break;
-                }// end of case 2
-                
-                case 4: {// Fall_Alert mode 3 or 4,  set up interupt, put in active mode
-                    char d[2];
-                    d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
-                    d[1] = 0x00;                                      //0x08 puts device in standby mode  
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err4",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if   
-                    
-                    // set RT_CFG reg 0x0e - Rate int config
-                    d[0] = 0x0e;                                        //set RT_CFG reg 0x0e - Rate int config
-                    d[1] = 0b00000111;                                      // enable x,y,z axis 
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err4a",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if 
-                      
-                    // set RT_THS reg 0x10 - Rate Threshold value
-                    d[0] = 0x10;                                        //set RT_THS reg 0x10 - Rate Threshold config
-    //                d[1] = 0b00000111;                                   // bit7=couter mode(1=clr,0=dec), rate Tresh(dps)=(THS+1)*Sensitivity(dps/LSB
-                    // Sensitivity(dps/LSB), we should have mdps/LSB=62.50 or a full range of +/- 2000 dps
-                    // Movement_Thresh 50 dps=(THS+1)*256*Sensitivity(dps/LSB) => THS = Movement_Thresh/(16.0f)-1
-                    // We specified that 50 dps was the magnitude some of all 3 axis so THS is 1/3 of that
-                    d[1] = (uint8_t)((Movement_Thresh/(3*16.0f))-1);  // Movement_Thresh 50 dps setting Tresh(dps)=(THS+1)*256*Sensitivity(dps/LSB)
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err4b",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if 
-                    
-                    // set RT_COUNT reg 0x11 - Rate Threshold counter
-                    d[0] = 0x11;                                    //set RT_COUNT reg 0x11 - Rate Threshold counter
-                    //  d[1] = 0b10000000;                            // debounce count value (Count=10, ODR=100Hz => 100mS)
-                    d[1] = (uint8_t)(Min_Movement_Time/0.01f);      // debounce count value (at ODR=100Hz, each count = 10mS) 2.55s=255
-                    // need to calculate and store this value
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                    oled.Label((uint8_t *)"gyr_err4c",20,45); // Display "error" at x,y 
-                    wait(3.0); // display for 3 seconds
-                    }//end if                   
-                    
-                    // set CTRL_REG2 reg 0x14 - Int config
-                    d[0] = 0x14;                                        //set CTRL_REG2 reg 0x14 - Int config
-                    d[1] = 0b01110000;                                  // enable RT &FIFO interupts, int=act_low, push/pull
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                    oled.Label((uint8_t *)"gyr_err4d",20,45); // Display "error" at x,y 
-                    wait(3.0); // display for 3 seconds
-                    }//end if                         
-                    
-                    // set CTRL_REG3 reg 0x15 - Auto inc config, external power, FSR <=don't need?
-                    d[0] = 0x15;                                       //CTRL_REG3 reg 0x15
-                    d[1] = 0x00;                                       //Auto inc config, external power, FSR
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err4e",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if  
-             
-                    d[0] = FXAS21002_CTRL_REG0;                       //CTRL_REG0=0x0d
-                    d[1] = 0x00;                                       //sets FS=0,mdps/LSB=62.50 => +/- 2000 dps
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err4f",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if  
-                    d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1 0x13 - Op mode, ODR selection, reset
-                    d[1] = 0b00001110;                                //0x0e puts device in active mode and sets ODR to 100Hz
-                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
-                        oled.Label((uint8_t *)"gyr_err4g",20,45); // Display "error" at x,y 
-                        wait(3.0); // display for 3 seconds
-                    }//end if  
-                    break;
-                }// end of case 4
-
+                }// end of case 3
 
                 case 10: {// reset Gyro IC 
                   char d[2];    
@@ -3243,14 +3612,14 @@
                         oled.Label((uint8_t *)"gyr_err10a",20,45); // Display "error" at x,y 
                         wait(3.0); // display for 3 seconds
                     }//end if   
-                    oled.Label((uint8_t *)"G_Reset ",30,45); // Display "reset" at x,y
+                   // oled.Label((uint8_t *)"G_Reset ",30,45); // Display "reset" at x,y
                     break;
                 }// end case 10  
 
-                case 11: {//  read gyro measurments
+                case 11: {//  set sensor to active to read gyro measurments
                     char d[2];
                     d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
-                    d[1] = 0x0e;                                       //0x0e puts device in active mode with ODR = 100Hz
+                    d[1] = 0b00001110;                                //0x0e puts device in active mode with ODR = 100Hz
                     if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
                         oled.Label((uint8_t *)"gyr_err11a",20,45); // Display "error" at x,y 
                         wait(3.0); // display for 3 seconds
@@ -3262,13 +3631,31 @@
                     /*For lowest power ~2.8uA in standby mode */
                     char d[2];
                     d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
-                    d[1] = 0x08;                                      //Puts device in standby mode
+                    d[1] = 0b00001100;                                //puts device in standby mode and leaves ODR set to 100Hz
                     if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
                         oled.Label((uint8_t *)"gyr_err12a",20,45); // Display "error" at x,y 
                         wait(3.0); // display for 3 seconds
                     }//end if 
                     break;    
                 }// end of case 12  
+                
+                case 13: {// put in standby then back to active, to clear counter
+                    /*For lowest power ~2.8uA in standby mode */
+                    char d[2];
+                    d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
+                    d[1] = 0b00001100;                                //puts device in standby mode and leaves ODR set to 100Hz
+                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)"gyr_err12a",20,45); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if 
+                    d[1] = 0b00001110;                                //0x0e puts device in active mode with ODR = 100Hz
+                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)"gyr_err11a",20,45); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if  
+                    
+                    break;    
+                }// end of case 13 
 
                 default: {
                     oled.Label((uint8_t *)"Gyro_Mode?",20,45); // Display "mode" at x,y
@@ -3354,11 +3741,12 @@
                     d[1] = 0b01000000;                                //resets IC
                     if(i2c_bus0.write(0xaf, d, 2) ==1){
                         oled.Label((uint8_t *)"MAX_W_Err10a",5,1); // Display "error" at x,y 
+                        wait(2.0);  // wait 0 seconds
                     }//end if   
                     else {
-                    oled.Label((uint8_t *)"MAX_Reset",20,30); // Display "reset" at x,y
+                   // oled.Label((uint8_t *)"MAX_Reset",20,30); // Display "reset" at x,y
                     }
-                    wait(0.1);  // wait 5 seconds
+                    wait(0.01);  // wait 0.01 seconds
                     break;    
                 }// end of case 10  
                 
@@ -3461,6 +3849,22 @@
             Heat_Index_Calculation();
             sprintf(text,"%i",heat_index);
             oled.TextBox((uint8_t *)text,3,80,15,15); //show HI in a 15px by 15px text box at x=3, y=80
+ 
+            textProperties.fontColor = COLOR_GRAY;
+            if(Fall_Alert == 1){
+                textProperties.fontColor = COLOR_GREEN; // is Fall protection on?
+            }
+            if(Fall_Alert == 1 && Led_clk1 == 1){
+                textProperties.fontColor = COLOR_YELLOW; // is Fall detected? 
+            }       
+            if(Fall_Alert == 1 && Led_clk1 == 1 && Led_clk2 == 1){
+                textProperties.fontColor = COLOR_RED; // is impact detected? 
+            }       
+            oled.SetTextProperties(&textProperties); 
+            oled.Label((uint8_t *)"FAP",1,0);  //Display "FAP" at x,y
+            textProperties.fontColor = COLOR_WHITE;
+            oled.SetTextProperties(&textProperties);
+            
             break;
         }// end case 0