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

main.cpp

Committer:
nbaker
Date:
2018-03-26
Revision:
10:eaea844e763c
Parent:
9:d2e39ee9fedd
Child:
11:ccda4d44bd8e

File content as of revision 10:eaea844e763c:

/**********************************************************************
Texas State University Senior Project - HexiHeart 
Team Zeta: Alex Song, Jasmine Rounsaville, Issam Hichami, Neil Baker

Program layout:
Declarations
Up Button routines
Down Button routines
Right Button routines
Left Button routines 
Main()
Main display screen routines
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.

v2.07 - 2/18/18 - Added fall mode option to test fall/impact separately, Added global 
interrupt disable prevent button interrupts while refreshing screen, this caused haptic 
timer to stop working right.

v1.0 - 11/12/17
This version has basic menu layout and screen timeout feature.  The menu
are just placeholders (for the most part) and will be either adjusted or
replaced with graphic images.

***********************************************************************/

#include "mbed.h"
#include "Hexi_KW40Z.h"         // Button and BLE fuctions
#include "FXOS8700.h"           // Freescale/NXP FXOS8700CQ - 3D Accelorometer & Mag
#include "FXAS21002.h"          // Freescale/NXP FXAS21002CQ - 3-Axis Gyroscope
//#include "MPL3115A2.h"          // Freescale/NXP MPL3115A2 - pressure sensor 
#include "HTU21D.h"             // Non-Freescale/NXP - HTU21D - combo temperature and Humidity
#include "W25Q64FV.h"           // Non-Freescale/NXP - W25Q64FVSSIG - 8MB/64Mbit Serial Flash memory
#include "MAX30101.h"           // Non-Freescale MAX30101 - Optical Heart rate sensor 
//#include "TSL2561.h"            // Non-Freescale/NXP TSL2561 - light sensor
#include "Hexi_Battery/hexi_battery.h"  // Battery status
#include "Hexi_OLED_SSD1351.h"  // OLED fuctions
#include "OLED_types.h"         // Text attributs
#include "string.h"
#include "OpenSans_Font.h"
#include "images.h"


// Definitions
#define SW_Ver          2.09    // For displaying software version
#define LED_ON          0
#define LED_OFF         1
#define SCRN_TIME       10.0
#define Debug           1 // If "Debug" is defined, our code will compile for debug.  Comment out for Production code.
#define HIGHEST_ZONE    4
#define LOWEST_ZONE     1
#define ENTER_BELOW     25
#define ENTER_ABOVE     50
#define EXIT_BELOW      75
#define EXIT_ABOVE      100
#define VIB_OPT_2       75
#define FXOS8700_I2C_ADDRESS_ (0x1E<<1) //pins SA0,SA1=0 
#define FXAS21002_I2C_ADDRESS_ 0x40      //
//#define TSL2561_I2C_ADDRESS_  (0x29 << 1) // Address select line is grounded
//#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 
void update_display(void);// Screen lables refreshed
void update_display_date(void);  // Screen data(only)refreshed 
void Decrement_Age();
void Set_Max_Bpm();
void Set_Zone_Boundaries();
void Increment_Age();
void Increment_Target_Zone();
void Decrement_Target_Zone();
void Increment_HR_Vibr_Pref();
void Decrement_HR_Vibr_Pref();
void Determine_Current_Zone();
void Heart_Rate_Vibrations();
void Increment_Heart_Rate();
void Decrement_Heart_Rate();
void Enable_Heart_Rate();
void Disable_Heart_Rate();
void Led_Zone_Indicator();
void Heat_Index_Calculation();
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);         // 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?
char display_buff[30];      //Buffer for conversion to char to display
char text[20];              // Text Buffer for dynamic value displayed
bool BLE_On = 0;            // Initialize as BLE on
char pass [20];              // Passcode
bool Led_Zones = 1;
bool HR_Enable = 0;
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 = 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 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;
uint8_t HR_buff[250];
uint8_t *HR_return;
uint8_t Age = 50;            // Initialize age
uint8_t Max_Bpm = 220 - Age;      // Initialize Max BPM
uint8_t Screen_Num = 0;      // Initialize to main screen
uint8_t Error_Num = 0;         // Error num for debug
uint8_t HR_Vibration = 2;       //Choose Heart Rate Vibration Options
uint8_t Target_Zone = 2;        //Initialize Target Heart Rate Zone to Zone 3
uint8_t HR_Zone1[2] = {Max_Bpm * .50, Max_Bpm * .60};       //Heart Rate Zone 1
uint8_t HR_Zone2[2] = {HR_Zone1[1] + 1, Max_Bpm * .70};       //Heart Rate Zone 2
uint8_t HR_Zone3[2] = {HR_Zone2[1] + 1, Max_Bpm * .80};       //Heart Rate Zone 3
uint8_t HR_Zone4[2] = {HR_Zone3[1] + 1, Max_Bpm};       //Heart Rate Zone 4
int sample_ftemp;               // used in Heat index calc
int sample_humid;                // used in Heat index calc
int heat_index;                  // used in Heat index calc
int hi_calc;                    // used in Heat index calc
int adjustment;                 // used in Heat index calc

// Pointers for screen images 
const uint8_t *Hexi_Heart_ = Hexi_Heart_bmp;
//const uint8_t *NB_Linkedin = NB_Linkedin_bmp;  
//const uint8_t *AS_Linkedin = NB_Linkedin_bmp;  
//const uint8_t *IR_Linkedin = NB_Linkedin_bmp;
//const uint8_t *IH_Linkedin = NB_Linkedin_bmp;


// ***************** Define pins *****************************
//W25Q64FVSSIG - 8MB/64Mbit Serial Flash memory (SPI1)(MOSI,SCLK,POWER,CS,RST,DC)
//W25Q64FV(PinName mosi, PinName miso, PinName sclk, PinName cs, int frequency=10000000);
//MKW40Z (SPI1)
SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); // SSD1351 OLED Driver SPI2(MOSI,SCLK,POWER,CS,RST,DC)
FXAS21002 gyro(PTC11,PTC10); // Gyroscope (I2C1 data bus(SDA, SCL))
FXOS8700 accel(PTC11, PTC10); // Accelorometer (I2C1 data bus(SDA, SCL))
FXOS8700 mag(PTC11, PTC10);   // Mag (same chip as Accel) (I2C1 data bus(SDA, SCL))
//MAX30101 heart(PTB1, PTB0); //Heart Rate Chip (I2C0 data bus(SDA, SCL))
HTU21D temphumid(PTB1,PTB0); // HTU21D Sensor (I2C0 data bus(SDA, SCL))
//TSL2561 - (PTB1, PTB0); //Amb light sensor (I2C0 data bus(SDA, SCL))

// initialize I2C bus for FXOS8700, FXAS-Gyro, MPL-Pressure
    I2C i2c_bus1(PTC11, PTC10);  // (SDA, SCL)
// initialize I2C bus for MAX30101, HTU21D, TSL2561
    I2C i2c_bus0(PTB1, PTB0);   // (SDA, SCL)
    
// initialize SPI bus for W25Q64FVSSIG, (and MKW40Z if needed)
//    SPI spi_bus1(PTD6, PTD7, PTD5);  // (MOSI, MISO, SCLK) CS=PTD4?(low=select)

DigitalOut RED_Led(LED1);
DigitalOut GRN_Led(LED2);
DigitalOut BLU_Led(LED3);
DigitalOut haptic(PTB9);
DigitalOut Led_clk1(PTA12);
DigitalOut Led_clk2(PTA13);
DigitalOut Led_clk3(PTA14);

DigitalOut OLED_PWR(PTC13);     // this pin turns on/off 15V supply to OLED display
DigitalOut PowerEN (PTB12);     // 3V3B Power Enable for HTU21D (Temp/Hum sensor) and Light sensor Sensor supply
DigitalOut HR_PWR(PTA29);       // this pin turns on/off power to heart rate sensor
//DigitalIn   Sw1(PTA12);       //Switch 'T1' on docking station AND Led_clk1!!
//DigitalIn   Sw2(PTA13);       //Switch 'T2' on docking station AND Led_clk2!!
DigitalIn   Sw3(PTA15);         //Switch 'T3' on docking station 


/* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */
KW40Z kw40z_device(PTE24, PTE25);

/* Define timer for haptic feedback */
RtosTimer hapticTimer(StopHaptic, osTimerOnce);

//***************** Interrups *****************
InterruptIn Accel_INT1(PTC1);       // Accel sensor's interupt 1
InterruptIn Accel_INT2(PTD13);      // Accel sensor's interupt 2
InterruptIn Gyro_INT1(PTD1);        // Gyro sensor's interupt 1
InterruptIn Gyro_INT2(PTC18);       // Gyro sensor's interupt 2
//InterruptIn Amb_Light_INT1(PTC0);  // TSL2561- Light sensor's interupt
//InterruptIn HR_INT1(PTB18);        // MAX30101 - Heart rate sensor's interupt
//InterruptIn Pressure_INT1(PTD12);  // MPL3115A2 pressure sensor's interupt 1
//InterruptIn Pressure_INT2(PTD10);  // MPL3115A2 pressure sensor's interupt 2

//***************** 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  
        HexiwearBattery battery;
        battery.sensorOn();  
                              
        if (battery.isBatteryCharging() || (uint8_t)battery.readLevelPercent()> 99) {
           Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED while fully charged
        } //end if
    else {
#endif        
//  oled.FillScreen(COLOR_BLACK); // Clear screen.. is there a better command for this?
     OLED_PWR = 0;  // Turn off OLED power supply
     OLED_ON = 0;  // set flag to off
     Screen_Timer.detach();  // detach Ticker
#ifdef Debug    // in debug keep screens on for demo  
     } // endelse
#endif   
}//end routine

void ButtonUp(void)
{
    Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED?
    if (OLED_ON == 0) {
        OLED_ON = 1; // Scree was off, set to On
        update_display();
    } else {
        switch(Screen_Num) {
            case 0: {// We're in Main Screen
                // do nothing, wrong button
                break;
            }
            case 1: {// Panic Alert option
                StartHaptic();
                Screen_Num = 5;  //Change to screen 5
#ifdef Debug    // in debug show debug/diagnostic screens                         
                Screen_Num = 26;  //Change to screen 20
#endif

                update_display();
                break;
            }
            case 2: {// Fall Alert option
                StartHaptic();
                Screen_Num = 71;  //Change to screen 71
                update_display();
                break;
            }
            case 3: {// Heart Rate Monitoring option
                StartHaptic();
                Screen_Num = 2;  //Change to screen 2
                update_display();
                break;
            }
            case 4: {// Alert History option
                StartHaptic();
                Screen_Num = 3; //Change to screen 3
                update_display();
                break;
            }
            case 5: {// About HexiHeart
                StartHaptic();
                Screen_Num = 4; //Change to screen 4
                update_display();
                break;
            }
            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;
            }
            case 7: {// Heart Rate Zone
                StartHaptic(50);
                Enable_Heart_Rate();
                //heart.enable();
                //HR_Enable = 1;
                //while(HR_Enable == 1)
                //    heart.readRawData(HR_buff, HR_return);
                //update_display();
                break;
            }
            case 8: {// Alert History
                StartHaptic();
                //Increment  alert index
                break;
            }
            case 9: {// HexiHeart About info1
                    StartHaptic();
                    Screen_Num = 11;  //Change to screen 11
                    update_display();
                    break;
                }    
            case 10: {// HexiHeart About info2
                    StartHaptic();
                    Screen_Num = 9;  //Change to screen 9
                    update_display();
                    break;
                }    
            case 11: {// HexiHeart About info3
                    StartHaptic();
                    Screen_Num = 10;  //Change to screen 9
                    update_display();
                    break;
                } 
            case 20: {// Diagnostic/Debug Screens
                StartHaptic();
                Screen_Num = 5;  //Change to screen 5
                update_display();
                break;
            }
            case 21: {// Fall Diagnostic
                StartHaptic();
                Screen_Num = 25;  //Change to screen 25
                update_display();
                break;
            }
            case 22: {// Fall Debug
                StartHaptic();
                Screen_Num = 21;  //Change to screen 21
                update_display();
                break;
            }
            case 23: {// Heart Rate Diagnostic
                StartHaptic();
                Screen_Num = 22;  //Change to screen 22
                update_display();
                break;
            }
            case 24: {// Heart Rate Debug
                StartHaptic();
                Screen_Num = 23;  //Change to screen 23
                update_display();
                break;
            }
            case 25: {// Heat Index Diagnostic
                StartHaptic();
                Screen_Num = 24;  //Change to screen 24
                update_display();
                break;
            }
            case 26: {//Heart Rate Config Option
                StartHaptic();
                Screen_Num = 20;
                update_display();
                break;
            }
            case 27: {//Incrementing Age
                Increment_Age();
                Set_Zone_Boundaries();
                update_display();
                break;
            }
            case 28: {//Changing Heart Rate Vibration Preferences
                Increment_HR_Vibr_Pref();
                update_display();
                break;
            }
            case 30: {//Change Target Heart Rate Zone Preference
                Increment_Target_Zone();
                update_display();
                break;
            }
            case 31: { //Manually Increment Heart Rate by 1
                Increment_Heart_Rate();
                Determine_Current_Zone();
                update_display();
                break;
            }
            
            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 > 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  
                wait(0.1);
                //gyro_sensor_config(Fall_Alert_Mode);  // leave gyro sensor active
                fall_config(Fall_Alert_Mode);
                wait(0.1);
                __enable_irq();     // Enable all Interrupts
                wait(0.3);
                update_display();
                break;
            }    
            case 42: {// F-Th adj
                StartHaptic();
                Fall_Thresh = Fall_Thresh + 0.05f;
                if(Fall_Thresh > 0.9f){
                Fall_Thresh = 0.9;
                }//endif
                update_display();
                break;
            }
            case 43: {// I-Th adj
                StartHaptic();
                Impact_Thresh = Impact_Thresh + 0.1f;
                if(Impact_Thresh > 3.9f){
                Impact_Thresh = 3.9;
                }//endif
                update_display();
                break;
            }
            case 44: {// M-Th adj
                StartHaptic();
                Movement_Thresh = Movement_Thresh + 5.0f;
                if(Movement_Thresh > 300.0f){
                Movement_Thresh = 300.0;
                }//endif
                update_display();
                break;
            }
            case 45: {// Min_Movement_Time adj
                StartHaptic();
                Min_Movement_Time = Min_Movement_Time + 0.1f;
                if(Min_Movement_Time > 2.4f){
                Min_Movement_Time = 2.4;
                }//endif
                update_display();
                break;
            }
            case 46: {// Min_Movement_duration adj
                StartHaptic();
                Min_Movement_duration = Min_Movement_duration + 5.0f;
                if(Min_Movement_duration > 300.0f){
                Min_Movement_duration = 300.0;
                }//endif
                update_display();
                break;
            }      
            
            case 71: {// BLE
                StartHaptic();
                Screen_Num = 1; //Change to screen 1
                update_display();
                break;
            }
            case 72: {// BlueTooth on/off
                // do nothing, wrong button or change to another screen number if you're making more BLE type screens
                break;
            }
            default: {
                break;
            }
        }
    }

}

