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
Revision 13:37cd579208e9, committed 2018-04-09
- Comitter:
- nbaker
- Date:
- Mon Apr 09 13:31:46 2018 +0000
- Parent:
- 12:fd39a7983e06
- Child:
- 14:c3b080cdf36b
- Commit message:
- v2.12 - Added hidden reset feature (push L-button 9+ times to reset), added line that might put K64 into low pow run mode, added dimming feature, changed humid/temp & battery measurement to a rolling average. Made new screen for panic alert.
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Thu Mar 29 16:55:40 2018 +0000 +++ b/main.cpp Mon Apr 09 13:31:46 2018 +0000 @@ -20,14 +20,18 @@ Display data screen update routines ************** Versions **************** -v2.11 - Added Send_Alert(0) to turn off alerts by sending amb_light=0, +v2.12 - Added hidden reset feature (push left button 9+ times, on screen zero, to reset), added line that +might put K64 into low power run mode, added dimming feature to display, changed humid/temp and battery +measurement to a rolling average. Made new screen for sending panic alert. + +v2.11 - 4/1/18 - Added Send_Alert(0) to turn off alerts by sending amb_light=0, added WDT and added WDT testing screens, changed fall Min_Movement_duration from 60s to 10s, added subtle vibration after impact for diagnostic purposes. v2.10 - Adding BLE pairing code, spoofing amb light sensor data for alert status light=10 =>Panic Alert, 20=Fall+asked for help, 30=Fall+No response, 40=?... -v2.09 - Added final fall mode (full sequential fall algorithm), including alert screen +v2.09 - 3/25/18 - 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. @@ -63,11 +67,11 @@ //*************** Definitions -#define SW_Ver 2.11 // For displaying software version +#define SW_Ver 2.12 // For displaying software version #define LED_ON 0 #define LED_OFF 1 #define SCRN_TIME 10.0 // Set OLED screen turn off time to 10.0 seconds -#define WDT_TIME 1.5 // Set Watch Dog timer to 1.5 seconds (1.0s reset in certain subroutines) +#define WDT_TIME 2.0 // Set Watch Dog timer to 1.5 seconds (1.5s reset in certain subroutines) #define Debug 1 // If "Debug" is defined, our code will compile for debug. Comment out for Production code. #define HIGHEST_ZONE 4 // Highest heart rate zone #define LOWEST_ZONE 1 @@ -81,6 +85,7 @@ //#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); @@ -88,6 +93,7 @@ void error_screen(void); // display error screen void update_display(void);// Screen lables refreshed void update_display_date(void); // Screen data(only)refreshed +void Screen_timer1(void); void Decrement_Age(); void Set_Max_Bpm(); void Set_Zone_Boundaries(); @@ -121,10 +127,14 @@ 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 chk_help_needed(void); // Routine used with Ticker void txTask(void); +void PassKey(void); void MAX30101_test_config(uint8_t); -void Send_Alert(uint8_t); // fuction to store and send alert +void Send_Alert(uint8_t); // function to store and send alert +void WDT_Timeout(void); // WDT Routine used reset +void CLRWDT(void); // function to clear WDT +void UpDate_Ave(void); // function used to update slow changing measurments // ***************** Global variables *********************** char text_1[20]; // Text buffer - Do we need more? @@ -152,6 +162,7 @@ float Min_Movement_Time=5.0; // Initialize Movement minimum movement time to 5 sec float Min_Movement_duration=10.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 Reset_Count = 0; uint8_t Current_Zone = 1; uint8_t Prev_Zone = 1; uint8_t Heart_Rate = 100; @@ -167,11 +178,14 @@ 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 +// slow changing variables +int sample_ftemp = 0; // used in Heat index calc +int sample_humid = 0; // used in Heat index calc +uint8_t batt_per_level = 0; // +uint8_t Ave_Num = 0; // Pointers for screen images const uint8_t *Hexi_Heart_ = Hexi_Heart_bmp; @@ -238,26 +252,43 @@ //***************** 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 +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; Ticker WDT_Timer; - /***************************************************************************** Name: timout_timer() -Purpose: Used to turn the OLED screen off after 10s to save power -Inputs: None -Returns: None +Purpose: Ticker interupt routine used to dim the OLED screen 3s before turning screen off +Inputs: Screen_Timer Ticker ******************************************************************************/ void timout_timer(){ // turn off display mode + HexiwearBattery battery; + battery.sensorOn(); + if (battery.isBatteryCharging() || batt_per_level > 99) { + oled.DimScreenOFF(); + Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED while fully charged + } //end if + else { + Screen_Timer.attach(&Screen_timer1,(3));// Dim display for 3 seconds befor turning off display + oled.DimScreenON(); //Dim display if 3 seconds from turning off + }//end else +}// end Screen_timer1() + +/***************************************************************************** +Name: Screen_timer1(() +Purpose: Ticker interupt routine used to turn off the OLED screen after ~13s to save power +Inputs: Screen_Timer Ticker +******************************************************************************/ +void Screen_timer1(){ // 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) { + if (battery.isBatteryCharging() || batt_per_level > 99) { Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED while fully charged + oled.DimScreenOFF(); } //end if else { #endif @@ -271,62 +302,6 @@ #endif }//end timout_timer routine -/***************************************************************************** -Name: WDT_Timeout() -Purpose: Interrupt routine used by Watch Dog timer Ticker. -Note that there are a few ways to implement a WDT. The best would be an external -circuit that resets the K46 if it became unresponsive. The next best would be using -the internal WDT that is built into microprocessor. And lastly there is this -method, using a Ticker/timer. -Inputs: None -Returns: None -******************************************************************************/ -void WDT_Timeout(){ // turn off display mode - 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 - } - oled_text_properties_t textProperties = {0}; // Need these to change font color - oled.GetTextProperties(&textProperties); // Need these to change font color - oled.FillScreen(COLOR_BLACK); // Clear screen - 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 *)"WatchDog",10,30); // Display "Back" at x,y - oled.Label((uint8_t *)" Reset!",20,55); // Display "Back" at x,y - wait(0.1);// display for 100ms - - NVIC_SystemReset(); // software reset -}//end WDT_Timeout routine - - -/***************************************************************************** -Name: CLRWDT() -Purpose: Routine to clear/reset Watch Dog timer Ticker -Inputs: None -Returns: None -******************************************************************************/ -void CLRWDT(){ // turn off display mode - WDT_Timer.attach(&WDT_Timeout,(WDT_TIME));//re-attach/reset WDT -}//end WDT_Timeout routine - - -/***************************************************************************** -Name: PassKey() -Purpose: Interrupt routine called when MK46 recieves Passkey from KW40 -Inputs: None -Returns: None -******************************************************************************/ -void PassKey(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 - } - Screen_Num = 72; //Change to screen BLE screen 72 - StartHaptic(); - update_display(); -}// PassKey /***************************************************************************** Name: ButtonUp() @@ -337,6 +312,7 @@ void ButtonUp(void) { Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED? + oled.DimScreenOFF(); if (OLED_ON == 0) { OLED_ON = 1; // Scree was off, set to On update_display(); @@ -382,13 +358,9 @@ } case 6: {// Panic Alert StartHaptic(); - Panic_Alert = !Panic_Alert; - if(Panic_Alert == 1){ + Screen_Num = 51; + Panic_Alert = 1; Send_Alert(10); // send/store alert type zero - }//endif - else{ - Send_Alert(0); - } update_display(); break; } @@ -588,6 +560,7 @@ void ButtonDown(void) { Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED? + oled.DimScreenOFF(); if (OLED_ON == 0) { OLED_ON = 1; // Screen was off, set to On update_display(); @@ -834,7 +807,9 @@ ******************************************************************************/ void ButtonRight(void) { + Reset_Count = 0; Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED? + oled.DimScreenOFF(); if (OLED_ON == 0) { OLED_ON = 1; // Screen was off, set to On update_display(); @@ -1027,13 +1002,31 @@ void ButtonLeft(void) { Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED? + oled.DimScreenOFF(); 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 + Reset_Count++; + if(Reset_Count >= 8){ + __disable_irq(); // Disable all Interrupts + oled_text_properties_t textProperties = {0}; // Need these to change font color + oled.GetTextProperties(&textProperties); // Need these to change font color + textProperties.font = OpenSans_12x18_Regular; // Max Width of Character = 12px, Max Height of Character = 18px + textProperties.fontColor = COLOR_WHITE; + oled.SetTextProperties(&textProperties); + wait_ms(100); + oled.FillScreen(COLOR_BLACK); // Clear screen + wait_ms(100); + oled.Label((uint8_t *)"Hidden",20,20); // Display "Back" at x,y + oled.Label((uint8_t *)" Reset ",20,40); // Display "Back" at x,y + oled.Label((uint8_t *)"Feature",20,60); // Display "Back" at x,y + wait_ms(500);// display for 100ms + NVIC_SystemReset(); // software reset + wait(3.0);// should never get here + }//end if break; } case 1: {// Panic Alert option @@ -1234,7 +1227,14 @@ update_display(); break; } - + case 51: {// Sending Panic Alert + StartHaptic(); + Screen_Num = 6; //Change to screen 6 + Panic_Alert = 0; + Send_Alert(0); // send/store alert type zero + update_display(); + break; + } case 71: {// BLE StartHaptic(); Screen_Num = 0; //Change to screen 0 @@ -1266,6 +1266,7 @@ 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? + oled.DimScreenOFF(); if (OLED_ON == 0) { OLED_ON = 1; // Screen was off, set to On } @@ -1277,11 +1278,16 @@ 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 +//__STATIC_INLINE void __set_PMCTRL(0b01000000);// set K64 SMC_PMCTRL register to VLPR (Very low power run) mode + // SMC->PMCTRL = (uint8_t)((SYSTEM_SMC_PMCTRL_VALUE) & (SMC_PMCTRL_RUNM_MASK)); // Enable VLPR mode + SMC->PMCTRL = (0b01000000);// set K64 SMC_PMCTRL register to VLPR (Very low power run) mode + +//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 9:59:31 + set_time((2018-1970)*365.25f*24*3600 + (31+28+31+18-1)*24*3600 + (10)*3600 + (0)*60+ (0) + 29); // Set RTC time to 4/18/2018 9:59:31 RED_Led = LED_OFF; GRN_Led = LED_OFF; BLU_Led = LED_OFF; @@ -1388,8 +1394,9 @@ wait(2); // wait 3 seconds // txThread.start(txTask); /*Start transmitting Sensor Tag Data */ - + oled.DimScreenOFF(); update_display(); // Displays current screen (screen 0) + UpDate_Ave(); // Update slow changing measurements once every 30 seconds Screen_Timer.attach(&timout_timer,(SCRN_TIME)); //start ticker timer for turning off LCD WDT_Timer.attach(&WDT_Timeout,(WDT_TIME)); //attach/start WDT // ******************* Main Loop ************************* @@ -1399,6 +1406,9 @@ { Thread::wait(500); // wait 0.5 sec each loop CLRWDT(); + // SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + // __WFI(); + // deepsleep(); if(OLED_PWR==1){ update_display_date(); // refresh display date w/o updating entire display }// end if @@ -1408,11 +1418,14 @@ 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 +// NVIC_VLPW(0.01); // BLIP led 1/10 sec each loop +// NVIC_SystemReset(); // software reset 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 + CLRWDT(); + UpDate_Ave(); // Update slow changing measurements once every 30 seconds } // end of while(true) } @@ -1434,10 +1447,11 @@ textProperties.fontColor = COLOR_GREEN; oled.SetTextProperties(&textProperties); // sprintf(text_1, "%s", "chrg"); - sprintf(text_1, "%i%%+", (uint8_t)battery.readLevelPercent()); + sprintf(text_1, "%i%%+", batt_per_level); Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED while fully charged + oled.DimScreenOFF(); } else { - sprintf(text_1, "%i%%", (uint8_t)battery.readLevelPercent()); + sprintf(text_1, "%i%%", batt_per_level); } 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 @@ -1473,7 +1487,7 @@ textProperties.fontColor = COLOR_RED; // is impact detected? } oled.SetTextProperties(&textProperties); - oled.Label((uint8_t *)"FAP",1,0); //Display "FAP" at x,y + oled.Label((uint8_t *)"FAP",3,0); //Display "FAP" at x,y textProperties.fontColor = COLOR_WHITE; oled.SetTextProperties(&textProperties); @@ -1498,7 +1512,7 @@ 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); + strcpy((char *) text,"F");oled.Label((uint8_t *)text,22,80); // was "dF" at 18,80 if(Heart_Rate_Mode == 1) { oled.Label((uint8_t *)"BPM",35,60); // Display "H.I." at x,y @@ -1577,11 +1591,7 @@ 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 *)"Send ",20,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 @@ -2089,6 +2099,7 @@ oled.Label((uint8_t *)display_buff, 71, 60); textProperties.fontColor = COLOR_WHITE; //Change font to white oled.SetTextProperties(&textProperties);//Implement color change + CLRWDT(); Led_Zone_Indicator(); break; } @@ -2308,6 +2319,24 @@ wait(WDT_TIME+1.0); break; }//end case 50 + + case 51: { //Sending panic alert screen + oled.FillScreen(COLOR_BLACK); + textProperties.fontColor = COLOR_RED; + oled.SetTextProperties(&textProperties); + oled.Label((uint8_t *)"Panic Alert!", 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 51 #endif // end of non-production/debug version code @@ -2735,9 +2764,9 @@ Returns: None ******************************************************************************/ void Heat_Index_Calculation(){ - sample_ftemp = temphumid.sample_ftemp(); + //sample_ftemp = temphumid.sample_ftemp(); - sample_humid = temphumid.sample_humid(); + //sample_humid = temphumid.sample_humid(); hi_calc = -42.379 + 2.04901523 * sample_ftemp + @@ -2777,7 +2806,7 @@ 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 - + oled.DimScreenOFF(); if (OLED_ON == 0) { OLED_ON = 1; // Scree was off, set to On update_display(); @@ -2831,6 +2860,7 @@ Led_clk2 = 1; // Turn LED2 on docking station on Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED + oled.DimScreenOFF(); if (OLED_ON == 0) { OLED_ON = 1; // Screen was off, set to On update_display(); @@ -2865,6 +2895,7 @@ Led_clk3 = 1; // Turn on LED3, on docking station Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED + oled.DimScreenOFF(); if (OLED_ON == 0) { OLED_ON = 1; // Screen was off, set to On update_display(); @@ -3042,6 +3073,7 @@ if (OLED_ON == 0) { OLED_ON = 1; // Screen was off, set to On } // endif + oled.DimScreenOFF(); update_display(); // chk_motion.attach(&chk_help_needed,(Do_You_Need_Help_Time)); //initialize ticker to send automatic alert CLRWDT(); @@ -3075,6 +3107,7 @@ if (OLED_ON == 0) { OLED_ON = 1; // Screen was off, set to On } // endif + oled.DimScreenOFF(); update_display(); oled_text_properties_t textProperties = {0}; oled.GetTextProperties(&textProperties); @@ -4029,10 +4062,10 @@ textProperties.fontColor = COLOR_GREEN; oled.SetTextProperties(&textProperties); - sprintf(text_1, "%i%%+", (uint8_t)battery.readLevelPercent()); + sprintf(text_1, "%i%%+", batt_per_level); // 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()); + sprintf(text_1, "%i%%", batt_per_level); } 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 @@ -4071,7 +4104,7 @@ textProperties.fontColor = COLOR_RED; // is impact detected? } oled.SetTextProperties(&textProperties); - oled.Label((uint8_t *)"FAP",1,0); //Display "FAP" at x,y + oled.Label((uint8_t *)"FAP",3,0); //Display "FAP" at x,y textProperties.fontColor = COLOR_WHITE; oled.SetTextProperties(&textProperties); @@ -4163,4 +4196,94 @@ */ Thread::wait(1000); }// end while -}// end TxTask \ No newline at end of file +}// end TxTask + + +/***************************************************************************** +Name: WDT_Timeout() +Purpose: Interrupt routine used by Watch Dog timer Ticker. +Note that there are a few ways to implement a WDT. The best would be an external +circuit that resets the K46 if it became unresponsive. The next best would be using +the internal WDT that is built into microprocessor. And lastly there is this +method, using a Ticker/timer. +Inputs: None +Returns: None +******************************************************************************/ +void WDT_Timeout(){ // turn off display mode + 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 + } + oled.DimScreenOFF(); + __disable_irq(); // Disable all Interrupts + oled_text_properties_t textProperties = {0}; // Need these to change font color + oled.GetTextProperties(&textProperties); // Need these to change font color + oled.FillScreen(COLOR_BLACK); // Clear screen + 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 *)"WatchDog",10,30); // Display "Back" at x,y + oled.Label((uint8_t *)" Reset!",20,55); // Display "Back" at x,y + wait(0.1);// display for 100ms + + NVIC_SystemReset(); // software reset +}//end WDT_Timeout routine + + +/***************************************************************************** +Name: CLRWDT() +Purpose: Routine to clear/reset Watch Dog timer Ticker +Inputs: None +Returns: None +******************************************************************************/ +void CLRWDT(){ // turn off display mode + WDT_Timer.attach(&WDT_Timeout,(WDT_TIME));//re-attach/reset WDT +}//end WDT_Timeout routine + + +/***************************************************************************** +Name: PassKey() +Purpose: Interrupt routine called when MK46 recieves Passkey from KW40 +Inputs: None +Returns: None +******************************************************************************/ +void PassKey(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 + } + oled.DimScreenOFF(); + Screen_Num = 72; //Change to screen BLE screen 72 + StartHaptic(); + update_display(); +}// PassKey + +/***************************************************************************** +Name: UpDate_Ave() +Purpose: Routine called to update rolling average of slow changing sensor readings +Inputs: Temp/humid sensor readings and battery measurement +Returns: updated global variables +******************************************************************************/ +void UpDate_Ave(void)// +{ + //int i = 4; // used in rolling average + HexiwearBattery battery; + battery.sensorOn(); + if(Ave_Num == 0){ + // this is first measurement since reboot + batt_per_level = (uint8_t)battery.readLevelPercent(); + sample_ftemp = temphumid.sample_ftemp(); + sample_humid = temphumid.sample_humid(); + }//end if + else{ + // updated measurments on a rolling average basis: 1/4 new measurement to 3/4 running average + batt_per_level = (Ave_Num-1)*batt_per_level/Ave_Num + (uint8_t)battery.readLevelPercent()/Ave_Num; + sample_ftemp = (Ave_Num-1)*sample_ftemp/Ave_Num + temphumid.sample_ftemp()/Ave_Num; + sample_humid = (Ave_Num-1)*sample_humid/Ave_Num + temphumid.sample_humid()/Ave_Num; + }//end else + Ave_Num++; + if(Ave_Num>4){ + Ave_Num = 4;//set limit + } + }// end UpDate_Ave \ No newline at end of file