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

Revision:
7:3d5a8aea0b63
Parent:
6:84e3ba00b995
Child:
8:a5c77b45008d
--- a/main.cpp	Tue Feb 13 15:42:22 2018 +0000
+++ b/main.cpp	Wed Feb 14 22:53:49 2018 +0000
@@ -84,6 +84,7 @@
 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 Gyro_Mag=0.0;         // Vector magnitude calculated from sensor data
 float Gyro_Data[3];         // Gyro data from sensor
 float Fall_Thresh=0.5;      // Initialize Fall detect Threshold
@@ -712,6 +713,8 @@
 
 int main()
 {
+//   set_time(1256729737);  // Set RTC time to Wed, 28 Oct 2009 11:35:37
+   set_time(48*365*24*3600+61*24*3600+10*3600);  // Set RTC time to Mon, 19 Feb 2018 10:00
     OLED_PWR = 1;  // Turn on OLED power supply
     
     
@@ -722,9 +725,9 @@
  
 // **************  configure sensor modules  ******************
     //    accel.accel_config();   // configure sensor
-    fall_config(1);         // configure sensor for fall detect
-    // Fall_config(Fall_Alert_Mode); // configure sensor for fall mode
-    mag.mag_config();
+ //   fall_config(1);         // configure sensor for fall detect
+     fall_config(3); // configure sensor for fall mode
+//    mag.mag_config();
     gyro.gyro_config();
 
     RED_Led = LED_OFF;
@@ -745,7 +748,7 @@
 
 // ***** attaching interupts to functions *********
    Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
- //  Accel_INT2.fall(&impact_detect); //Accel sensor's int#2 calls interupt routine
+   Accel_INT2.fall(&impact_detect); //Accel sensor's int#2 calls interupt routine
    
 
 // **** Get OLED Class Default Text Properties ****************
@@ -830,9 +833,27 @@
             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;
+            oled.SetTextProperties(&textProperties);
+            oled.Label((uint8_t *)"BT",40,80);  //Display "BT" 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));
+            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]);
+            oled.Label((uint8_t *)text_1,25,40);// Time at x,y
+         
+        
+                          
             Heat_Index_Calculation();
             sprintf(text,"%i",heat_index);
             oled.TextBox((uint8_t *)text,3,80,15,15); 
@@ -857,7 +878,7 @@
             oled.Label((uint8_t *)"Fall Alert",20,5); // Display at x,y
             oled.Label((uint8_t *)"Protection",15,25);  
             if (Fall_Alert == 1){  
-            oled.Label((uint8_t *)" On ",42,40);   
+            oled.Label((uint8_t *)" On ",40,40);   
             }
             else {               
             oled.Label((uint8_t *)" Off ",40,40);   
@@ -879,7 +900,7 @@
         }
         case 4: {// Alert History option
             oled.FillScreen(COLOR_BLACK); // Clear screen
-            oled.Label((uint8_t *)"Alert History",5,5); // Display at x,y
+            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
@@ -974,13 +995,13 @@
             oled.FillScreen(COLOR_BLACK); // Clear screen
             textProperties.fontColor = COLOR_RED;
             oled.SetTextProperties(&textProperties);
-            oled.Label((uint8_t *)"Fall",30,5); // Display at x,y
-            oled.Label((uint8_t *)"Diagnostic",25,5); // Display at x,y
+            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);
             accel.acquire_accel_data_g(Accel_Data);
 //                   gyro.acquire_gyro_data_g(Gyro_Data);
-            Accel_Mag = sqrt(((Accel_Data[0]*Accel_Data[0])+(Accel_Data[1]*Accel_Data[1])+(Accel_Data[2]*Accel_Data[2])));
+            Accel_Mag = 2*sqrt(((Accel_Data[0]*Accel_Data[0])+(Accel_Data[1]*Accel_Data[1])+(Accel_Data[2]*Accel_Data[2])));
             //                  Gyro_Mag = (abs(Gyro_Data[0])+abs(Gyro_Data[1])+abs(Gyro_Data[3]));
             sprintf(text_1," Accel:%2.2f g  ",Accel_Mag);
             oled.Label((uint8_t *)text_1,10,40);// text_1 at x,y