void ButtonDown(void)
{
    Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED?
    if (OLED_ON == 0) {
        OLED_ON = 1; // Screen was off, set to On
        update_display();
    } else {

        switch(Screen_Num) {
            case 0: {// We're in Main Screen
                // do nothing, wrong button
                break;
            }
            case 1: {// Panic Alert option
                StartHaptic();
                Screen_Num = 71;  //Change to screen 71
                update_display();
                break;
            }
            case 2: {// Fall Alert option
                StartHaptic();
                Screen_Num = 3;  //Change to screen 3
                update_display();
                break;
            }
            case 3: {// Heart Rate Monitoring option
                StartHaptic();
                Screen_Num = 4;  //Change to screen 4
                update_display();
                break;
            }
            case 4: {// Alert History option
                StartHaptic();
                Screen_Num = 5;  //Change to screen 5
                update_display();
                break;
            }
            case 5: {// About HexiHeart option
                StartHaptic();
                Screen_Num = 26;  //Change to screen 1
#ifdef Debug    // in debug show debug/diagnostic screens                         
                Screen_Num = 20;  //Change to screen 20
#endif
                update_display();
                break;
            }
            case 6: {// Panic Alert
                // do nothing, wrong button
                break;
            }
            case 7: {// Heart Rate Zone
                StartHaptic(100);
                Disable_Heart_Rate();
                break;
            }
            case 8: {// Alert History
                StartHaptic();
                //decriment alert index
                break;
            }
            case 9: {// HexiHeart About info1
                    StartHaptic();
                    Screen_Num = 10;  //Change to screen 10
                    update_display();
                    break;
                }
            case 10: {// HexiHeart About info2
                    StartHaptic();
                    Screen_Num = 11;  //Change to screen 11
                    update_display();
                    break;
                }
            case 11: {// HexiHeart About info3
                    StartHaptic();
                    Screen_Num = 9;  //Change to screen 9
                    update_display();
                    break;
                }            
            case 20: {// Diagnostic/Debug Screens
                StartHaptic();
                Screen_Num = 26;  //Change to screen 1
                update_display();
                break;
            }
            case 21: {// Fall Diagnostic
                StartHaptic();
                Screen_Num = 22;  //Change to screen 22
                update_display();
                break;
            }
            case 22: {// Fall Debug
                StartHaptic();
                Screen_Num = 23;  //Change to screen 23
                update_display();
                break;
            }
            case 23: {// Heart Rate Diagnostic
                StartHaptic();
                Screen_Num = 24;  //Change to screen 24
                update_display();
                break;
            }
            case 24: {// Heart Rate Debug
                StartHaptic();
                Screen_Num = 25;  //Change to screen 25
                update_display();
                break;
            }
            case 25: {// Heat Index Diagnostic
                StartHaptic();
                Screen_Num = 21;  //Change to screen 21
                update_display();
                break;
            }
            case 26: {//Heart Rate Configs
                StartHaptic();
                Screen_Num = 1;
                update_display();
                break;
            }
            case 27: { //Decrement Age
                Decrement_Age();
                Set_Zone_Boundaries();
                update_display();
                break;

            }
            case 28: { //Changing Heart Rate Vibration Preference
                /*
                    StartHaptic();
                    if(HR_Vibration == 1) {
                        HR_Vibration = 3;
                    } else {
                        HR_Vibration -= 1;
                    }
                */
                Decrement_HR_Vibr_Pref();
                update_display();
                break;
            }
            case 30: {//Change Target Heart Rate Zone Preference
                Decrement_Target_Zone();
                update_display();
                break;
            }
            case 31: { //Manually decrement heart rate by 1
                Decrement_Heart_Rate();
                Determine_Current_Zone();
                update_display();
                break;
            }
            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 > 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  
                wait(0.1);
                //gyro_sensor_config(Fall_Alert_Mode);  // leave gyro sensor active
                fall_config(Fall_Alert_Mode);
                wait(0.1);
                __enable_irq();     // Enable all Interrupts
                wait(0.2);
                update_display();
                break;
            }
            case 42: {// F-Th adj
                StartHaptic();
                Fall_Thresh = Fall_Thresh - 0.05f;
                if(Fall_Thresh < 0.1f){
                Fall_Thresh = 0.1;
                }//endif
                update_display();
                break;
            }
            case 43: {// I-Th adj
                StartHaptic();
                Impact_Thresh = Impact_Thresh - 0.1f;
                if(Impact_Thresh < 0.9f){
                Impact_Thresh = 0.9;
                }//endif
                update_display();
                break;
            }
            case 44: {// M-Th adj
                StartHaptic();
                Movement_Thresh = Movement_Thresh - 5.0f;
                if(Movement_Thresh < 5.0f){
                Movement_Thresh = 5.0;
                }//endif
                update_display();
                break;
            }
            case 45: {// Min_Movement_Time adj
                StartHaptic();
                Min_Movement_Time = Min_Movement_Time - 0.1f;
                if(Min_Movement_Time < 0.5f){
                Min_Movement_Time = 0.5;
                }//endif
                update_display();
                break;
            }
            case 46: {// Min_Movement_duration adj
                StartHaptic();
                Min_Movement_duration = Min_Movement_duration - 5.0f;
                if(Min_Movement_duration < 5.0f){
                Min_Movement_duration = 5.0;
                }//endif
                update_display();
                break;
            }

            case 71: {// BLE
                StartHaptic();
                Screen_Num = 2; //Change to screen 2
                update_display();
                break;
            }
            case 72: {// BlueTooth on/off
                // do nothing, wrong button or change to another screen number if you're making more BLE type screens
                break;
            }
            
            default: {
                break;
            }
        }
    }
}

