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

Dependencies:   FXAS21002 FXOS8700 Hexi_KW40Z Hexi_OLED_SSD1351 MAXIM W25Q64FVSSIG HTU21D MPL3115A2 TSL2561

Fork of HexiHeart_Alex by Hexiwear_zeta

Files at this revision

API Documentation at this revision

Comitter:
nbaker
Date:
Wed Feb 14 22:53:49 2018 +0000
Parent:
6:84e3ba00b995
Child:
8:a5c77b45008d
Commit message:
This version has both the free-fall interrupt (set to 0.5g) and the impact interrupt (set to about 2g) working independently (either one can occur at any time). Also, time and date disp now work but are not adj (defaults to 2/19/18 at 10am).

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- 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