@@ -1764,9 +1785,9 @@
 
 void fall_detect(){// fall detect interupt rutine
 if(Fall_Alert == 1){
- 
+ accel.acquire_accel_data_g(Accel_Data_Event);
 // for now just turn on display and give haptic feedback
-   Screen_Num = 22;  //Change to screen 22 (Fall diag screen)
+   Screen_Num = 21;  //Change to screen 21 (Fall diag screen)
     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  
@@ -1776,6 +1797,10 @@
 //    oled.Label((uint8_t *)" Fall Detected ",05,70); // Display at x,y 
  
     update_display();
+            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,10,5);// text_1 at x,y
+
     BLU_Led = LED_ON;  // LEDs default to on, need to turn off
     Led_clk2 = 1;  // Turn LED2 on docking station on
     haptic = 1;
@@ -1805,9 +1830,23 @@
 ******************************************************************************/
       
 void impact_detect(){
- //       oled.Label((uint8_t *)" Impact Detected ",05,60); // Display at x,y
- //       GRN_Led = LED_ON;  // LEDs default to on, need to turn off
-        Led_clk3 = 1;  // Turn LED2 on docking station on
+ if(Fall_Alert == 1){
+    accel.acquire_accel_data_g(Accel_Data_Event);
+// for now just turn on display and give haptic feedback
+   Screen_Num = 21;  //Change to screen 21 (Fall diag screen)
+    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  
+         }  // endif
+    //        update_display();
+            
+            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,10,20);// text_1 at x,y
+ 
+         Led_clk3 = 1;  // Turn LED2 on docking station on
+ }// end if     
 }//end impact_detect interupt routine
 
 /*****************************************************************************
@@ -1919,7 +1958,145 @@
                     oled.Label((uint8_t *)" Mode 1 ",30,60); // Display "mode" at x,y   
                     GRN_Led = LED_ON;  // LEDs default to on, need to turn on     
                     break;
-                }
+                }// end of case 1
+                
+                 //  case 2 was an attempt at using vector-mag int for free-fall  
+                               
+                 case 3: {// configure FFMT for free-fall event AND config for vector impact
+
+                    StartHaptic();  // for debug
+                    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 *)" Step1 error ",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 *)" Step1a error ",30,05); // Display "error" at x,y      
+                        wait(3.0); // display for 3 seconds
+                    }//end if
+ 
+                    d[0] = 0x0a;                                    //TRIG_CFG (address of 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 *)" Step3 error ",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 *)" Step4 error ",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 *)" Step5 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 *)" Step3 error ",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] = 0b00001111;                                //set impact threshold to less than 1g for now                   
+  //                 d[1] = uint8_t((1000*Impact_Thresh/0.488)/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 *)" Step4a error ",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(256*((1000*Impact_Thresh/0.488)%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 *)" Step4b error ",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 *)" Step5 error ",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
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step6 error ",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 *)" Step7 error ",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] = 0b00000110;                              // FFMT and Vector int enabled
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step8 error ",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) and Vector on INT2(PTD13)
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step9 error ",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 *)" Step10 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if  
+                    
+                    //oled.FillScreen(COLOR_BLACK); // Clear screen
+                    oled.Label((uint8_t *)" Mode 3 ",30,60); // Display "mode" at x,y   
+          //          GRN_Led = LED_ON;  // LEDs default to on, need to turn on  
+ 
+
+                    break;
+                }// end of case 3
+                       
+                case 10: {// reset IC 
+                  char d[2]; 
+                    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 *)" reset ",30,60); // Display "reset" at x,y
+                    break;
+                }// end case 10      
+                
                 default: {
                     oled.Label((uint8_t *)" Mode ? ",30,60); // Display "mode" at x,y
                     // unknown config