void ButtonRight(void)
{
    Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED?
    if (OLED_ON == 0) {
        OLED_ON = 1; // Screen was off, set to On
        update_display();
    } else {
        switch(Screen_Num) {
            case 0: {// We're in Main Screen
                StartHaptic();
                Screen_Num = 1;  //Change to screen 1
                update_display();
                break;
            }
            case 1: {// Panic Alert option
                StartHaptic();
                Screen_Num = 6;  //Change to screen 6
                update_display();
                break;
            }
            case 2: {// Fall Alert option
                StartHaptic();
                if(Fall_Alert == 1){
                    Fall_Alert = 0;
                    fall_config(0); // configure sensors for standby
                    }
                else{     
                    //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;
            }
            case 3: {// Heart Rate Monitoring option
                StartHaptic();
                Screen_Num = 7;  //Change to screen 7
                update_display();
                break;
            }
            case 4: {// Alert History option
                StartHaptic();
                Screen_Num = 8;  //Change to screen 8
                update_display();
                break;
            }
            case 5: {// About HexiHeart option
                StartHaptic();
                Screen_Num = 9;  //Change to screen 9
                update_display();
                break;
            }

            case 6: {// Panic Alert
                // do nothing, wrong button
                break;
            }
            case 7: {// Heart Rate Zone
                StartHaptic();
                Screen_Num = 31;
                update_display();
                break;
            }
            case 20: {// Diagnostic/Debug Screens
                StartHaptic();
                Screen_Num = 21;  //Change to screen 21
                update_display();
                break;
            }
            case 22: {// Fall Debug
                StartHaptic();
                Screen_Num = 41;  //Change to screen 41
                update_display();
                break;
            }
            case 26: {//Change to Heart Rate Config Screen
                StartHaptic();
                Screen_Num = 27;
                update_display();
                break;
            }
            case 27: {//Change to Heart Rate Vibration Preferences
                StartHaptic();
                Screen_Num = 28;
                update_display();
                break;
            }
            case 28: {//Change to Heart Rate Zone Boundary Info
                StartHaptic();
                Screen_Num = 29;
                update_display();
                break;
            }
            case 29: {//Change Target Heart Rate Zone Preference
                StartHaptic();
                Screen_Num = 30;
                update_display();
                break;
            }
            case 30: {//Change to Heart Rate Config Screen
                StartHaptic();
                Screen_Num = 27;
                update_display();
                break;
            }
            case 31: {
                StartHaptic();
                Screen_Num = 32;
                update_display();
                break;
            }
            case 32: {
                StartHaptic();
                Screen_Num = 7;
                update_display();
                break;
            }
            case 41: {// Fall-Mode adj
                StartHaptic();
                Screen_Num = 42;  //Change to screen 42
                update_display();
                break;
            }       
            case 42: {// F-Th adj
                StartHaptic();
                Screen_Num = 43;  //Change to screen 43
                update_display();
                break;
            }
            case 43: {// I-Th adj
                StartHaptic();
                Screen_Num = 44;  //Change to screen 44
                update_display();
                break;
            }
            case 44: {// M-Th adj
                StartHaptic();
                Screen_Num = 45;  //Change to screen 44
                update_display();
                break;
            }
            case 45: {// Min_time adj
                StartHaptic();
                Screen_Num = 46;  //Change to screen 44
                update_display();
                break;
            }
            case 46: {// Time_dur adj
                    //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
                update_display();
                break;
            }
             case 72: {// BlueTooth on/off
                StartHaptic();
                BLE_On = !BLE_On;
                update_display();
                break;
            }           
            
            default: {
                break;
            }
        }
    }
}

void ButtonLeft(void)
{
    Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED?
    if (OLED_ON == 0) {
        OLED_ON = 1; // Screen was off, set to On
        update_display();
    } else {
        switch(Screen_Num) {
            case 0: {// We're in Main Screen
                // do nothing, wrong button
                break;
            }
            case 1: {// Panic Alert option
                StartHaptic();
                Screen_Num = 0;  //Change to screen 0
                update_display();
                break;
            }
            case 2: {// Fall Alert option
                StartHaptic();
                Screen_Num = 0;  //Change to screen 0
                update_display();
                break;
            }
            case 3: {// Heart Rate Monitoring option
                StartHaptic();
                Screen_Num = 0;  //Change to screen 0
                update_display();
                break;
            }
            case 4: {// Alert History option
                StartHaptic();
                Screen_Num = 0;  //Change to screen 0
                update_display();
                break;
            }
            case 5: {// About HexiHeart option
                StartHaptic();
                Screen_Num = 0;  //Change to screen 0
                update_display();
                break;
            }
            case 6: {// Panic Alert
                StartHaptic();
                Screen_Num = 1;  //Change to screen 1
                update_display();
                break;
            }
            case 7: {// Heart Rate Zone
                StartHaptic();
                Screen_Num = 3;  //Change to screen 3
                update_display();
                break;
            }
            case 8: {// Alert History
                StartHaptic();
                Screen_Num = 4;  //Change to screen 4
                update_display();
                break;
            }
            case 9: {// About HexiHeart info1
                    StartHaptic();
                    Screen_Num = 5;  //Change to screen 5
                    update_display();
                    break;
                }
            case 10: {// HexiHeart About info2
                    StartHaptic();
                    Screen_Num = 5;  //Change to screen 5
                    update_display();
                    break;
                }
            case 11: {// HexiHeart About info3
                    StartHaptic();
                    Screen_Num = 5;  //Change to screen 5
                    update_display();
                    break;
                }            
            case 20: {// Diagnostic/Debug Screens
                StartHaptic();
                Screen_Num = 0;  //Change to screen 0
                update_display();
                break;
            }
            case 21: {// Fall Diagnostic
                StartHaptic();
                Screen_Num = 20;  //Change to screen 20
                update_display();
                break;
            }
            case 22: {// Fall Debug
                StartHaptic();
                Screen_Num = 20;  //Change to screen 20
                update_display();
                break;
            }
            case 23: {// Heart Rate Diagnostic
                StartHaptic();
                Screen_Num = 20;  //Change to screen 20
                update_display();
                break;
            }
            case 24: {// Heart Rate Debug
                StartHaptic();
                Screen_Num = 20;  //Change to screen 20
                update_display();
                break;
            }
            case 25: {// Heat Index Diagnostic
                StartHaptic();
                Screen_Num = 20;  //Change to screen 20
                update_display();
                break;
            }
            case 26: {//Heart Rate Config Option
                StartHaptic();
                Screen_Num = 0;
                update_display();
                break;
            }
            case 27: {//Enter Age
                StartHaptic();
                Screen_Num = 26;
                update_display();
                break;
            }
            case 28: {//Heart Rate Vibration Preference Screen
                StartHaptic();
                Screen_Num = 27;
                update_display();
                break;
            }
            case 29: {//Heart Rate Zone Boundary Info
                StartHaptic();
                Screen_Num = 28;
                update_display();
                break;
            }
            case 30: {//Change Target Heart Rate Zone Preference
                StartHaptic();
                Screen_Num = 29;
                update_display();
                break;
            }
            case 31: {
                StartHaptic();
                Screen_Num = 7;
                update_display();
                break;
            }
            case 32: {
                StartHaptic();
                Screen_Num = 31;
                update_display();
                break;
            }
            case 41: {// Fall mode screen
                StartHaptic();
                Screen_Num = 22;
                update_display();
                break;
            }    
            case 42: {// F-Th adj
                StartHaptic();
                Screen_Num = 41;  //Change to screen 41
                update_display();
                break;
            }
            case 43: {// I-Th adj
                StartHaptic();
                Screen_Num = 42;  //Change to screen 42
                update_display();
                break;
            }
            case 44: {// M-Th adj
                StartHaptic();
                Screen_Num = 43;  //Change to screen 43
                update_display();
                break;
            }    
            case 45: {// M-time adj
                StartHaptic();
                Screen_Num = 44;  //Change to screen 44
                update_display();
                break;
            }   
            case 46: {// M-dur adj
                StartHaptic();
                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();
                Screen_Num = 0;  //Change to screen 0
                update_display();
                break;
            }

            case 72: {// BlueTooth on/off
                StartHaptic();
                Screen_Num = 71;  //Change to screen 71
                update_display();
                break;
            }
           
            default: {
                break;
            }
        }
    }
}


void ButtonSlide(void)  // What is this Slide button???
{
    Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED?
    if (OLED_ON == 0) {
        OLED_ON = 1; // Screen was off, set to On
    }
    StartHaptic();
    oled.FillScreen(COLOR_BLACK); // Clear screen
    strcpy((char *) text_1,"Slide Button");
    oled.Label((uint8_t *)text_1,0,40);
}

int main()
{
//   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 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;
    Led_clk1 = 0;       // LEDs on docking station default to off, need to turn on with a 1
    Led_clk2 = 0;       // LEDs on docking station default to off, need to turn on with a 1
    Led_clk3 = 0;       // LEDs on docking station default to off, need to turn on with a 1
    
// *****************  Reset sensors   ***********************
    OLED_PWR = 0;  // Turn off OLED power supply
    PowerEN = 1;    // Turn off (=1)HTU21(Temp/Hum) and TSL2561(Light) sensors to reset them
    HR_PWR = 0;     // Turn off (=0) Heart rate sensor 1.8V and HRM(3.3V) supply to reset
    wait(0.2);      // how long should we wait for sensors to power down?
    
    PowerEN = 0;    // Turn on (=0) HTU21(Temp/Hum) and TSL2561(Light) sensors to reset them
    HR_PWR = 1;     // Turn on (=1)Heart rate sensor 
    OLED_PWR = 1;   // Turn on OLED power supply
    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 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 
    
// *****************  Local variables  ***********************
//   float accel_data[3]; float accel_rms=0.0;
    int i;
 
// **************  configure sensor modules  ******************

    //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 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);


// ***** Register callbacks/interupts to application functions *********
    kw40z_device.attach_buttonUp(&ButtonUp);
    kw40z_device.attach_buttonDown(&ButtonDown);
    kw40z_device.attach_buttonLeft(&ButtonLeft);
    kw40z_device.attach_buttonRight(&ButtonRight);
 //   kw40z_device.attach_buttonSlide(&ButtonSlide);

// ***** attaching interupts to functions *********
    //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};
    oled.GetTextProperties(&textProperties);

// *********Set text color and screen alignment  **************
    //textProperties.font = OpenSans_12x18_Regular;  //  Max Width of Character  = 12px, Max Height of Character = 18px 
    //textProperties.font = OpenSans_10x15_Regular;  //  <-This is default Font, Max Width of Character  = 10px, Max Height of Character = 15px 
    textProperties.fontColor = COLOR_WHITE;
    textProperties.alignParam = OLED_TEXT_ALIGN_LEFT;
    oled.SetTextProperties(&textProperties);

// **************  Display spash screen  **********************
/*
    oled.FillScreen(COLOR_BLACK); // Clear screen
    oled.DrawImage(Hexi_Heart_,0,0);  // my Hexi_Heart image is offset for some reason
    wait(0.5);  // wait 3 seconds
*/
    oled.FillScreen(COLOR_BLACK); // Clear screen
    oled.Label((uint8_t *)"Hexi",20,5); // Display white "Hexi" at x,y
    textProperties.fontColor = COLOR_RED;
    oled.SetTextProperties(&textProperties);
    oled.Label((uint8_t *)"Heart",45,5); // Display red "Heart" at x,y

#ifdef Debug  // if this is non-production version - do this
    strcpy((char *) text_1,"This is Debug");
    oled.Label((uint8_t *)text_1,15,45);  // text_1 at x,y
    strcpy((char *) text_1,"Ver:");
    oled.Label((uint8_t *)text_1,15,60);  // text_1 at x,y
    sprintf(text_1,"%2.2f  ",SW_Ver);
    oled.Label((uint8_t *)text_1,60,60);// text_1 at x,y
    StartHaptic(); 
    #endif
    
    textProperties.fontColor = COLOR_WHITE;
    oled.SetTextProperties(&textProperties);
    wait(2);  // wait 3 seconds
    

    update_display(); // Displays current screen (screen 0)
    Screen_Timer.attach(&timout_timer,(SCRN_TIME));//start ticker timer for turning off LCD
//  ******************* Main Loop *************************
    while (true) {
            i=0;
    while (i<20)// used for "Heart beat flash and updated any displayed data)
    {
    Thread::wait(500);          // wait 0.5 sec each loop
    if(OLED_PWR==1){
    update_display_date();     // refresh display date w/o updating entire display 
        }// end if
          
    i++;
    }// end while(i<20)
        
//    wait(10);          // wait 10 sec each loop, was orig half sec
    RED_Led = LED_ON;    // Used only for diagnostic of wait command
    Led_clk3 = 1;         // Used only for diagnostic of wait command
    wait(0.01);          // BLIP led 1/10 sec each loop
///    VLPW(0.01);          // BLIP led 1/10 sec each loop
    RED_Led = LED_OFF;    // Used only for diagnostic of wait command
    Led_clk3 = 0; 
    Thread::wait(490);    // keep up the pace, at 0.5 sec (0.01s+0.49s) update date 
    
    } // end of while(true)

}
//  ************** end of main()

void update_display(void)
{
    OLED_PWR = 1;  // make sure OLED power supply is on
    oled_text_properties_t textProperties = {0};  // Need these to change font color
    oled.GetTextProperties(&textProperties);      // Need these to change font color
    __disable_irq();    // Disable all Interrupts
    switch(Screen_Num) {
        case 0: {// Main Screen
            HexiwearBattery battery;
            battery.sensorOn();  
            oled.FillScreen(COLOR_BLACK); // Clear screen
            
            if (battery.isBatteryCharging()) {
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);  
  //          sprintf(text_1, "%s", "chrg");           
            sprintf(text_1, "%i%%+", (uint8_t)battery.readLevelPercent());
            Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED while fully charged
            } else {
            sprintf(text_1, "%i%%", (uint8_t)battery.readLevelPercent());
            }
            oled.TextBox((uint8_t *)text_1,60,0,35,15); //show level value of battery in a 35px by 15px text box at x=60, y=0
        
        textProperties.fontColor = COLOR_WHITE;
        oled.SetTextProperties(&textProperties);
            
            oled.Label((uint8_t *)"Batt",35,0); // Display "Batt" at x,y
//            oled.Label((uint8_t *)"Date",35,20); // Display "Date" at x,y
//           oled.Label((uint8_t *)"Time",35,40); // Display "Time" at x,y
//            oled.Label((uint8_t *)"H.I.",10,80); // Display "H.I." at x,y

            oled.Label((uint8_t *)"BT",40,80);  //Display "BT" at x,y
            oled.Label((uint8_t *)"Menu",60,80);  //Display "Menu" at x,y
            
            textProperties.fontColor = COLOR_GRAY;
            if(BLE_On == 1){
               textProperties.fontColor = COLOR_BLUE; // If BLE on make "BT" blue!
               }
            oled.SetTextProperties(&textProperties);
            
            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];
            time_t seconds = time(NULL);
            strftime(buffer,32, "%a,%d %m %Y.%H:%M:%S\r", localtime(&seconds)); //format local time and store in buffer
            
            textProperties.font = OpenSans_12x18_Regular;  //  Max Width of Character  = 12px, Max Height of Character = 18px 
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);        
            
            sprintf(text_1,"%c%c/%c%c/%c%c%c%c ",buffer[7],buffer[8],buffer[4],buffer[5],buffer[10],buffer[11],buffer[12],buffer[13]);
            oled.Label((uint8_t *)text_1,15,25);// Date at x,y
            sprintf(text_1,"%c%c:%c%c:%c%c ",buffer[15],buffer[16],buffer[18],buffer[19],buffer[21],buffer[22]);
            oled.Label((uint8_t *)text_1,25,40);// Time 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);
                      
            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
            strcpy((char *) text,"dF");oled.Label((uint8_t *)text,18,80);
            
            if(Heart_Rate_Mode == 1) {
                oled.Label((uint8_t *)"BPM",35,60); // Display "H.I." at x,y
            }
            break;
        }
        case 1: {// Panic Alert option
            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"Panic Alert",20,5); // Display at x,y
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Enter",60,80);  //Display "enter" at x,y
            break;
        }
        case 2: {// Fall Alert option
            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 ",42,40);   
            }
            else {               
            textProperties.fontColor = COLOR_GRAY;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)" Off ",40,40);  
        
                } 
            textProperties.fontColor = COLOR_WHITE; 
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Toggle",59,80);  //Display "Toggle" at x,y
            break;
        }
        case 3: {// Heart Rate Monitoring option
            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"Heart Rate",20,5); // Display at x,y
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Enter",60,80);  //Display at x,y
            break;
        }
        case 4: {// Alert History option
            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"Alert History",10,5); // Display at x,y
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Enter",60,80);  //Display at x,y
            break;
        }
        case 5: {// About HexiHeart Screen

            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"Hexi",20,20); // Display white "Hexi" at x,y
            textProperties.fontColor = COLOR_RED;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"Heart",45,20); // Display red "Heart" at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            strcpy((char *) text_1,"About");
            oled.Label((uint8_t *)text_1,30,5);  // text_1 at x,y
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Enter",60,80);  //Display at x,y
            break;
        }

        case 6: {// Panic Alert
            oled.FillScreen(COLOR_BLACK); // Clear screen
            if (Panic_Alert == 0) {
                oled.Label((uint8_t *)"Send ",20,10); // Display at x,y
            } else {
                oled.Label((uint8_t *)"Dismiss ",17,10); // Display at x,y
            }
            oled.Label((uint8_t *)"Panic Alert",15,40); // Display at x,y
            oled.Label((uint8_t *)"-->",80,15); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            break;
        }
        case 7: {// Heart Rate Zone

            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"Heart Rate",15,5); // Display at x,y
            oled.Label((uint8_t *)"HR:",15,25); // Display at x,y
            sprintf(display_buff, "%u", Heart_Rate);
            textProperties.fontColor = COLOR_RED; //Change font to red
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)display_buff,43,25); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"Age: ",15,45); // Display at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties); //implements the color change
            sprintf(display_buff, "%u", Age); //Convert int to char array for displaying user age
            oled.Label((uint8_t *)display_buff,43,45); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"On",80,15); // "+" at x,y
            oled.Label((uint8_t *)"Off",78,60); // "-" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80); // Display "Next" at x,y

            //heart.enable();
            //sprintf(display_buff, "%u", heart.getRevisionID()); //Convert int to char array for displaying user age
            //oled.Label((uint8_t *)display_buff,45,25); // Display at x,y
            //update_display();
            break;
        }
        case 8: {// Alert History
            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"Alert History",5,5); // Display at x,y
            oled.Label((uint8_t *)"Date - Time",20,40); // Display at x,y
            oled.Label((uint8_t *)"Alert Type:",20,60); // Display at x,y
            oled.Label((uint8_t *)"+",85,15); // "*" at x,y
            oled.Label((uint8_t *)"-",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            break;
        }
        
        case 9: {// About HexiHeart info1
                    oled.FillScreen(COLOR_BLACK); // Clear screen
                    oled.Label((uint8_t *)"Hexi",20,1); // Display white "Hexi" at x,y
                    textProperties.fontColor = COLOR_RED;
                    oled.SetTextProperties(&textProperties);  
                    oled.Label((uint8_t *)"Heart",45,0); // Display red "Heart" at x,y  
                    textProperties.fontColor = COLOR_WHITE;
                    oled.SetTextProperties(&textProperties);  
                    oled.Label((uint8_t *)"Senior Proj",5,15); //
                    oled.Label((uint8_t *)"Team Zeta E2.7",5,30); //
                    oled.Label((uint8_t *)"Texas State Univ",0,45); //        
                    oled.Label((uint8_t *)"+",85,15); // "*" at x,y
                    oled.Label((uint8_t *)"-",85,60); // "*" at x,y
                    oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y                  
                        break;
                }
                        
            case 10: {// About HexiHeart info2
                    oled.FillScreen(COLOR_BLACK); // Clear screen
                    oled.Label((uint8_t *)"Hexi",20,0); // Display white "Hexi" at x,y
                    textProperties.fontColor = COLOR_RED;
                    oled.SetTextProperties(&textProperties);  
                    oled.Label((uint8_t *)"Heart",45,0); // Display red "Heart" at x,y  
                    textProperties.fontColor = COLOR_WHITE;
                    oled.SetTextProperties(&textProperties);  
  //                  oled.Label((uint8_t *)"E2.7 Team Zeta",2,12); //
                    oled.Label((uint8_t *)"Alex Song",5,12); //
                    oled.Label((uint8_t *)"Jasmine ",5,24); // Jasmine Rounsaville is to long
                    oled.Label((uint8_t *)"Rounsaville",15,37); // Jasmine Rounsaville is to long
                    oled.Label((uint8_t *)"Issam Hichami",5,51); // 
                    oled.Label((uint8_t *)"Neil Baker",5,64); //           

                    oled.Label((uint8_t *)"+",85,15); // "*" at x,y
                    oled.Label((uint8_t *)"-",85,60); // "*" at x,y
                    oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y                  
                        break;
                }
                    
            case 11: {// About HexiHeart info3
                    oled.FillScreen(COLOR_BLACK); // Clear screen
                    oled.Label((uint8_t *)"Hexi",20,0); // Display white "Hexi" at x,y
                    textProperties.fontColor = COLOR_RED;
                    oled.SetTextProperties(&textProperties);  
                    oled.Label((uint8_t *)"Heart",45,0); // Display red "Heart" at x,y  
                // *********get screen alignment  **************
                    oled_text_properties_t textProperties = {0};
                    oled.GetTextProperties(&textProperties); 
                // *********Set text color and screen alignment  **************
                    textProperties.alignParam = OLED_TEXT_ALIGN_CENTER;
                    oled.SetTextProperties(&textProperties);   
  
                    #ifdef Debug  // if this is non-production version - do this
                        oled.Label((uint8_t *)"This is Debug",0,25);  // text_1 at X=10,y=25
                        oled.Label((uint8_t *)"Ver of SW",0,40);  // text_1 at x=20,y=40
                    #endif
                    textProperties.fontColor = COLOR_WHITE;
                    oled.SetTextProperties(&textProperties);  
                    sprintf(text_1," SW_Ver:%2.2f  ",SW_Ver);
                    oled.Label((uint8_t *)text_1,0,55);// text_1 at x=10,y
                    textProperties.alignParam = OLED_TEXT_ALIGN_LEFT;
                    oled.SetTextProperties(&textProperties);  
                    oled.Label((uint8_t *)"+",85,15); // "*" at x,y
                    oled.Label((uint8_t *)"-",85,60); // "*" at x,y
                    oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y                  
                        break;
                }       
        
#ifdef Debug  // if this is non-production/debug version - do this
        case 20: {// Diagnostic/Debug Screens
            oled.FillScreen(COLOR_BLACK); // Clear screen
            textProperties.fontColor = COLOR_RED;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"Diagnostics",10,5); // Display at x,y
            oled.Label((uint8_t *)"Enter",60,80);  //Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y

            break;
        }
        case 21: {// Fall Alert Diagnostic Screen
            if(Fall_Alert_Mode == 0){
                fall_config(11); // turn accel sensor to active to take reading
            }
            oled.FillScreen(COLOR_BLACK); // Clear screen
            textProperties.fontColor = COLOR_RED;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"Fall-Diag",25,5); // Display at x,y
       //     oled.Label((uint8_t *)"Diagnostic",25,5); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            gyro.acquire_gyro_data_dps(Gyro_Data);
            Gyro_Mag = (abs(Gyro_Data[0])+abs(Gyro_Data[1])+abs(Gyro_Data[2]));
            accel.acquire_accel_data_g(Accel_Data);
            if(Fall_Alert_Mode == 0){
                fall_config(12); // turn accel sensor to standby
            }
            Accel_Mag = 2*sqrt(((Accel_Data[0]*Accel_Data[0])+(Accel_Data[1]*Accel_Data[1])+(Accel_Data[2]*Accel_Data[2])));     
            sprintf(text_1," Accel:%2.2f g  ",Accel_Mag);
            oled.Label((uint8_t *)text_1,5,40);// text_1 at x,y
            sprintf(text_1," Gyro:%4.0f D/S  ",Gyro_Mag);
            oled.Label((uint8_t *)text_1,5,60);// text_1 at x,y
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            break;
        }
        case 22: {// Fall Alert Debug Screen
            oled.FillScreen(COLOR_BLACK); // Clear screen
            textProperties.fontColor = COLOR_RED;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"Fall Debug",15,5); // Display at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);
            sprintf(text_1," %i ",Fall_Alert_Mode);
            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){
                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){
                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){
                textProperties.fontColor = COLOR_GREEN;
            }
            oled.SetTextProperties(&textProperties);
            sprintf(text_1," %3.0f D/S  ",Movement_Thresh);
            oled.Label((uint8_t *)text_1,35,65);// text_1 at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"Mode:",5,20); // "*" at x,y
            oled.Label((uint8_t *)"F-Th:",5,35); // "*" at x,y
            oled.Label((uint8_t *)"I-Th:",5,50); // "*" at x,y
            oled.Label((uint8_t *)"M-Th:",5,65); // "*" at x,y
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Enter",60,80);  //Display at x,y
            break;
        }
        case 23: {// Heart Rate Diagnostic Screen
            oled.FillScreen(COLOR_BLACK); // Clear screen
            textProperties.fontColor = COLOR_RED;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"H.R. Diagnostic",5,5); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            //               oled.Label((uint8_t *)" Enter ",59,80);  //Display at x,y
            break;
        }
        case 24: {// Heart Rate Debug Screen
            oled.FillScreen(COLOR_BLACK); // Clear screen
            textProperties.fontColor = COLOR_RED;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"H.R. Debug",10,5); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            //               oled.Label((uint8_t *)" Enter ",59,80);  //Display at x,y
            break;
        }
        case 25: {// Heat Index Diagnostic Screen
            oled.FillScreen(COLOR_BLACK); // Clear screen
            textProperties.fontColor = COLOR_RED;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"H.I. Diagnostic",5,5); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            //             oled.Label((uint8_t *)" Enter ",59,80);  //Display at x,y

            Heat_Index_Calculation();
            
            oled_text_properties_t textProperties = {0};
            oled.GetTextProperties(&textProperties);
      
            strcpy((char *) text,"Temp.");
            oled.Label((uint8_t *)text,5,40); 
            strcpy((char *) text,"Humidity");
            oled.Label((uint8_t *)text,5,57);   
            strcpy((char *) text,"H.I.");
            oled.Label((uint8_t *)text,5,23);        
      
        /* Set text properties to white and right aligned for the dynamic text */
            textProperties.fontColor = COLOR_GREEN;
            textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
            oled.SetTextProperties(&textProperties);  
            
        /* Format the value */
            sprintf(text,"%i",sample_ftemp);
        
        /* Display temp reading in 15px by 15px textbox at(x=55, y=40) */
            oled.TextBox((uint8_t *)text,55,40,15,15); //Increase textbox for more digits
        
        /* Display Units */
            strcpy((char *) text,"dF");
            oled.Label((uint8_t *)text,71,40);       
      
        /* Format the value */
            sprintf(text,"%i",sample_humid);
        
        /* Display Hum reading in 15px by 15px textbox at(x=55, y=57) */
            oled.TextBox((uint8_t *)text,55,57,15,15); //Increase textbox for more digits
        
        /* Display Units */
            strcpy((char *) text,"%");
            oled.Label((uint8_t *)text,71,57); 
        
         /* Set text properties to white and right aligned for the dynamic text */
            textProperties.fontColor = COLOR_BLUE;
            textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
            oled.SetTextProperties(&textProperties);        
      
        /* Format the value */
            sprintf(text,"%i",heat_index);
        
        /* Display HI reading in 15px by 15px textbox at(x=55, y=23) */
            oled.TextBox((uint8_t *)text,55,23,15,15); //Increase textbox for more digits
        
        /* Display Units */
            strcpy((char *) text,"dF");oled.Label((uint8_t *)text,71,23);
            
            break;
        }
        case 26: {//Heart Rate Config Option
            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"HR Config",10,5); // Display at x,y
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Enter",60,80);  //Display "enter" at x,y
            break;
        }
        case 27: { //Enter Age Screen
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Input Age", 10, 5);
            sprintf(display_buff, "%u", Age); //Convert int to char array for displaying user age
            oled.Label((uint8_t *)"Age:", 10, 30);
            oled.Label((uint8_t *)"+",85,15); // "*" at x,y
            oled.Label((uint8_t *)"-",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Menu",10,80); // Display "Menu" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)display_buff,43,30); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"Max bpm:",10,50);
            textProperties.fontColor = COLOR_RED;
            oled.SetTextProperties(&textProperties); //implements the color change
            sprintf(display_buff, "%u", Max_Bpm); //Convert int to char array for displaying user max bpm
            oled.Label((uint8_t *)display_buff, 65, 50);
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            break;
        }
        case 28: {//Choose Heart Rate Vibration Option
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Vibrate Pref", 10, 10);
            oled.Label((uint8_t *)"Option:", 10, 25);
            oled.Label((uint8_t *)"+",85,15); // "+" at x,y
            oled.Label((uint8_t *)"-",85,60); // "-" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            sprintf(display_buff, "%u", HR_Vibration); //Convert int to char array for displaying user preference
            textProperties.fontColor = COLOR_GREEN; //Change font to green
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)display_buff,55,25); // Display at x,y
            if(HR_Vibration == 1) {
                textProperties.fontColor = COLOR_RED; //Change font to red
                oled.SetTextProperties(&textProperties); //Implement color change
                oled.Label((uint8_t *)"All On",10,45); // Display at x,y
            } else if(HR_Vibration == 2) {
                textProperties.fontColor = COLOR_RED; //Change font to red
                oled.SetTextProperties(&textProperties);//Implement color change
                oled.Label((uint8_t *)"Only Entering",10,38);// Display at x,y
                oled.Label((uint8_t *)"And Exiting",10,53);// Display at x,y
                oled.Label((uint8_t *)"Target Zone",10,68);// Display at x,y

            } else if(HR_Vibration == 3) {
                textProperties.fontColor = COLOR_RED; //Change font to red
                oled.SetTextProperties(&textProperties); //Implement color change
                oled.Label((uint8_t *)"All Off",10,45);// Display at x,y
            }
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            break;
        }
        case 29: { //Zone Boundary Info
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"HR Zone Info", 10, 5);// Display at x,y
            textProperties.fontColor = COLOR_YELLOW; //Change font to yellow
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Z1:", 10, 20);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone1[0]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 30, 20);// Display at x,y
            oled.Label((uint8_t *)"-", 52, 20);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone1[1]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 60, 20);// Display at x,y
            textProperties.fontColor = COLOR_BLUE; //Change font to blue
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Z2:", 10, 35);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone2[0]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 30, 35);// Display at x,y
            oled.Label((uint8_t *)"-", 52, 35);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone2[1]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 60, 35);// Display at x,y
            textProperties.fontColor = COLOR_GREEN; //Change font to green
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Z3:", 10, 50);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone3[0]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 30, 50);// Display at x,y
            oled.Label((uint8_t *)"-", 52, 50);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone3[1]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 60, 50);// Display at x,y
            textProperties.fontColor = COLOR_RED; //Change font to red
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Z4:", 10, 65);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone4[0]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 30, 65);// Display at x,y
            oled.Label((uint8_t *)"-", 52, 65);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone4[1]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 60, 65);// Display at x,y
            textProperties.fontColor = COLOR_WHITE; //Change font to white
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            break;
        }
        case 30: { //Enter Target Heart Rate Zone Preference
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Zone Pref", 10, 5);// Display at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            oled.Label((uint8_t *)"+",85,15); // "+" at x,y
            oled.Label((uint8_t *)"-",85,60); // "-" at x,y
            oled.Label((uint8_t *)"Target:", 10, 25);// Display at x,y
            sprintf(display_buff, "%u", Target_Zone); // Convert int to char to display
            if(Target_Zone == 1) {
                textProperties.fontColor = COLOR_YELLOW; //Change font to yellow
                oled.SetTextProperties(&textProperties);//Implement color change
            } else if(Target_Zone == 2) {
                textProperties.fontColor = COLOR_BLUE; //Change font to blue
                oled.SetTextProperties(&textProperties);//Implement color change
            } else if(Target_Zone == 3) {
                textProperties.fontColor = COLOR_GREEN; //Change font to green
                oled.SetTextProperties(&textProperties);//Implement color change
            } else if(Target_Zone == 4) {
                textProperties.fontColor = COLOR_RED; //Change font to red
                oled.SetTextProperties(&textProperties);//Implement color change
            }
            oled.Label((uint8_t *)display_buff, 55, 25);// Display at x,y
            textProperties.fontColor = COLOR_WHITE; //Change font to white
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Bounds:", 10, 45);// Display at x,y
            if(Target_Zone == 1) {
                textProperties.fontColor = COLOR_YELLOW; //Change font to yellow
                oled.SetTextProperties(&textProperties);//Implement color change
                sprintf(display_buff, "%u", HR_Zone1[0]); // Convert int to char to display
                oled.Label((uint8_t *)display_buff, 10, 60);// Display at x,y
                oled.Label((uint8_t *)"-", 32, 60);// Display at x,y
                sprintf(display_buff, "%u", HR_Zone1[1]); // Convert int to char to display
                oled.Label((uint8_t *)display_buff, 40, 60);// Display at x,y
            } else if(Target_Zone == 2) {
                textProperties.fontColor = COLOR_BLUE; //Change font to blue
                oled.SetTextProperties(&textProperties);//Implement color change
                sprintf(display_buff, "%u", HR_Zone2[0]); // Convert int to char to display
                oled.Label((uint8_t *)display_buff, 10, 60);// Display at x,y
                oled.Label((uint8_t *)"-", 32, 60);// Display at x,y
                sprintf(display_buff, "%u", HR_Zone2[1]); // Convert int to char to display
                oled.Label((uint8_t *)display_buff, 40, 60);// Display at x,y
            } else if(Target_Zone == 3) {
                textProperties.fontColor = COLOR_GREEN; //Change font to green
                oled.SetTextProperties(&textProperties);//Implement color change
                sprintf(display_buff, "%u", HR_Zone3[0]); // Convert int to char to display
                oled.Label((uint8_t *)display_buff, 10, 60); // Display at x,y
                oled.Label((uint8_t *)"-", 32, 60); // Display at x,y
                sprintf(display_buff, "%u", HR_Zone3[1]); // Convert int to char to display
                oled.Label((uint8_t *)display_buff, 40, 60);// Display at x,y
            } else if(Target_Zone == 4) {
                textProperties.fontColor = COLOR_RED; //Change font to red
                oled.SetTextProperties(&textProperties);//Implement color change
                sprintf(display_buff, "%u", HR_Zone4[0]); // Convert int to char to display
                oled.Label((uint8_t *)display_buff, 10, 60); // Display at x,y
                oled.Label((uint8_t *)"-", 32, 60); // Display at x,y
                sprintf(display_buff, "%u", HR_Zone4[1]); // Convert int to char to display
                oled.Label((uint8_t *)display_buff, 40, 60); // Display at x,y
            }
            textProperties.fontColor = COLOR_WHITE; //Change font to white
            oled.SetTextProperties(&textProperties);//Implement color change
            break;
        }
        case 31: {
            oled.FillScreen(COLOR_BLACK);
            Heart_Rate_Vibrations();
            oled.Label((uint8_t *)"Enter HR", 10, 5);// Display at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            oled.Label((uint8_t *)"+",85,15); // "+" at x,y
            oled.Label((uint8_t *)"-",85,60); // "-" at x,y
            oled.Label((uint8_t *)"HR:", 10, 25);
            sprintf(display_buff, "%u", Heart_Rate); // Convert int to char to display
            textProperties.fontColor = COLOR_RED; //Change font to red
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)display_buff, 40, 25);
            textProperties.fontColor = COLOR_WHITE; //Change font to white
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Cur Zone:", 10, 45);
            if(Current_Zone == 1) {
                textProperties.fontColor = COLOR_YELLOW;
                oled.SetTextProperties(&textProperties);
            } else if(Current_Zone == 2) {
                textProperties.fontColor = COLOR_BLUE;
                oled.SetTextProperties(&textProperties);
            } else if(Current_Zone == 3) {
                textProperties.fontColor = COLOR_GREEN;
                oled.SetTextProperties(&textProperties);
            } else if(Current_Zone == 4) {
                textProperties.fontColor = COLOR_RED;
                oled.SetTextProperties(&textProperties);
            }
            sprintf(display_buff, "%u", Current_Zone); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 71, 45);
            textProperties.fontColor = COLOR_WHITE; //Change font to white
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Prev Zone:", 10, 60);
            if(Prev_Zone == 1) {
                textProperties.fontColor = COLOR_YELLOW;
                oled.SetTextProperties(&textProperties);
            } else if(Prev_Zone == 2) {
                textProperties.fontColor = COLOR_BLUE;
                oled.SetTextProperties(&textProperties);
            } else if(Prev_Zone == 3) {
                textProperties.fontColor = COLOR_GREEN;
                oled.SetTextProperties(&textProperties);
            } else if(Prev_Zone == 4) {
                textProperties.fontColor = COLOR_RED;
                oled.SetTextProperties(&textProperties);
            }
            sprintf(display_buff, "%u", Prev_Zone); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 71, 60);
            textProperties.fontColor = COLOR_WHITE; //Change font to white
            oled.SetTextProperties(&textProperties);//Implement color change
            Led_Zone_Indicator();
            break;
        }
        case 32: {
            //Zone Boundary Info
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"HR Zone Info", 10, 5);// Display at x,y
            textProperties.fontColor = COLOR_YELLOW; //Change font to yellow
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Z1:", 10, 20);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone1[0]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 30, 20);// Display at x,y
            oled.Label((uint8_t *)"-", 52, 20);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone1[1]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 60, 20);// Display at x,y
            textProperties.fontColor = COLOR_BLUE; //Change font to blue
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Z2:", 10, 35);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone2[0]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 30, 35);// Display at x,y
            oled.Label((uint8_t *)"-", 52, 35);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone2[1]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 60, 35);// Display at x,y
            textProperties.fontColor = COLOR_GREEN; //Change font to green
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Z3:", 10, 50);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone3[0]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 30, 50);// Display at x,y
            oled.Label((uint8_t *)"-", 52, 50);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone3[1]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 60, 50);// Display at x,y
            textProperties.fontColor = COLOR_RED; //Change font to red
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Z4:", 10, 65);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone4[0]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 30, 65);// Display at x,y
            oled.Label((uint8_t *)"-", 52, 65);// Display at x,y
            sprintf(display_buff, "%u", HR_Zone4[1]); // Convert int to char to display
            oled.Label((uint8_t *)display_buff, 60, 65);// Display at x,y
            textProperties.fontColor = COLOR_WHITE; //Change font to white
            oled.SetTextProperties(&textProperties);//Implement color change
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            break;
        }  
        case 41: { //Fall mode
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Adj Fall Mode", 10, 5);
            sprintf(display_buff, "%u", Fall_Alert_Mode); //Convert int to char array for displaying mode
            oled.Label((uint8_t *)"Mode:", 5, 30);
            oled.Label((uint8_t *)"+",85,15); // "*" at x,y
            oled.Label((uint8_t *)"-",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)display_buff,43,30); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            break;
        }
        case 42: { //Fall Thresh
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Adj F-Th", 10, 5);
            sprintf(display_buff, "%2.2f g", Fall_Thresh); //Convert int to char array for displaying mode
            oled.Label((uint8_t *)"F_Th:", 5, 30);
            oled.Label((uint8_t *)"+",85,15); // "*" at x,y
            oled.Label((uint8_t *)"-",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)display_buff,43,30); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            break;
        }
        case 43: { //Impact Thresh
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Adj I-Th", 10, 5);
            sprintf(display_buff, "%2.2f g", Impact_Thresh); //Convert int to char array for displaying mode
            oled.Label((uint8_t *)"I_Th:", 5, 30);
            oled.Label((uint8_t *)"+",85,15); // "*" at x,y
            oled.Label((uint8_t *)"-",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)display_buff,43,30); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            break;
        }
        case 44: { //Motion Thresh
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Adj M-Th", 10, 5);
            sprintf(display_buff, "%4.0f D/S", Movement_Thresh); //Convert int to char array for displaying mode
            oled.Label((uint8_t *)"M_Th:", 5, 30);
            oled.Label((uint8_t *)"+",85,15); // "*" at x,y
            oled.Label((uint8_t *)"-",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)display_buff,43,30); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            break;
        }//end case 44
        case 45: { //Min_Movement_Time
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Adj MinM_Tim", 10, 5);
            sprintf(display_buff, "%1.2fSec", Min_Movement_Time); //Convert int to char array for displaying mode
            oled.Label((uint8_t *)"m_Tm:", 5, 30);
            oled.Label((uint8_t *)"+",85,15); // "*" at x,y
            oled.Label((uint8_t *)"-",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)display_buff,43,30); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            break;
        }//end case 45
        case 46: { //Min_Movement_Time
            oled.FillScreen(COLOR_BLACK);
            oled.Label((uint8_t *)"Adj MinM_Dur", 10, 5);
            sprintf(display_buff, "%2.1fSec", Min_Movement_duration); //Convert int to char array for displaying mode
            oled.Label((uint8_t *)"mDur:", 5, 30);
            oled.Label((uint8_t *)"+",85,15); // "*" at x,y
            oled.Label((uint8_t *)"-",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
           // oled.Label((uint8_t *)"Next",60,80);  //Display "Next" at x,y
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)display_buff,43,30); // Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            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

        case 71: {// BLE
            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"BLUETOOTH",5,5); // Display at x,y
            oled.Label((uint8_t *)"Enter",60,80);  //Display at x,y
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            oled.Label((uint8_t *)"*",85,15); // "*" at x,y
            oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            break;
        }

        case 72: {// BlueTooth on/off
            oled.FillScreen(COLOR_BLACK); // Clear screen
            oled.Label((uint8_t *)"BLUETOOTH",5,5); // Display at x,y
            if (BLE_On == 1) {
                strcpy((char *) text,"PAIR CODE");
                oled.TextBox((uint8_t *)text,5,25,85,18);
                /* Display Bond Pass Key in a 85px by 18px textbox at x=5,y=25 */
                
/* This part was not compiling
                sprintf(text,"%d", kw40z_device.GetPassKey());
                oled.TextBox((uint8_t *)text,0,40,95,18);
*/        
                oled.TextBox((uint8_t *)"Passkey",5,40,85,18); //show passkey in a 85px by 18px text box at x=5, y=40
            } else {
                oled.Label((uint8_t *)" Off ",40,40);
            }
  //          oled.Label((uint8_t *)"*",85,15); // "*" at x,y
  //          oled.Label((uint8_t *)"*",85,60); // "*" at x,y
            oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
            oled.Label((uint8_t *)"Toggle",59,80);  //Display "Toggle" at x,y
            break;
        }


        default: {
            Error_Num=1;
            error_screen(); // Clear screen
            break;
        }
    }//end of switch
    __enable_irq();     // Enable all Interrupts
}// end upday_display()

void error_screen(void)
{
    oled.FillScreen(COLOR_RED); // Clear screen
    oled.Label((uint8_t *)"Error! ",30,30); // Display error at x,y
    sprintf(text_1," %i  ",Error_Num);
    oled.Label((uint8_t *)text_1,30,60); // Display error at x,y
    wait(3);  // wait 3 seconds
    oled.FillScreen(COLOR_BLACK); // Clear screen
}

/*****************************************************************************
Name: StartHaptic
Purpose: Cause the HexiHeart device to vibrate for a predetermined amount of
         time
Inputs: None
Returns: None
******************************************************************************/
void StartHaptic(void)
{
    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
Purpose: Cause the HexiHeart device to vibrate for x amount of time
Inputs: An int representing the duration of the vibration
Returns: None
******************************************************************************/

void StartHaptic(int x)
{   
    hapticTimer.start(x);
    haptic = 1;
}

void StopHaptic(void const *n)
{
    haptic = 0;
    hapticTimer.stop();
}

/*****************************************************************************
Name: Increment_Age
Purpose: Increment the user's age by 1
Inputs: None
Returns: None
******************************************************************************/
void Increment_Age()
{
    StartHaptic();
    if(Age < 100) {
        Age += 1;
        Screen_Num = 27;
    } else {
        Age = 1;
    }
}

/*****************************************************************************
Name: Decrement_Age
Purpose: Decrement the user's age by 1
Inputs: None
Returns: None
******************************************************************************/
void Decrement_Age()
{
    StartHaptic();
    if(Age == 1) {
        Age = 100;
    } else {
        Age -= 1;
        Screen_Num = 27;
    }
}

/*****************************************************************************
Name: Set_Max_Bpm
Purpose: Calculates the user's maximum heart rate based on their age
Inputs: None
Returns: None
******************************************************************************/
void Set_Max_Bpm()
{
    Max_Bpm = 220 - Age;
}

/*****************************************************************************
Name: Set_Zone_Boundaries
Purpose: Calculates the user's heart rate zones' boundaries based on the user's
         maximum heart rate
Inputs: None
Returns: None
******************************************************************************/
void Set_Zone_Boundaries()
{
    Set_Max_Bpm();
    HR_Zone1[0] = Max_Bpm * .50;   //Set Heart Rate Zone 1
    HR_Zone1[1] = Max_Bpm * .60;   //Set Heart Rate Zone 1
    HR_Zone2[0] = HR_Zone1[1] + 1;   //Set Heart Rate Zone 2
    HR_Zone2[1] = Max_Bpm * .70;   //Set Heart Rate Zone 2
    HR_Zone3[0] = HR_Zone2[1] + 1;   //Set Heart Rate Zone 3
    HR_Zone3[1] = Max_Bpm * .80;   //Set Heart Rate Zone 3
    HR_Zone4[0] = HR_Zone3[1] + 1;   //Set Heart Rate Zone 4
    HR_Zone4[1] = Max_Bpm;   //Set Heart Rate Zone 4
}

/*****************************************************************************
Name: Increment_Target_Zone
Purpose: Imcrements the user's target heart rate zone preference by 1
Inputs: None
Returns: None
******************************************************************************/
void Increment_Target_Zone()
{
    StartHaptic();
    if(Target_Zone == 4) {
        Target_Zone = 1;
    } else {
        Target_Zone += 1;
    }
}

/*****************************************************************************
Name: Decrement_Target_Zone
Purpose: Decrements the user's target heart rate zone preference by 1
Inputs: None
Returns: None
******************************************************************************/
void Decrement_Target_Zone()
{
    StartHaptic();
    if(Target_Zone == 1) {
        Target_Zone = 4;
    } else {
        Target_Zone -= 1;
    }
}

/*****************************************************************************
Name: Increment_HR_Vibr_Pref
Purpose: Increment the user's heart rate vibration preference by 1
Inputs: None
Returns: None
******************************************************************************/
void Increment_HR_Vibr_Pref()
{
    StartHaptic();
    if(HR_Vibration == 3) {
        HR_Vibration = 1;
    } else {
        HR_Vibration += 1;
    }
}

/*****************************************************************************
Name: Decrement_HR_Vibr_Pref
Purpose: Decrement the user's heart rate vibration preference by 1
Inputs: None
Returns: None
******************************************************************************/
void Decrement_HR_Vibr_Pref()
{
    StartHaptic();
    if(HR_Vibration == 1) {
        HR_Vibration = 3;
    } else {
        HR_Vibration -= 1;
    }
}

/*****************************************************************************
Name: Enable_Heart_Rate
Purpose: Turn on the HexiHeart heart rate function
Inputs: None
Returns: None
******************************************************************************/
void Enable_Heart_Rate()
{
    Heart_Rate_Mode = true;
    Heart_Rate_Vibrations();
}

/*****************************************************************************
Name: Disable_Heart_Rate
Purpose: Turn off the HexiHeart heart rate function
Inputs: None
Returns: None
******************************************************************************/
void Disable_Heart_Rate()
{
    Heart_Rate_Mode = false;
    Heart_Rate_Vibrations();
}

/*****************************************************************************
Name: Determine_Current_Zone
Purpose: Determines which zone the heart rate is in and assigns the curent
         zone and previous zone
Inputs: None
Returns: None
******************************************************************************/
void Determine_Current_Zone()
{
    Prev_Zone = Current_Zone;

    if(Heart_Rate >= HR_Zone1[0] && Heart_Rate <= HR_Zone1[1]) {
        Current_Zone = 1;
    } else if(Heart_Rate >= HR_Zone2[0] && Heart_Rate <= HR_Zone2[1]) {
        Current_Zone = 2;
    } else if(Heart_Rate >= HR_Zone3[0] && Heart_Rate <= HR_Zone3[1]) {
        Current_Zone = 3;
    } else if(Heart_Rate >= HR_Zone4[0] && Heart_Rate <= HR_Zone4[1]) {
        Current_Zone = 4;
    } else {
        //error reading, don't change anything
    }


}
/*****************************************************************************
Name: Run_Heart_Vibrations
Purpose: Performs the HexiHeart heart rate function
Inputs: None
Returns: None
******************************************************************************/
void Heart_Rate_Vibrations()
{
    if(Heart_Rate_Mode == true) {
        if(HR_Vibration == 1) {
            //All Pre-loaded vibrations enabled
            if(Current_Zone == Prev_Zone) {
                // Do nothing if no zone change
            } else if(Current_Zone == Target_Zone) { //Changed to target zone
                if(Target_Zone == LOWEST_ZONE || Prev_Zone > Target_Zone) { //must have entered from above
                    StartHaptic(ENTER_ABOVE);
                } else if(Target_Zone == HIGHEST_ZONE || Prev_Zone < Target_Zone) { //must have entered from below
                    StartHaptic(ENTER_BELOW);
                }
            } else if(Current_Zone != Target_Zone && Prev_Zone == Target_Zone) {
                if(Target_Zone == HIGHEST_ZONE || Current_Zone < Target_Zone) { //must have exited below
                    StartHaptic(EXIT_BELOW);
                } else if(Target_Zone == LOWEST_ZONE || Current_Zone > Target_Zone) { //must have exited above
                    StartHaptic(EXIT_ABOVE);
                }
            }
        } else if(HR_Vibration == 2) {
            //Only Entering and Exiting target zone
            if(Current_Zone == Prev_Zone) {
                //do nothing
            } else if(Current_Zone == Target_Zone) {
                StartHaptic(VIB_OPT_2);
                wait(0.1);
                StartHaptic(VIB_OPT_2);
            } else if(Current_Zone != Target_Zone && Prev_Zone == Target_Zone) {
                StartHaptic(VIB_OPT_2);
                wait(0.1);
                StartHaptic(VIB_OPT_2);
                wait(0.1);
                StartHaptic(VIB_OPT_2);
            }

        } else  if(HR_Vibration == 3) {
            //No Vibrations

        } else {
            //Error, can only be choices 1-3
            error_screen();
        }
    }
}

/*****************************************************************************
Name: Increment_Heart_Rate
Purpose: Manually increment the the heart rate measurement by 1 for testing
         purposes
Inputs: None
Returns: None
******************************************************************************/
void Increment_Heart_Rate()
{
    //StartHaptic();
    if(Heart_Rate == HR_Zone4[1]) {
        Heart_Rate = HR_Zone1[0];
    } else {
        Heart_Rate += 1;
    }
}

/*****************************************************************************
Name: Decrement_Heart_Rate
Purpose: Manually decrement the the heart rate measurement by 1 for testing
         purposes
Inputs: None
Returns: None
******************************************************************************/
void Decrement_Heart_Rate()
{
    //StartHaptic();
    if(Heart_Rate == HR_Zone1[0]) {
        Heart_Rate = HR_Zone4[1];
    } else {
        Heart_Rate -= 1;
    }
}  // end of Decrement_Heart_Rate

void Led_Zone_Indicator()
{
  if(Led_Zones == true)
  {
    if(Current_Zone == 1)
    {
        BLU_Led = LED_OFF;
        RED_Led = LED_ON;
        GRN_Led = LED_ON;
        
        wait(0.5);
        RED_Led = LED_OFF;
        GRN_Led = LED_OFF;
    }  
    else if(Current_Zone == 2)
    {
        if(Prev_Zone == 1)
        {
            RED_Led = LED_OFF;
            GRN_Led = LED_OFF;
        }
        else if(Prev_Zone == 3)
        {
            GRN_Led = LED_OFF;
        }
        BLU_Led = LED_ON;
        wait(0.5);  
        BLU_Led = LED_OFF; 
    }
    else if(Current_Zone == 3)
    {
        if(Prev_Zone == 2)
        {
            BLU_Led = LED_OFF;
        }
        else if(Prev_Zone == 4)
        {
            RED_Led = LED_OFF;
        }
        GRN_Led = LED_ON;
        wait(0.5);  
        GRN_Led = LED_OFF; 
    }
    else if(Current_Zone == 4)
    {
        GRN_Led = LED_OFF;
        RED_Led = LED_ON;
        wait(0.5);  
        RED_Led = LED_OFF; 
    }
  }  
}//end of Led_Zone_Indicator 

/*****************************************************************************
Name: Heat_Index_Calculation()
Purpose: Calculates the heat index using the temperature and humidity sensors
Inputs: None
Returns: None
******************************************************************************/
void Heat_Index_Calculation(){
    sample_ftemp = temphumid.sample_ftemp();
 
    sample_humid = temphumid.sample_humid();
            
    hi_calc = -42.379 +
           2.04901523 * sample_ftemp +
           10.14333127 * sample_humid -
           0.22475541 * sample_ftemp * sample_humid -
           0.00683783 * sample_ftemp * sample_ftemp -
           0.05481717 * sample_humid * sample_humid +
           0.00122874 * sample_ftemp * sample_ftemp * sample_humid +
           0.00085282 * sample_ftemp * sample_humid * sample_humid -
           0.00000199 * sample_ftemp * sample_ftemp * sample_humid * sample_humid;
           
        if (sample_humid < 13 && sample_ftemp > 80 && sample_ftemp < 112){
                adjustment = ((13 - sample_humid) / 4) * sqrt((17-abs(sample_ftemp-95.0))/17);
                heat_index = hi_calc - adjustment;
                }
                
        else if (sample_humid > 85 && sample_ftemp > 80 && sample_ftemp < 87){
                adjustment = ((sample_humid - 85) / 10) * ((87 - sample_ftemp)/5);
                heat_index = hi_calc + adjustment;
                }
                
        else if (hi_calc < 80){
                heat_index = 0.5 * (sample_ftemp + 61.0 + ((sample_ftemp - 68.0) * 1.2) + (sample_humid * 0.094));
                }
 
        else {heat_index = hi_calc;}               
}

/*****************************************************************************
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_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
    Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED
         
        if (OLED_ON == 0) {
        OLED_ON = 1; // Scree was off, set to On  
        update_display();      
         }  // endif        
        if (Screen_Num != 21){
            Screen_Num = 21;  //Change to screen 21 (Fall diag screen)
            update_display();
        }  // endif      
         
//__disable_irq();    // Disable all Interrupts
//    oled.Label((uint8_t *)" Fall Detected ",05,70); // Display at x,y 

    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])));
    sprintf(text_1,"Free-Fall:%2.2fg",Accel_Mag);
    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_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_debug interupt routine

/*****************************************************************************
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_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_debug); // reset accel sensor's int#1 to active low and proper int routine
}    //end fall_det_end_debug interupt routine

/*****************************************************************************
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_debug(){
 if(Fall_Alert == 1){
    accel.acquire_accel_data_g(Accel_Data_Event);
    haptic = 1;
    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) {
        OLED_ON = 1; // Screen was off, set to On  
        update_display();      
         }  // endif 
         
        if (Screen_Num != 21){
            Screen_Num = 21;  //Change to screen 21 (Fall diag screen)
            update_display();
        }  // endif    
        accel.acquire_accel_data_g(Accel_Data);
        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])));
        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_clk2 = 0;  // Turn LED2 off docking station on
        haptic = 0;
 }// end if     
}//end impact_detect_debug interupt routine

/*****************************************************************************
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_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_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) {
        OLED_ON = 1; // Screen was off, set to On  
        update_display();      
         }  // endif 
         
        if (Screen_Num != 21){
            Screen_Num = 21;  //Change to screen 21 (Fall diag screen)
            update_display();
        }  // 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_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 accel_sensor_config(uint8_t Num){ 
// use case switches here to configure for 
switch(Num) {           
                case 0: {// put in standby
                  char d[2]; 
                    d[0] = FXOS8700_CTRL_REG1;                     //Puts device in Standby mode
                    d[1] = 0x00; 
                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2);                            
                    /*For lowest power ~8uA, set ODR-12.5Hz,(low-pwr accel mode) or 2uA in standby mode */
                    break;      
                }// end of case 0
                
                case 1: {// configure for free-fall int only
                    char d[2]; 
                    d[0] = 0x2a;                                       //0x2a Config reg1
                    d[1] = 0x00;                                    //Put device in Standby mode
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1a err",30,05); // Display "error" at x,y                  
                        wait(3.0); // display for 3 seconds
                    }//end if
                    
                    d[0] = 0x0e;                                    //XYZ_DATA_CFG (set full-scall range)
                    d[1] = 0b00000001;                              //Set data to default range of +/-2g for full range (2x0.488mg/LSB), High-pass filter off
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1b err",30,05); // Display "error" at x,y      
                        wait(3.0); // display for 3 seconds
                    }//end if
 /*
                    d[0] = 0x0a;                                    //TRIG_CFG (address of FIFO trigger config reg)
                    d[1] = 0b00000100;                              //Trigger on freefall
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)" Step2 error ",30,05); // Display "error" at x,y      
                        wait(3.0); // display for 3 seconds
                    }//end if
 */                   
                    d[0] = 0x15;                                    //A_FFMT_CFG (address of Free fall trigger config reg), write in Standby only
                    d[1] = 0b00111000;                              //set to freefall, and look at all axis.
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1c err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if
                       
                    d[0] = 0x17;                                    //A_FFMT_THS (address of Free fall threshold reg), write in Active or Standby
  //                  d[1] = 0b00001000;                                //set freefall threshold to about 756mg for now                   
                    d[1] = (uint8_t)(1000*Fall_Thresh/63);            //set freefall threshold - Resolution is 63mg/LSB, 0b111_1111 is maximum value
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1d err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
                     
                    d[0] = 0x18;                                    //A_FFMT_COUNT (address of Free fall debounce counter), write in Active or Standby
                    d[1] = 0b00000110;                              //with ODR at 100Hz, should equal 60mS debounce time or 120mS in Sleep
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1e err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                           
                    d[0] = 0x2b;                                    //CTRL_REG2 (address of control reg), write in Standby only
 //                   d[1] = 0b00001101;                              //Turns Auto-Sleep mode on and low-noise, low power
                    d[1] = 0b00001001;                              //Turns Auto-Sleep mode off (b/c it wasn't waking on int) and low-noise, low power
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1f err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if    
                    
                    d[0] = 0x2c;                                    //CTRL_REG3 (address of Int control reg), write in Standby only
                    d[1] = 0b00001000;                              //FFMT will wake chip from sleep, int are active high
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1g err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if    
                        
                    d[0] = 0x2d;                                    //CTRL_REG4 (address of Int enable reg), write in Standby only
                    d[1] = 0b10000100;                              // FFMT int enabled and for debug I'm using a sleep int
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1h err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if            
                    
                    d[0] = 0x2e;                                    //CTRL_REG5 (Int routing reg), write in Standby only
                    d[1] = 0b00000100;                              // Make FFMT int output on pin INT1(PTC1)
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1i err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if                  
                    
                    d[0] = 0x29;                                    //ASLP_Count (counter used to go to sleep reg), write in Standby only
                    d[1] = 0b00001010;                              // 10*320mS=3.2S of no inturrupts to go to sleep
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1j err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if    
                    
                    d[0] = 0x2a;                         //0x2a Config reg1, write in Standby only except for bit[0]
                    d[1] = 0b00011001;                    //Auto-Sleep mode on set to 50Hz, ODR set to 100Hz Puts device back into Active mode 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc1k err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
                                     
                    break;
                }// end of case 1
                
                case 2: {// configure for vector impact only
                    char d[2]; 
                    
                    d[0] = FXOS8700_CTRL_REG1;                      //Config reg1 0x2a
                    d[1] = 0x00;                                    //Put device in Standby mode
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2a err",30,05); // Display "error" at x,y                  
                        wait(3.0); // display for 3 seconds
                    }//end if
 
                    d[0] = 0x0e;                                    //XYZ_DATA_CFG (set full-scall range)
                    d[1] = 0b00000001;                              //Set data to +/-4g for full range (0.488mg/LSB), High-pass filter off
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2b err",30,05); // Display "error" at x,y      
                        wait(3.0); // display for 3 seconds
                    }//end if
 /*
                    d[0] = 0x0a;                                    //TRIG_CFG (address of FIFO trigger config reg)
                    d[1] = 0b00000110;                              //Trigger on freefall and on Vector
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)" Step2 error ",30,05); // Display "error" at x,y      
                        wait(3.0); // display for 3 seconds
                    }//end if
 */                                      
                    d[0] = 0x5f;                                    //A_VECM_CFG (address of Vector config reg), write in Standby only
                    d[1] = 0b00111000;                              //Use reference values, don't update ref, enable.
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2c err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if
                       
                    d[0] = 0x60;                                    //A_VECM_MSB (address of Vector threshold reg), write in Active or Standby
 //                   d[1] = 0b00000111;                                //set impact threshold to less than 1g for now                   
                    d[1] = (uint8_t)((1000*Impact_Thresh/0.488f)/256);        //set MSB Impact threshold - Resolution is 0.488mg/LSB so 0.5g=1024.6 => MSB=0b00000100 LSB=0b00000000 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2d err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
           
                    d[0] = 0x61;                                    //A_VECM_LSB (address of Vector threshold reg), write in Active or Standby
//                    d[1] = 0b00000011;                                //set impact threshold to less than 1g for now                   
                    d[1] = (uint8_t)(1000*Impact_Thresh/0.488f);
                    d[1] = (uint8_t)(d[1]%256);  //set MSB Impact threshold - Resolution 0.488mg/LSB so 0.5g=1024.6 => MSB=0b00000100 LSB=0b00000000 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2e err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if              
                     
                    d[0] = 0x62;                                    //A_VECM_COUNT (address of Vector debounce counter), write in Active or Standby
                    d[1] = 0b00000110;                              //with ODR at 100Hz, should equal ??mS debounce time or ??mS in Sleep
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2f err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                           
                   // Registers 0x63 - 0x68 are vector reference values which I'm leaving set to 0 because we want absolute measurements    
                                  
                    d[0] = 0x2b;                                    //CTRL_REG2 (address of control reg), write in Standby only
 //                   d[1] = 0b00001101;                              //Turns Auto-Sleep mode on and low-noise, low power
                    d[1] = 0b00001001;                              //Turns Auto-Sleep mode off (b/c it wasn't waking on int) and low-noise, low power
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2g err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if    
                    
                    d[0] = 0x2c;                                    //CTRL_REG3 (address of Int control reg), write in Standby only
                    d[1] = 0b00000100;                              //Vector will wake chip from sleep, int are active high
  //                  d[1] = 0b00001000;                              //FFMT will wake chip from sleep, int are active high
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2h err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if    
                        
                    d[0] = 0x2d;                                    //CTRL_REG4 (address of Int enable reg), write in Standby only
                    d[1] = 0b10000010;                              // Vector int enabled
 //                   d[1] = 0b00000100;                              // FFMT int enabled 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2i err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if            
                    //wait(0.2);  // people have had a problem here and needed a delay
                    
                    d[0] = 0x2e;                                    //CTRL_REG5 (Int routing reg), write in Standby only
                    d[1] = 0b00000100;                              // Make FFMT int output on pin INT1(PTC1) and Vector on INT2(PTD13)
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2j err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if                  
                    
                    d[0] = 0x29;                                    //ASLP_Count (counter used to go to sleep reg), write in Standby only
                    d[1] = 0b00001010;                              // 10*320mS=3.2S of no inturrupts to go to sleep
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2k err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if    
                    
                    d[0] = FXOS8700_CTRL_REG1;                     //CTRL_REG1, write in Standby only except for bit[0]
                    d[1] = 0b00011001;                              //Auto-Sleep mode on set to 50Hz, ODR set to 100Hz Puts device back into Active mode 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc2L err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
                    break;
                }// end of case 2    
     
                case 3: {// configure for motion int only
                    char d[2]; 
                    d[0] = 0x2a;                                      //0x2a Config reg1
                    d[1] = 0x00;                                    //Put device in Standby mode
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc3a err",30,05); // Display "error" at x,y                  
                        wait(3.0); // display for 3 seconds
                    }//end if
                    
                    d[0] = 0x0e;                                    //XYZ_DATA_CFG (set full-scall range)
                    d[1] = 0b00000001;                              //Set data to default range of +/-2g for full range (2x0.488mg/LSB), High-pass filter off
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc3b err",30,05); // Display "error" at x,y      
                        wait(3.0); // display for 3 seconds
                    }//end if
                    
                    d[0] = 0x2a;                         //0x2a Config reg1, write in Standby only except for bit[0]
                    d[1] = 0b00011001;                    //Auto-Sleep mode on set to 50Hz, ODR set to 100Hz Puts device back into Active mode 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc3c err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
                    break;
                }// end of case 3           
                                            
                 case 4: {// configure FFMT for free-fall event AND config for vector impact   
                    char d[2];       
                    d[0] = 0x2a;                                    //0x2a Config reg1,  
                    d[1] = 0x00;                                    //Put device in Standby mode
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4a err",30,05); // Display "error" at x,y                  
                        wait(3.0); // display for 3 seconds
                    }//end if 
 
                    d[0] = 0x0e;                                    //XYZ_DATA_CFG (set full-scall range)
                    d[1] = 0b00000001;                              //Set data to +/-4g for full range (0.488mg/LSB), High-pass filter off
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4b err",30,05); // Display "error" at x,y      
                        wait(3.0); // display for 3 seconds
                    }//end if
 /*
                    d[0] = 0x0a;                                    //TRIG_CFG (address of FIFO trigger config reg)
                    d[1] = 0b00000110;                              //Trigger on freefall and on Vector
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)" Step2 error ",30,05); // Display "error" at x,y      
                        wait(3.0); // display for 3 seconds
                    }//end if
  */                  
                    d[0] = 0x15;                                    //A_FFMT_CFG (address of Free fall trigger config reg), write in Standby only
                    d[1] = 0b00111000;                              //set to freefall, and look at all axis.
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4c err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if
                       
                    d[0] = 0x17;                                    //A_FFMT_THS (address of Free fall threshold reg), write in Active or Standby
 //                   d[1] = 0b00001000;                                //set freefall threshold to about 756mg for now                   
                   d[1] = (uint8_t)(1000*Fall_Thresh/63);            //set freefall threshold - Resolution is 63mg/LSB, 0b111_1111 is maximum value
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4d err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
                     
                    d[0] = 0x18;                                    //A_FFMT_COUNT (address of Free fall debounce counter), write in Active or Standby
                    d[1] = 0b00000110;                              //with ODR at 100Hz, should equal 60mS debounce time or 120mS in Sleep
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4e err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                                             
                    d[0] = 0x5f;                                    //A_VECM_CFG (address of Vector config reg), write in Standby only
                    d[1] = 0b00111000;                              //Use reference values, don't update ref, enable.
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4f err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if
                       
                    d[0] = 0x60;                                    //A_VECM_MSB (address of Vector threshold reg), write in Active or Standby
 //                   d[1] = 0b00000111;                                //set impact threshold to less than 1g for now                   
                    d[1] = (uint8_t)((1000*Impact_Thresh/0.488f)/256);        //set MSB Impact threshold - Resolution is 0.488mg/LSB so 0.5g=1024.6 => MSB=0b00000100 LSB=0b00000000 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4g err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
           
                    d[0] = 0x61;                                    //A_VECM_LSB (address of Vector threshold reg), write in Active or Standby
//                    d[1] = 0b00000011;                                //set impact threshold to less than 1g for now                   
                    d[1] = (uint8_t)(1000*Impact_Thresh/0.488f);
                    d[1] = (uint8_t)(d[1]%256);  //set MSB Impact threshold - Resolution 0.488mg/LSB so 0.5g=1024.6 => MSB=0b00000100 LSB=0b00000000 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4h err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if             
                     
                    d[0] = 0x62;                                    //A_VECM_COUNT (address of Vector debounce counter), write in Active or Standby
                    d[1] = 0b00000100;                              //with ODR at 100Hz, 0x04 should equal 40mS debounce time or 80mS in 50Hz Sleep
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4i err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                           
                   // Registers 0x63 - 0x68 are vector reference values which I'm leaving set to 0 because we want absolute measurements    
                                  
                    d[0] = 0x2b;                                    //CTRL_REG2 (address of control reg), write in Standby only
 //                   d[1] = 0b00001101;                              //Turns Auto-Sleep mode on and low-noise, low power
                    d[1] = 0b00001001;                              //Turns Auto-Sleep mode off (b/c it wasn't waking on int) and low-noise, low power
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4jerr",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if    
                    
                    d[0] = 0x2c;                                    //CTRL_REG3 (address of Int control reg), write in Standby only
                    d[1] = 0b00001100;                              //FFMT or Vector will wake chip from sleep, int are active high
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4k err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if    
                        
                    d[0] = 0x2d;                                    //CTRL_REG4 (address of Int enable reg), write in Standby only
                    d[1] = 0b10000110;                              // FFMT and Vector int enabled
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4L err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if            
                   // wait(0.2);  // people have had a problem here and needed a delay
                    
                    d[0] = 0x2e;                                    //CTRL_REG5 (Int routing reg), write in Standby only
                    d[1] = 0b00000100;                              // Make FFMT int output on pin INT1(PTC1) and Vector on INT2(PTD13)
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4m err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if                  
                    
                    d[0] = 0x29;                                    //ASLP_Count (counter used to go to sleep reg), write in Standby only
                    d[1] = 0b00001010;                              // 10*320mS=3.2S of no inturrupts to go to sleep
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4n err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if                  
                    
                    d[0] = 0x2a;                          //0x2a Config reg1, write in Standby only except for bit[0]
                    d[1] = 0b00011001;                    //Auto-Sleep mode on set to 50Hz, ODR set to 100Hz Puts device back into Active mode 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"Acc4o err",30,05); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if   
                    break;
                }// end of case 4
                       
                case 10: {// reset IC 
                  char d[2]; 
                    d[0] = 0x2a;                          //0x2a Config reg1
                    d[1] = 0x00;                                    //Put device in Standby mode
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)" Step10a err",30,05); // Display "error" at x,y                  
                        wait(3.0); // display for 3 seconds
                    }//end if
                       
                    d[0] = 0x2b;                                //CTRL_REG2 
                    d[1] = 0b01000000;                          // set bit to force reset of FXOS8700 
                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
                        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
                    break;
                }// end case 10      
                
                case 11: {// wake for simple data read, was in stanby
                  char d[2];
                    d[0] = FXOS8700_CTRL_REG1;                     //Puts device in Standby mode just in case
                    d[1] = 0x00; 
                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2); 
                      
                    d[0] = 0x0e;                                    //XYZ_DATA_CFG (set full-scall range)
                    d[1] = 0b00000001;                              //Set data to +/-4g for full range (0.488mg/LSB), High-pass filter off
                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2);  
                                               
                    /*For lowest power ~8uA, set ODR-12.5Hz,(low-pwr accel mode) or 2uA in standby mode */        
                    d[0] = 0x2a;                          //0x2a Config reg1, write in Standby only except for bit[0]
                    d[1] = 0b00011001;                    //Auto-Sleep mode on set to 50Hz, ODR set to 100Hz Puts device back into Active mode 
                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d, 2);
                    break;
                }// end of case 11 
                
                case 12: {// put into standby for low power
                  char d[2]; 
                    d[0] = FXOS8700_CTRL_REG1;                     //Puts device in Standby mode
                    d[1] = 0x00; 
                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d, 2);                       
                    /*For lowest power ~8uA, set ODR-12.5Hz,(low-pwr accel mode) or 2uA in standby mode */
                    break;
                }// end of case 11             
                
                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 accel_sensor_cconfig

/*****************************************************************************
Name: gyro_sensor_config()
Purpose: Used to set gyro IC's internal registers for chip level
interrupts and power modes
Inputs: int value from 0 to 256
Returns: None
******************************************************************************/

void gyro_sensor_config(uint8_t Num){ 
// use case switches here to configure for 
switch(Num) {                     
                case 0: {// put in standby
                    /*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_err0a",20,45); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                    break;    
                }// end of case 0  
                
                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  
                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"gyr_err1a",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_err1b",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_err1c",20,45); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
                    break;
                }// end of case 1
                
                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  
                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"gyr_err3",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_err3a",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_err3b",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_err3c",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_err3d",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_err3e",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_err3f",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_err3g",20,45); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if  
                    break;
                }// end of case 3

                case 10: {// reset Gyro IC 
                  char d[2];    
                    d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1 0x13 - Op mode, ODR selection, reset
                    d[1] = 0b01000000;                                //resets IC
                    if(i2c_bus1.write(FXAS21002_I2C_ADDRESS_, d,2) ==1){
                        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
                    break;
                }// end case 10  

                case 11: {//  set sensor to active to read gyro measurments
                    char d[2];
                    d[0] = FXAS21002_CTRL_REG1;                       //CTRL_REG1=0x13
                    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 11

                case 12: {// put in standby
                    /*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 
                    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
                    // unknown config
                    break;
                } 
    }// end switch    
}// end gyro_sensor_config

/*****************************************************************************
Name: press_config()
Purpose: Used to set pressure sensor's internal registers for power modes
Inputs: int value from 0 to 256
Returns: None
******************************************************************************/

void press_config(uint8_t Num){
// use case switches here to configure
switch(Num) {                     
                case 0: {// put in standby (AKA powered down) mode
                    //For lowest power ~2.8uA in standby mode, sensor should default to this after reset 
                    char d[2];
                    d[0] = 0x26;                                      //CTRL_REG1=0x26
                    d[1] = 0x00;                                      //Puts device in powered down mode
                    if(i2c_bus1.write(0xC0, d,2) ==1){                 // 0xc0 is MPL3115A2 address
                        oled.Label((uint8_t *)"press_err0a",20,30);     // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                    break;    
                }// end of case 0  
                 
                default: {
                    oled.Label((uint8_t *)"PRESS_Mode?",20,45); // Display "mode" at x,y
                    // unknown config
                    break;
                } 
    }// end switch    
}// end press_config

/*****************************************************************************
Name: MAX30101_test_config()
Purpose: Used to test operation of the MAX30101 heart-rate sensor
Inputs: int value from 0 to 256
Returns: None
******************************************************************************/
void MAX30101_test_config(uint8_t Num){
// use case switches here to configure
switch(Num) {                     
                case 0: {// test 
                    char d[2] = {0xfe, 0x07};
                    if(i2c_bus0.read(0xae, d, 2) == 1){ // read RevID value 0-255
                        sprintf(text_1,"M_R_Er %i %i",d[0],d[1]);
                        oled.Label((uint8_t *)text_1,5,16); // Display error at x,y 
                    }//end if
                    else{
                        sprintf(text_1,"M_R_data %i %i",d[0],d[1]);
                        oled.Label((uint8_t *)text_1,5,16); // Display good data at x,y
                        }
                    wait(1);  // wait 1 seconds
                    d[0] = 0x09;  //  Mod_conf reg - SHDN, reset, modes
                    d[1] = 0b00000111;   //  set mode to red, green and/or IR LEDs
                    if(i2c_bus0.write(0xaf, d, 1) ==1){; // "true" is needed to prevent stop, MAX30101 address is 0xae but left shifted
                        oled.Label((uint8_t *)"MAX_W_err0a",5,30);     // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                    wait(5); // wait 5 seconds
                    
                    /*
                    d[0] = 0xfe;                                      //lets try to read revID value 0-255
                    d[1] = 0x00;                                      //Puts device in powered down mode
                    if(i2c_bus0.write(0xae<<1, d,2) ==1){             // MAX30101 address is 0xae but left shifted
                        oled.Label((uint8_t *)"Max_err0a",20,30); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                    */
                    break;    
                }// end of case 0  
               
               
                case 10: {// reset
                    char d[2];    
                    d[0] = 0x09;                      // Mod_conf reg - SHDN, reset, modes
                    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
                    }
                    wait(0.01);  // wait 0.01 seconds
                    break;    
                }// end of case 10  
                
                default: {
                    oled.Label((uint8_t *)"MAX_Mode?",20,45); // Display "mode" at x,y
                    // unknown config
                    break;
                } 
    }// end switch    
}// end light_config

/*****************************************************************************
Name: light_config()
Purpose: Used to set ambient light sensor's internal registers for power modes
Inputs: int value from 0 to 256
Returns: None
******************************************************************************/
/*
void light_config(uint8_t Num){
// use case switches here to configure
switch(Num) {                     
                case 0: {// put in standby (AKA powered down) mode
                    //For lowest power ~2.8uA in standby mode, sensor should default to this after reset 
                    char d[2];
                    d[0] = TSL2561_CONTROL;                                      //CTRL_REG0=0x00
                    d[1] = 0x00;                                      //Puts device in powered down mode
                    if(i2c_bus0.write(TSL2561_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"light_err0a",20,30); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                    break;    
                }// end of case 0  
                
                case 1: {// put in active
                    char d[2];
                    d[0] = TSL2561_CONTROL;                                      //CTRL_REG=0x00
                    d[1] = 0x03;                                      //Puts device in powered up mode
                    if(i2c_bus0.write(TSL2561_I2C_ADDRESS_, d,2) ==1){
                        oled.Label((uint8_t *)"light_err0a",20,30); // Display "error" at x,y 
                        wait(3.0); // display for 3 seconds
                    }//end if 
                    break;    
                }// end of case 1  
                
                default: {
                    oled.Label((uint8_t *)"LGHT_Mode?",20,45); // Display "mode" at x,y
                    // unknown config
                    break;
                } 
    }// end switch    
}// end light_config
*/

/*****************************************************************************
Name: update_display_date
Purpose: Updating display data without updating any data labels.  This keeps
measurements and time values current while reducing screen flicker.
******************************************************************************/
void update_display_date(void)
{
    oled_text_properties_t textProperties = {0};  // Need these to change font color
    oled.GetTextProperties(&textProperties);      // Need these to change font color
    __disable_irq();    // Disable all Interrupts
    
        switch(Screen_Num) {
    case 0: {// Main Screen
            HexiwearBattery battery;
            battery.sensorOn();  
            if (battery.isBatteryCharging()) {
            textProperties.fontColor = COLOR_GREEN;
            oled.SetTextProperties(&textProperties);  
                     
            sprintf(text_1, "%i%%+", (uint8_t)battery.readLevelPercent());
  //          Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED while fully charged
            } else {
            sprintf(text_1, "%i%%", (uint8_t)battery.readLevelPercent());
            }
            oled.TextBox((uint8_t *)text_1,60,0,35,15); //show level value of battery in a 35px by 15px text box at x=60, y=0

            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);  
           
// added real time and date information            
            char buffer[32];
            time_t seconds = time(NULL);
            strftime(buffer,32, "%a,%d %m %Y.%H:%M:%S\r", localtime(&seconds));
//        sprintf(text_1,"%c%c/%c%c/%c%c%c%c ",buffer[7],buffer[8],buffer[4],buffer[5],buffer[10],buffer[11],buffer[12],buffer[13]);
//        oled.Label((uint8_t *)text_1,20,20);// Date at x,y
            sprintf(text_1,"%c%c:%c%c:%c%c ",buffer[15],buffer[16],buffer[18],buffer[19],buffer[21],buffer[22]);

    
            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 *)text_1,25,40);// Time 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);
            
            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
                     
            case 21: {// Fall Alert Diagnostic Screen
            if(Fall_Alert_Mode == 0){
                fall_config(11); // turn accel sensor to active mode to take a reading, may take 80mS to 300mS
            }
            textProperties.fontColor = COLOR_WHITE;
            oled.SetTextProperties(&textProperties);
            gyro.acquire_gyro_data_dps(Gyro_Data);
            Gyro_Mag = (abs(Gyro_Data[0])+abs(Gyro_Data[1])+abs(Gyro_Data[2]));
            sprintf(text_1," %4.0f D/S  ",Gyro_Mag);
            oled.Label((uint8_t *)text_1,37,60);// text_1 at x,y
            
            accel.acquire_accel_data_g(Accel_Data);
            if(Fall_Alert_Mode == 0){
                fall_config(12); // turn accel sensor back to standby
            }
            Accel_Mag = 2*sqrt(((Accel_Data[0]*Accel_Data[0])+(Accel_Data[1]*Accel_Data[1])+(Accel_Data[2]*Accel_Data[2])));
            sprintf(text_1," %2.2f g  ",Accel_Mag);
            oled.Label((uint8_t *)text_1,39,40);// text_1 at x,y
            if(Accel_Mag > Fall_Thresh + 0.05f && Led_clk2 == 1){// are we stuck in limbo?
            fall_det_end(); 
            }
            break;
        }//end case 21       
            
            default: {
                    // do nothing for other screens
             break;
                } 
    }// end switch   
    __enable_irq();     // Enable all Interrupts 
}// end of update_display_date


/*****************************************************************************
Name: BLUETOOTH
Purpose: HexiHeart Connecction
Inputs: None
Returns: None
******************************************************************************/


void txTask(void)
{

    while (true) {
        /*Notify Hexiwear App that it is running Sensor Tag mode*/
 /*    This part was not compiling   
      kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG);
 */     
    }
}